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.