Jquery禁用Asp.net核心中的选定选项无法正常工作

Posted

技术标签:

【中文标题】Jquery禁用Asp.net核心中的选定选项无法正常工作【英文标题】:Jquery disable selected option in Asp.net core not working properly 【发布时间】:2021-10-17 10:03:46 【问题描述】:

在我的项目中,我有一个带有添加新行的按钮的表格。当我选择一个选项时,在每一行中都有一个选择框,它应该在所有其他选择框(包括新选择框)中被禁用。当我在这里尝试此代码时enter link description here 有用。但是在 Asp.net 核心中它并不完全有效,它只适用于第一个选择框选项。

这是我在 Asp.net Core 中的代码,我对其进行了修改以使其正常工作,但仍未更新和禁用所有选择框选择的选项

为什么相同的代码在 Visual Studio 之外工作,而在 Visual Studio 上却不一样>

      <table id="empData">
        <thead>
            <tr>
                <th>Location</th>
                <th>Role</th>
                <th>Action</th>

            </tr>
        </thead>
        <tbody id="UserLocation">

            <tr>
                <td>
                    <select id="select1" asp-for="@Model.Location" asp- 
                  items="html.GetEnumSelectList<Location>()" class="stockCode form-control" 
                  name="locations">
                    </select>
                </td>
                <td>
                    <select id="select2" asp-for="@Model.roles" asp-items="ViewBag.Rolelist" 
                     class="form-control" name="role">
                    </select>
                </td>
                <td><Button onClick='deleteRow(this)' class="kx-repeatable" /></td>
            </tr>
        </tbody>
    </table>
<button onClick="addNewRow()" id="AddNew">Add New Row</button>

jQuery 代码

$(document).ready(function () 

            addNewRow = function () 

                var newRow = $("#empData tbody tr").first().clone()
                $("#UserLocation").append(newRow);



            

            deleteRow = function (element) 
                $(element).parent().parent().remove();
            
        );


        $(document).ready(function () 

            var masterList = [];

            var selectedList = [];




                Array.prototype.equals = function (array) 

                // if the other array is a falsy value, return

                if (!array)

                    return false;



                // compare lengths - can save a lot of time 

                if (this.length != array.length)

                    return false;



                for (var i = 0, l = this.length; i < l; i++) 

                    // Check if we have nested arrays

                    if (this[i] instanceof Array && array[i] instanceof Array) 

                        // recurse into the nested arrays

                        if (!this[i].equals(array[i]))

                            return false;

                    

                    else if (this[i] != array[i]) 

                        // Warning - two different object instances will never be equal: x:20 != 
                           x:20

                        return false;

                    

                

                return true;

            



            function createMasterList() 

                masterList = [];

                $('#select1\\(1\\)').children('#select1 option').each(function () 

                    masterList.push($(this).val());

                );

                masterList.shift(); //remove blank value

            



            createMasterList(); //used to check if all dropdown values have been selected



            function updateSelectedList() 

                selectedList = [];

                var selectedValue;

                $('#empData #select1').each(function () 

                    selectedValue = $(this).find('#select1 option:selected').val();

                    if (selectedValue != "" && $.inArray(selectedValue, selectedList) == "-1") 

                        selectedList.push(selectedValue);

                    

                );

            



            //disable the dropdown items that have already been selected

            function disableAlreadySelected() 

                $('#select1 > option:selected').each(function () 

                    if ($.inArray(this.value, selectedList) != "-1") 

                        $(this).attr("disabled", "disabled");

                     else 

                        $(this).attr("disabled", "");

                    

                );

            



            //If all values have been selected, don't let the user add more rows

            function hideAddButtonIfDone() 

                masterList.sort();

                selectedList.sort();

                if (masterList.equals(selectedList)) 

                    console.log("lists equal, hiding add button");

                    $('#empData #AddNew').hide();

                

                else 

                    console.log("lists not equal, showing add button");

                    $('#empData #AddNew').show();

                

            



            $('#empData').on('change', '.stockCode', function () 

                setTimeout(function () 

                    updateSelectedList();

                    disableAlreadySelected();

                    hideAddButtonIfDone();

                , 0.1);

            );



            //when a new table row is added, disable the dropdown options that have already been 
            selected

            $('#empData #AddNew').on('click', disableAlreadySelected);



            //when a table row is removed, update all dropdowns (the removed row's dropdown option 
            will be re-enabled
     
            //in remaining dropdowns

            $('#empData').on('DOMNodeRemoved', '.kx-repeatable > tr', function () 

                updateSelectedList();

                disableAlreadySelected();

                hideAddButtonIfDone();

            );



        );

【问题讨论】:

你在fiddle中写的HTML和ASP.NET代码生成的HTML有什么区别?如果你使用那个精确生成的 HTML 并用它创建一个小提琴,代码仍然会失败吗?调试时,哪个具体操作没有达到您的预期? @David 不同之处在于我使用枚举来填充选择选项。在小提琴中,它是一个带有选项的基本 html 选择。如果我在位置的第一个选择框中选择一个选项,则在小提琴中。然后在另一个位置选择框中它将被禁用,因此您无法再次选择它。现在在 asp 代码中,如果我从第一个位置选择框中选择一个选项,它将在其他选择框中被禁用,但是如果我从其他位置选择框中选择一个选项,则该选项不会像第一个中发生的那样被禁用选择框。 @David 用户不能在其他位置选择框中选择相同的选项。它一定是不同的。 如果您不熟悉如何在浏览器中调试代码,那么现在是开始熟悉它的好时机。在浏览器的调试工具中,您可以观察由服务器端代码生成的实际结果 HTML,并查看它与您在手写示例 HTML 中所期望的有何不同。您还可以使用浏览器的脚本调试器在 javascript 代码中放置断点,并在执行时逐行逐行执行,观察每个单独操作的结果。当你这样做时,你的目标是找到第一个以某种方式失败的操作。 【参考方案1】:

我认为这是因为 id 不是唯一的,当添加新行时,它会创建具有相同 id 的选择,因此 id 无法找到和正确使用元素。这是一个工作演示:

<table id="empData">
        <thead>
            <tr>
                <th>Location</th>
                <th>Role</th>
                <th>Action</th>

            </tr>
        </thead>
        <tbody id="UserLocation">

            <tr>
                <td>
                    <select asp-for="@Model.Location" asp- 
                  items="Html.GetEnumSelectList<Location>()" class="stockCode form-control" 
                  name="locations">
                    </select>
                </td>
                <td>
                    <select asp-for="@Model.roles" asp-items="ViewBag.Rolelist" 
                     class="form-control" name="role">
                    </select>
                </td>
                <td><Button onClick='deleteRow(this)' class="kx-repeatable" /></td>
            </tr>
        </tbody>
    </table>
<button onClick="addNewRow()" id="AddNew">Add New Row</button>

js:

$(document).ready(function () 
            addNewRow = function () 

                var newRow = $("#empData tbody tr").first().clone()
                $("#UserLocation").append(newRow);
                disableAlreadySelected();


            

            deleteRow = function (element) 
                $(element).parent().parent().remove();
            

            var masterList = [];

            var selectedList = [];




            Array.prototype.equals = function (array) 

                // if the other array is a falsy value, return

                if (!array)

                    return false;



                // compare lengths - can save a lot of time 

                if (this.length != array.length)

                    return false;



                for (var i = 0, l = this.length; i < l; i++) 

                    // Check if we have nested arrays

                    if (this[i] instanceof Array && array[i] instanceof Array) 

                        // recurse into the nested arrays

                        if (!this[i].equals(array[i]))

                            return false;

                    

                    else if (this[i] != array[i]) 

                        // Warning - two different object instances will never be equal: x:20 != 
                         x: 20 

                        return false;

                    

                

                return true;

            



            function createMasterList() 

                masterList = [];

                $('#select1\\(1\\)').children('#select1 option').each(function () 

                    masterList.push($(this).val());

                );

                masterList.shift(); //remove blank value

            



            createMasterList(); //used to check if all dropdown values have been selected



            function updateSelectedList() 

                selectedList = [];

                var selectedValue;

                $('#empData .stockCode').each(function (index,element) 

                    selectedValue = $(element).find('option:selected').val();

                    if (selectedValue != "" && $.inArray(selectedValue, selectedList) == "-1") 

                        selectedList.push(selectedValue);

                    

                );

            



            //disable the dropdown items that have already been selected

            function disableAlreadySelected() 
                
                $('.stockCode > option').each(function (index,element) 

                    if ($.inArray(element.value, selectedList) != "-1") 

                        $(element).attr("disabled", "disabled");

                     else 

                        $(element).removeAttr("disabled");

                    

                );

            



            //If all values have been selected, don't let the user add more rows

            function hideAddButtonIfDone() 

                masterList.sort();

                selectedList.sort();

                if (masterList.equals(selectedList)) 

                    console.log("lists equal, hiding add button");

                    $('#empData #AddNew').hide();

                

                else 

                    console.log("lists not equal, showing add button");

                    $('#empData #AddNew').show();

                

            



            $('#empData').on('change', '.stockCode', function () 

                setTimeout(function () 

                    updateSelectedList();

                    disableAlreadySelected();

                    hideAddButtonIfDone();

                , 0.1);

            );



            //when a new table row is added, disable the dropdown options that have already been selected

            //$('#empData #AddNew').on('click', disableAlreadySelected);



            //when a table row is removed, update all dropdowns (the removed row's dropdown option 
            //will be re - enabled

            //in remaining dropdowns

            $('#empData').on('DOMNodeRemoved', '.kx-repeatable > tr', function () 

                updateSelectedList();

                disableAlreadySelected();

                hideAddButtonIfDone();

            );



        );

结果:

【讨论】:

现在,在其中一个选择框中选择的项目在所有其他选项中都被禁用,但如果我检查该选项,它也会显示为禁用,因此我实际上无法使用它。我该如何解决这个问题? &lt;select&gt;&lt;/select&gt; 将有一个默认值,例如显示巴黎,选择的值为巴黎,function updateSelectedList() 之后,该值将添加到 selectedList。在您检查选项之前, option 已经是 select 的选定值。这就是为什么在 function updateSelectedList() 之后禁用该选项的原因。 我该如何解决这个问题?因为现在我无法将它们添加到我的数据库中,因为它们已被禁用。 恐怕不行,不能去掉它的默认值。

以上是关于Jquery禁用Asp.net核心中的选定选项无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

通过 jQuery 在选择菜单中添加禁用的选定选项

使用 asp.net 从后面的代码中获取 Jquery 的 Select2 的多个选定值

JQuery Select2 不会更改选定的 html 选项

使用 jQuery 启用/禁用特定“验证组”中的 asp.net 验证控件?

ASP.NET MVC 4 验证后自定义 jQuery 脚本无法正常工作

带有jquery的gridview asp.net中选定行的标签