Мне нужно имя и значение кнопки (не тип ввода = отправить), когда форма отправляется с помощью кнопки типа отправки.
Я знаю, что все всегда спрашивают, почему, хотя это не является частью ответа на вопрос, поэтому я отвечу, почему, чтобы сэкономить время. Я хочу, чтобы форма направляла человека на выбор: войти в систему, зарегистрироваться или отправить подтверждение по электронной почте. Таким образом, наличие кнопок, для которых я могу установить метку, каждая из которых имеет уникальное значение для данного имени, решит эту проблему, но имя и значения не включаются в POST с остальными входными данными, когда используется тип BUTTON = submit .
Учитывая информацию в спецификации HTML5, показанную на этом сайте https://www.htmlquick.com/reference/tags/button-submit.html похоже, что это должно работать. Но если не считать добавления javascript для ручного добавления пары ключ-значение в сообщение при нажатии, это, похоже, не работает.
Теперь я хочу спросить, почему? Если в список данных можно добавить только входные данные, то почему нет возможности изменить метку входных данных отправки?
* РЕДАКТИРОВАТЬ Пока что все согласны с тем, что то, что я сделал, должно работать, поэтому давайте перейдем к конкретному случаю и посмотрим, сможем ли мы найти, в чем проблема.
Используя эту форму:
<form data-targetblock="accountBlock" class="fetchForm" action="<?=ADDRESS ?>/MAINhubs/accountBlockHub.php" method="post">
<fieldset>
<legend>Member Login</legend>
<input type="hidden" name="formTarget1" value="test">
<button type="submit" name="formTarget" value="login">Log In</button>
<button type="submit" name="formTarget" value="register">Register</button>
<button type="submit" name="formTarget" value="verify">Verify Your Email</button>
</fieldset>
</form>
Отправлено с этим:
function addFetch(event, targetBlock, domain)
{
event.preventDefault();
const form = new FormData(event.target);
const request = new Request(event.target.action,
{
method: event.target.method,
body: form,
mode: 'same-origin',
credentials: 'same-origin'
});
fetch(request)
.then(response => {
if(response.ok)
{
return response.text();
}
else
{
document.getElementById(targetBlock).innerHTML = 'ERROR! ERROR! There has been an ERROR!'
}
})
.then(function(text){document.getElementById(targetBlock).innerHTML = text;})
.catch(error => console.log('There was an error:', error))
}
Переходим к этому:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === "POST")
{
var_dump($_POST);
}
?>
Получает это, когда я нажимаю «Войти»:
formTarget1 = тест
Я предполагаю, что это связано с этой строкой в Fetch:
const form = new FormData(event.target);
Чтобы ответить на вопрос о том, как вызывается функция, запускается этот JS, чтобы добавить функцию ко всем применимым формам:
function fetchFormCallback(mutations)
{
mutations.forEach(function(mutation)
{
for (const thisForm of Array.from(document.getElementsByClassName('fetchForm')))
{
addFormListener(thisForm, thisForm.dataset.targetblock)
}
});
}
function generalCallback(mutations)
{
mutations.forEach(function(mutation)
{
// Take alertBlocks and move them to bottom of ID outerFrame because of IOS bug
if (newAlertBlock = document.getElementById('alertMessageBlock'))
{
if (newAlertBlock.dataset.relocated !== 'true')
{
var destinationBlock = document.getElementById('outerFrame');
destinationBlock.appendChild(newAlertBlock);
newAlertBlock.dataset.relocated = 'true';
}
}
// Get getElementsByClassName closeButton
for (var closeButton of Array.from(document.getElementsByClassName('closeButton')))
{
if (closeButton.dataset.closeButton !== 'true')
{
closeButton.dataset.closeButton = 'true';
closeButton.addEventListener('click', function(){this.parentNode.parentNode.removeChild(this.parentNode);});
}
}
// Potentially auto close based on a closeButton class of AUTO
});
}
document.addEventListener("DOMContentLoaded", function()
{
var config = {childList: true};
for (const thisForm of Array.from(document.getElementsByClassName('fetchForm')))
{ // setup all fetchforms
addFormListener(thisForm, thisForm.dataset.targetblock);
var thisTargetBlock = document.getElementById(thisForm.dataset.targetblock);
// if notset dataset.mutationobserver OR
if (thisTargetBlock.dataset.mutationobserver !== 'true')
{
thisTargetBlock.dataset.mutationobserver = 'true';
var observer = new MutationObserver(fetchFormCallback);
observer.observe(thisTargetBlock, config);
}
}
config = {childList: true, subtree: true};
var generalObserver = new MutationObserver(generalCallback);
generalObserver.observe(document, config);
});
function addFormListener(form, targetBlock)
{ // first check if element has attribute set for eventListeners
if (form.dataset.submitlistener !== 'true')
{
form.dataset.submitlistener = 'true';
form.addEventListener('submit', function()
{
addFetch(event, targetBlock);
});
}
}
РЕДАКТИРОВАТЬ:
Мы подтвердили, что проблема здесь в том, что FormData по какой-то причине не должен включать значение отправки. Почему значение должно быть исключено только потому, что оно может не присутствовать/не понадобиться в варианте использования, мне не понятно. У меня есть причина, по которой это должно быть включено, и я задокументировал это выше. Я разработал эту структуру так, чтобы она была как можно более универсальной без добавления кода для особых случаев.
Итак, теперь мой развивающийся вопрос стал таким:
Как; используя приведенные выше функции, я могу получить значение нажатой кнопки отправки и включить эту пару значений имени в FormData без изменения фундаментальной структуры этих функций, которые в противном случае делают именно то, что я хочу, чтобы они делали во всех остальных случаях.
Это обсуждение показывает, что это возможно, но было переработано на основе спецификации, чтобы больше не делать именно то, что я пытаюсь сделать: Объект FormData() не добавляет вводы типа submit из формы, в то время как в Firefox
Если я не могу получить доступ к имени и значению кнопки в момент отправки, то я мог бы также сделать еще один прослушиватель событий для всех элементов BUTTON в формах, который добавляет скрытый ввод с его значениями при нажатии... Прежде чем я пойду и сделать это, я уже вижу препятствия, такие как event.preventDefault(); строка в функции addFetch может предотвратить нажатие кнопки? Я думаю, что это снова метод проб и ошибок, если у кого-то нет лучшей мысли.
$_POST['formTarget']
? Не могли бы вы также показать нам соответствующий PHP-код? - person Magnus Eriksson   schedule 30.11.2020