Две кнопки отправки в одной форме


534

У меня есть две кнопки отправки в форме. Как определить, какая из них была поражена серверной стороной?


Подумайте об изменении принятого ответа на ответ Попугаев .
Питер Мортенсен

2
@PeterMortensen - Ни принятый ответ, ни ответ Попугая не являются лучшими сегодня. См . Ответ Лео о новом решении HTML5 с использованием атрибута formaction. Или посмотрите ответ Кирилла о том, как сделать так, чтобы HTML, видимый пользователю, был независимым от значения, отправляемого в браузер, - решая проблему интернационализации более простым способом, чем ответ Грега или Попугая.
ToolmakerSteve

Ответы:


448

Если вы дадите каждому имя, то выбранное будет отправлено как любой другой ввод.

<input type="submit" name="button_1" value="Click me">

101
Также убедитесь, что название кнопки имеет правильное имя! Например "кнопка-1" не будет работать. Может спасти кого-то много хлопот, так что имейте это в виду.
pdolinaj

22
Обычно все входные данные в форме отправляются вместе с формой. Поскольку значение кнопки передается только при нажатии, вам придется искать значения формы для этих предварительно определенных имен. Я думаю, что другой ответ ( stackoverflow.com/a/21778226/88409 ), который включает в себя присвоение им одинаковых имен с разными значениями, имеет больше смысла. Затем вы просто берете значение под одним известным именем поля формы. Это также делает более очевидным, что для данного имени входа будет отправлено только одно значение (выбранное), что очень похоже на работу переключателей (одно и то же имя, разные значения).
Triynko

6
@Triynko, как сказал Робин Грин в комментариях к этому ответу, этот лучше для интернационализации. Например, если страница отображается на испанском языке, текст кнопок, скорее всего, будет другим. Таким образом, логика вашего кода зависит от текста этой кнопки в этом случае. Переход по имени более безопасен, так как это значение, которое не отображается пользователю и поэтому может рассматриваться скорее как «частная» переменная, а не как сообщение для пользователей.
сфарбота

Чтобы уточнить комментарий @ sfarbota: первое решение, показанное в ответе Parrot, проблематично, так как оно основано на тестировании видимого пользователем значения. Это сомнительно - код, который ломается при изменении видимого пользователем слова, считается «хрупким». Второе решение , показанное в ответ Попугая прекрасно - это то же самое , как этот. Второе решение Parrot также показывает соответствующий код для записи, следовательно, это более полезный ответ, чем этот.
ToolmakerSteve

2
См . Ответ Лео о новом решении HTML5 с использованием атрибута formaction. Или посмотрите ответ Кирилла о том, как сделать HTML видимым для пользователя независимым от значения, отправляемого в браузер, - решая проблему интернационализации.
ToolmakerSteve

875

Решение 1:
присвойте каждому входу различное значение и сохраняйте то же имя:

<input type="submit" name="action" value="Update" />
<input type="submit" name="action" value="Delete" />

Затем в коде проверьте, что было сработало:

if ($_POST['action'] == 'Update') {
    //action for update here
} else if ($_POST['action'] == 'Delete') {
    //action for delete
} else {
    //invalid action!
}

Проблема в том, что вы связываете свою логику с видимым пользователем текстом на входе.


Решение 2.
Дайте каждому уникальное имя и проверьте $ _POST на наличие этих входных данных:

<input type="submit" name="update_button" value="Update" />
<input type="submit" name="delete_button" value="Delete" />

И в коде:

if (isset($_POST['update_button'])) {
    //update action
} else if (isset($_POST['delete_button'])) {
    //delete action
} else {
    //no button pressed
}

37
Для целей i18n может быть лучше использовать выбранный ответ.
Робин Грин

11
@LaszloPapp, как говорит сам ответ, если вы используете выбранный ответ выше, вы можете интернационализировать форму (т.е. переводить на разные языки или диалекты), не затрагивая логику. Если вы используете первую опцию в этом ответе, логика зависит от языка, на котором фактически представлена ​​форма.
Робин Грин

1
@RobinGreen: я думаю, что большинство людей будут использовать вторую логику, не так ли?
lpapp

5
i18n = i [n internationalizatio] n, а 18 означает 18 букв между первым и последним.
Баттл Буткус

18
ОП не просил PHP.
Рудей

110

Еще лучшее решение состоит в использовании тегов кнопок для отправки формы:

<form>
    ...
    <button type="submit" name="action" value="update">Update</button>
    <button type="submit" name="action" value="delete">Delete</button>
</form>

HTML внутри кнопки (например, ..>Update<..это то, что видит пользователь; поскольку предоставляется HTML, valueон невидим для пользователя; он отправляется только на сервер. Таким образом, нет никаких неудобств с интернационализацией и несколькими языками отображения (в прежнее решение, метка кнопки также является значением, отправленным на сервер).


13
Видимо поведение браузера отличается; некоторые передают атрибут value, другие - строку между тегами ... Так что будьте осторожны с этим.
Йерун Диркс

1
Я думаю, что предоставленный фрагмент полностью поддерживается ( w3schools.com/tags/att_button_type.asp )
кирил

2
@kiril фрагмент этой ссылки использует два различных типа <button>: submitи reset. Обратите внимание, что resetничего не отправляет, а просто сбрасывает форму. Таким образом, аргумент Jeroen остается.
Физрук

7
Хорошо, ты прав. Затем я проверил рабочий проект HTML5 W3C. Цитирование: >> Атрибут value дает значение элемента для целей отправки формы. Значение элемента - это значение атрибута значения элемента, если он есть, или пустая строка в противном случае. >> ПРИМЕЧАНИЕ. Кнопка (и ее значение) включается в отправку формы только в том случае, если сама кнопка использовалась для инициирования отправки формы.
Кирил

8
@Jeroen Bull. Какие браузеры отправляют текст между тегами? Вход или кнопка должны только когда-либо отправлять атрибут 'value'. Кнопка может буквально иметь между тегами что угодно, включая изображения или другие теги HTML. В этом весь смысл использования кнопки над элементом ввода, и вы пытаетесь предположить, что браузер собирается сбросить весь этот контент в качестве значения? Ни за что.
Triynko

93

Существует новый подход HTML5 к этому, formactionатрибут:

<button type="submit" formaction="/action_one">First action</button>
<button type="submit" formaction="/action_two">Second action</button>

По-видимому, это не работает в IE9 и более ранних версиях , но для других браузеров у вас все должно быть в порядке (см .: w3schools.com HTML <button> Атрибут formaction ).

Лично я обычно использую Javascript для удаленной отправки форм (для более быстрой обратной связи) с этим подходом в качестве резервного. Между двумя единственными людьми, которые не охвачены, являются IE <9 с отключенным Javascript.

Конечно, это может быть неуместно, если вы в основном выполняете одно и то же действие на стороне сервера, независимо от того, какая кнопка была нажата, но часто, если доступно два действия на стороне пользователя, они также сопоставляются с двумя действиями на стороне сервера.

Редактировать: Как отметил Pascal_dher в комментариях, этот атрибут также доступен для <input>тега.


1
Также доступно для тега «input». В соответствии с w3schools: при использовании тега кнопки разные браузеры могут отправлять разные значения: w3schools.com/tags/tag_button.asp
Pascal_dher

3
Я был веб-разработчиком в течение 12 лет, и этот новый для меня и был именно то, что мне нужно, на самом деле. Спасибо!
KyleFarris

1
Всегда пожалуйста @KyleFarris! Я считаю, что это стало возможным только относительно недавно, поэтому не удивительно, если вы еще не столкнулись с этим.
Лев

2
Примечание для пользователей Rails: добавление этого атрибута не будет работать, если ваша форма создана с использованием form_tag. Единственный способ заставить его работать - это переключиться form_forи использовать f.submit formaction: 'your_path'.
fgblomqvist


27

Это очень легко проверить

<form action="" method="get">

<input type="submit" name="sb" value="One">
<input type="submit" name="sb" value="Two">
<input type="submit" name="sb" value="Three">

</form>

Просто поместите это на HTML-страницу, нажмите кнопки и посмотрите на URL


5
Использование GET здесь является несколько плохой практикой, следует использовать POST, когда это возможно.
Синкросс

6
@Syncrossus Это для целей тестирования.
Этьен Мартин

22

Используйте formactionатрибут HTML (5-я строка):

<form action="/action_page.php" method="get">
    First name: <input type="text" name="fname"><br>
    Last name: <input type="text" name="lname"><br>
    <button type="submit">Submit</button><br>
    <button type="submit" formaction="/action_page2.php">Submit to another page</button>
</form>


@ToolmakerSteve - но пользователи проголосовали . выбирайте!!
user12379095

21
<form>
    <input type="submit" value="Submit to a" formaction="/submit/a">
    <input type="submit" value="submit to b" formaction="/submit/b">    
</form>

Особенность HTML5. Отлично работает на последних веб-браузерах, спасибо!
Стефан Лаллемань

1
ПРИМЕЧАНИЕ. Это похоже на предыдущий ответ Лео , за исключением того, что в нем показано использование inputтега, а не buttonтега.
ToolmakerSteve

11

Лучший способ справиться с несколькими кнопками отправки - использование регистра переключателя в скрипте сервера.

<form action="demo_form.php" method="get">

Choose your favorite subject:

<button name="subject" type="submit" value="html">HTML</button>
<button name="subject" type="submit" value="css">CSS</button>
<button name="subject" type="submit" value="javascript">Java Script</button>
<button name="subject" type="submit" value="jquery">jQuery</button>

</form>

серверный код / ​​серверный скрипт - где вы отправляете форму:

demo_form.php

<?php

switch($_REQUEST['subject']) {

    case 'html': //action for html here
                break;

    case 'css': //action for css here
                break;

    case 'javascript': //action for javascript here
                        break;

    case 'jquery': //action for jquery here
                    break;
}

?>

Источник: W3Schools.com


да, вы должны иметь представление о сценариях действий (технология сценариев на стороне сервера). Вы можете использовать любой сценарий / файл для обработки отправленных данных, например, php, asp, jsp и т. д. <form action="demo_form.php" method="get">
Shailesh Sonare

Ладно. Это сбивало с толку, потому что есть также язык с именем ActionScript. Вместо этого вы должны сказать: «код сервера» или «серверный скрипт».
Гражданское

Я понятия не имел, что вы можете сделать это с помощью кнопок
Уильям Истед

10

Возможно, предложенные здесь решения сработали в 2009 году, но я проверил все эти ответы, и никто не работает ни в одном браузере.

единственное решение, которое я нашел работающим, это: (но я думаю, его немного уродливо использовать)

<form method="post" name="form">
<input type="submit" value="dosomething" onclick="javascript: form.action='actionurl1';"/>
<input type="submit" value="dosomethingelse" onclick="javascript: form.action='actionurl2';"/>


2
Почему бы просто не использовать formaction="actionurl1"? Вам не нужен JavaScript.
rybo111

3
@ rybo111 IE9 браузер (ведьма относительно все еще широко используется) не поддерживаетformaction
clueless007

1
@inaliaghle Правда, это около 1% пользователей - это зависит от того, на кого ориентирован проект. Приблизительно 1% пользователей не используют JavaScript.
rybo111

1
Для будущих читателей: нет ничего плохого в использовании JavaScript, как в этом ответе. Это полезный навык, чтобы знать. OTOH, более высоко проголосовавшие ответы также работают отлично - игнорируйте главное предложение этого ответа. Если по какой-то причине вы не можете заставить эти другие ответы работать, то опубликуйте свой полный код в виде SO-вопроса, объясните, что происходит (или не происходит), и спрашивайте, что вы делаете неправильно.
ToolmakerSteve

6

Определить nameкак array.

<form action='' method=POST>
    (...) some input fields (...)
    <input type=submit name=submit[save] value=Save>
    <input type=submit name=submit[delete] value=Delete>
</form>

Пример кода сервера (PHP):

if (isset($_POST["submit"])) {
    $sub = $_POST["submit"];

    if (isset($sub["save"])) {
        // save something;
    } elseif (isset($sub["delete"])) {
        // delete something
    }
}

elseifочень важно, потому что оба будут проанализированы, если нет. Наслаждаться.


Теперь это отличное предложение - в основном потому, что вы можете очень легко добавить больше кнопок с большим количеством дел и использовать действие switchс действием по умолчанию, если кто-то добавил кнопку и забыл добавить ее в switch(и / или что-то неправильно написал и т. Д.)
Гвинет Ллевелин

Кроме того, @Pato добавил аналогичный ответ, который, возможно, более идиоматичен, но ваш работает отлично!
Гвинет Ллевелин

1
@GwynethLlewelyn Я не видел другой ответ назад или не заметил, когда я написал свой собственный. Это на самом деле то же самое, но это просто подчеркивает, как большинство людей предпочитают эту логику. Разница только в именах по семантическим причинам, в хорошем понимании для новичков или тех, кому нравится начинать с них.
Thielicious

5

Поскольку вы не указали, какой метод сценариев на стороне сервера вы используете, я приведу пример, который работает для Python, используя CherryPy (хотя это может быть полезно и для других контекстов):

<button type="submit" name="register">Create a new account</button>
<button type="submit" name="login">Log into your account</button>

Вместо того, чтобы использовать значение, чтобы определить, какая кнопка была нажата, вы можете использовать имя (с <button>тегом вместо <input>). Таким образом, если ваши кнопки имеют одинаковый текст, это не вызовет проблем. Имена всех элементов формы, включая кнопки, отправляются как часть URL. В CherryPy каждый из них является аргументом для метода, который выполняет код на стороне сервера. Итак, если ваш метод имеет только **kwargsсвой список параметров (вместо утомительного ввода каждого имени каждого элемента формы), вы можете проверить, какая кнопка была нажата следующим образом:

if "register" in kwargs:
    pass #Do the register code
elif "login" in kwargs:
    pass #Do the login code

3
<form method="post">
<input type="hidden" name="id" value="'.$id.'" readonly="readonly"/>'; //any value to post PHP
<input type='submit' name='update' value='update' formAction='updateCars.php'/>
<input type='submit' name='delete' value='delete' formAction='sqlDelete.php'/>
</form>

2

Я думаю, вы должны быть в состоянии прочитать имя / значение в вашем массиве GET. Я думаю, что кнопка, которая не была нажата, не появится в этом списке.


Вы, скорее всего, имеете в виду массив POST.
ypnos

3
Не обязательно, если метод формы «POST», он не будет отображаться в массиве GET. Большинство форм отправляются через POST.
Попугаи

2
Либо / или технически правильно, и все же так неправильно. Вы можете отправить форму с методом = "GET", но она заслуживает внимания.
Билл Ящерица

4
Это только «cringeworthy» при использовании по назначению: w3.org/2001/tag/doc/whenToUseGet.html .
Меркатор

2
Да, я не пытался предложить GET, я просто пытался обобщить вещи.
Джон Бубриски

1

Вы также можете сделать это так (я думаю, это очень удобно, если у вас есть N входов).

<input type="submit" name="row[456]" value="something">
<input type="submit" name="row[123]" value="something">
<input type="submit" name="row[789]" value="something">

Распространенным вариантом использования будет использование разных идентификаторов из базы данных для каждой кнопки, чтобы вы могли позже узнать, на каком сервере щелкали строки.

На стороне сервера (в данном примере PHP) вы можете прочитать строку как массив, чтобы получить идентификатор. $_POST['row']будет массивом только с одним элементом в форме [ id => value ](например:) [ '123' => 'something' ].

Итак, чтобы получить идентификатор клика, вы делаете:

$index = key($_POST['row']);

http://php.net/manual/en/function.key.php


Это похоже на ответ @Thielicious публикуемого , но у вас, возможно , более идиоматические. Лично я предпочитаю использовать алфавитно-цифровые теги для индекса (в отличие от цифр) для удобства чтения (легче запомнить, что должна делать каждая кнопка), но YMMV. Но воспользоваться преимуществом $_POST['row']ассоциативного массива - умно!
Гвинет Ллевелин

1
Я согласен, что если вы имеете дело со статическими кнопками, вы должны использовать именованные ключи. Но в некоторых случаях вы не можете. Иногда вы генерируете эти входы динамически. Наиболее распространенным случаем этого является список строк, каждая из которых идентифицируется идентификатором. Я думаю, я думал о том случае, когда я написал ответ (4 года назад!). Я отредактировал это так, чтобы было более очевидно, что число является идентификатором, а не индексом.
Пато

Отлично сработано! Да, я согласен, теперь это более очевидно; Я все еще верю, что ваш ответ немного лучше, чем ответ @Thielicious (и, возможно, даже немного более эффективен, особенно если есть много кнопок).
Гвинет Ллевелин

1

Вы Formaction для нескольких кнопки отправки в одном примере формы

 <input type="submit" name="" class="btn action_bg btn-sm loadGif" value="Add Address" title="" formaction="/addAddress"> 
 <input type="submit" name="" class="btn action_bg btn-sm loadGif" value="update Address" title="" formaction="/updateAddress"> 

0

Просто вы можете изменить действие формы на разные кнопки отправки Нажмите.

Попробуйте это в документе.

$(".acceptOffer").click(function () {
       $("form").attr("action", "/Managers/SubdomainTransactions");
});

$(".declineOffer").click(function () {
       $("form").attr("action", "/Sales/SubdomainTransactions");
});

0

Вы также можете использовать атрибут href и отправить get со значением, добавленным для каждой кнопки. Но тогда форма не потребуется

href="/SubmitForm?action=delete"
href="/SubmitForm?action=save"

Это не будет работать для контроллеров под POSTмаршрутами.
Хави Монтеро

следовательно, «отправить получить»
Джонатан Лалиберте

3
Извините, что не согласен, но GETне всегда подходит. Если вы «изменяете состояние своей модели», то никогда не должны использовать a GET, поскольку обновление браузера может привести к прозрачной отправке двух раз одного и того же запроса. Используйте GETтолько для «просмотра» вещей и POSTотправки запросов об изменении состояния (добавление, удаление, редактирование и т. Д.). затем в POSTдействии вашего контроллера измените состояние (база данных, sesion ...) и создайте ответ перенаправления, который затем отобразит GETновое измененное состояние. Делать GETдля изменения состояния модели очень грязно, и любой хороший кодер должен избегать этого. Извините, что сказал это. Чистый код рулез.
Хави Монтеро

Правда. Но иногда грязная игра может быть чистой. Это зависит от того, что вы делаете точно. Лично он не отображает запросы на удаление и редактирование при получении, но есть способы заставить его работать .. например, проверить, было ли оно уже удалено, или проверить, есть ли у пользователя разрешение на это и т. Д.
Джонатан Лалиберте,

-1

Вы можете представить кнопки так:

<input type="submit" name="typeBtn" value="BUY">
<input type="submit" name="typeBtn" value="SELL">

И тогда в коде вы можете получить значение, используя:

if request.method == 'POST':
    #valUnits = request.POST.get('unitsInput','')
    #valPrice = request.POST.get('priceInput','')
    valType = request.POST.get('typeBtn','')

(valUnits и valPrice - некоторые другие значения, которые я извлекаю из формы, оставленной для иллюстрации)


-1

Поскольку вы не указали, какой метод сценариев на стороне сервера вы используете, я приведу пример, который работает для PHP

<?php
   if(isset($_POST["loginForm"]))
   {
    print_r ($_POST); // FOR Showing POST DATA
   }
   elseif(isset($_POST["registrationForm"]))
   {
    print_r ($_POST);
   }
   elseif(isset($_POST["saveForm"]))
   {
    print_r ($_POST);
   }
   else{

   }
?>
<html>
<head>
</head>
<body>
  
  <fieldset>
    <legend>FORM-1 with 2 buttons</legend>
      <form method="post" >
      <input type="text" name="loginname" value ="ABC" >

     <!--Always use type="password" for password --> 
     <input type="text" name="loginpassword" value ="abc123" >
     
     <input type="submit" name="loginForm" value="Login"><!--SUBMIT Button 1 -->
     <input type="submit" name="saveForm" value="Save">  <!--SUBMIT Button 2 -->
   </form>
  </fieldset>



  <fieldset>
    <legend>FORM-2 with 1 button</legend>
     <form method="post" >
      <input type="text" name="registrationname" value ="XYZ" >
      
     <!--Always use type="password" for password -->
     <input type="text" name="registrationpassword" value ="xyz123" >
     
     <input type="submit" name="registrationForm" value="Register"> <!--SUBMIT Button 3 -->
   </form>
  </fieldset>
  

</body>
</html>

формы

Когда нажимаете на Login -> loginForm

При нажатии Сохранить -> saveForm

Когда нажимаете Зарегистрироваться -> Форма регистрации

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.