级联下拉菜单

时间:2010-06-13 12:11:48

标签: javascript jquery html asp.net-mvc drop-down-menu

我正在使用MVC中的级联下拉列表。似乎我无法按需轻松创建下拉列表,而是在将其发送到客户端之前必须添加下拉列表。

这就是我现在正在做的事情:

在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 --")%>

这是这样的:

<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>

这就是页面上的脚本:

<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>

然后我有一个包含此文件的包含文件:

$.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();
                }
            });
        }
    });
}

我现在遇到的问题是我需要隐藏不包含任何选项或仅包含一个选项的下拉列表。在对服务进行调用时以及将页面发送到客户端时(“POSTBACK”),应该检查这一点。

我需要的是:

  • 4下拉列表
  • 首次进入页面时,只有第一个下拉列表可见。
  • 从dropdown1中选择一个选项时,将填充dropdown2,依此类推
  • 如果只有1个选项,则应隐藏下拉列表
  • 如果设置了所有4个下拉菜单且最终用户更改了dropdown1,则应重新下载dropdown2,其余部分将被隐藏
  • 如果用户选择了某些下拉菜单(例如1,2和3)并点击提交并且服务器端不接受该页面(无效),则应将下拉菜单设置为与用户单击提交时完全相同的设置页面返回给用户时按钮。

对此有何建议?

3 个答案:

答案 0 :(得分:3)

我写了一篇关于这个here的博客文章(减去隐藏部分 - 你似乎已经确定了这个部分)。 实际上,如果出现错误,您将需要使用所选值重建下拉列表。

$("#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();

答案 1 :(得分:0)

使用PartialViews还有另一种方法。

如果为每个下拉列表创建局部视图,或者如果可以,则创建一个普通视图,那么您只需在加载时渲染第一个视图。

当你更改下拉列表的选择时,你会做一个ajax回发,它会做两件事之一。

1)它检查下拉列表中是否有选择。如果您执行此操作,则会抓取数据并执行return PartialView("PVName", PVModel);这会将您的局部视图作为完全呈现的html返回。

2)如果没有选择则返回空字符串或null;

然后你的jquery只是用返回的html的内容替换div。在null的情况下,你将用无效的替换dic来有效地删除下拉列表。

所以你的html可能看起来像这样;

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

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

来自ajax调用的回调只是$('.seconddd').html(returnedHTML);

我希望这有意义,并在某种程度上简化您的代码。

答案 2 :(得分:0)

我没有找到任何解决方案,所以我决定尝试这个:http://weblogs.asp.net/rajbk/archive/2010/05/20/cascadingdropdown-jquery-plugin-for-asp-net-mvc.aspx

这里的问题是我需要隐藏未选中的下拉菜单并完成此操作我已更改为:

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();
                            }
                        });
                    }
                }; 

如您所见,我添加的只是

                        if (hideEmpty == true) {

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

这样做的结果是它会工作,直到用户发布一个不正确的表单并将视图返回给客户端。那么即使设置了其他下拉菜单,除了第一个下拉列表之外的所有下拉列表都会被隐藏?

我习惯当MVC设置下拉列表时我必须运行一些函数来检查它是否应该隐藏,但是我该怎么做?