简体   繁体   English

级联下拉菜单

[英]Cascading dropdowns

I am working with cascading dropdowns in MVC. 我正在使用MVC中的级联下拉菜单。 It appears that I will not be able to easily create dropdowns on demand, instead I will have to add the dropdowns before sending it to the client. 看来我将无法轻松地按需创建下拉菜单,相反,在将其发送到客户端之前,我将不得不添加下拉菜单。

This is how I am doing it right now: 这就是我现在正在做的事情:

In the aspx page 在aspx页面

                <%: Html.DropDownListFor(model => model.ModelViewAd.Category1, Model.ModelViewAd.Category1List, "-- Välj kategori --")%>
            <%: Html.DropDownListFor(model => model.ModelViewAd.Category2, Model.ModelViewAd.Category2List, "-- Välj kategori --")%>
            <%: Html.DropDownListFor(model => model.ModelViewAd.Category3, Model.ModelViewAd.Category3List, "-- Välj kategori --")%>
            <%: Html.DropDownListFor(model => model.ModelViewAd.Category4, Model.ModelViewAd.Category4List, "-- Välj kategori --")%>

This is rendered like this : 这是这样呈现的:

<select id="ModelViewAd_Category1" name="ModelViewAd.Category1">
    <option value="">-- V&#228;lj kategori --</option>    
    <option value="10">Fordon</option>
    <option value="15">F&#246;r hemmet</option>
    <option value="17">Bostad</option>
    </select>
<select id="ModelViewAd_Category2" name="ModelViewAd.Category2">
    <option value="">-- V&#228;lj kategori --</option>
</select>
<select id="ModelViewAd_Category3" name="ModelViewAd.Category3">
    <option value="">-- V&#228;lj kategori --</option>
</select>
<select id="ModelViewAd_Category4" name="ModelViewAd.Category4">
    <option value="">-- V&#228;lj kategori --</option>
</select>

This is what the script on the page looks like: 这是页面上的脚本的样子:

<script type="text/javascript">


            $(function () {
                $("select#ModelViewAd_Category1").change(function () {
                    var id = $(this).val();
                    var urlAction = "/AdCategory/GetCategoriesByParent1/" + id;
                    $.getJSON(urlAction, { id: id }, function (data) {
                        $("#ModelViewAd_Category2").addItems(data.d);
                    });
                });

                $("select#ModelViewAd_Category2").change(function () {
                    var id = $(this).val();
                    var urlAction = "/AdCategory/GetCategoriesByParent1/" + id;
                    $.getJSON(urlAction, { id: id }, function (data) {
                        $("#ModelViewAd_Category3").addItems(data.d);
                    });
                });

                $("select#ModelViewAd_Category3").change(function () {
                    var id = $(this).val();
                    var urlAction = "/AdCategory/GetCategoriesByParent1/" + id;
                    $.getJSON(urlAction, { id: id }, function (data) {
                        $("#ModelViewAd_Category4").addItems(data.d);
                    });
                });



            });


    </script>

And then I have an included file that contains this: 然后,我有一个包含此文件的文件:

$.fn.clearSelect = function () {
    return this.each(function () {
        if (this.tagName == 'SELECT')
            this.options.length = 0;
    });
}

$.fn.addItems = function (data) {
    return this.clearSelect().each(function () {
        if (this.tagName == 'SELECT') {
            var dropdownList = this;
            $.each(data, function (index, optionData) {
                var option = new Option(optionData.Text,
                         optionData.Value);
                if ($.browser.msie) {
                    dropdownList.add(option);
                }
                else {
                    dropdownList.add(option, null);
                }

                if ($(this).children().size() < 2) {
                    $(this).hide();
                }
                else {
                    $(this).show();
                }
            });
        }
    });
}

The problem I now have is that I need to hide the dropdowns that do not contain any options or only contain one option. 我现在遇到的问题是,我需要隐藏不包含任何选项或仅包含一个选项的下拉菜单。 This should be checked when doing a call to the service as well as when the page is sent to the client ("POSTBACK"). 在调用服务以及将页面发送到客户端时(“ POSTBACK”),应进行检查。

What I need is : 我需要的是:

  • 4 Dropdowns 4个下拉菜单
  • Only the first dropdown is visible when first entering the page. 首次进入页面时,只有第一个下拉菜单可见。
  • When selecting an option from dropdown1 the dropdown2 will be populated and so on 从dropdown1中选择一个选项时,将填充dropdown2,依此类推
  • If there is only 1 option then the dropdown should be hidden 如果只有1个选项,则下拉菜单应隐藏
  • If all 4 dropdowns are set and the end-user changes dropdown1, then dropdown2 should be reloaded and the rest be hidden 如果设置了所有四个下拉菜单,并且最终用户更改了dropdown1,则应该重新加载dropdown2,其余的隐藏
  • If the user has selected some of the dropdowns (say 1, 2 and 3) and hit submit and the page is not accepted on the server side (not valid) the dropdowns should be set exactly as when the user clicked the submit button when the page returns to the user. 如果用户选择了某些下拉菜单(例如1、2和3)并点击了提交,并且服务器端不接受该页面(无效),则下拉菜单的设置应与用户单击提交按钮时的完全相同。页面返回给用户。

Any suggestions on this? 有什么建议吗?

I wrote a blog post about this here (minus the hiding part - which you seem to have nailed down). 在这里写了一篇有关此内容的博客文章(减去隐藏部分-您似乎已经将其固定下来了)。 Essentially, you will need to rebuild the dropdown with the selected values if there is an error. 本质上,如果发生错误,您将需要使用选定的值重建下拉列表。

$("#ClientId").change(function () {
    var clientId = "";
    $("#ClientId option:selected").each(function () {
        clientId += $(this)[0].value;
    });
    var url = '<%:Url.Action("ProjectList", "Client") %>' + "/" + clientId;
    $.getJSON(url, null, function (data) {
        var selectedValue = '<%:Model.ProjectId %>';
        $("#ProjectId").empty();
        $.each(data, function (index, optionData) {
            if (optionData.OBJID == parseInt(selectedValue))
                $("#ProjectId").append("<option value='" + optionData.ObjId+ "' selected='true'>" + optionData.Name + "</option>");
            else 
                $("#ProjectId").append("<option value='" + optionData.ObjId + "'>" + optionData.Name + "</option>");
        });
    });
}).change();

There is another way to do this using PartialViews. 使用PartialViews还有另一种方法。

If you create a partial view for each dropdown, or a generic one if you can, then you simply render the first one on load. 如果为每个下拉列表创建局部视图,或者如果可以,则创建一个通用视图,则只需在加载时渲染第一个视图。

When you change the selection of a dropdown you do an ajax postback which does one of two things. 当您更改下拉列表的选择时,您将执行ajax回发,该回发将执行以下两项操作之一。

1) it checks to see if you have a selection in the dropdown. 1)它检查下拉列表中是否有选择。 If you do thet\\n it grabs data and does a return PartialView("PVName", PVModel); 如果这样做,它将获取数据并return PartialView("PVName", PVModel); This will return your partial view as fully rendered html. 这会将您的部分视图返回为完全呈现的html。

2) if there is no selection then return an empty string or null; 2)如果没有选择,则返回一个空字符串或空值;

Your jquery then simply replaces a div with the contents of the returned html. 然后,您的jquery只需将div替换为返回的html的内容。 in the case of null you'd replace the dic with nothing which effectively removes the dropdown. 在null的情况下,您可以将dic替换为没有任何内容,这样可以有效地删除下拉列表。

So you html might look like this; 因此,您的html可能看起来像这样;

<div class="firstdd"><dropdown/></div>

<div class="seconddd"></div>

on callback from the ajax call you simply $('.seconddd').html(returnedHTML); 从ajax调用回调时,您只需$('.seconddd').html(returnedHTML);

i hope this makes sense and simplifies your code somewhat. 我希望这有意义,并且可以简化您的代码。

I did not find any solution on the prevouse solution so I decided to try this : http://weblogs.asp.net/rajbk/archive/2010/05/20/cascadingdropdown-jquery-plugin-for-asp-net-mvc.aspx 我在prevouse解决方案上找不到任何解决方案,因此决定尝试以下方法: http ://weblogs.asp.net/rajbk/archive/2010/05/20/cascadingdropdown-jquery-plugin-for-asp-net-mvc .aspx

The problem here is that I need to hide the dropdowns that are not selected and to acomplish this I have changed to this : 这里的问题是,我需要隐藏未选择的下拉菜单,并完成此操作,因此我已更改为:

post: function () {
                        methods.showLoading();
                        $.isFunction(config.onLoading) && config.onLoading.call($this);
                        $.ajax({
                            url: actionPath,
                            type: 'POST',
                            dataType: 'json',
                            data: ((typeof config.postData == "function") ? config.postData() : config.postData) || 'id=' + $(source).val(),
                            success: function (data) {
                                methods.reset();
                                $.each(data, function () {
                                    $this.append($(optionTag)
                                        .attr("value", this.Value)
                                        .text(this.Text));
                                });

                                if (hideEmpty == true) {

                                    if ($this.children().size() < 2) {
                                        $this.css("visibility", "hidden");
                                    }
                                    else {
                                        $this.css("visibility", "visible");
                                    }
                                }

                                methods.loaded();
                                $.isFunction(config.onLoaded) && config.onLoaded.call($this);
                            },
                            error: function () {
                                methods.showError();
                            }
                        });
                    }
                }; 

As you can see, all I have added is the 如您所见,我添加的只是

                        if (hideEmpty == true) {

                            if ($this.children().size() < 2) {
                                $this.css("visibility", "hidden");
                            }
                            else {
                                $this.css("visibility", "visible");
                            }
                        }

The effect of this is that it will work grate untill the user posts a form that is not correct and the view is returned to the client. 这样做的效果是它将起作用,直到用户发布了不正确的表单并将视图返回给客户端为止。 Then all but the first dropdown is hidden even when the other dropdowns is set? 那么即使设置了其他下拉菜单,除了第一个下拉菜单之外的所有菜单都将被隐藏?

I supose I will have to run some function when MVC sets the dropdown to check if it should be hidden or not, but how do I do this? 我想当MVC设置下拉菜单以检查是否应该隐藏时,我必须运行一些功能,但是我该怎么做呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM