У меня есть javascript, в котором при нажатии кнопки в таблицу добавляется строка с двумя ячейками. В одной ячейке имеется текстовое поле живого поиска, а в другой ячейке — текстовое поле количества, значение которого предполагается динамически изменяться и/или определяться при нажатии на результаты текстового поля живого поиска.
Я что-то пробовал, но проблема, с которой я столкнулся, заключается в том, что значение динамически определенного текстового поля других строк сохраняет значение текстового файла первой строки.
Поэтому мне нужна помощь в том, как очистить сценарий, чтобы каждая строка реагировала в соответствии с соответствующими значениями в текстовом поле живого поиска.
<div style = "overflow-x:auto">
<table id = "stockTransfer" class = "table">
<thead>
<tr>
<th style = "color:blue">Search Product's(Name/Code)</th>
<th style = "color:blue">instore Availability</th>
<th style = "color:blue">Price/Unit</th>
<th style = "color:blue">Choose Selling Unit(eg:cartons/etc)</th>
<th style = "color:blue">Quantity</th>
<th style = "color:blue">Cummulative Price</th>
<th style = "color:blue"> Delete </th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
<script>
//stock transfer dynamic textboxes
$(document).ready(function() {
$(document).on('click', '.btnaddstockTransfer', function() {
var html = '';
html += '<tr>';
html += '<td><div class = "search-box"><input id = "stock" class = "form-control is-warning stock" type = "text" name = "stock[]" placeholder = "Search by name or code"><div class = "result"></div></div></td>';
html += '<td><input class = "form-control is-warning eqty" type = "text" name = "stockeqty[]" readonly size = "2"></td>';
html += '</tr>';
$('#stockTransfer').append(html);
$(document).on('keyup input', '.search-box input[type = "text"]', function() {
/* Get input value on change */
var inputVal = $(this).val();
var resultDropdown = $(this).siblings(".result");
if (inputVal.length) {
$.get("backend-search.php", {
term: inputVal
}).done(function(data) {
// Display the returned data in browser
resultDropdown.html(data);
});
} else {
resultDropdown.empty();
}
});
// Set search input value on click of result item
$(document).on("click", ".result p", function() {
var stock = $(this).text();
$(this).parents(".search-box").find('.stock').val(stock);
$(this).parent(".result").empty();
var tr = $(this).parent(".search-box").parent().parent().parent();
$.ajax({
method: "get",
url: "saleqtyOnFly.php",
data: {
item: stock
},
success: function(data) {
tr.find(".eqty").val(data);
}
})
});
});
});
Пожалуйста, посмотрите Как мне форматировать сообщения? , Как спрашивать и как составить минимальный воспроизводимый пример вашей проблемы. Смотрите также тур , раз уж вы его еще не взяли. Вы можете редактировать свою публикацию. Спасибо.
Наличие $(document).ready внутри другого $(document).ready совершенно избыточно и бессмысленно.
another text field in another td tag
...это расплывчато. Уточните, о какой именно области вы говорите и как нам следует ее идентифицировать, тогда не будет никакой двусмысленности.
var stock = document.getElementsById('stock')
вызовет у вас проблемы, потому что похоже, что на вашей странице может быть более одного <input id = "stock"
. Идентификатор должен быть уникальным. Таким образом, JS всегда будет искать и использовать только первый элемент с этим идентификатором. Все остальные считаются недействительными. Несколькими строками выше вы уже использовали $(this).parents(".search-box").find('.stock')
, чтобы найти конкретную «акцию» по ее положению... так почему бы вам не сделать это еще раз чуть ниже? Кажется, вы не очень внимательно подумали об этом getElementById
коде, когда писали его.
Кроме того, размещение обработчиков событий внутри других обработчиков событий, как вы это сделали, — плохая идея. В конечном итоге вы создадите несколько обработчиков для каждого из этих элементов, которые затем будут срабатывать всякий раз, когда происходит событие. Обычно это приводит к непредвиденным и запутанным последствиям. Я предполагаю, что вы сделали это таким образом, потому что не знаете о шаблоне обработки «делегированных событий». Взгляните на раздел «Прямые и делегированные обработчики событий» на сайте api.jquery.com/on
@ADyson Я принял к сведению ваши предложения, я поработаю над этим и вернусь, если у меня возникнут какие-либо дальнейшие проблемы.
@ADyson Я исправил замеченные вами ошибки. Также для запаса var я использовал это var stock = $(this).text();
вместо var stock = document.getElementsById('stock');
. Однако я заметил, что моя ячейка количества tr.find(".eqty").val(data);
для всех ранее вставленных строк меняется на значение ячейки количества самой последней строки. На данном этапе мне нужна ваша помощь, чтобы остановить это происшествие.
for all previously inserted rows
... это восходит к тому, что я сказал о том факте, что вы поместили обработчик $(document).on("click", ".result p", function()
внутри обработчика $(document).on('click', '.btnaddstockTransfer', function()
. Поэтому каждый раз, когда запускается событие щелчка btnaddstockTransfer, оно добавляет еще один обработчик событий для .result p... а затем еще один и еще. Таким образом, в конечном итоге у вас будет 2 или более функций, работающих для этого события, и предыдущие могут запомнить значения переменных, переданные им из контекста, который у них был на момент их первого добавления.
Другая причина может заключаться в том, что var tr = $(".search-box").parent().parent().parent();
найдет все строки родительской таблицы всех полей поиска, а не только поле поиска рядом с результатом, по которому щелкнули. Вероятно, вместо этого вам нужен $(this).parents(".search-box").parent().parent().parent();
.
@ADyson Да, я пытался использовать это, но вместо этого ячейка была пустой. То есть, чтобы var tr = $(this).parents(".search-box").parent().parent().parent();
не указывал на ячейку. пожалуйста, мы почти у цели, помогите с другим вариантом
@ADyson Да, я разделил два события щелчка
Можете ли вы отредактировать вопрос, используя последнюю версию кода, чтобы показать, как вы это сделали и как выглядит последняя версия? Таким образом, мы оба говорим об одном и том же. Кроме того, у нас нет образца вашего общего HTML-кода, поэтому сложнее определить, каким должен быть правильный jQuery, поскольку мы немного догадываемся о структуре.
Рассмотрим следующий пример.
//stock transfer dynamic textboxes
$(function() {
function makeRow(table) {
console.info("Add Row to " + $(table).attr("id"));
var row = $("<tr>").appendTo($("tbody", table));
$("thead th", table).each(function() {
$("<td>").html(" ").appendTo(row);
});
$("td")
.eq(0)
.append($("<div>", {
class: "search-box"
}), $("<input>", {
id: "stock-" + row.index(),
class: "form-control is-warning stock",
type: "text",
name: "stock[]",
placeholder: "Search by name or code"
}), $("<div>", {
class: "result"
}));
$("td")
.eq(4)
.append($("<input>", {
class: "form-control is-warning eqty",
type: "text",
name: "stockeqty[]",
size: "2",
readonly: true
}));
return row;
}
$(document).on('click', '.btnaddstockTransfer', function() {
makeRow($("#stockTransfer"));
});
$(document).on('keyup input', '.search-box input[type = "text"]', function() {
/* Get input value on change */
var inputVal = $(this).val();
var resultDropdown = $(this).closest("tr").find(".result");
if (inputVal.length) {
$.get("backend-search.php", {
term: inputVal
}).done(function(data) {
// Display the returned data in browser
resultDropdown.html(data);
});
} else {
resultDropdown.empty();
}
});
// Set search input value on click of result item
$(document).on("click", ".result", function() {
var row = $(this).closest("tr");
$('.stock', row).val($(this).text().trim());
$(this).html("");
$.ajax({
method: "get",
url: "saleqtyOnFly.php",
data: {
item: stock
},
success: function(data) {
$(".eqty", row).val(data);
}
});
});
});
#stockTransfer thead th {
color: blue;
}
<link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel = "stylesheet" integrity = "sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin = "anonymous">
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<button class = "btnaddstockTransfer">Add Stock Transfer</button>
<div style = "overflow-x:auto">
<table id = "stockTransfer" class = "table">
<thead>
<tr>
<th>Search Product's(Name/Code)</th>
<th>Instore Availability</th>
<th>Price/Unit</th>
<th>Choose Selling Unit(eg:cartons/etc)</th>
<th>Quantity</th>
<th>Cummulative Price</th>
<th>Delete </th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
Самый быстрый способ навести порядок — взять повторяемый код и переместить его в функцию.
Также может быть полезно использовать .closest()
для поиска определенных родительских элементов.
Причина, по которой текстовое поле «количество» не заполняется, заключается в том, что внутри $(document).on("click", ".result p", function()
, tr
не содержится объект jQuery. Это потому, что $(this).parent(".result").empty();
очищает div «result», а это означает, что $(this)
больше не существует, поскольку он указывает на элемент внутри div «result».
Простое решение — назначить tr
перед очисткой элемента div «result»:
$(this).parents(".search-box").find('.stock').val(stock);
var tr = $(this).parent().parent().parent().parent();
$(this).parent(".result").empty();
Вот рабочая демонстрация (просто используются жестко запрограммированные образцы данных вместо ответов на ваши вызовы AJAX):
$(document).ready(function() {
$(document).on('click', '.btnaddstockTransfer', function() {
var html = '';
html += '<tr>';
html += '<td><div class = "search-box"><input id = "stock" class = "form-control is-warning stock" type = "text" name = "stock[]" placeholder = "Search by name or code"><div class = "result"></div></div></td>';
html += '<td><input class = "form-control is-warning eqty" type = "text" name = "stockeqty[]" readonly size = "2"></td>';
html += '</tr>';
$('#stockTransfer').append(html);
$(document).on('keyup input', '.search-box input[type = "text"]', function() {
/* Get input value on change */
var inputVal = $(this).val();
var resultDropdown = $(this).siblings(".result");
if (inputVal.length) {
//just dummy data for example purposes:
resultDropdown.html("<p>Result 1</p><p>Result 2</p>");
/*$.get("backend-search.php", {
term: inputVal
}).done(function(data) {
// Display the returned data in browser
resultDropdown.html(data);
});*/
} else {
resultDropdown.empty();
}
});
// Set search input value on click of result item
$(document).on("click", ".result p", function() {
var stock = $(this).text();
$(this).parents(".search-box").find('.stock').val(stock);
var tr = $(this).parent().parent().parent().parent();
$(this).parent(".result").empty();
/*$.ajax({
method: "get",
url: "saleqtyOnFly.php",
data: {
item: stock
},
success: function(data) {
tr.find(".eqty").val(data);
}
})*/
//just dummy data for example purposes:
tr.find(".eqty").val(123);
});
});
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<button class = "btnaddstockTransfer" type = "button">
Add stock transfer
</button>
<div style = "overflow-x:auto">
<table id = "stockTransfer" class = "table">
<thead>
<tr>
<th style = "color:blue">Search Product's(Name/Code)</th>
<th style = "color:blue">instore Availability</th>
<th style = "color:blue">Price/Unit</th>
<th style = "color:blue">Choose Selling Unit(eg:cartons/etc)</th>
<th style = "color:blue">Quantity</th>
<th style = "color:blue">Cummulative Price</th>
<th style = "color:blue"> Delete </th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
Пожалуйста, отформатируйте код правильно. В таком виде, как сейчас, это почти неразборчиво.