Як заборонити кнопкам надсилати форми


917

На наступній сторінці за допомогою Firefox кнопка видалення подає форму, але кнопка "Додати" не робить. Як запобігти надсиланню форми кнопкою видалення?

<html>

<head>
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        function addItem() {
            var v = $('form :hidden:last').attr('name');
            var n = /(.*)input/.exec(v);

            var newPrefix;
            if (n[1].length == 0) {
                newPrefix = '1';
            } else {
                newPrefix = parseInt(n[1]) + 1;
            }

            var oldElem = $('form tr:last');
            var newElem = oldElem.clone(true);
            var lastHidden = $('form :hidden:last');

            lastHidden.val(newPrefix);

            var pat = '=\"' + n[1] + 'input';

            newElem.html(newElem.html().replace(new RegExp(pat, 'g'), '=\"' + newPrefix + 'input'));
            newElem.appendTo('table');
            $('form :hidden:last').val('');
        }

        function removeItem() {
            var rows = $('form tr');
            if (rows.length > 2) {
                rows[rows.length - 1].html('');
                $('form :hidden:last').val('');
            } else {
                alert('Cannot remove any more rows');
            }
        }
    </script>
</head>

<body>
    <form autocomplete="off" method="post" action="">
        <p>Title:<input type="text" /></p>
        <button onclick="addItem(); return false;">Add Item</button>
        <button onclick="removeItem(); return false;">Remove Last Item</button>
        <table>
            <th>Name</th>

            <tr>
                <td><input type="text" id="input1" name="input1" /></td>
                <td><input type="hidden" id="input2" name="input2" /></td>
            </tr>
        </table>
        <input id="submit" type="submit" name="submit" value="Submit">
    </form>
</body>

</html>

яку відповідь ви рекомендуєте, будь ласка?
санепете

Відповіді:


1795

Ви використовуєте елемент кнопки HTML5. Пам’ятайте, що ця кнопка має поведінку за замовчуванням при поданні, як зазначено в специфікації W3, як показано тут: Кнопка W3C HTML5

Тому потрібно чітко вказати його тип:

<button type="button">Button</button>

щоб змінити тип подання за замовчуванням. Я просто хочу вказати на причину, чому це відбувається =)

=)


17
Я також хочу зазначити, що HTML-елемент, який має атрибут типу, одним із типів якого є кнопка , не повинен мати # # '' n типом подання за замовчуванням . Це просто простий ідіот і величезна помилка в специфікації. Я постійно використовую кнопки у формах, і навіть якщо це був кращий регістр (якого це не так), все одно має сенс подати тип за замовчуванням.
dudewad

3
Я провів більшу частину цього тижня роздратований тим, що мій додаток Electron "оновився", коли я відкриваю модаль за допомогою кнопки у формі. Це сталося б один раз, і тоді додаток поводиться так, як я очікував. Я абсолютно не мав уявлення, що відбувається. Це було все! У мене немає проблем із типом, що надсилається за замовчуванням. Здається, це є трохи хатча, хоча з огляду на це мені знадобилося п'ять років.
freethebees

4
Завдяки вашій довідці, я щойно дізнався, що існує форма = скидання для форми. Дивовижно!
Duong Nguyen

602

Встановіть тип на своїх кнопках:

<button type="button" onclick="addItem(); return false;">Add Item</button>
<button type="button" onclick="removeItem(); return false;">Remove Last Item</button>

... це не дозволить їм ініціювати дію надсилання, коли в обробнику подій трапляється виняток. Потім виправте свою removeItem()функцію так, щоб вона не викликала винятку:

function removeItem() {
  var rows = $('form tr');
  if ( rows.length > 2 ) {
    // change: work on filtered jQuery object
    rows.filter(":last").html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

Зверніть увагу на зміну: ваш початковий код вилучив елемент HTML з набору jQuery, а потім спробував викликати метод jQuery на ньому - це викинуло виняток, що призвело до поведінки кнопки за замовчуванням.

FWIW, є й інший спосіб, як ви могли б скористатися цим ... Підключіть обробники подій за допомогою jQuery і скористайтеся методом prevenDefault () об'єкта події jQuery, щоб скасувати поведінку за замовчуванням наперед :

$(function() // execute once the DOM has loaded
{

  // wire up Add Item button click event
  $("#AddItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of add logic
  });

  // wire up Remove Last Item button click event
  $("RemoveLastItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of remove last logic
  });

});

...

<button type="button" id="AddItem" name="AddItem">Add Item</button>
<button type="button" id="RemoveLastItem" name="RemoveLastItem">Remove Last Item</button>

Цей прийом зберігає всю вашу логіку в одному місці, полегшуючи налагодження ... він також дозволяє реалізувати запасний процес, змінюючи кнопки typeвключення назад submitі обробляти події на стороні сервера - це відоме як ненав'язливий JavaScript .


4
type = "button" не завжди для мене працює у Firefox. Якщо js досить складний, і помилка все одно надішле Firefox. Божевілля!
Метью Лок

1
@MatthewLock: Навряд чи - помилка в скрипті просто закриває цей блок коду, і дія триває як завжди. Спробуйте викликати методи подій jQuery e.preventDefault () та / або e.stopPropgation () в якості перших рядків методу. Дивіться stackoverflow.com/questions/2017755/…, щоб дізнатися більше
brichins

8
type = кнопка ніколи не повинна надсилати форму, незважаючи ні на що
Метью Блокування

1
return falseтак важливо. іноді навіть використовують його для кнопки подання ( onclick
Джеймі,

7
Я думаю, що html тут дивний. За замовчуванням має бути type = "button", не надсилаючи. Мені завжди несподівано бачити це надсилання за замовчуванням. Це виняток.
httpste

31

Десь тому мені було потрібно щось дуже схоже ... і я це отримав.

Тож, що я вкладаю сюди, це те, як я роблю трюки, щоб форма могла бути представлена ​​JavaScript без будь-якої перевірки та виконання перевірки лише тоді, коли користувач натискає кнопку (як правило, кнопку відправки).

Для прикладу я використовуватиму мінімальну форму, лише з двома полями та кнопкою подання.

Пам’ятайте, що потрібно: з JavaScript це потрібно мати можливість подавати без будь-якої перевірки. Однак якщо користувач натискає таку кнопку, перевірку потрібно виконати, а форму надсилати лише у разі проходження перевірки.

Зазвичай все починається з чогось поблизу (я видалив усі зайві речі, не важливі):

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="submit" value="Send" onclick="JavaScript:return Validator();" />
</form>

Подивіться, як тег форми не має onsubmit="..."(пам’ятайте, це було умовою не мати його).

Проблема полягає в тому, що форма завжди подається, незалежно від того, onclickповертається trueчи false.

Якщо я замінюсь type="submit"на type="button"це, то, здається, це працює, але це не так. Він ніколи не надсилає форму, але це можна зробити легко.

Тож нарешті я використав це:

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="button" value="Send" onclick="JavaScript:return Validator();" />
</form>

І function Validatorде return True;я також додаю речення для надсилання JavaScript, щось подібне до цього:

function Validator(){
   //  ...bla bla bla... the checks
   if(                              ){
      document.getElementById('theFormID').submit();
      return(true);
   }else{
      return(false);
   }
}

Це id=""тільки для JavaScript getElementById, name=""це лише для того, щоб він відображався на даних POST.

Так працює, як мені потрібно.

Я ставлю це лише людям, які не потребують onsubmitфункції у формі, але роблять певну перевірку, коли користувач натискає кнопку.

Чому мені не потрібно підписувати тег форми? Легко, в інших частинах JavaScript мені потрібно виконати подання, але я не хочу, щоб там було підтвердження.

Причина: Якщо користувач - це той, хто виконує подання, я хочу, і потрібна перевірка, але якщо це JavaScript, іноді мені потрібно виконати подання, тоді як такі перевірки уникнуть цього.

Це може здатися дивним, але не замислюючись, наприклад: при вході в систему ... з деякими обмеженнями ... як, наприклад, не дозволяється використовувати сеанси PHP, і жодне cookie не дозволено!

Отже, будь-яке посилання має бути перетворене на таку форму подання, щоб дані про вхід не втрачалися. Якщо вхід ще не виконаний, він також повинен працювати. Тому перевірка не повинна проводитися на посиланнях. Але я хочу представити повідомлення користувачеві, якщо користувач не ввів і поля, і користувача, і пропуск. Тож якщо одного немає, форму не потрібно надсилати! є проблема.

Дивіться проблему: форма не повинна надсилатися, коли одне поле порожнє, лише якщо користувач натиснув кнопку, якщо це код JavaScript, він повинен мати можливість надсилати.

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

Тож рішення - не мати підписки на тезі форми. Інсейд поклав її там, де це дійсно потрібно, на кнопку.

З іншого боку, навіщо ставити код подання, оскільки концептуально я не хочу перевірити подання. Я дуже хочу перевірити кнопку.

Код не тільки зрозуміліший, він і повинен бути. Пам'ятайте лише про це: - Я не хочу, щоб JavaScript перевіряв форму (це завжди повинно робити PHP на стороні сервера) - Я хочу показати користувачеві повідомлення про те, що всі поля не повинні бути порожніми, для чого потрібен JavaScript (клієнт сторона)

То чому деякі люди (подумайте чи скажіть мені) це потрібно зробити на короткий час? Ні, концептуально я не роблю навантаження, яке перевіряється на стороні клієнта. Я просто щось роблю на натисканні кнопки, так чому б не просто дозволити це реалізовувати?

Добре, що код і стиль справляють трюк ідеально. На будь-який JavaScript, який мені потрібно надіслати форму, яку я просто помістив:

document.getElementById('theFormID').action='./GoToThisPage.php'; // Where to go
document.getElementById('theFormID').submit(); // Send POST data and go there

І це пропускає перевірку, коли мені це не потрібно. Він просто надсилає форму та завантажує іншу сторінку тощо.

Але якщо користувач натискає кнопку "Надіслати" (він же type="button"не type="submit"), перевірка проводиться перед тим, як форму надсилати, а якщо недійсна - не надсилається.

Сподіваємось, це допомагає іншим не пробувати довгий і складний код. Просто не використовуйте, onsubmitякщо не потрібно, а використовуйте onclick. Але тільки НЕ забудьте змінити type="submit"до type="button"і , будь ласка , не забудьте зробити з submit()допомогою JavaScript.


28

Я погоджуюся з Shog9, хоча замість цього я можу використовувати:

<input type = "button" onClick="addItem(); return false;" value="Add Item" />

За даними w3schools , <button>тег має різну поведінку в різних браузерах.


18

Припустимо, у вашій HTML-формі є id="form_id"

<form id="form_id">
<!--your HTML code-->
</form>

Додайте цей фрагмент jQuery у свій код, щоб побачити результат,

$("#form_id").submit(function(){
  return false;
});

18

Ви можете просто отримати посилання на ваші кнопки за допомогою jQuery та запобігти її розповсюдженню, як показано нижче:

 $(document).ready(function () {
    $('#BUTTON_ID').click(function(e) {

            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();

            return false;
    });});

2
e.preventDefault(); e.stopPropagation();достатньо, щоб справи працювали. e.stopImmediatePropagation()це призводить до помилки невизначеного методу в Chrome.
Суброто

14

$("form").submit(function () { return false; }); це не дозволить натиснути кнопку, або ви можете просто змінити тип кнопки на "кнопка", <input type="button"/>замість <input type="submit"/> якої працюватиме лише якщо ця кнопка не є єдиною кнопкою у цій формі.


2
Це для jQuery, еквівалентом у Javascript є: myform.onsubmit = function () {return false} ... також, навіть якщо ви видалите кнопку для надсилання, форму можна також надіслати, натиснувши клавішу enter з іншого поля форми.
Синексис

10

Це помилка html5, як уже було сказано, ви все одно можете мати кнопку як подати (якщо ви хочете охопити як javascript, так і користувачів, які не користуються javascript), використовуючи її:

     <button type="submit" onclick="return false"> Register </button>

Таким чином ви скасуєте подання, але все одно будете робити все, що ви робите, у jquery або javascript функції `s та виконайте подання для користувачів, у яких немає JavaScript.


8

Я впевнений, що на FF

removeItem 

Функція стикається з помилкою JavaScript, це не відбувається в IE

Коли з'явиться помилка javascript, код "повернути помилковий" не запуститься, що зробить сторінку післяповерненням


8

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

 <button id="btnSubmit" type="button">PostData</button>
 <Script> $("#btnSubmit").click(function(){
   // do stuff
   return false;
}); </Script>

Або просто можна поставити так

 <button type="submit" onclick="return false"> PostData</button>

7

Просто додайте e.preventDefault();у свій метод, це не дозволяє вашій сторінці надсилати форми.

function myFunc(e){
       e.preventDefault();
}

Згідно з веб-документами MDN

Метод prevenDefault () інтерфейсу події повідомляє агенту користувача, що якщо подія не буде явно оброблена, її дії за замовчуванням не повинні враховуватися, як це було б зазвичай. Подія продовжує розповсюджуватися як завжди, якщо тільки хтось із її слухачів не дзвонить stopPropagation ()або stopImmediatePropagation ()один із них не припиняє розповсюдження.


6

Встановіть кнопку у звичайний спосіб та використовуйте event.preventDefault як ..

   <button onclick="myFunc(e)"> Remove </button>  
   ...
   ...

   In function...

   function myFunc(e){
       e.preventDefault();
   }

4
return false;

Ви можете повернути помилкове в кінці функції або після виклику функції.

Поки це останнє, що трапляється, форма не надсилається.


2

Ось простий підхід:

$('.mybutton').click(function(){

    /* Perform some button action ... */
    alert("I don't like it when you press my button!");

    /* Then, the most important part ... */
    return false;

});

1

Наведений нижче зразок коду показує, як запобігти натисканню кнопки від подання форми.

Ви можете спробувати мій зразок коду:

 <form autocomplete="off" method="post" action="">
   <p>Title:
     <input type="text" />
   </p>
   <input type="button" onclick="addItem()" value="Add Item">
   <input type="button" onclick="removeItem()" value="Remove Last Item">
   <table>
     <th>Name</th>

     <tr>
       <td>
         <input type="text" id="input1" name="input1" />
       </td>
       <td>
         <input type="hidden" id="input2" name="input2" />
       </td>
     </tr>
   </table>
   <input id="submit" type="submit" name="submit" value="Submit">
 </form>
<script language="javascript">
function addItem() {
return false;
}

function removeItem() {
return false;
}
</script>


0

Функція removeItem насправді містить помилку, завдяки якій кнопка форми виконує поведінку за замовчуванням (подаючи форму). У цьому випадку консоль помилок javascript зазвичай дасть вказівник.

Перевірте функцію RemoveItem у частині javascript:

Лінія:

rows[rows.length-1].html('');

не працює. Спробуйте це замість цього:

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