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

本文关键字:隐藏 下拉列表 选项 输入 文本 | 更新日期: 2023-09-27 18:24:44

我会尽力用我掌握的信息解释我的情况。简而言之,根据文本框中的值,我需要在下拉列表中隐藏选项。

我有一个有建筑限制的文本框。它有一个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是250000美元,那么下拉列表的值不应该大于这个值。如果他们再次将其更改为1000000美元,则下拉列表需要调整为值不大于1000000美元

我现在真的很纠结。这听起来很简单,但我不知道该怎么做。

这就是我目前所拥有的:

 $("[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; }
    }

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

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

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

var MyNamespace = MyNamespace || {};
MyNamespace.AggregateList = [
    100000,
    250000,
    500000,
    ...
];

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

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

其中AggregateListValues将是List<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搜索每个元素之前,这会将字段缩小到只输入元素原生document.getElementsByClassName。)

对于您的事件处理程序:

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