Cleaven Cleaven - 21 days ago 5
C# Question

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

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

bcr bcr
Answer

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.