Ответ Ajax в нужную строку таблицы формы
В форме имеется таблица с дополняемыми строками скриптом JS
При вводе в первое поле "артикул" по AJAX делается запрос и в div получаем результат для выбора нужной позиции При нажатии на выбранную позицию нужно заполнить поля название и код (item_name и item_code) в той строке таблицы в которой был ввод артикула В JS новичок и совсем не понимаю как получить строку с полями и в нее же внести значения из одного общего DIV. Или целесообразнее делать вывод результатов в DIV для каждой строки таблицы? Прошу помочь или подсказать или скинуть примеры подобной реализации
function find_item(str) {
if (str.length==0) {
document.getElementById("livesearch").innerHTML="";
document.getElementById("livesearch").style.border="0px";
return;
}
if (window.XMLHttpRequest) {
// код для IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else { // код для IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (this.readyState==4 && this.status==200) {
document.getElementById("livesearch").innerHTML=this.responseText;
document.getElementById("livesearch").style.border="1px solid #A5ACB2";
}
}
xmlhttp.open("POST","test_ajax_out.php?q="+str,true);
xmlhttp.send();
}
<form id="myForm">
<table>
<tr>
<td><input type="text" name="article[]" onkeyup="find_item(this.value)" placeholder="Артикул" /></td>
<td><input name="item_name[]" placeholder="Название" /></td>
<td><input name="item_code[]" placeholder="Код" /></td></tr>
<tr>
<td><input type="text" name="article[]" onkeyup="find_item(this.value)" placeholder="Артикул" /></td>
<td><input name="item_name[]" placeholder="Название" /></td>
<td><input name="item_code[]" placeholder="Код" /></td></tr>
<tr>
<td><input type="text" name="article[]" onkeyup="find_item(this.value)" placeholder="Артикул" /></td>
<td><input name="item_name[]" placeholder="Название" /></td>
<td><input name="item_code[]" placeholder="Код" /></td></tr>
</table>
<div id="livesearch">найденные варианты</div>
</form>
Ответ AJAX - по запросу будут получены данные <a href="#" onclick="" id="aa11">aaaaa</a><br /> <a href="#" onclick="" id="bb22">bbbbb</a><br /> <a href="#" onclick="" id="cc33">ccccc</a><br /> <a href="#" onclick="" id="dd44">ddddd</a><br /> <a href="#" onclick="" id="ee55">eeeee</a><br /> |
jquery-3.4.1 подключен
cms нет, весь код свой |
И не использовать метод POST для GET запроса
Цитата:
|
Спасибо за подсказку.
-Переделал вывод на json -Настроил вставку нескольких значений в свои поля Но в силу своей безграмотности и малого опыта не понимаю как реализовать работу с несколькими строками. Сейчас работает только первая строка. Т.е. куда и как прикрутить $(this).closest('tr') чтобы не использовать id в полях. Пожалуйста, помогите докурутить построчную работу. <div> <table> <tr> <td><input type="text" name="article[]" id="article" placeholder="article" /></td> <td><input type="text" name="name[]" id="name" placeholder="Name" /></td> <td><input type="text" name="code[]" id="code" placeholder="Code" /></td> <td><input type="text" name="ven[]" id="ven" placeholder="ven" /></td> </tr> <tr> <td><input type="text" name="article[]" placeholder="article" /></td> <td><input type="text" name="name[]" placeholder="Name" /></td> <td><input type="text" name="code[]" placeholder="Code" /></td> <td><input type="text" name="ven[]" placeholder="ven" /></td> </tr> <tr> <td><input type="text" name="article[]" placeholder="article" /></td> <td><input type="text" name="name[]" placeholder="Name" /></td> <td><input type="text" name="code[]" placeholder="Code" /></td> <td><input type="text" name="ven[]" placeholder="ven" /></td> </tr> </table> <ul id="result"></ul> </div>
$(document).ready(function(){
$.ajaxSetup({ cache: false });
$('#article').keyup(function(){
$('#result').html('');
$('#code').val('');
var searchField = $('#article').val();
var expression = new RegExp(searchField, "i");
var flickerAPI = "test_ajax5_out.php";
$.getJSON(flickerAPI , function(data) {
$.each(data, function(key, value){
if (value.article.search(expression) != -1)
{
$('#result').append('<li>'+value.name+'<span style="visibility: hidden;">|'+value.code+'|'+value.article+'|'+value.ven+'</span></li>');
}
});
});
});
$('#result').on('click', 'li', function() {
var click_text = $(this).text().split('|');
$('#article').val($.trim(click_text[2]));
$('#name').val($.trim(click_text[0]));
$('#code').val($.trim(click_text[1]));
$('#ven').val($.trim(click_text[3]));
$("#result").html('');
});
});
|
Да, данные на сервер пока не передаются, т.к. основная проблема в многострочности поиска.
По первой строке все работает как нужно/ Вводится артикул - выдаются совпадающие по коду данные выборка из базы это на потом отложил. Пока важнее настроить таблицу flickerAPI убрал, это было наследие от проб разных скриптов |
Хотелось бы понять всю задачу, что бы код 100 раз не делать.
У вас в таблице input задан и для Name и для Code и для ven вместе с placeholder. В них тоже должно что то вводиться и искаться по ним? |
задача:
- вводится артикул или его часть - появляется список, где есть вхождения введенного значения. если в списке есть позиция и ее выбирают, то заполняются поля name code ven, а так-же сам артикул заполняется полностью. При заполнении из списка поля name code ven перестают быть доступными для ввода (readonly), далее переход к новой строке... - Если введенный артикул или его часть не нашлись в списке или из списка не было ничего выбрано, то руками заполняются все поля, далее переход к новой строке... Список формируется по запросу введенного артикула и выбирается из базы более 50000 позиций Собственно это все |
Переделав вариант из поста #1
могу предложить следующее
<div>
<table>
<tr>
<td><input type="text" name="article[]" id="article" placeholder="article" /></td>
<td><input type="text" name="name[]" id="name" placeholder="Name" /></td>
<td><input type="text" name="code[]" id="code" placeholder="Code" /></td>
<td><input type="text" name="ven[]" id="ven" placeholder="ven" /></td>
</tr>
<tr>
<td><input type="text" name="article[]" id="article" placeholder="article" /></td>
<td><input type="text" name="name[]" id="name" placeholder="Name" /></td>
<td><input type="text" name="code[]" id="code" placeholder="Code" /></td>
<td><input type="text" name="ven[]" id="ven" placeholder="ven" /></td>
</tr>
<tr>
<td><input type="text" name="article[]" id="article" placeholder="article" /></td>
<td><input type="text" name="name[]" id="name" placeholder="Name" /></td>
<td><input type="text" name="code[]" id="code" placeholder="Code" /></td>
<td><input type="text" name="ven[]" id="ven" placeholder="ven" /></td>
</tr>
</table>
<ul id="result"></ul>
</div>
</body>
// Заполнение строки даблицы
// data - эдемент массива данных
// inp - элемент ввода по которому искали
// li - элемент на котором кликнули
function outputInTable(data, inp, li) {
const tr = inp.closest('tr');
tr.querySelector('[name="article[]"]').value = data.article;
tr.querySelector('[name="name[]"]').value = data.name;
tr.querySelector('[name="code[]"]').value = data.code;
tr.querySelector('[name="ven[]"]').value = data.ven;
li.closest('ul').textContent = '';
}
// Вывод списка найденых
// inp - элемент в котором был ввод
// ardata - массив найденых значений
function outputSearchData (inp, ardata) {
const ul = document.getElementById('result');
ul.textContent = '';
for (const data of ardata) {
const li = document.createElement('li');
li.textContent = data.name;
ul.append(li);
li.addEventListener('click', () => outputInTable(data, inp, li), {once:true});
}
}
function findItem ({target}) {
const searchStr = target.value;
fetch('test_ajax_out.php?q='+searchStr)
.then(responce => responce.json())
.then (data => outputSearchData(target, data))
}
document.addEventListener('DOMContentLoaded', () => {
const articles = document.querySelectorAll('input[name="article[]"]')
articles.forEach(article => article.addEventListener('keyup', findItem));
})
|
Спасибо!
Отличная работа! 1 вопрос - в каком месте и как установить readonly для трех полей? 2 вопрос - после выбора в списке и подстановки в таблицу, в случае правки артикула нужно сбросить заполненные поля и снять readonly |
Цитата:
// Заполнение строки даблицы
// data - эдемент массива данных
// inp - элемент ввода по которому искали
function outputInTable(data, inp) {
const tr = inp.closest('tr');
const article = tr.querySelector('[name="article[]"]');
article.value = data.article;
const name = tr.querySelector('[name="name[]"]');
name.value = data.name;
name.readOnly = true;
const code = tr.querySelector('[name="code[]"]');
code.value = data.code;
code.readOnly = true;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = data.ven;
ven.readOnly = true;
}
// Вывод списка найденых
// inp - элемент в котором был ввод
// ardata - массив найденых значений
function outputSearchData (inp, ardata) {
const ul = document.getElementById('result');
ul.textContent = '';
for (const data of ardata) {
const li = document.createElement('li');
li.textContent = data.name;
ul.append(li);
li.addEventListener('click', () => {
outputInTable(data, inp);
ul.textContent = '';
},
{once:true}
);
}
}
function findItem ({target}) {
const searchStr = target.value;
fetch('test_ajax_out.php?q='+searchStr)
.then(responce => responce.json())
.then (data => outputSearchData(target, data))
}
document.addEventListener('DOMContentLoaded', () => {
const articles = document.querySelectorAll('input[name="article[]"]')
articles.forEach(article => article.addEventListener('input', findItem));
})
|
readonly работает
но как ее снять и очистить поля, если решил ввести новую позиции как-бы отменив свой выбор в списке а то получается что можно использовать name code и ven с любым article не совпадающем в списке |
Цитата:
Другое дело, что если пользователь вводит в article, потом выбирает из списка, потом решает, что ошибся, меняет article так, что список оказывается пустым и теперь ему надо вводить все поля вручную. Тут уже будет невозможно ввести, так как поля уже отмечены readonly. Надо снимать этот атрибут, если список пуст. По хорошему надо и значения всех полей убирать, если пользователь начинает исправлять article Что то типа такого
// Заполнение строки даблицы
// data - эдемент массива данных
// tr - строка в которую был ввод
function outputInTable(data, tr) {
const article = tr.querySelector('[name="article[]"]');
article.value = data.article;
const name = tr.querySelector('[name="name[]"]');
name.value = data.name;
name.readOnly = true;
const code = tr.querySelector('[name="code[]"]');
code.value = data.code;
code.readOnly = true;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = data.ven;
ven.readOnly = true;
}
// Очистка строки в которую идет ввод и снятие readonly
// tr - строка в которую был ввод
function clearFields (tr) {
const name = tr.querySelector('[name="name[]"]');
name.value = '';
name.readOnly = false;
const code = tr.querySelector('[name="code[]"]');
code.value = '';
code.readOnly = false;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = '';
ven.readOnly = false;
}
// Вывод списка найденых
// inp - элемент в котором был ввод
// ardata - массив найденых значений
function outputSearchData (inp, ardata) {
const ul = document.getElementById('result');
ul.textContent = '';
const tr = inp.closest('tr');
clearFields(tr);
for (const data of ardata) {
const li = document.createElement('li');
li.textContent = data.name;
ul.append(li);
li.addEventListener('click', () => outputInTable(data, tr), {once:true} );
}
}
function findItem ({target}) {
const searchStr = target.value;
fetch('test_ajax_out.php?q='+searchStr)
.then(responce => responce.json())
.then (data => outputSearchData(target, data))
}
document.addEventListener('DOMContentLoaded', () => {
const articles = document.querySelectorAll('input[name="article[]"]')
articles.forEach(article => article.addEventListener('input', findItem));
})
|
Цитата:
|
Ну значит убирать список. Но, что бы его снова получить, пользователь должен начать редактировать поле article. Ему так и так придется его редактировать, что бы получить список. По полностью заполненному значению поля мы получим только одну строку (или не одной).
// Заполнение строки таблицы
// data - элемент массива данных
// tr - строка в которую был ввод
function outputInTable(data, tr) {
const article = tr.querySelector('[name="article[]"]');
article.value = data.article;
const name = tr.querySelector('[name="name[]"]');
name.value = data.name;
name.readOnly = true;
const code = tr.querySelector('[name="code[]"]');
code.value = data.code;
code.readOnly = true;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = data.ven;
ven.readOnly = true;
}
// Очистка строки в которую идет ввод и снятие readonly
// tr - строка в которую был ввод
function clearFields (tr) {
const name = tr.querySelector('[name="name[]"]');
name.value = '';
name.readOnly = false;
const code = tr.querySelector('[name="code[]"]');
code.value = '';
code.readOnly = false;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = '';
ven.readOnly = false;
}
// Вывод списка найденых
// inp - элемент в котором был ввод
// ardata - массив найденых значений
function outputSearchData (inp, ardata) {
const ul = document.getElementById('result');
ul.textContent = '';
const tr = inp.closest('tr');
clearFields(tr);
for (const data of ardata) {
const li = document.createElement('li');
li.textContent = data.name;
ul.append(li);
li.addEventListener('click', () => {
outputInTable(data, tr);
ul.textContent = '';
},
{once:true} );
}
}
function findItem ({target}) {
const searchStr = target.value;
fetch('test_ajax_out.php?q='+searchStr)
.then(responce => responce.json())
.then (data => outputSearchData(target, data))
}
document.addEventListener('DOMContentLoaded', () => {
const articles = document.querySelectorAll('input[name="article[]"]')
articles.forEach(article => article.addEventListener('input', findItem));
})
PS Если там более 50 000 позиций, то имеет смыл подумать, что бы не выводить так много. Может быть выводить список только если введено не менее 3-4 символов. |
Цитата:
Или рекомендуешь не делать JS запрос если текста мало? |
Цитата:
Эту функцию так переписать
const MINSEARCHLENGTH = 3;
async function findItem ({target}) {
const searchStr = target.value;
let data;
if (searchStr.length >= MINSEARCHLENGTH) {
const responce = await fetch('test_ajax_out.php?q='+searchStr);
data = await responce.json();
} else {
data = await [];
}
outputSearchData(target, data);
}
|
Все отлично!
Единственно, что в "боевом" скрипте не зашла совместимость с добавлением строк В добавленных сроках не работает поиск сможешь помочь в нем? |
Цитата:
Тогда к table id добавить
<body>
<div>
<table id="table">
<tr>
<td><input type="text" name="article[]" placeholder="article" /></td>
<td><input type="text" name="name[]" placeholder="Name" /></td>
<td><input type="text" name="code[]" placeholder="Code" /></td>
<td><input type="text" name="ven[]" placeholder="ven" /></td>
</tr>
<tr>
<td><input type="text" name="article[]" placeholder="article" /></td>
<td><input type="text" name="name[]" placeholder="Name" /></td>
<td><input type="text" name="code[]" placeholder="Code" /></td>
<td><input type="text" name="ven[]" placeholder="ven" /></td>
</tr>
<tr>
<td><input type="text" name="article[]" placeholder="article" /></td>
<td><input type="text" name="name[]" placeholder="Name" /></td>
<td><input type="text" name="code[]" placeholder="Code" /></td>
<td><input type="text" name="ven[]" placeholder="ven" /></td>
</tr>
</table>
<ul id="result"></ul>
</div>
И событие input ловим на таблице и проверяем, что это нужный элемент (делегирование)
// Заполнение строки таблицы
// data - элемент массива данных
// tr - строка в которую был ввод
function outputInTable(data, tr) {
const article = tr.querySelector('[name="article[]"]');
article.value = data.article;
const name = tr.querySelector('[name="name[]"]');
name.value = data.name;
name.readOnly = true;
const code = tr.querySelector('[name="code[]"]');
code.value = data.code;
code.readOnly = true;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = data.ven;
ven.readOnly = true;
}
// Очистка строки в которую идет ввод и снятие readonly
// tr - строка в которую был ввод
function clearFields (tr) {
const name = tr.querySelector('[name="name[]"]');
name.value = '';
name.readOnly = false;
const code = tr.querySelector('[name="code[]"]');
code.value = '';
code.readOnly = false;
const ven = tr.querySelector('[name="ven[]"]');
ven.value = '';
ven.readOnly = false;
}
// Вывод списка найденных
// inp - элемент в котором был ввод
// ardata - массив найденных значений
function outputSearchData (inp, ardata) {
const ul = document.getElementById('result');
ul.textContent = '';
const tr = inp.closest('tr');
clearFields(tr);
for (const data of ardata) {
const li = document.createElement('li');
li.textContent = data.name;
ul.append(li);
li.addEventListener('click', () => {
outputInTable(data, tr);
ul.textContent = '';
},
{once:true} );
}
}
const MINSEARCHLENGTH = 3;
async function findItem ({target}) {
if (target.name !== 'article[]') return;
const searchStr = target.value;
let data;
if (searchStr.length >= MINSEARCHLENGTH) {
const responce = await fetch('test_ajax_out.php?q='+searchStr);
data = await responce.json();
} else {
data = await [];
}
outputSearchData(target, data);
}
document.addEventListener('DOMContentLoaded', () => {
const table = document.getElementById('table')
table.addEventListener('input', findItem);
})
|
Цитата:
На странице еще десяток полей и пересчет значений, что здесь не к месту. А на объяснение всего механизма уйдет куча лишних слов, которые запутают и не позволят решить проблему. А так, конечно, согласен лучше видеть всю картину, но и вникать во весь проект это уже лишнее. Где грань что надо, что нет для именно этого решения сложно угадать, когда знаний в вопросе минимум... Сорри... ---- не ищет сейчас совсем ---- при вводе первого символа уже появляется div в котором вывод результата Добавил закрыть список когда мешает и открытие видимости при его обновлении. function outputSearchData (inp, ardata) { document.getElementById('search_result').style.dis play='block'; |
Цитата:
table.addEventListener('input', findItem); Если вы свою table обозвали id='11' то и в .getElementById надо было '11' ставить. В консоле же ошибки сразу видны. |
Увы, таблиц несколько и они еще и вложенные в другую таблицу
|
Так и надо указать ид самой внешней таблицы (или внутренние все разные? в примере одинаковые)
|
вложенные по структуре одинаковые
|
на основную индекс добавил, в скрипте указал
нет поиска правились имена полей в таблице и скрипте |
нашел ошибку, работает поиск
|
появление div с поиском при вводе 1,2 символов как скрыть?
(внизу зеленый div) |
Цитата:
// Вывод списка найденых
// inp - элемент в котором был ввод
// ardata - массив найденых значений
function outputSearchData (inp, ardata) {
const ul = document.getElementById('result');
ul.textContent = '';
const tr = inp.closest('tr');
clearFields(tr);
let disp = 'none';
for (const data of ardata) {
const li = document.createElement('li');
li.textContent = data.name;
ul.append(li);
disp = 'block';
li.addEventListener('click', () => {
outputInTable(data, tr);
ul.textContent = '';
},
{once:true} );
}
document.getElementById('search_result').style.display = disp;
}
|
Через несколько попыток удалось решить так
li.addEventListener('click', () => {
outputInTable(data, tr);
ul.textContent = '';
document.getElementById('search_result').style.display='none';
Огромное спасибо за терпение и помощь!!! :thanks: |
| Часовой пояс GMT +3, время: 17:02. |