📜 ⬆️ ⬇️

ASP.NET MVC and unobtrusive validation with Backbone.js

When developing web applications, we use Asp.net MVC and backbone.js. When writing the validation logic, we had the problem of code duplication. Logic has to be described in the model on the server and in the backbone model on the client. I would like to automatically transfer the rules of validation from the server to the client. To solve this problem, we implemented an analogue of the standard unobtrusive validation of MVC data for backbone.js. Details below.

Introduction


Recently, users in web applications usually expect an immediate verification response — without having to send anything to the server. This is called client side validation. The MVC Framework supports unobtrusive data validation on the client side. The term “unobtrusive” means that validation rules are expressed using attributes that are added to the generated HTML elements. They are interpreted by the JavaScript library (jquery.validatate.unbtrusive.js), which is part of the MVC Framework, which applies the value of attributes to the configuration of the jQuery Validation library, which does all the validation work.

I would like to use a similar approach to data validation if Backbone.js is used on the client side. This article discusses the implementation of this approach.

More details about the client-side built-in validation check in MVC can be found here:

')

Implementation


You need to write your own adapter, which will interpret the attributes added to the generated HTML elements for the configuration of the Backbone.Validation library, which will do all the work on the validation.

Backbone provides only a point where we can describe our validation logic. To describe our validation logic, we use Backbone.Validation. This library allows you to set simple validation rules as follows.

var SomeModel = Backbone.Model.extend({ validation: { name: { required: true, msg: 'Please enter Name } } }); 

More details about the Backbone.Validation library can be found here:

The idea of ​​our approach is to read the rules from the attributes and create validation rules for Backbone.Validation.

The point of embedding Backbone.validation in our code is a call to the Backbone.Validation.bind (view) method inside the view:

 var SomeView = Backbone.View.extend({ initialize: function(){ Backbone.Validation.bind(this); } }); 

Therefore, we will place the attribute conversion code in the rules in it by replacing it with our own wrapper.

  Backbone.Validation.bind = _.wrap(Backbone.Validation.bind, function (bind, view, options) { if (options.autoValidation) { var validation = {}; //      view.$("[data-val=true]").each(function (item, selector) { var data = $(this).data(); var options = Backbone.Validation.adapters._create(data); if (options) validation[data.valAttr || this.name] = options; }); if (view.model && !_.isEmpty(validation)) view.model.validation = validation; } return bind(view, options); }); 

In our wrapper, we used Backbone.Validation.adapters. This object consists of the list of adapters of each attribute and the central _create method calling adapters for all attributes of the element. Its abbreviated code is shown below.

  Backbone.Validation.adapters = { valRequired: function (data) { return { required: true, msg: data.valRequired }; }, valLength: function (data) { return { rangeLength: [data.valLengthMin, data.valLengthMax], msg: data.valLength }; }, //       _create: function (data) { var options = []; for (var p in data) if (this[p]) options.push(this[p](data)); return options.length ? options : undefined; }, }; 

Now, if we want the validation rules to be read, we need to add the autoValidation: true parameter to the bind method call as shown below:

 Backbone.Validation.bind(this, {autoValidation: true}); 

Summary


This article describes an approach to validating data if Backbone.js is used on the client side. We avoided duplicating logic and code on the client and server side. A standard MVC approach to client data validation was used.

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


All Articles