Дві кнопки подання в одній формі


534

У мене є дві кнопки подання у формі. Як визначити, на кого потрапив сервер?


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

2
@PeterMortensen - Ні прийнята відповідь, ні відповідь Папуга сьогодні не найкращі. Дивіться відповідь Лео про новіше рішення HTML5 за допомогою атрибута formaction. Або подивіться відповідь kiril про те, як бачити HTML, який користувач може бачити незалежним від значення, надісланого браузеру - вирішення проблеми інтернаціоналізації простішим у коді способом, ніж відповідь Грега чи Папуга.
ToolmakerSteve

Відповіді:


446

Якщо ви дасте ім’я кожному, натиснутий буде надісланий, як і будь-який інший вхід.

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

101
Також переконайтесь, що назва кнопки має правильну назву! Наприклад, "кнопка-1" НЕ працює. Може врятувати когось багато клопоту, тому пам’ятайте про це.
pdolinaj

22
Зазвичай всі вхідні дані у формі надсилаються разом із формою. Оскільки значення кнопки подається лише при натисканні, вам доведеться шукати значення форм для цих заздалегідь визначених імен. Я думаю, що інша відповідь ( stackoverflow.com/a/21778226/88409 ), яка передбачає надання їм однакових назв, з різними значеннями, має більше сенсу. Тоді ви просто захопите значення під одним відомим іменем поля форми. Це також робить більш очевидним, що для даного імені введення буде надіслано лише одне значення (натиснуте), як і те, як працюють перемикачі (однакова назва, різні значення).
Трайнко

6
@Triynko, як сказав Робін Грін у коментарях до цієї відповіді, цей варіант краще для інтернаціоналізації. Наприклад, якщо сторінка надана іспанською мовою, текст кнопок, ймовірно, буде іншим. Тож наявність логіки вашого коду, що залежить від тексту цієї кнопки, в цьому випадку порушиться. Переходити по імені безпечніше, оскільки це значення, яке не відображається користувачеві, і тому його можна трактувати більше як "приватну" змінну і менше як повідомлення для користувачів.
sfarbota

Щоб уточнити коментар @ sfarbota: Перше рішення, показане у відповіді Папуга, є проблематичним, оскільки воно покладається на тестування видимого для користувача значення. Це сумнівно - код, який ламається при зміні видимого користувачем слова, вважається "крихким". Друге рішення , показане у відповідь Папугу прекрасно - це те ж саме , як цей. Друге рішення Папуга також показує відповідний код для запису, отже, це більш корисна відповідь, ніж цей.
ToolmakerSteve

2
Дивіться відповідь Лео про новіше рішення HTML5 за допомогою атрибута formaction. Або дивіться відповідь kiril про те, як бачити 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 [nternationalizatio] n, а 18 означає 18 літер між першою та останньою.
Buttle Butkus

18
ОП не просила PHP.
Rudey

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
Мабуть, поведінка браузера відрізняється; одні надсилають атрибут значення, інші - рядок між тегами ... Тому будьте обережні з цим.
Jeroen Dierckx

1
Я думаю, що наданий фрагмент повністю підтримується ( w3schools.com/tags/att_button_type.asp )
kiril

2
@kiril У фрагменті цього посилання використовується два різні типи <button>: submitі reset. Зауважте, що resetнічого не надсилається, він просто скидає форму. Тож аргумент Джерона залишається.
фізрук

7
Гаразд, ваше право. Потім я перевірив робочу чернетку HTML5 W3C. Цитуючи: >> Атрибут value надає значення елемента для цілей подання форми. Значення елемента - це значення атрибута значення елемента, якщо він є, або порожній рядок інакше. >> ПРИМІТКА. Кнопка (та її значення) включається до подання форми лише тоді, коли сама кнопка була використана для ініціювання надсилання форми.
Кіріл

8
@Jeroen Bull. Які браузери подають текст між тегами? Вхід або кнопка повинні коли-небудь надсилати атрибут 'value'. Кнопка може буквально містити що-небудь між тегами, включаючи зображення або інші теги HTML. У цьому вся суть використання кнопки над вхідним елементом, і ви намагаєтесь припустити, що браузер скидає весь цей вміст як значення? У жодному разі.
Трайнко

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> Атрибут формації ).

Особисто я використовую Javascript для подачі форм дистанційно (для швидшого сприйняття зворотного зв'язку) з таким підходом як резервне копіювання. Між цими двома особами, які не охоплені, є IE <9 з відключеним Javascript.

Звичайно, це може бути недоцільним, якщо ви в основному виконуєте одну і ту ж дію на сервері дій незалежно від того, яка кнопка була натиснута, але часто, якщо доступні дві дії на стороні користувача, вони також будуть відповідати двом діям на стороні сервера.

Редагувати: Як зазначив Pascal_dher у коментарях, цей атрибут також доступний і в <input>тегу.


1
Також доступний для тегу "введення". Кодування до 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 - Але користувачі отримали підтримку . бери свій вибір !!
користувач12379095

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, як у цій відповіді. Це корисний навик знати. ОТОХ, більш високооборочені відповіді також добре працюють - ігноруйте головне речення цієї відповіді. Якщо з якихось причин ви не можете отримати відповіді на інші відповіді, тоді опублікуйте повний код як питання ТАК, поясніть, що відбувається (чи не відбувається), і запитайте, що ви робите неправильно.
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 іншої відповіді я не бачив або не помітив, коли я писав власну. Це насправді те саме, але це просто підкреслює, як більшість людей віддає перевагу цій логіці. Різниця полягає лише в назвах з смислових причин, добре розуміння новичок або того, хто любить починати з цього.
Тиеліко

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
Це лише "наглядно", коли використовується неправильно: 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

Ви формуєте для декількох кнопку подання в одному прикладі форми

 <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 та надіслати отримання зі значенням, доданим до кожної кнопки. Але тоді форма не потрібна

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

Це не працює для контролерів під POSTмаршрутами.
Хаві Монтеро

отже, "надішліть"
Джонатан Лаліберте,

3
Вибачте, не погоджуючись, але GETне завжди підходить. Якщо ви "модифікуєте стан своєї моделі", ви ніколи не повинні використовувати a GET, оскільки оновлення браузера може дати прозорі надсилання двох запитів у два рази. Використовуйте GETлише для "перегляду" речей та POSTнадсилання запитів змін держав (додавання, видалення, редагування тощо). то у вашому POSTдії контролера змініть стан (база даних, сесія ...) та видайте відповідь перенаправлення, яка потім 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>

Форми

При натисканні на вхід -> loginForm

При натисканні кнопки "Зберегти" -> "зберегти форму"

При натисканні на Реєстрація -> реєстраційна форма

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.