Library that facilitates the development of forms on sites

    Hello, Habr!

    I want to share with the public my small (only 6 Kbytes) js-library , which greatly facilitates my work with forms when developing sites, and allows me to reduce code writing.
    In any, more or less medium and large project, there are more than a dozen forms, many of which are desirable to send through AJAX. Often, a handler is simply hung up for this and a script is written, something like this:

    $(function () {
        $('.contact-submit').click(function () {
            $.ajax({
                url: '/path/to/action',
                method: 'post',
                data: $(this).closest('form').serialize(),
                success: function () {
                    /* success action */
                }
            });
        });
    });
    

    And everything seems to work, but, unfortunately, very often developers forget trifles, such as:
    • lack of indication of form submission;
    • as a result, the ability to post a lot of requests (re-sending is not blocked);
    • the inability to submit the form from the keyboard;
    • lack of indication in case of form submission error (for example, the server responded with the 500th error);
    • controller url hardcode in js script.

    In addition, there are many subtleties that are not taken into account in most similar libraries, such as: transferring a name=valuebutton that sends a form, support and attributes form, formaction, formmethod.
    And given that there are a lot of forms in large projects, such handlers for each type of form as a result form a significant amount of code. But often, the forms are quite simple, such as the “feedback form”, we just need to send the form and show the status - a letter has been sent or an error has occurred. Using the library described in this article, you don’t have to write code for such simple forms at all.
    I will begin to describe the possibilities.

    Support for html5 attributes for older browsers


    Thanks to attributes, form, formaction, formmethod, formenctype, formtargetyou can flexibly change form submission behavior. The most common example is the choice of an operation on a set of objects selected by the user using the checkbox:
    Example code
    Выбрать
    Выбрать
    ...


    With the help of attributes form, formactionwe were able to solve the problem of the impossibility of nested forms, as well as the choice of the controller url depending on the action.
    The library provides a polyfill for browsers that do not support these attributes (IE <10).

    Demo

    Resend Block and Status Display


    I think many have met this more than once, that the user clicks the submit form button several times, and as a result, instead of, for example, one comment, three of them are published at once. Very often, to avoid such an effect, they simply write a script that makes the submit button disabled after clicking, forgetting that the form can still be sent from the keyboard.
    The library also adds a class form-loadingwhen the sending process occurs, thanks to this it is possible to CSS-style this form state as you like.
    If you still need to be able to resubmit the form before completing the previous one, just add a class form-no-block.

    Demo

    Filter blank fields when sending


    This feature can be useful for product search / filtering forms, in which there are many fields, so that the URLs look more visual. Agree that it’s better to see in the address bar
    example.com/?price_to=1000
    than
    example.com/?price_to=1000&price_to=&amount_from=&amount_to=
    just add a class form-no-emptyto the form.

    Demo

    AJAX form submission


    This is perhaps one of the main functions of the library. Unfortunately, many plugins can submit forms via AJAX, but unfortunately not. In particular, it supports the attributes described above html5 form, formaction, formmethod, transfer of active submit-button and the coordinate parameters for . In order for the form to be submitted via AJAX, you need to add the CSS class form-ajaxto the form, and to display the result, add a tag or another tag with the class to an arbitrary place inside the form form-output. You can specify an element outside the form, for this in the attributedata-form-outputindicate the jQuery selector of this element. A similar attribute can be used in the root element of the response (it is more priority). And if the root element of the response has a CSS class form-replace, then the form itself will be used as the output element, and it will be replaced, which is very convenient for “one-time” forms. Consider this using the feedback form as an example:
    Feedback Form Code


    // контроллер на примере Yii 2
    public function actionCallback() {
        $model = new CallbackForm();
        $model->load(Yii::$app->request->post())
        if ($model->validate()) {
            // тут отправляем письмо, успех статус в $success
            if ($success) {
                return '
    Сообщение отправлено
    '; } } return '
    Ошибка отправки
    '; }

    The algorithm is this - the form is sent via AJAX, and if it passes validation and there are no errors in the submission, then we print Bootstrap Alert that everything is in order, and it will replace the form. If there are any errors, display them in a tag . And note, there is not a single line of JavaScript. The library has support for Bootstrap Alert, so that it automatically does alert-dismissibleand independently adds a close button.

    The following events are generated for AJAX forms:
    • formajaxbefore- before submitting the form, allows you to change all the settings $.ajax;
    • formajaxdone - in case of successful sending;
    • formajaxfail - in case of an error;
    • formajaxalways - in any case, after the completion of the AJAX request.

    In general, this also makes it easier to write your own scripts, because it allows you to hang code directly on the event of a successful response, bypassing the routine with passing the URL and parameters. In events, you can cancel the default behavior of the script, just call it e.preventDefault()- no manipulation of the output of the content will occur.
    If, on the contrary, the loaded content is needed and, moreover, contains other components that need to be initialized (for example, datepicker). For this, the library generates two more events:
    • contentprepare - before adding content to the DOM;
    • contentinit - after adding content to the DOM.

    For myself, I concluded that it is easier for me to have the same initialization procedure for all plugins, so I came to this process:
    $(function () {
        $(document).trigger('contentinit', [$(document)]);
    });
    $(document).on('contentinit', function (e, cont) {
        cont.find('.datepicker').datepicker();
    });
    

    That is, when the page loads, we also generate an event contentiniton which we attach a handler that initializes all the plugins.

    Demo

    AJAX file upload


    It is even more difficult to submit a form with files without reloading the page, because outdated browsers do not know how to do this, and here you need an iframe method to emulate this process. Here I did not invent a bicycle, and gave this functionality completely to the malsup jquery.form shoulders plugin, leaving only a single way to send it. On the server side, everything looks the same as if you were submitting forms in a standard way.
    To send a form with files, you need to connect the malsup jquery.form plugin and specify enctype = "multipart / form-data". For the form sent by this method, an additional event will be generated:
    • formajaxprogress - an event informing about the current state of sending.

    Demo

    AJAX redirect


    Another small useful little thing. To force a page to switch to a new one (to redirect it), simply indicate the title X-Redirect, the value of which is the URL to go to.

    Demo

    Button, for classic submit in AJAX-form


    You can make it so that in an AJAX form there will be one or more buttons that submit the form in the usual way. For example, I use this on the cart page - when the user changes the quantity of the product, then AJAX is used to save the changes. When he clicks the button "Go to registration", the usual submission of the same form occurs.

    Demo

    Change the appearance of the submit button


    The library provides several more helpers in order to change the appearance of the submit button so that users understand that the form is in the process of being submitted. To do this, add a CSS class to the button btn-loading, and also use one or both of the following options:
    1. attribute data-loading-text- changes the button text during form submission to the one specified in the attribute, and after completion, returns back;
    2. attribute data-loading-icon- adds an icon to the button showing the loading process.

    For instance:

    Additionally, you can specify a class for one or more buttons btn-submit-default, then if the form is sent from the keyboard, the buttons will still change their appearance.

    Demo

    Alerts for forms


    Sometimes it is necessary that you need to display some warnings or error messages in the form to the user, for example, about validation errors. The library provides a simple interface for adding bootstrap alerts to the form output element. Used like this:
    $('form').formAlert('Ошибка! Заполните обязательные поля!', 'danger');
    $('form').formAlert('#external-alert', 'success', true);
    

    Demo

    Conclusion


    The library is available in the npm and bower repositories under the name paulzi-form:
    bower install paulzi-form
    npm install paulzi-form
    

    She is quite young, so I'm waiting for bug reports on the github. I would be glad if someone could make life easier for someone, as well as for me.

    GitHub Project

    Also popular now: