📜 ⬆️ ⬇️

A library that facilitates the development of forms on sites

Hi, Habr!

I want to share with the public my small (only 6 Kbytes) js-library , which greatly facilitates my work with forms when developing websites, and allows us to reduce the writing of code.
In any, more or less medium and large project, there are more than one dozen forms, many of which it is desirable to send via AJAX. Often a handler is just 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, developers often forget little things, such as:

In addition, there are many subtleties that are not taken into account in most similar libraries, such as: sending the name=value button that sends the form, supporting <input type="image"> and the form, formaction, formmethod .
And taking into account that there are a lot of forms in large projects, then such handlers for each type of forms 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. With the help of the library described in this article, it is possible not to write code for such simple forms at all.
I will begin to describe the possibilities.
')

Support html5 attributes for older browsers


Due to the attributes form, formaction, formmethod, formenctype, formtarget you can flexibly change the behavior of form form, formaction, formmethod, formenctype, formtarget . The most common example is the selection of operations on a variety of objects selected by the user using the checkbox:
Sample code
 <div class="items"> <div class="item"> <input type="checkbox" form="mass">  <form action="/cart/add"> <input type="text" value="1"> <button type="submit">  </button> </form> </div> <div class="item"> <input type="checkbox" form="mass">  <form action="/cart/add"> <input type="text" value="1"> <button type="submit">  </button> </form> </div> ... <form id="mass" method="post"> <button type="submit" formaction="/controller/move"></button> <button type="submit" formaction="/controller/delete"></button> </form> </div> 


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

Demo

Block re-sending and status display


I think many have met with this more than once, that the user presses the submit button several times, and as a result, instead of, for example, one comment, three identical ones are published at once. Very often, to avoid this effect, simply write a script that makes the send button disabled after clicking, forgetting that the form can still be sent from the keyboard.
The library also adds a form-loading class when the submission process takes place, thanks to which you can use CSS to hide this form state as you like.
If you still need the ability to resubmit the form before completing the previous one, then it is enough to add the form-no-block class.

Demo

Filtering empty fields when sending


This feature can be useful for product search / filtering forms, in which there are many fields, in order to make the URL look more visually. Agree to see in the address bar better
example.com/?price_to=1000
than
example.com/?price_to=1000&price_to=&amount_from=&amount_to=
Just add a form-no-empty class to the form.

Demo

AJAX form submission


This is perhaps one of the main functions of the library. Many plug-ins are able to send forms via AJAX, but unfortunately they do not send the form in the same way as the browser does. In particular, it supports the above-described html5 attributes of the form , formaction , formmethod , passing parameters of the active submit button and coordinates for <input type="image"> . In order to submit the form via AJAX, you need to add the form-ajax CSS class to the form, and to display the result, add the <output> tag to an arbitrary place inside the form or another tag with the form-output class. You can specify an element outside the form, for this in the data-form-output attribute specify the jQuery-selector of this element. A similar attribute can be used in the root element of the response (it has a higher priority). And if the root element of the response has the form-replace CSS class, then the form itself will be used as the output element, and it will be replaced, which is very convenient for “one-off” forms. Consider this on the example of the feedback form:
Feedback Form Code
 <form action="/site/callback" method="post" class="form-ajax"> <div class="form-group"> <label></label> <input type="text" name="name"> </div> <div class="form-group"> <label>Email</label> <input type="text" name="email"> </div> <div class="form-group"> <label></label> <textarea name="message"></textarea> </div> <output></output> <button type="submit"></button> </form> 


 //    Yii 2 public function actionCallback() { $model = new CallbackForm(); $model->load(Yii::$app->request->post()) if ($model->validate()) { //   ,    $success if ($success) { return '<div class="alert alert-success form-replace"> </div>'; } } return '<div class="alert alert-danger"> </div>'; } 

The algorithm is as follows - the form is sent via AJAX, and if it passes validation and there are no errors in the submission, then we deduce a Bootstrap Alert that everything is in order, and it will replace the form with itself. If there are any errors, we <output> them to the <output> . And note, there is not a single line of JavaScript. The library has support for Bootstrap Alert, so that it automatically makes alert-dismissible and adds a close button on its own.

For AJAX forms, the following events are generated:

In general, this also makes it easier to write your scripts, because it allows you to hang the 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, it is enough to call e.preventDefault() - no manipulation of the output will not 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:

For myself, I concluded that it was easier for me to have the same procedure for initializing 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 a contentinit event, on which we hang a handler that initializes all the plugins.

Demo

AJAX file sending


It is even more difficult to send a form with files without reloading the page, since obsolete browsers do not know this at all, and here you need an iframe method for emulating this process. Here I did not reinvent the wheel, and gave this functionality completely on the shoulders of the malsup jquery.form plugin, leaving only one way to send it. On the server side, everything looks the same as if you sent the forms in the standard way.
To submit the form with the files, you need to connect the malsup jquery.form plugin and specify enctype = "multipart / form-data". For the form sent in this way, an event will additionally be generated:

Demo

AJAX Redirect


Another small useful little thing. To force the page to switch to a new one (make a redirect), simply enter the X-Redirect header, the value of which is the URL for the conversion.

Demo

Button, for classic submission in AJAX-form


You can make it so that in an AJAX form there will be one or several buttons that send the form in the usual way. For example, I use it on the cart page - when the user changes the quantity of goods, then AJAX is used to save the changes. When he presses the “Go to checkout” button, the normal sending of the same form takes place.

Demo

Change the appearance of the submit button


The library provides some more helpers to change the appearance of the submit button so that users understand that the form is in the process of sending. To do this, add a btn-loading CSS class to the button, and use one or both of the following options:
  1. attribute data-loading-text - changes the text of the button while submitting the form to the one specified in the attribute, and upon completion returns it;
  2. The attribute data-loading-icon adds an icon to the button that indicates the loading process.

For example:
 <!-- font awesome --> <button type="submit" class="btn btn-primary btn-loading" data-loading-icon="fa fa-refresh fa-spin">Submit</button> <!-- bootstrap glyph --> <button type="submit" class="btn btn-primary btn-loading" data-loading-icon="glyphicon glyphicon-refresh">Submit</button> 

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

Demo

Alerts for forms


Sometimes it is necessary to display some warnings or error messages to the user in the form, for example, validation errors. The library provides a simple interface for adding bootstrap alert-s to the form output element. Used as follows:
 $('form').formAlert('!  <b> </b>!', '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 githaba. I would be glad if someone script also make life easier, like me.

GitHub project

Source: https://habr.com/ru/post/261347/


All Articles