03.12.2019, 12:55
|
Новичок на форуме
|
|
Регистрация: 03.12.2019
Сообщений: 4
|
|
Повесить событие на несколько кнопок
Добрый день всем.
Мне нужно, чтобы при нажатии на кнопку ОК отправлялся на сервер POST. Сейчас это работает только с первой кнопкой, которая в таблице в первой строке. Остальные молчат. Как сделать, чтобы каждая из динамически отрисованных foreach кнопоквыполняла онинаковые действия - оправка POST. Желательно, чтобы JavaScript не менять, поскольку он работает, а я в JS тюлень. Дайте, пожалуйста, готовое решение, как повесить события на каждую кнопку и как их обрабатывать, или повесить собитые на общий класс кнопок или еще как - нибудь.
<?php foreach ($stores as $store): ?>
<tr class="trColor">
<td><input type="text" id="id" readonly name="id" value="<?= $store->getId() ?>" size="4"></td>
<td><?= $store->getTradeShop() ?></td>
<td><?= $store->getFactoryNumber() ?></td>
<td><?= $store->getDateOfd() ?></td>
<td><?= $store->getMonth() ?></td>
<td><select id="status" name="status" >
<option class="selectChange" id="resultStatus" ><?= $store->getStatus() ?></option>
<?php if (($user->getRole()) === 'admin'): ?>
<option value="Выполнено"><h1>Выполнено</h1></option>
<option value="Зарегистрировать">Зарегистрировать</option>
<option value="Заменить">Заменить</option>
<input id="INSERT" type="submit" value="ОК">
<?php endif; ?>
</select>
</td>
</tr>
<?php endforeach; ?>
document.addEventListener("DOMContentLoaded", function () {
// получить кнопку
var mybutton = document.getElementById('INSERT');
//подписаться на событие click по кнопке и назначить обработчик, который будет выполнять действия, указанные в безымянной функции
mybutton.addEventListener('click',function () {
//1. Сбор данных, необходимых для выполнения запроса на сервере
var status = document.getElementById('status').value;
var id = document.getElementById('id').value;
//Подготовка данных для отправки на сервер
//т.е. кодирование с помощью метода encodeURIComponent
//select = 'select=' + encodeURIComponent(select);
//login = 'post=' + encodeURIComponent(login);
const together = "&status=" + status + "&id=" + id;
// 2. Создание переменной request
var request = new XMLHttpRequest();
// 3. Настройка запроса
request.open('POST', 'http://fiscaloop.ru/stores/kosarev/edit-store/', true);
// 4. Подписка на событие onreadystatechange и обработка его с помощью анонимной функции
request.addEventListener('readystatechange', function () {
//если запрос пришёл и статус запроса 200 (OK)
if ((request.readyState == 4) && (request.status == 200)) {
// например, выведем объект XHR в консоль браузера
console.log(request);
// получить элемент c id = resultSELECT
var resultStatus = document.getElementById('resultStatus');
// заменить содержимое элемента ответом, пришедшим с сервера
resultStatus.innerHTML = request.responseText;
$('.selectChange:contains("Зарегистрировать")').parents(".trColor").css('background','#ffd700');
$('.selectChange:contains("Заменить")').parents(".trColor").css('background','#E9967A');
$('.selectChange:contains("Выполнено")').parents(".trColor").css('background', '#fff8dc');
}
});
// Устанавливаем заголовок Content-Type(обязательно для метода POST).
// Он предназначен для указания кодировки, с помощью которой зашифрован запрос. Это необходимо для того, чтобы сервер знал как его раскодировать.
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 5. Отправка запроса на сервер. В качестве параметра указываем данные, которые необходимо передать (необходимо для POST)
request.send(together);
});
$('.selectChange:contains("Зарегистрировать")').parents(".trColor").css('background','#ffd700');
$('.selectChange:contains("Заменить")').parents(".trColor").css('background','#E9967A');
});
|
|
03.12.2019, 15:29
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
foreach ($stores as $store): и id="id", id="status", id="INSERT" означает присутствие на странице одинаковых ID, а это недопустимо - document.getElementById('INSERT') вернет первый найденный. Кроме того, в теге select кроме тегов option других быть не может.
|
|
04.12.2019, 13:27
|
Новичок на форуме
|
|
Регистрация: 03.12.2019
Сообщений: 4
|
|
Вот поэтому я и обратился к вам: можно ли повесить addEventListener не на id, а , например, на класс, который будут иметь все кнопки?
|
|
04.12.2019, 13:49
|
|
CacheVar
|
|
Регистрация: 19.08.2010
Сообщений: 14,209
|
|
Сообщение от creeptos
|
можно ли повесить addEventListener не на id, а , например, на класс, который будут иметь все кнопки?
|
Метод addEventListener() нужно применять к каждому элементу в отдельности...
Но можно его применить к родительскому элементу, если таковой может обрабатывать, нужное тебе, событие... А в обработчике проверять, на том ли элементе то событие произошло...
Это называется "делегированием событий"
|
|
04.12.2019, 14:16
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
creeptos, если задача отправлять на сервер идентификатор, то:
1) Не формировать в цикле id="...", это бессмыслица.
2) Заменить <input type="text" id="id" readonly name="id" value="<?= $store->getId() ?>" size="4"> на просто вывод в ячейку <td><?= $store->getId() ?></td>.
3) Убрать из списка <input id="INSERT" type="submit" value="ОК">, это ошибка, и заменить его на <button name="id" value="<?= $store->getId() ?>">Нужный текст</button>
4) Делегировать обработку щелчков по этим кнопкам таблице, отправляя на сервер, и он будет получать имя кнопки как ключ и ее значение.
Последний раз редактировалось laimas, 04.12.2019 в 14:39.
|
|
04.12.2019, 17:46
|
Новичок на форуме
|
|
Регистрация: 03.12.2019
Сообщений: 4
|
|
Напишите, пож, в моем JS что конкретно изменить для делегирования событий.
|
|
04.12.2019, 18:17
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
На сервере:
<?php foreach ($stores as $store): ?>
<tr class="trColor">
<td><?= $store->getId() ?></td>
<td><?= $store->getTradeShop() ?></td>
<td><?= $store->getFactoryNumber() ?></td>
<td><?= $store->getDateOfd() ?></td>
<td><?= $store->getMonth() ?></td>
<td><select>
<option class="selectChange"><?= $store->getStatus() ?></option>
<?php if (($user->getRole()) === 'admin'): ?>
<option value="Выполнено"><h1>Выполнено</h1></option>
<option value="Зарегистрировать">Зарегистрировать</option>
<option value="Заменить">Заменить</option>
<?php endif; ?>
</select>
<?php if (($user->getRole()) === 'admin'): ?>
<button value="<?= $store->getId() ?>">Send</button>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
Таблице даем id (в примере это sender), тогда:
document.addEventListener("DOMContentLoaded", function () {
document.getElementById('sender').addEventListener('click', function(e) {
if(e.target.localName == 'button') {
const together = "status=" + e.target.parentNode.querySelector('select').value + "&id=" + e.target.value;
var request = new XMLHttpRequest();
request.open('POST', 'http://fiscaloop.ru/stores/kosarev/edit-store/', true);
request.addEventListener('readystatechange', function () {
if ((request.readyState == 4) && (request.status == 200)) {
var resultStatus = document.getElementById('resultStatus');
resultStatus.innerHTML = request.responseText;
//это какая-то билиберда
$('.selectChange:contains("Зарегистрировать")').parents(".trColor").css('background','#ffd700');
$('.selectChange:contains("Заменить")').parents(".trColor").css('background','#E9967A');
$('.selectChange:contains("Выполнено")').parents(".trColor").css('background', '#fff8dc');
}
});
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(together);
}
})
//что к чему тут не понять
$('.selectChange:contains("Зарегистрировать")').parents(".trColor").css('background','#ffd700');
$('.selectChange:contains("Заменить")').parents(".trColor").css('background','#E9967A');
});
|
|
04.12.2019, 19:10
|
Новичок на форуме
|
|
Регистрация: 03.12.2019
Сообщений: 4
|
|
Спасибо тебе ОГРОМНОЕ!!!! теперь все получилось как хотел. немного поправил, чтобы ответ приходил и устанавливался в ту строку, откуда ушел. Спасибо!
|
|
|
|