Update partial view from drop down list selection using MVC 5 EF 6

10,118

You could retrieve the data from the server and construct/change the DOM via JQuery, or you could use a partial view that is appropriate for each question type, attaching an event handler to the change event of the drop-down via JQuery.

One approach, loading partial views:

yourNamespace.yourScript.js file (include the file in your main view via the <script> tag with the src attribute):

    (function ($) {     
        if (!window.yourNamespace) {
            window.yourNamespace = {};
        }
        if (!window.yourNamespace.yourPageScript) {
            window.yourNamespace.yourPageScript = function () {
                var populateView = function (dropDown) {
                    if (dropDown && dropDown.length) {
                        var value = dropdown.val();
                        $.ajax({
                            method: "GET",
                            cache: false,
                            url: "some.url/PopulateType",
                            dataType: "HTML"
                            data: { selectedValue: value }
                        })
                        .done(function (response) { // jQuery 1.8 deprecates success() callback
                            var div = $('#partialViewDiv');
                            div.html('');
                            div.html(response);
                        });
                    }
                };

                return {
                    populateView: populateView
                };
            };
        }
    }(jQuery));

Your main view could have something like this:

<script type="text/javascript">
    // put the script section somewhere appropriate in the page
    $(document).ready(function () {
        var dropDown = $('#TypeId'); // assuming the ID of this element is 'TypeId'
        dropDown.change(function () {
            yourNamespace.yourPageScript.populateView(dropDown);
        });
    });
</script>
<div id="partialViewDiv">
@Html.RenderPartial("path to initial partial view", model);
</div>

partial view example (adjust to be proper for any particular dropdown selection):

@model namespaceName.QuestionTypeModel

<div class="form-group>
    @* put controls appropriate to the particular partial views here, such as radio buttons for the multiple choice question type, etc. *@
<div>
<div class="form-group">
    @Html.LabelFor(model => model.TypeID, "TypeID", new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("TypeID", Model.QuestionTypeValues)
        @Html.ValidationMessageFor(model => model.TypeID)
   </div>
</div>

Part of the controller:

    [HttpGet]
    public ActionResult Index()
    {
        var model = new MainViewModel();
        // populate the model with data here for the initial display, including the initial drop-down values, 
        // presumably the same way you do now
        // into model.QuestionTypeValues

        return View(model); // the main view
    }

    [HttpGet]
    public ActionResult PopulateType(int selectedValue) // could use an enum for the selectable values
    {
        var model = new QuestionViewModel();

        string partialViewName = null;
        // populate with data appropriate to the partial views
        switch (selectedValue)
        {
            case 0:
                partialViewName = "partial view name for item 0";
                // populate "model" with the appropriate data
                break;
            case 1:
                partialViewName = "partial view name for item 1";
                 // populate "model" with the appropriate data
                break;
            // and so on...
            default:
                throw new ArgumentException("unknown selected value", "selectedValue");
                break;
        }

        return PartialView(partialViewName, model);
    }

The approach to use jQuery to build the DOM elements instead of using partial views is left as an exercise.

Share:
10,118
Cleaven
Author by

Cleaven

Any help is better than no help.

Updated on June 04, 2022

Comments

  • Cleaven
    Cleaven almost 2 years

    I am working on my third year project and I'm struggling with this one section so badly, I have looked around and found some answers but I really done know how to implement in my code because it always just doesn't work. So I don't know what I'm doing wrong.

    What i would like is for the partial view to change when the drop down selected item has changed.

    This is what was generated in the view for this section.

    <div class="form-group">
        @Html.LabelFor(model => model.TypeID, "TypeID", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("TypeID", String.Empty)
            @Html.ValidationMessageFor(model => model.TypeID)
        </div>
    </div>
    

    Most solutions I have seen use a @html.dropdownlistfor().

    Any help would be appreciated even if you could just point me to the right place.

    image

    The drop down list is filled from the database relationships.

    I have got this to work if i use labels in an "a" tag with an href but they are hard coded onto the page. I want to use the drop down list so that if i update the database it will have the updated list instead of me going to change it in the code, its also more user friendly in my eyes.

    Thanx in advance

  • Cleaven
    Cleaven almost 9 years
    Hi, thank you for the detailed answer, I will mark it as correct cause it looks like you know what you're doing and I assume my implementation of it was wrong, if you have time and would like to help further, it would be appreciated, i will play around with it further and try to get it right. The main problem is that im brand new to jquery, ajax and mvc all together.
  • bcr
    bcr almost 9 years
    I can help further, just try to understand what I've got there and feel free to ask any questions about it that you have.
  • Cleaven
    Cleaven almost 9 years
    Currently just busy with my last two exams, I will ask away when I'm done :)