根据文本框中输入的值隐藏下拉列表选项?

时间:2014-09-26 16:31:06

标签: c# jquery asp.net-mvc

我会尽力用我掌握的信息来解释我的情况。缺点是基于文本框中的值,我需要隐藏下拉列表中的选项。

我有一个带有建筑限制的文本框。它有一个ID,然后是一个位置编号,因为同一页面上有多个建筑物:

<div class="col-md-6 col-sm-6">
        <label>Limit</label>
        @Html.TextBoxFor(m => m.Building.Limit, htmlAttributes: new { id = "buildingLimit-" + Model.LocationNum })
    </div>

在下面我有一个下拉列表,其中包含不同的ID,但位置号相同:

<div class="col-md-6 col-sm-6">
        <label>Occurrence</label>
        @Html.DropDownListFor(m => m.Earthquake.Occurrence, new SelectList(Model.Earthquake.AggregateList, "Value", "Text"), htmlAttributes: new { id = "EarthquakeOcc-" + Model.LocationNum })
    </div>

现在,该下拉列表与buildingLimit完全无关。它显示几个可以选择的不同值。我想要做的是,如果buildingLimit说250,000美元,那么下拉列表的值不应大于该值。如果他们再次将其更改为1,000,000美元,则下拉列表需要调整为不超过$ 1,000,000

我现在真的在努力争取这个。这听起来很简单,但我无法弄清楚如何做到这一点。

这是我到目前为止所做的:

 $("[id^='buildingLimit-']").change(function () {
    var location = $(this).attr("id").split("-")[1];
    var buildingLimit = $(this).val();

    var occArray = [];
    $("[id^='EarthquakeOcc-']").each(function (i, selected) {
        occArray[i] = $(selected).val();
        alert(occAccary[i]);
        if (occArray[i] > buildingLimit) {
            $("[id^='EarthquakeOcc'] option[value = occArray[i]").remove();
        }
    });

我知道它有几个问题:它仅在文本框被更改时才有效,它只是删除。不通过.append()添加回来。此外,这些值是硬编码的:

public List<SelectListItem> AggregateList
    {
        get
        {
            if (aggregateList == null)
            {
                aggregateList = new List<SelectListItem>();
                aggregateList.Add(new SelectListItem { Text = "$100,000", Value = "100000" });
                aggregateList.Add(new SelectListItem { Text = "$250,000", Value = "250000" });
                aggregateList.Add(new SelectListItem { Text = "$500,000", Value = "500000" });
                aggregateList.Add(new SelectListItem { Text = "$1,000,000", Value = "1000000" });
                aggregateList.Add(new SelectListItem { Text = "$2,000,000", Value = "2000000" });
                aggregateList.Add(new SelectListItem { Text = "$3,000,000", Value = "3000000" });
                aggregateList.Add(new SelectListItem { Text = "$4,000,000", Value = "4000000" });
                aggregateList.Add(new SelectListItem { Text = "$5,000,000", Value = "5000000" });
                aggregateList.Add(new SelectListItem { Text = "$6,000,000", Value = "6000000" });
                aggregateList.Add(new SelectListItem { Text = "$7,000,000", Value = "7000000" });
                aggregateList.Add(new SelectListItem { Text = "$8,000,000", Value = "8000000" });
                aggregateList.Add(new SelectListItem { Text = "$9,000,000", Value = "8000000" });
                aggregateList.Add(new SelectListItem { Text = "$10,000,000", Value = "10000000" });
                aggregateList.Add(new SelectListItem { Text = "$25,000,000", Value = "25000000" });
            }
            return aggregateList;
        }
        set { aggregateList = value; }
    }

1 个答案:

答案 0 :(得分:1)

首先,您需要一个包含所有可能值的不可变列表。试图删除和重新创建选项,同时也保持正确的顺序,这是一个不必要的痛苦。如果您有可能值的列表,则可以根据文本框条目从该列表中拉出,直到达到定义的阈值,以重新创建整个选项列表。我还建议使用一个名为accounting.js的漂亮小JS库。要实现这一目标并不是一项严格的要求,但它可以使格式化的货币字符串值和实际数值之间来回转换更容易。

基本上,您只需要JS中的值列表:

var MyNamespace = MyNamespace || {};

MyNamespace.AggregateList = [
    100000,
    250000,
    500000,
    ...
];

如果您希望在MVC视图模型中创建此列表并将其传递给视图,则可以使用以下内容:

MyNamespace.AggregateList = @Json.Encode(Model.AggregateListValues);

其中AggregateListValuesList<int>或类似。

接下来,您选择建筑物限制和地震发生字段的方式非常低效。最好将每对字段放在包装器中,以便您可以根据其邻近度选择另一对:

<div class="location">
    <input id="buildingLimit" />
    <select id="EarthquakeOcc"> ... </select>
</div>

有意简化该代码以说明发生了什么;您仍然可以自由使用当前包含这些字段的任何其他HTML。只需确保两者在一个父级中组合在一起。然后:

    $('[id^=buildingLimit]').on('change', function () {
        var parent = $(this).closest('.location');
        var select = $('[id^=EarthquakeOcc]', parent);
    });

此外,对于它的价值,这可以让您释放使用原始ID,而无需手动指定ID,或者可能更好,您可以在字段中添加类,以便您可以根据该类选择它们,而不是以某个字符串开头的id属性,这将是jQuery处理的更便宜的选择器。 (当您按属性选择时,您的选择器实际上是*[attribute=value]。换句话说,jQuery必须选择DOM中的每个元素,然后过滤掉那些没有匹配id值的元素。使用类似的选择器input[attribute=value]会更好,因为在jQuery搜索每个字段之前,将字段缩小到只输入元素。但是,类总是会更快,因为jQuery可以只依赖于本地document.getElementsByClassName。)< / p>

对于您的事件处理程序:

$('[id^=buildingLimit]').on('change', function () {
    var parent = $(this).closest('.location');
    var select = $('[id^=EarthquakeOcc]', parent);

    // if you choose not to use accounting.js, you just need to ensure that the value
    // gets turned into a number, using a combination of something like `replace` with
    // a regex and `parseInt`, etc.
    var limit = accounting.unformat($(this).val());

    var output = [];
    var i = 0;
    while (MyNamespace.AggregateList[i] <= limit) {
        // If you choose not to use accounting.js, you just need to implement your
        // own logic for formatting the number as you want
        output.push('<option value="' + MyNamespace.AggregateList[i] + '">$' + accounting.formatNumber(MyNamespace.AggregateList[i]) + '</option>');
        i++;
    }
    select.html(output.join(''));
});