Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Ответ Ajax в нужную строку таблицы формы (https://javascript.ru/forum/dom-window/85499-otvet-ajax-v-nuzhnuyu-stroku-tablicy-formy.html)

Sheratan 22.09.2023 11:18

readonly работает
но как ее снять и очистить поля, если решил ввести новую позиции как-бы отменив свой выбор в списке
а то получается что можно использовать name code и ven с любым article не совпадающем в списке

voraa 22.09.2023 11:55

Цитата:

Сообщение от Sheratan
если решил ввести новую позиции как-бы отменив свой выбор в списке

Не убирать список после выбора позиции в нем. При вводе в другой 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));
})

Sheratan 22.09.2023 13:16

Цитата:

Сообщение от voraa
Не убирать список после выбора позиции в нем. При вводе в другой article просто показывать новый список.

Полученный список вариантов после нажатия и заполнения полей конечно надо убрать т.к. он мешает дальнейшей работе

voraa 22.09.2023 13:38

Ну значит убирать список. Но, что бы его снова получить, пользователь должен начать редактировать поле 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 символов.

Sheratan 22.09.2023 14:09

Цитата:

Сообщение от voraa (Сообщение 553367)
PS Если там более 50 000 позиций, то имеет смыл подумать, что бы не выводить так много. Может быть выводить список только если введено не менее 3-4 символов.

Это я планировал делать на SQL запросе. (кол-во введенных символов и LIMIT)
Или рекомендуешь не делать JS запрос если текста мало?

voraa 22.09.2023 14:57

Цитата:

Сообщение от Sheratan
Это я планировал делать на SQL запросе.
Или рекомендуешь не делать 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);
}

Sheratan 22.09.2023 16:02

Все отлично!

Единственно, что в "боевом" скрипте не зашла совместимость с добавлением строк
В добавленных сроках не работает поиск

сможешь помочь в нем?

voraa 22.09.2023 16:16

Цитата:

Сообщение от Sheratan
В добавленных сроках не работает поиск

Вот почему не спрашивать и не описывать задачу всю сразу. Со всеми особенностями. Как будто одно от другого не зависит
Тогда к 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);
})

Sheratan 22.09.2023 16:42

Цитата:

Сообщение от voraa
Вот почему не спрашивать и не описывать задачу всю сразу. Со всеми особенностями.

Из-за того что тогда не будет ясна основная проблема.
На странице еще десяток полей и пересчет значений, что здесь не к месту.
А на объяснение всего механизма уйдет куча лишних слов, которые запутают и не позволят решить проблему.
А так, конечно, согласен лучше видеть всю картину, но и вникать во весь проект это уже лишнее. Где грань что надо, что нет для именно этого решения сложно угадать, когда знаний в вопросе минимум...
Сорри...

----
не ищет сейчас совсем
----
при вводе первого символа уже появляется div в котором вывод результата
Добавил закрыть список когда мешает и открытие видимости при его обновлении.

function outputSearchData (inp, ardata) {
document.getElementById('search_result').style.dis play='block';

voraa 22.09.2023 16:48

Цитата:

Сообщение от Sheratan
не ищет сейчас совсем

const table = document.getElementById('table')
table.addEventListener('input', findItem);

Если вы свою table обозвали id='11' то и в .getElementById надо было '11' ставить. В консоле же ошибки сразу видны.


Часовой пояс GMT +3, время: 02:59.