user2471103
user2471103

Reputation: 68

MVC controller method not being triggered by jquery in the view

I have the following method in a controller called "ProductController":

public ActionResult LoadProducts(int prodID)
{
    return View();
}

I'm trying to trigger it from a view cshtml page this way:

@section Scripts {
<script type="text/jscript">
    $('#MyProducts').change(function () {
        var selectedID = $(this).val();
        $.get('/Product/LoadProducts/' + selectedID, function (data) {
            window.alert(selectedID);
        });
    });
</script>
}

<div>
    @using (Html.BeginForm("Update", "Product", FormMethod.Post, new
    { enctype = "multipart/form-data" }))
    {
       @Html.DropDownList("MyProducts", 
       (IEnumerable<SelectListItem>)ViewBag.MyProducts as 
           IEnumerable<SelectListItem>, "Select")
    }
</div>

The call to the jquery works when I change the value in the drop down, as I tested it via the popup box, but getting it to trigger the action method in the controller is not working.

Thanks.

Upvotes: 0

Views: 340

Answers (4)

Svet Angelov
Svet Angelov

Reputation: 799

I agree with Collin on that using razor in your javascript marries them and that can be a pain if you try to split the js into its own file. I recently had to go through it.

Edit: This is just to show how to use Url.Action and still be able to separate js into a separate file by the use of data property in the div

What I suggest is doing something like:

@section Scripts {
<script type="text/javascript">
    $('#MyProducts').change(function () {
        var url = $('#mydiv').data('url') + '?prodId=' + selectedID;

        var selectedID = $(this).val();
        $.get(url, function (data) {
            window.alert(selectedID);
        });
    });
</script>
}

<div id="mydiv" data-url="@(Url.Action("ActionName","ConttrolerName"))">
    @using (Html.BeginForm("Update", "Product", FormMethod.Post, new
    { enctype = "multipart/form-data" }))
    {
       @Html.DropDownList("MyProducts", 
       (IEnumerable<SelectListItem>)ViewBag.MyProducts as 
           IEnumerable<SelectListItem>, "Select")
    }
</div>

Upvotes: 0

Transcendent
Transcendent

Reputation: 5755

In your controller, you can use HttpGetArribute to define the route. Without specifying the route, the parameter is considered as optional and it should be called as Product/LoadProducts?prodId=1. Example of HttpGetAttribute:

[HttpGet("[controller]\[action]\{prodId}")]
public ActionResult LoadProducts(int prodID)
{
     return View();
}

Upvotes: 1

Collin Yeadon
Collin Yeadon

Reputation: 41

Suggestion: use script type="text/javascript". I am not an expert on which browsers support "jscript" but after 20 years of development I can assure you all browsers support javascript.

Also, I would discourage you from using the code which Farhad Bagherlo posted. If at all possible you should avoid using razor code inside your script tag because you may want to move this code into separate JS files or later on refactor to use TypeScript. Also, why invoke a method on the server to get an endpoint/url if you already know the path which is needed. seems wasteful. However, you could use the method he outlined to ensure that you are actually giving the correct URL. If his code works then what is the value of "Url"? (also, the client side standard for naming variables is camelCase, so url should be lower.)

If you are debugging your code and set a breakpoint in your controller. then you should be able to get it to break on that line by simply navigating to that route.

If you go to http://localhost:post/Product/LoadProducts/1 does it actually break on that line in Visual Studio?

Edit: @Transcendent is correct and would get my vote, need to understand how routing is defined vs arguments/parameters passed to the action method. Nice call Transcendent!

Upvotes: 1

Farhad Bagherlo
Farhad Bagherlo

Reputation: 6699

set Url by Url.Action

 var Url='@(Url.Action("ActionName","ConttrolerName"))';

and Put the variable name of the sent with the same variable received

SelectedID to ProdID


<script type="text/jscript">
        $('#MyProducts').on("change",function () {
            var Url='@(Url.Action("LoadProducts","Product"))';
            var SelectedProdID = $(this).find("option:selected").val();
            $.get( Url,{prodID:SelectedProdID}, function (data) {
                window.alert(selectedID);
            });
        });
</script>

Upvotes: 1

Related Questions