Danny van der Kraan
Danny van der Kraan

Reputation: 5366

Can't pass selected value DropDownListFor to javascript function

My simpel test Model:

public class MovieModel {

    public string SelectedCategorieID { get; set; }

    public List<CategorieModel> Categories { get; set; }

    public MovieModel() {
        this.SelectedCategorieID = "0";
        this.Categories = new List<CategorieModel>() {new CategorieModel {ID = 1,
            Name = "Drama"},
        new CategorieModel {ID = 2,
            Name = "Scifi"}};
    }
}

public class CategorieModel {
    public int ID { get; set; }
    public string Name { get; set; }
}

My Home controller action Index:

    public ActionResult Index() {

        Models.MovieModel mm = new Models.MovieModel();

        return View(mm);
    }

My strongly typed View:

@model MvcDropDownList.Models.MovieModel
@{
    ViewBag.Title = "Home Page";
}
<script type="text/javascript">
    function categoryChosen(selectedCatID) {
//        debugger;
        var url = "Home/CategoryChosen?SelectedCategorieID=" + selectedCatID;
        $.post(url, function (data) {
            $("#minicart").html(data);
        });
    }
</script>

@using (Html.BeginForm("CategoryChosen", "Home", FormMethod.Get)) {

    <fieldset>
        Movie Type
        @Html.DropDownListFor(m => m.SelectedCategorieID, new SelectList(Model.Categories, "ID", "Name", Model.SelectedCategorieID), "---Select categorie---")
        <p>
            <input type="submit" value="Submit" />
        </p>
    </fieldset>

}
<input type="button" value="Minicart test" onclick="categoryChosen('@Model.SelectedCategorieID');" />
<div id="minicart">
    @Html.Partial("Information")
</div>

Please ignore the first input, because I'm using the second input with 'Minicart test' on it (the HTML.Beginform is there to learn something else later). The mini cart stuff is from another tutorial, I apologize. Don't let it distract you please.

When the button is clicked categoryChosen jQuery is called, which calls the action:

    [AcceptVerbs("POST")]
    public ActionResult CategoryChosen(string SelectedCategorieID) {

        ViewBag.messageString = SelectedCategorieID;

        return PartialView("Information");

    }

The partial view Information looks like this:

@{
    ViewBag.Title = "Information";
}

<h2>Information</h2>
<h2>You selected: @ViewBag.messageString</h2>

My question is why is Model.SelectCategorieID zero (Model.SelectCategorieID = 0) even after I changed the value in the dropdownlist? What am I doing wrong? Thank you very much in advance for answering. If you need any information or anything in unclear, please let me know.

Upvotes: 0

Views: 4573

Answers (2)

mostruash
mostruash

Reputation: 4189

Provide an id for your dropdownlist:

@Html.DropDownListFor(m => m.SelectedCategorieID, new SelectList(Model.Categories, "ID",
  "Name", Model.SelectedCategorieID), new {id = "myDropDownList"})

And your javascript function as follows:

<script type="text/javascript">
  function categoryChosen() {
    var cat = $("#myDropDownList").val();

    var url = "Home/CategoryChosen?SelectedCategorieID=" + cat;
    $.post(url, function (data) {
        $("#minicart").html(data);
    });
  }
</script>

Why your code did not work?

onclick="categoryChosen('@Model.SelectedCategorieID')

is generated as

onclick="categoryChosen('0')

because the value of SelectedCategorieID is 0 when it is generated.

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039358

My question is why is Model.SelectCategorieID zero (Model.SelectCategorieID = 0) even after I changed the value in the dropdownlist?

That's because you have hardcoded that value in your onclick handler:

onclick="categoryChosen('@Model.SelectedCategorieID');"

If you want to do that properly you should read the value from the dropdown list:

onclick="categoryChosen(this);"

and then modify your categoryChosen function:

<script type="text/javascript">
    function categoryChosen(ddl) {
        // debugger;
        var url = 'Home/CategoryChosen';
        $.post(url, { selectedCategorieID: $(ddl).val() }, function (data) {
            $('#minicart').html(data);
        });
    }
</script>

Also I would recommend you using an URL helper to generate the url to invoke instead of hardcoding it in your javascript function. And last but not least, I would recommend you doing this unobtrusively, so that you could put this in a separate javascript file and stop mixing markup and script.

So here's how your code will look like after taking into consideration my remarks:

@model MvcDropDownList.Models.MovieModel
@{
    ViewBag.Title = "Home Page";
}

@using (Html.BeginForm("CategoryChosen", "Home", FormMethod.Get)) 
{
    <fieldset>
        Movie Type
        @Html.DropDownListFor(
            m => m.SelectedCategorieID, 
            new SelectList(Model.Categories, "ID", "Name"), 
            "---Select categorie---",
            new { 
                id = "categoryDdl"
                data_url = Url.Action("CategoryChoosen", "Home") 
            }
        )
        <p>
            <input type="submit" value="Submit" />
        </p>
    </fieldset>

}

<input type="button" value="Minicart test" id="minicart-button" />

<div id="minicart">
    @Html.Partial("Information")
</div>

and then in your separate javascript file unobtrusively subscribe to the click handler of your button and send the AJAX request:

$(function() {
    $('#minicart-button').click(function() {
        // debugger;
        var $categoryDdl = $('#categoryDdl');
        var selectedCategorieID = $categoryDdl.val();
        var url = $categoryDdl.data('url');
        $.post(url, { selectedCategorieID: selectedCategorieID }, function (data) {
            $('#minicart').html(data);
        });
    });
});

Upvotes: 3

Related Questions