Question

I am new to MVC in general, as well as JQuery and AJAX and I have come across a strange issue.

I have finished my first run-through of building a practice website and the past few days I devoted my time to adding JQuery's and such to make the site more interactive.

Today I finished all my JQuerys and everything works great so I decided to clean it all out of the View and just put them into a script.js file in the Scripts folder of MVC.

Inserted into the View as @Scripts.Render("~/Scripts/Employees.js")

However when I do this anything in regards to AJAX does not work.

Now this only entails two mini-snippets of code that interact with the controller to either Edit or Save a change, but everything else works great! Even the edit and save JQuerys that make menus and other UI changes all work just fine, but the actual $.post to update the change does not work.

Here are the two snippets of code that sit within functions of JQuery that all work just fine.

$.post(
'@Url.Action("customEdit", "Employee")',
{
    'id': newID,
    'name': newName,
    'birth': newDate
},
function (data) { },
"json"
);

and

$.post(
'@Url.Action("customDelete", "Employee")',
{
    'id': newID
},
function (data) { },
"json"
);

and again, if I move the entire script literally back into the View it works just great! So I am confused as to why moving it to a .js suddenly makes only these two little snippets not work.

There is no re-ordering of code, it re-inserts exactly where it was before.

For an overview here is my entire <script>.

 $(function () {
        $("td[colspan=12]").find("p").hide();
        $("td[colspan=12]").addClass("nopadding");

        $("tr").click(function (e) {
            if (!$(e.target).is('button') && !$(e.target).is('input')) {
                var $target = $(this);
                var $detailsTd = $target.find("td[colspan=12]");
                if ($detailsTd.length) {
                    $detailsTd.find("p").slideUp();
                    $detailsTd.addClass("nopadding");
                } else {
                    $detailsTd = $target.next().find("td[colspan=12]");
                    $detailsTd.find("p").slideToggle();
                    $detailsTd.toggleClass("nopadding");
                    $detailsTd.stopPropagation();
                }
            }
        });
    });

    function editFunction(element) {

        $(element).closest("span").hide();
        $(element).closest("td").find("span.item-save-button").show();
        $(element).closest("td").find("span.item-delete-button").hide();


        $(element).closest("td").prev("td").find("span.item-display")
            .hide()
            .next("span.item-field")
            .show();

        $(element).closest("td").prev("td").prev("td").find("span.item-display")
            .hide()
            .next("span.item-field")
            .show();

    }

function saveFunction(element) {
    var one = $(element).closest("td").prev("td").find("span.item-field").find(":input:first").val();
    var two = $(element).closest("td").prev("td").prev("td").find("span.item-field").find(":input:first").val();

    if (one == "" || two == "") {

        if (one == "") {
            alert("invalid name");
        }
        if (two == "") {
            alert("invalid birthday");
        }

    } else {

        $(element).closest("span").hide();
        $(element).closest("td").find("span.item-edit-button").show();
        $(element).closest("td").find("span.item-delete-button").show();

        $(element).closest("td").prev("td").find("span.item-display").html($(element).closest("td").prev("td").find("span.item-field").find(":input:first").val());
        $(element).closest("td").prev("td").find("span.item-display")
            .show()
            .next("span.item-field")
            .hide();

        $(element).closest("td").prev("td").prev("td").find("span.item-display").html($(element).closest("td").prev("td").prev("td").find("span.item-field").find(":input:first").val());
        $(element).closest("td").prev("td").prev("td").find("span.item-display")
            .show()
            .next("span.item-field")
            .hide();

        var newID = $(element).closest("td").find("span.ID").text();
        var newDate = $(element).closest("td").prev("td").find("span.item-display").text();
        var newName = $(element).closest("td").prev("td").prev("td").find("span.item-display").text();

        $.post(
            '@Url.Action("customEdit", "Employee")',
             {
                 'id': newID,
                 'name': newName,
                 'birth': newDate
             },
            function (data) { },
            "json"
        );

    }
}

function deleteStart(element) {
    $(element).closest("table").toggleClass("table-hover");
    $(element).closest("tr").css('background-color', 'red');
}

function deleteStopped(element) {
    $(element).closest("table").toggleClass("table-hover");
    $(element).closest("tr").css('background-color', 'initial');
}

function deleteFunction(element) {
    var newID = $(element).closest("td").find("span.ID").text();
    console.log(newID);
    $('#'+newID).removeClass('fade');
    $('#' + newID).modal('hide');
    $(element).closest("table").toggleClass("table-hover");
    $(element).closest("tr").next("tr").remove();
    $(element).closest("tr").remove();
    $.post(
'@Url.Action("customDelete", "Employee")',
{
    'id': newID
},
function (data) { },
"json"
);
    $(element).closest("tr").css('background-color', 'initial');
}

Sooo yea, EVERYTHING works just as before, even the Save and Edit interactions (row updates, modals, ect..) but the actual $.post does not work (controller isn't even hit in Debug). Yet if I just re-insert all the code back into the View it works.

Any and all help appreciated! :)

Was it helpful?

Solution

When you put your Javascript in a view, Razor rendering engine will resolve the following line to appropriate URL:

'@Url.Action("customDelete", "Employee")'

But .js files do not get rendered by the view engine, so the above line stays the same which is not a URL.

OTHER TIPS

The JS file is not being parsed by the rendering engine, only your views are. So you'll need to save those URL's from Razor as JS variables in the main view.

Place this in your main view:

<script>var action_custom_delete = '@Url.Action("customDelete", "Employee")';</script>
@Scripts.Render("~/Scripts/Employees.js")

Now you can use the variable action_custom_delete in the JS file wherever you need the URL.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top