#javascript #c# #jquery #asp.net-core-mvc
Вопрос:
В моем проекте у меня есть таблица с кнопкой для добавления новой строки. В каждой строке есть поле выбора, когда я выбираю опцию, она должна быть отключена во всех других полях выбора, включая новые. Когда я попробовал этот код здесь, введите описание ссылки здесь, это работает. Но в Asp.net ядро это работает не полностью, оно работает только для первого варианта выбора.
Это мой код в Asp.net Ядро, я изменил его, чтобы он работал, но все еще не все выбранные опции в поле выбора обновлены и отключены
Почему один и тот же код работает за пределами 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 amp;amp; 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 != "" amp;amp; $.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();
});
});
Комментарии:
1. В чем разница между HTML, который вы написали в скрипке, и HTML, сгенерированным ASP.NET код? Если вы возьмете тот самый сгенерированный HTML и создадите с ним возню, все равно ли произойдет сбой кода? Когда вы отлаживаете, какая конкретная операция не делает то, что вы ожидаете?
2. @David разница в том, что я использую перечисления для заполнения выбранных параметров. В то время как в fiddle это базовый html-выбор с опциями. В скрипке, если я выберу опцию в первом поле выбора мест. затем в поле выбрать другое местоположение он будет отключен, поэтому вы не сможете выбрать его снова. Теперь в коде asp это не сработало, если я выберу опцию из первого поля выбора местоположения, она будет отключена в других полях выбора, но если я выберу опцию из других полей выбора местоположения, опция не будет отключена, как это произошло в первом поле выбора.
3. @David пользователь не должен иметь возможности выбрать ту же опцию в других полях выбора местоположения. Должно быть, все по-другому.
4. Если вы не знакомы с тем, как отлаживать код в браузере, то сейчас самое подходящее время, чтобы начать знакомиться с этим. В инструментах отладки вашего браузера вы можете просмотреть фактический результирующий HTML-код, сгенерированный кодом на стороне сервера, и посмотреть, чем он отличается от того, что вы ожидали в написанном от руки образце HTML. Вы также можете использовать отладчик сценариев браузера, чтобы размещать точки останова в своем коде JavaScript и последовательно просматривать его по мере выполнения, наблюдая за результатами каждой отдельной операции. Когда вы это делаете, ваша цель состоит в том, чтобы найти первую операцию, которая каким-то образом завершилась неудачно.
Ответ №1:
Я думаю,это связано с тем, что идентификатор не уникален, при добавлении новой строки он создаст выборки с одинаковыми идентификаторами,поэтому элемент не может быть найден и правильно использован идентификатором.Вот рабочая демонстрация:
<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 amp;amp; 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 != "" amp;amp; $.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();
});
});
Комментарии:
1. прямо сейчас элемент, выбранный в одном из полей выбора, отключен во всех остальных, но проблема в том, что он также кажется отключенным, если я проверю, что опция отключена, поэтому я не могу ее использовать. Как я могу это исправить?
2.
<select></select>
будет иметь значение по умолчанию,например,он показывает Париж,выбранное значение-Париж,послеfunction updateSelectedList()
этого значение будет добавлено в список выбранных.Перед тем ,как вы проверите параметр,для параметра уже было выбрано значение выбрать. Вот почему после этого опция отключаетсяfunction updateSelectedList()
.3. Как я могу это исправить? потому что прямо сейчас я не могу добавить их в свою базу данных, потому что они отключены .
4. Боюсь, что нет,<выбрать><выбрать></выбрать> не удается удалить значение по умолчанию.