jQuery - запобігання за замовчуванням, а потім продовження за замовчуванням


104

У мене є форма, що після її надсилання мені потрібно зробити додаткову обробку, перш ніж вона повинна подати форму. Я можу запобігти поведінці подання форми за замовчуванням, потім проведу додаткову обробку (в основному це дзвінок API Google Maps і додавання до форми декількох прихованих полів) - і тоді мені потрібна форма для надсилання.

Чи є спосіб "запобігти дефолту", а потім через деякий час "продовжити дефолт"?


@FelixKling ви мали в виду stackoverflow.com/questions/7610871 / ... ?
— М. Мімпен

Відповіді:


53

Якщо ви пов'язуєте .submit()подію з формою, і ви робите все, що хочете зробити, перш ніж повернутися (правда), ці речі відбуваються до фактичного подання.

Наприклад:

$('form').submit(function(){
    alert('I do something before the actual submission');
    return true;
});

Простий приклад

Ще один приклад на jquery.com: http://api.jquery.com/submit/#entry-examples


2
ти кажеш, що форма не надсилатиметься доти, доки весь код не стане "істинним поверненням"; заява виконується?
— develoarvin

2
Так, саме це робить функція submit () .
— Рон ван дер Хайден

8
Це не гарний приклад, оскільки це синхронічно. Що робити, якщо мені потрібно зробити асинхронний дзвінок? Тож справа в тому, що "натисніть надіслати -> зробіть асинхронний матеріал і не зробіть" надішліть форму -> в асинхронному зворотному звороті заповніть деякі поля у формі -> надішліть форму з зворотного дзвінка "
— Хрещений батько

1
А як запустити якийсь код асинхронного jQuery ?! Чи буде теж працювати?
— підсвічник

це чудово працює для мене. Я використовую його для контролю над речами перед надсиланням, і якщо вони невірні, я використовую "return false". Я шукав це рішення протягом дня. дуже дякую.
— livefreeor

53

Використовуйте jQuery.one()

Приєднайте обробник до події для елементів. Обробник виконується не більше одного разу на елемент для кожного типу події

$('form').one('submit', function(e) {
    e.preventDefault();
    // do your things ...

    // and when you done:
    $(this).submit();
});

Використання oneзапобігання також нескінченного циклу, оскільки ця спеціальна submitподія знімається після першого надсилання.


2
він надійде після повторного натискання :(
— цікавість

Ймовірно, ви зіткнетеся з нескінченною петлею
— Мехрдад ХоссейнНеджад

Нескінченна петля, функція повинна бути .on not
— .one

26

Я просто зробив би:

 $('#submiteButtonID').click(function(e){
     e.preventDefault();
     //do your stuff.
     $('#formId').submit();
 });

preventDefaultСпочатку зателефонуйте та скористайтесь submit()функцією пізніше, якщо вам просто потрібно подати форму


не включайте логіку в обробник подій клацання. делегувати це іншій відповідальності.
— Рой Намір

27
Це передбачає впевненість, що натисне кнопку. Що робити, якщо користувач просто натискає кнопку "ввести" з форми? Це також подасть форму. Тож, мабуть, не дуже гарно покладатися на натискання кнопки подання.
— StackOverflowNewbie

я тільки давав приклад клацання ... оскільки в цьому питанні не було згаданих відповідних кодів ....
— bipen

2
У будь-якому випадку фрагмент, який ви надали, працюватиме лише у випадку, якщо користувач натисне кнопку. Це не так, як працюють форми. Будь-які інші пропозиції?
— StackOverflowNewbie

прив'язати клацання, запобігти його замовчуванню та запустити натискання кнопки подання
— свічка

18

Використовуючи цей спосіб, ви зробите нескінченний цикл на своєму JS. щоб зробити кращий спосіб, ви можете скористатися наступним

var on_submit_function = function(evt){
    evt.preventDefault(); //The form wouln't be submitted Yet.
    (...yourcode...)

    $(this).off('submit', on_submit_function); //It will remove this handle and will submit the form again if it's all ok.
    $(this).submit();
}

$('form').on('submit', on_submit_function); //Registering on submit.

Я сподіваюся, що це допомагає! Дякую!


найкращий спосіб насправді, варіація з функцією async - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
— srghma

@bjornmelgaard Я маю пам’ятати, що асинхроніка нестандартна .
— Валеріо Бозз

6

Це, IMHO, найбільш загальне і надійне рішення (якщо ваші дії викликаються користувачем, наприклад, "користувач натискає кнопку"):

  • перший раз, коли обробник викликається, перевірити, хто його викликав:
    • якщо користувач налаштував його - зробіть ваші речі, а потім повторіть його (якщо хочете) - програмно
    • в іншому випадку - нічого не робити (= "продовжити за замовчуванням")

Як приклад, відзначте це елегантне рішення, додавши "Ви впевнені?" спливаюче вікно до будь-якої кнопки, просто прикрасивши кнопку з атрибутом. Ми умовно продовжимо поведінку за замовчуванням, якщо користувач не відмовиться.

1. Додамо до кожної кнопки, що нам потрібен спливаючий текст "Ви впевнені":

<button class="btn btn-success-outline float-right" type="submit"  ays_text="You will lose any unsaved changes... Do you want to continue?"                >Do something dangerous</button>

2. Приєднайте обробники до ВСІХ таких кнопок:

$('button[ays_text]').click(function (e, from) {
    if (from == null) {  // user clicked it!
        var btn = $(this);
        e.preventDefault();
        if (confirm() == true) {
            btn.trigger('click', ['your-app-name-here-or-anything-that-is-not-null']);
        }
    }
    // otherwise - do nothing, ie continue default
});

Це воно.


1
Чудова відповідь! Я не знав, що ви можете передати додатковий аргумент до .trigger ()
— Джеймс Хіббард


3

З jQueryі невеликою варіацією відповіді @ Joepreludian вище:

Важливі моменти, які слід пам’ятати:

  • .one(...) замість цього .on(...) or .submit(...)
  • namedфункція замість того, що anonymous functionми будемо посилатися на неї в межах callback.

$('form#my-form').one('submit', function myFormSubmitCallback(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var $this = $(this);
    if (allIsWell) {
        $this.submit(); // submit the form and it will not re-enter the callback because we have worked with .one(...)
    } else {
        $this.one('submit', myFormSubmitCallback); // lets get into the callback 'one' more time...
    }
});

Ви можете змінити значення allIsWellзмінної у фрагменті нижче на trueабо falseперевірити функціональність:

$('form#my-form').one('submit', function myFormSubmitCallback(evt){
  evt.stopPropagation();
  evt.preventDefault();
  var $this = $(this);
  var allIsWell = $('#allIsWell').get(0).checked;
  if(allIsWell) {
    $this.submit();
  } else {
    $this.one('submit', myFormSubmitCallback);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="/" id="my-form">
  <input name="./fname" value="John" />
  <input name="./lname" value="Smith" />
  <input type="submit" value="Lets Do This!" />
  <br>
  <label>
    <input type="checkbox" value="true" id="allIsWell" />
    All Is Well
  </label>
</form>

Щасти...


2

Чистим способом Javascript ви можете надіслати форму після запобігання дефолту.

Це відбувається тому , що HTMLFormElement.submit() ніколи не називаєonSubmit() . Тож ми покладаємось на цю специфікацію специфіки, щоб надіслати форму так, як ніби тут немає спеціального оброблювача підписки.

var submitHandler = (event) => {
  event.preventDefault()
  console.log('You should only see this once')
  document.getElementById('formId').submit()
}

Дивіться цю скрипку для синхронного запиту.


Очікування запиту на асинхронізацію так само просто:

var submitHandler = (event) => {
  event.preventDefault()
  console.log('before')
  setTimeout(function() {
    console.log('done')
    document.getElementById('formId').submit()
  }, 1400);
  console.log('after')
}

Ви можете перевірити мою загадку на прикладі асинхронного запиту.


А якщо ви обіцяєте обіцянки:

var submitHandler = (event) => {
  event.preventDefault()
  console.log('Before')
    new Promise((res, rej) => {
      setTimeout(function() {
        console.log('done')
        res()
      }, 1400);
    }).then(() => {
      document.getElementById('bob').submit()
    })
  console.log('After')
}

І ось що запит .


1

Ви можете використовувати, e.preventDefault()що зупинить поточну операцію.

ніж ти можеш зробити$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}

це дуже заплутано для мене .. Чи не буде це просто навколо і навколо?
— dapidmini

1

"Введення перевірки без циклу подання":

Я просто хочу перевірити reCaptcha та деякі інші речі перед валідацією HTML5, тому я зробив щось подібне (функція перевірки повертає справжнє чи хибне):

$(document).ready(function(){
   var application_form = $('form#application-form');

   application_form.on('submit',function(e){

        if(application_form_extra_validation()===true){
           return true;
        }

        e.preventDefault();

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