📜 ⬆️ ⬇️

An alternative look at the plugin for the number input mask and not only in input and textarea

In pursuit of the published earlier article Plugin for input mask of numbers in input , I would like to share my view on the solution of this problem.

Details under Habrokat.


Given:
A large Web project, for the UI part of which backbone.js, underscore, jQuery, jQueryUI are used.
Due to the specifics of the project, it is necessary to use masks and validate input fields (input, textarea, etc.), depending on the type (int, float, price, phone, text, combobox). At first glance, there is nothing difficult in this task and you can get by with something from the whole sea of ​​plug-ins that jQuery so kindly supplies us with. However, later date (made on the basis of jQuery DatePicker) and a text editor (tinyMCE) were added to these types. On the approach there were several more types, the specification for which was just being created, and it’s far from a fact that we would be able to find a ready-made solution.
This is where the issue of validation has become more acute. The number of plug-ins used grew by leaps and bounds and began to alarm. In general, tired of the constant otmashek "We did like this, because here we can not do this - this is the standard behavior of the plugin," it was decided to create its own validation system.
')
To find:
Create your own validation module based on the technologies used in the project.

Decision:
The module was based on the backbone.js model, since it already has a built-in validation check of the data, it would be foolish to refuse this possibility.

I will not describe the entire structure of the project, people who worked with backbone.js will easily figure out who is not, easily find introductory articles on Habré.

So, in our common View, a validation () method was created that accepts certain validation parameters and passes them to the custom module Validation.js (a separate Utils folder was created for it, which lies with the rest common elements), creating a model object based on it :

validate: function (params) { if (_.isArray(params.items) && params.type === 'form') { _.each(params.items, function (item) { new core.utils.Validation(item); }, this); new core.utils.Validation(params); } else { new core.utils.Validation(params); } } 


All custom Views in the project are inherited from the common View, therefore, they contain the validation () method. Validation is called as follows: in the controller, after rendering a specific View, the custom validationFields method is immediately called, which is different for all Views, for example:

 this.getView('SomeView').render({ 'someParams': someValue, … }).validateFields(); 


The validationFields method itself might look like this:

 validateFields: function () { this.validate({ id: "description", type: "text", required: false, maxLength: 500, separate: true }); } 


We inform our plugin that
id: "description" - you need to validate the field with id = "description";
type: “text” - type of input data - text (i.e. letters, numbers, punctuation marks, etc., are allowed);
required: false - the field is not necessary for filling, does not give any error message about the entered data, however, it allows to drive only what is defined for the text type (ie, the mask remains working);
maxLength: 500 - the maximum text length is 500 characters;
separate: true - cut every character after the five hundredth.

What would we have in the module itself:

 text : function() { $("#"+this.id).live("paste", $.proxy(this.maskPasteText, this)); $("#"+this.id).live("keyup", $.proxy(this.validateText, this)); $("#"+this.id).live("blur", $.proxy(this.finishText, this)); }, 


Here we hang validation methods and masks on paste, keyup, blur events.

 maskPasteText: function(event) { var context = this; setTimeout(function() { context.validateText(event); }, 0); }, 


When inserting data, we hang up a timeout and call the validation function, the same thing with the blur:

 finishText: function(event) { this.validateText(event); }, 


Actually, here is the text validation function itself:
 validateText: function(event) { var value = $("#"+this.id).val(), selectionStart = event.target.selectionStart, selectionEnd = event.target.selectionEnd; if (this.maxLength && this.separate) { value = value.slice(0, this.maxLength); $("#"+this.id).val(value); event.target.selectionStart = selectionStart, event.target.selectionEnd = selectionEnd; } this.bind("error", $.proxy(this.showError, this)); this.validate = this.validations()[this.type]; this.hideError(); this.set({ currentValue: value, required: this.required, errorMessage: this.errorMessage, minLength: this.minLength, maxLength: this.maxLength }); }, 


It is clear that for other data types, for example, int, float, you still need to add an input mask, for this we hang up functions for the keypress event:

 maskTypeInt : function (event) { if ( !(event.charCode >= 48 && event.charCode <= 57 || event.charCode === 0) ) { event.preventDefault(); } }, maskTypeFloat : function (event) { var value = $("#"+this.id).val(), dots = value.search(/\./ig), commas = value.search(/,/ig); if ( !( event.charCode >= 48 && event.charCode <= 57 || (event.charCode === 46 && dots === -1) || (event.charCode === 44 && dots === -1 && commas === -1) || event.charCode === 0) ) { event.preventDefault(); } } 


Currently validation is implemented for the following data types:
int,
float
price,
phone,
text,
wordProcessor (for tinyMCE validation),
combobox
form (here validation takes place for several fields, options for which are passed in the items array, it works when a button is pressed, the button id is passed).

View the functionality of the module, ready at the moment here .
The module itself is still being finalized, so that the code is not completely cleaned, but it is quite easy to read.

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


All Articles