JQuery AJAX отправить форму

939

У меня есть форма с именем orderproductFormи неопределенным количеством входов.

Я хочу сделать что-то вроде jQuery.get или ajax или что-то подобное, что вызовет страницу через Ajax, и отправить все входные данные формы orderproductForm.

Я полагаю, один из способов сделать что-то вроде

jQuery.get("myurl",
          {action : document.orderproductForm.action.value,
           cartproductid : document.orderproductForm.cartproductid.value,
           productid : document.orderproductForm.productid.value,
           ...

Однако я не знаю точно все формы ввода. Есть ли функция, функция или что-то, что просто отправит ВСЕ входные данные формы?

Натан Х
источник

Ответы:

814

Вы можете использовать функции ajaxForm / ajaxSubmit из Ajax Form Plugin или функцию сериализации jQuery.

AjaxForm :

$("#theForm").ajaxForm({url: 'server.php', type: 'post'})

или

$("#theForm").ajaxSubmit({url: 'server.php', type: 'post'})

ajaxForm отправит при нажатии кнопки отправки. ajaxSubmit отправляет немедленно.

Сериализация :

$.get('server.php?' + $('#theForm').serialize())

$.post('server.php', $('#theForm').serialize())

Документация по сериализации AJAX находится здесь .

jspcal
источник
2
интересная идея, однако, я не контролирую серверную часть, на которую я звоню, поэтому я не могу отправить ей сериализованные данные
Натан Х
25
Да, вы можете, имя не важно, что он будет делать, это отправлять пары каждого ключа формы и каждой переменной формы.
6
Он сериализуется в строку запроса, точно так же, как данные, которые вы помещаете в массив вручную при вызове GET. Это то, что вы хотите, я уверен.
JAL
1
ооо, я вижу, я тогда добавляю эту строку в конец URL в вызове get. Я думал, что PHP сериализовать. Сожалею. Спасибо!
Натан Х
238
.ajaxSubmit()/ .ajaxForm()не являются основными функциями jQuery - вам нужен плагин jQuery Form
Yarin
1401

Это простая ссылка:

// this is the id of the form
$("#idForm").submit(function(e) {

    e.preventDefault(); // avoid to execute the actual submit of the form.

    var form = $(this);
    var url = form.attr('action');

    $.ajax({
           type: "POST",
           url: url,
           data: form.serialize(), // serializes the form's elements.
           success: function(data)
           {
               alert(data); // show response from the php script.
           }
         });


});

Я надеюсь, что это поможет вам.

Alfrekjv
источник
46
Но form.serialize () не может публиковать <input type = "file"> в IE
macio.Jun
2
Отличный ответ для нормальной подачи формы!
Шик Geek
1
Подобно @ BjørnBørresen, вы также можете использовать, type: $(this).attr('method')если вы используете methodатрибут в вашей форме.
djule5
2
Стоит упомянуть, что начиная с jQuery 1.8, .success, .error и .complete устарели в пользу .done, .fail и .always.
Адам
2
@ Комментарий JohnKary - отличная статья, похоже, она больше не доступна. Вот архив событий jQuery: Stop (Mis), использующий Return False
KyleMit
455

Другое похожее решение с использованием атрибутов, определенных в элементе формы:

<form id="contactForm1" action="/your_url" method="post">
    <!-- Form input fields here (do not forget your name attributes). -->
</form>

<script type="text/javascript">
    var frm = $('#contactForm1');

    frm.submit(function (e) {

        e.preventDefault();

        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                console.log('Submission was successful.');
                console.log(data);
            },
            error: function (data) {
                console.log('An error occurred.');
                console.log(data);
            },
        });
    });
</script>
Davide Icardi
источник
Любые предложения о том, как это сделать, если атрибут name содержит «.»? (Требование на стороне сервера, не моя идея).
Йозеф Энгельфрост
Включите ответ об ошибке, чтобы завершить его. Никогда не знаешь, когда получишь ошибку, всегда должен это учитывать.
кодирование
1
Если вы не установите метод или действие, они по умолчанию getи текущий URL-адрес соответственно. Можно сделать с добавлением этого предположения в код.
rybo111
1
Согласно документации jQuery ( api.jquery.com/submit ), frm.submit (function (event) {..}); эквивалентно frm.on ("представить", функция (событие) {..}) ;. Для меня последнее более читабельно, так как очевидно, что вы присоединяете обработчик события к элементу, который будет выполняться при возникновении события.
Мехмет
177

Есть несколько вещей, которые вы должны иметь в виду.

1. Есть несколько способов отправить форму

  • используя кнопку отправки
  • нажав клавишу ввода
  • запустив событие отправки в JavaScript
  • возможно больше в зависимости от устройства или будущего устройства.

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

2. Hijax

Возможно, у пользователя не включен JavaScript. Здесь хорошо использовать шаблон hijax , где мы бережно контролируем форму с помощью JavaScript, но оставляем ее для отправки в случае сбоя JavaScript.

Мы должны извлечь URL и метод из формы, поэтому, если HTML меняется, нам не нужно обновлять JavaScript.

3. Ненавязчивый JavaScript

Использование event.preventDefault () вместо return false - это хорошая практика, поскольку оно позволяет всплыть событию. Это позволяет другим сценариям связываться с событием, например, аналитическим сценариям, которые могут отслеживать взаимодействия с пользователем.

скорость

В идеале мы должны использовать внешний скрипт, а не вставлять наш скрипт в строку. Мы можем сделать ссылку на это в разделе заголовка страницы, используя тег скрипта, или ссылку на него внизу страницы для скорости. Скрипт должен спокойно улучшать пользовательский опыт, а не мешать.

Код

Предполагая, что вы согласны со всем вышеперечисленным, и вы хотите перехватить событие submit и обработать его с помощью AJAX (шаблон hijax), вы можете сделать что-то вроде этого:

$(function() {
  $('form.my_form').submit(function(event) {
    event.preventDefault(); // Prevent the form from submitting via the browser
    var form = $(this);
    $.ajax({
      type: form.attr('method'),
      url: form.attr('action'),
      data: form.serialize()
    }).done(function(data) {
      // Optionally alert the user of success here...
    }).fail(function(data) {
      // Optionally alert the user of an error here...
    });
  });
});

Вы можете вручную запустить отправку формы в любое время через JavaScript, используя что-то вроде:

$(function() {
  $('form.my_form').trigger('submit');
});

Редактировать:

Я недавно должен был сделать это и закончил тем, что написал плагин.

(function($) {
  $.fn.autosubmit = function() {
    this.submit(function(event) {
      event.preventDefault();
      var form = $(this);
      $.ajax({
        type: form.attr('method'),
        url: form.attr('action'),
        data: form.serialize()
      }).done(function(data) {
        // Optionally alert the user of success here...
      }).fail(function(data) {
        // Optionally alert the user of an error here...
      });
    });
    return this;
  }
})(jQuery)

Добавьте атрибут data-autosubmit к вашему тегу формы, и тогда вы можете сделать это:

HTML

<form action="/blah" method="post" data-autosubmit>
  <!-- Form goes here -->
</form>

JS

$(function() {
  $('form[data-autosubmit]').autosubmit();
});
superluminary
источник
2
как я могу добавить обратные вызовы для функций «done» и «fail»? что-то вроде $ ('form [data-autosubmit]'). autosubmit (). done (function ({...}); это возможно?
Crusader
1
Привет @Crusader - конечно, вместо того, чтобы этот плагин возвращал это, вы могли бы заставить его возвращать событие ajax, тогда вы могли бы цепляться прямо на него. С другой стороны, вы могли бы получить плагин успешного обратного вызова.
сверхсветовой
Я не вижу, как это происходит "... оставить его отправимым, если JavaScript не работает" здесь?
Мехмет
@mmatt - если JavaScript отключен, форма все еще остается формой. Пользователь нажимает кнопку «Отправить», и происходит регулярная отправка формы в браузере. Мы называем это прогрессивным улучшением. В наше время это не так уж важно, поскольку современные программы чтения с экрана поддерживают JavaScript.
суперсветовой
@mmatt - обратные вызовы обещания при желании получат параметр, который содержит данные.
суперсветовой
41

Вы также можете использовать FormData (но не доступно в IE):

var formData = new FormData(document.getElementsByName('yourForm')[0]);// yourForm: form selector        
$.ajax({
    type: "POST",
    url: "yourURL",// where you wanna post
    data: formData,
    processData: false,
    contentType: false,
    error: function(jqXHR, textStatus, errorMessage) {
        console.log(errorMessage); // Optional
    },
    success: function(data) {console.log(data)} 
});

Вот как вы используете FormData .

macio.Jun
источник
8
Я вижу, FormData теперь поддерживается IE10. Через несколько лет это будет предпочтительным решением.
Сверхсветовой
3
В чем преимущество этого способа?
подписать
1
Преимущество @insign в том, что плагин вообще не требуется, и работает во многих современных браузерах.
Хофи
4
@insign FormData также может обрабатывать файлы (если в вашей форме есть одно такое поле), тогда как serialize () просто игнорирует его.
Мехмет
Uncaught TypeError: Не удалось создать «FormData»: параметр 1 не относится к типу «HTMLFormElement»
rahim.nagori
28

Простая версия (не отправляет изображения)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>

Скопируйте и вставьте ajaxification формы или всех форм на странице

Это модифицированная версия ответа Alfrekjv

  • Это будет работать с jQuery> = 1.3.2
  • Вы можете запустить это до того, как документ будет готов
  • Вы можете удалить и повторно добавить форму, и она все еще будет работать
  • Он будет публиковаться в том же месте, что и обычная форма, указанная в атрибуте «action» формы

JavaScript

jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

Я хотел отредактировать ответ Alfrekjv, но слишком отклонился от него, поэтому решил опубликовать его как отдельный ответ.

Не отправляет файлы, не поддерживает кнопки, например, нажатие кнопки (включая кнопку отправки) отправляет ее значение в виде данных формы, но, поскольку это ajax-запрос, нажатие кнопки не будет отправлено.

Для поддержки кнопок вы можете зафиксировать фактическое нажатие кнопки вместо отправки.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});

На стороне сервера вы можете обнаружить ajax-запрос с этим заголовком, который jquery устанавливает HTTP_X_REQUESTED_WITH для php

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}
Тимо Хуовинен
источник
Как это будет работать, если вы хотите отправить файл с этой формой?
Ями Медина
1
@YamiMedina Это не простое решение, вам нужно отправить весь запрос в другом формате (многочастном формате) с данными файла
Тимо Хуовинен
22

Этот код работает даже с вводом файла

$(document).on("submit", "form", function(event)
{
    event.preventDefault();        
    $.ajax({
        url: $(this).attr("action"),
        type: $(this).attr("method"),
        dataType: "JSON",
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data, status)
        {

        },
        error: function (xhr, desc, err)
        {


        }
    });        
});
Shaiful Ислам
источник
3
Следует отметить, что formData () - это IE10 + developer.mozilla.org/en-US/docs/Web/API/FormData
Крис Хопкинс,
1
dataType: 'json' важен, если вы хотите использовать form.serialize ()
Дэвид Морроу
вау, эта FormData замечательная! если кому-то нужно: Array.from(new FormData(form))перебирает этот итератор формданных :)
test30
13

Мне очень понравился этот ответ от superluminary, и особенно то, как он обернулся, является решением в плагине jQuery . Так что спасибо superluminary за очень полезный ответ. В моем случае, однако, я хотел плагин, который позволял бы мне определять обработчики событий успеха и ошибок с помощью опций при инициализации плагина.

Итак, вот что я придумал:

;(function(defaults, $, undefined) {
    var getSubmitHandler = function(onsubmit, success, error) {
        return function(event) {
            if (typeof onsubmit === 'function') {
                onsubmit.call(this, event);
            }
            var form = $(this);
            $.ajax({
                type: form.attr('method'),
                url: form.attr('action'),
                data: form.serialize()
            }).done(function() {
                if (typeof success === 'function') {
                    success.apply(this, arguments);
                }
            }).fail(function() {
                if (typeof error === 'function') {
                    error.apply(this, arguments);
                }
            });
            event.preventDefault();
        };
    };
    $.fn.extend({
        // Usage:
        // jQuery(selector).ajaxForm({ 
        //                              onsubmit:function() {},
        //                              success:function() {}, 
        //                              error: function() {} 
        //                           });
        ajaxForm : function(options) {
            options = $.extend({}, defaults, options);
            return $(this).each(function() {
                $(this).submit(getSubmitHandler(options['onsubmit'], options['success'], options['error']));
            });
        }
    });
})({}, jQuery);

Этот плагин позволяет мне очень легко «отрегулировать» html-формы на странице и предоставить обработчики событий on- submit , success и error для реализации обратной связи с пользователем о статусе отправки формы. Это позволило использовать плагин следующим образом:

 $('form').ajaxForm({
      onsubmit: function(event) {
          // User submitted the form
      },
      success: function(data, textStatus, jqXHR) {
          // The form was successfully submitted
      },
      error: function(jqXHR, textStatus, errorThrown) {
          // The submit action failed
      }
 });

Обратите внимание, что обработчики событий success и error получают те же аргументы, которые вы получили бы от соответствующих событий метода jQuery ajax .

BruceHill
источник
9

Я получил следующее для меня:

formSubmit('#login-form', '/api/user/login', '/members/');

где

function formSubmit(form, url, target) {
    $(form).submit(function(event) {
        $.post(url, $(form).serialize())
            .done(function(res) {
                if (res.success) {
                    window.location = target;
                }
                else {
                    alert(res.error);
                }
            })
            .fail(function(res) {
                alert("Server Error: " + res.status + " " + res.statusText);

            })
        event.preventDefault();
    });
}

Это предполагает, что сообщение для 'url' возвращает ajax в форме {success: false, error:'my Error to display'}

Вы можете изменить это, как вам нравится. Не стесняйтесь использовать этот фрагмент.

Тарион
источник
1
Для чего targetздесь? Зачем вам отправлять форму с AJAX, только для перенаправления на новую страницу?
1252748
9

Форма отправки jQuery AJAX - это ничто иное, как отправка формы с использованием идентификатора формы при нажатии на кнопку

Пожалуйста, следуйте инструкциям

Шаг 1 - тег формы должен иметь поле идентификатора

<form method="post" class="form-horizontal" action="test/user/add" id="submitForm">
.....
</form>

Кнопка, которую вы собираетесь нажать

<button>Save</button>

Шаг 2 - отправить событие в jQuery, что помогает отправить форму. в приведенном ниже коде мы готовим JSON-запрос от имени элемента HTML .

$("#submitForm").submit(function(e) {
    e.preventDefault();
    var frm = $("#submitForm");
    var data = {};
    $.each(this, function(i, v){
        var input = $(v);
        data[input.attr("name")] = input.val();
        delete data["undefined"];
    });
    $.ajax({
        contentType:"application/json; charset=utf-8",
        type:frm.attr("method"),
        url:frm.attr("action"),
        dataType:'json',
        data:JSON.stringify(data),
        success:function(data) {
            alert(data.message);
        }
    });
});

для демонстрации нажмите на ссылку ниже

Как отправить форму, используя jQuery AJAX?

Джит Сингх Пармар
источник
5

рассмотреть возможность использования closest

$('table+table form').closest('tr').filter(':not(:last-child)').submit(function (ev, frm) {
        frm = $(ev.target).closest('form');
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                alert(data);
            }
        })
        ev.preventDefault();
    });
test30
источник
5

Я знаю, что это jQueryсвязанный вопрос, но сейчас с JS ES6 все намного проще. Поскольку чистого javascriptответа нет, я подумал, что мог бы добавить к этому простое чистое javascriptрешение, которое, на мой взгляд, намного чище, используя fetch()API. Это современный способ реализации сетевых запросов. В вашем случае, поскольку у вас уже есть элемент формы, мы можем просто использовать его для построения нашего запроса.

const form = document.forms["orderproductForm"];
const formInputs = form.getElementsByTagName("input"); 
let formData = new FormData(); 
for (let input of formInputs) {
    formData.append(input.name, input.value); 
}

fetch(form.action,
    {
        method: form.method,
        body: formData
    })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.log(error.message))
    .finally(() => console.log("Done"));
Ален Круз
источник
4

Чтобы избежать отправки нескольких формданных:

Не забудьте отменить привязку события отправки, прежде чем форма снова будет отправлена, пользователь может вызывать функцию sumbit более одного раза, возможно, он что-то забыл или произошла ошибка проверки.

 $("#idForm").unbind().submit( function(e) {
  ....
Павел Желиба
источник
4

Если вы используете форму .serialize () - вам нужно дать каждому элементу формы имя, подобное этому:

<input id="firstName" name="firstName" ...

И форма сериализуется так:

firstName=Chris&lastName=Halcrow ...
Крис Хэлкроу
источник
4

Вы можете использовать это при отправке функции, как показано ниже.

HTML-форма

<form class="form" action="" method="post">
    <input type="text" name="name" id="name" >
    <textarea name="text" id="message" placeholder="Write something to us"> </textarea>
    <input type="button" onclick="return formSubmit();" value="Send">
</form>

функция jQuery:

<script>
    function formSubmit(){
        var name = document.getElementById("name").value;
        var message = document.getElementById("message").value;
        var dataString = 'name='+ name + '&message=' + message;
        jQuery.ajax({
            url: "submit.php",
            data: dataString,
            type: "POST",
            success: function(data){
                $("#myForm").html(data);
            },
            error: function (){}
        });
    return true;
    }
</script>

Для получения более подробной информации и образца посетите: http://www.spiderscode.com/simple-ajax-contact-form/

Суреш Радж
источник
2

Это не ответ на вопрос OP,
но в случае, если вы не можете использовать статическую форму DOM, вы также можете попробовать вот так.

var $form = $('<form/>').append(
    $('<input/>', {name: 'username'}).val('John Doe'),
    $('<input/>', {name: 'user_id'}).val('john.1234')
);

$.ajax({
    url: 'api/user/search',
    type: 'POST',
    contentType: 'application/x-www-form-urlencoded',
    data: $form.serialize(),
    success: function(data, textStatus, jqXHR) {
        console.info(data);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        var errorMessage = jqXHR.responseText;
        if (errorMessage.length > 0) {
            alert(errorMessage);
        }
    }
});
wonsuc
источник
2

Пытаться

fetch(form.action,{method:'post', body: new FormData(form)});

Камил Келчевски
источник
1

Просто дружеское напоминание, что dataтоже может быть объектом:

$('form#foo').submit(function () {
    $.ajax({
        url: 'http://foo.bar/some-ajax-script',
        type: 'POST',
        dataType: 'json',
        data: {
            'foo': 'some-foo',
            'bar': 'some-bar'
        }
    }).always(function (data) {
        console.log(data);
    });

    return false;
});
Лукас Бустаманте
источник
1

JavaScript

(function ($) {
    var form= $('#add-form'),
      input = $('#exampleFormControlTextarea1');


   form.submit(function(event) {

       event.preventDefault(); 

       var req = $.ajax({
           url: form.attr('action'),
           type: 'POST',
           data: form.serialize()
       });
    req.done(function(data) {
       if (data === 'success') {
           var li = $('<li class="list-group-item">'+ input.val() +'</li>');
            li.hide()
                .appendTo('.list-group')
                .fadeIn();
            $('input[type="text"],textarea').val('');
        }
   });
});


}(jQuery));

HTML

    <ul class="list-group col-sm-6 float-left">
            <?php
            foreach ($data as $item) {
                echo '<li class="list-group-item">'.$item.'</li>';
            }
            ?>
        </ul>

        <form id="add-form" class="col-sm-6 float-right" action="_inc/add-new.php" method="post">
            <p class="form-group">
                <textarea class="form-control" name="message" id="exampleFormControlTextarea1" rows="3" placeholder="Is there something new?"></textarea>
            </p>
            <button type="submit" class="btn btn-danger">Add new item</button>
        </form>
Marty
источник
-21

Также есть событие submit, которое может быть вызвано так: $ ("# form_id"). Submit (). Вы бы использовали этот метод, если форма уже хорошо представлена ​​в HTML. Вы просто прочитали бы на странице, заполнили поля ввода данными, а затем вызвали .submit (). Он будет использовать метод и действие, определенные в объявлении формы, поэтому вам не нужно копировать его в свой javascript.

Примеры

billw
источник
58
если вы удалите свое сообщение, вы получите штрафные очки, которые были забраны у вас обратно.
sparkyspider
2
Это отправит форму, но не через AJAX, поэтому не отвечает на вопрос.
Сверхсветовой
11
что сказал @spider, плюс вы получите хороший значок под названием «давление со стороны сверстников»
nurettin