{"id":43,"date":"2012-09-02T14:08:00","date_gmt":"2012-09-02T14:08:00","guid":{"rendered":"http:\/\/tpodolak.com.hostingasp.pl\/blog\/2012\/09\/02\/extjs-4-1-1-validatable-grid\/"},"modified":"2016-01-31T00:08:04","modified_gmt":"2016-01-31T00:08:04","slug":"extjs-4-1-1-validatable-grid","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2012\/09\/02\/extjs-4-1-1-validatable-grid\/","title":{"rendered":"Extjs 4.1.1 &#8211; validatable grid"},"content":{"rendered":"<p>In this post I will present a simple plugin to <i>Ext.panel.Grid<\/i> which displays validation errors on a grid. The validation mechanism is based on the model validation &#8211; useful feature of <i>Extjs<\/i> framework. Let&#8217;s start from creating a simple model:<\/p>\n<pre lang=\"javascript\">\r\nExt.define('CustomerModel', {\r\n    extend: 'Ext.data.Model',\r\n    fields: [\r\n        {name: 'id',  type: 'int'},\r\n        { name: 'lastname', type: 'string' },\r\n        {name: 'firstname',type:'string'}\r\n    ],\r\n    validations: [{type: 'presence', field: 'lastname', message:'Required field'}]\r\n});\r\n<\/pre>\n<p>As we can see, this model has a <i>validation<\/i> field where we can define a validation mechanism for every field in our model. In this example the <i>lastname<\/i> field is required, I use build in Extjs validator of the <i>presence<\/i> type. More build-in validation types might be found <a href=\"http:\/\/www.sencha.com\/learn\/using-validations-and-associations-in-sencha-touch\">here<\/a>. Of course, it is possible to define custom validation types, simple example can be found on <a href=\"http:\/\/stackoverflow.com\/questions\/7414115\/how-to-add-a-custom-validation-rule-to-a-model-in-sencha-touch\">Stackoverflow<\/a>Having defined model validation, let&#8217;s create <i>ValidatableGrid<\/i>plugin. The main function of <i>ValidatableGrid<\/i> plugin is function called <i>validate<\/i> which is attached to grid component. This function looks this way;<\/p>\n<pre lang=\"javascript\">\r\nvalidate: function(){\r\n       var me = this, view = this.getView(),isValid = true;\r\n       var columnLength = me.columns.length;\r\n       me.getStore().each(function(record,idx){\r\n           \/\/remove existing validation errors\r\n           for (var j = 0; j < columnLength; j++) {\r\n               var cell = view.getCellByPosition({row: idx, column: j});\r\n               cell.removeCls(me.clsInvalidField);\r\n           }\r\n           var validationResult = record.validate();\r\n           if(!validationResult.isValid()){\r\n               isValid= false;\r\n               for(var i =0;i < validationResult.items.length;i++){\r\n                   for (var j = 0; j < columnLength; j++) {\r\n                       var cell = view.getCellByPosition({row: idx, column: j});\r\n                       if(validationResult.items[i].field == me.columns[j].dataIndex){\r\n                           cell.addCls(\"x-form-invalid-field\");\r\n                           cell.set({'data-errorqtip': validationResult.items[i].message});\r\n                       }\r\n                   }\r\n               }\r\n           }\r\n       })\r\n       return isValid;\r\n   }\r\n<\/pre>\n<p>This function iterates through every model in grid's store and runs validation method. As a result, we get a <i>validationResult<\/i> object which holds information about errors of model. This object has a function <i>isValid<\/i> which returns true if there is no errors or false otherwise. Having checked the model, we have to show errors on the grid. In order to do that, we have to find a cell, in which invalid field is displayed using <i>getCellByPosition<\/i> function. In the last step, we only have to modify CSS classes of cell. That is why, I added <i>x-form-invalid-field<\/i> class to show red line in cell and also <i>data-errorqtip<\/i> class to show validation error tooltip. The entire listing looks this way;<\/p>\n<pre lang=\"javascript\">\r\nExt.define('ValidatableGrid', {\r\n    grid:null,\r\n    init: function (grid) {\r\n        var me = this;\r\n        me.grid = grid;\r\n        me.grid.validate = me.validate;\r\n    },\r\n\r\n   validate: function(){\r\n        var me = this, view = this.getView(),isValid = true;\r\n        var columnLength = me.columns.length;\r\n        me.getStore().each(function(record,idx){\r\n            \/\/remove existing validation errors\r\n            for (var j = 0; j < columnLength; j++) {\r\n                var cell = view.getCellByPosition({row: idx, column: j});\r\n                cell.removeCls(me.clsInvalidField);\r\n            }\r\n            var validationResult = record.validate();\r\n            if(!validationResult.isValid()){\r\n                isValid= false;\r\n                for(var i =0;i < validationResult.items.length;i++){\r\n                    for (var j = 0; j < columnLength; j++) {\r\n                        var cell = view.getCellByPosition({row: idx, column: j});\r\n                        if(validationResult.items[i].field == me.columns[j].dataIndex){\r\n                            cell.addCls(\"x-form-invalid-field\");\r\n                            cell.set({'data-errorqtip': validationResult.items[i].message});\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        })\r\n        return isValid;\r\n    }\r\n})\r\n<\/pre>\n<p>here is example of usage;<\/p>\n<pre lang=\"javascript\">\r\nExt.QuickTips.init();\r\n\r\nvar store = Ext.create('Ext.data.Store', {\r\n    model: 'CustomerModel'\r\n});\r\nstore.add([{\r\n    id: 1,\r\n    firstname: 'John'\r\n}, {\r\n    id: 1,\r\n    firstname: 'Mat'\r\n}, {\r\n    id: 1,\r\n    firstname: 'Kate',\r\n    lastname:  'Smith'\r\n}, {\r\n    id: 1,\r\n    firstname: 'Richard',\r\n    lastname:  'Smith'\r\n}, {\r\n    id: 1,\r\n    firstname: 'Nick'\r\n}]);\r\n\r\nvGrid = Ext.create('Ext.grid.Panel', {\r\n    store: store,\r\n    plugins: [Ext.create('ValidatableGrid')],\r\n    columns: [ { text: 'Id', dataIndex: 'id' },\r\n               { text: 'First name', dataIndex: 'firstname' },\r\n               { text: 'Last name', dataIndex: 'lastname' }]});\r\n\r\nvGrid.validate();\r\n<\/pre>\n<p>and the result<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/09\/extjs-4-1-1-validatable-grid\/ValidatableGridWithTooltip.jpg\" rel=\"attachment wp-att-401\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/09\/extjs-4-1-1-validatable-grid\/ValidatableGridWithTooltip.jpg\" alt=\"validatable grid\" width=\"376\" class=\"aligncenter size-full wp-image-401\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/09\/extjs-4-1-1-validatable-grid\/ValidatableGridWithTooltip.jpg 376w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/09\/extjs-4-1-1-validatable-grid\/ValidatableGridWithTooltip-150x70.jpg 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2012\/09\/extjs-4-1-1-validatable-grid\/ValidatableGridWithTooltip-300x140.jpg 300w\" sizes=\"(max-width: 376px) 100vw, 376px\" \/><\/a><br \/>\nSource code for this post can be found <a href=\"https:\/\/github.com\/tpodolak\/Blog\/tree\/master\/ExtjsValidatableGrid\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post I will present a simple plugin to Ext.panel.Grid which displays validation errors on a grid. The validation mechanism is based on the model validation &#8211; useful feature of Extjs framework. Let&#8217;s start from creating a simple model: Ext.define(&#8216;CustomerModel&#8217;, { extend: &#8216;Ext.data.Model&#8217;, fields: [ {name: &#8216;id&#8217;, type: &#8216;int&#8217;}, { name: &#8216;lastname&#8217;, type: &#8216;string&#8217; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[63,67,100,61,99,84],"tags":[203,210,234,205,229],"class_list":["post-43","post","type-post","status-publish","format-standard","hentry","category-ext-panel-grid","category-extjs-4-1-1","category-grid","category-plugin","category-plugins","category-validation","tag-ext-panel-grid","tag-extjs-4-1-1","tag-grid","tag-plugin","tag-validation"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/43","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=43"}],"version-history":[{"count":5,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/43\/revisions"}],"predecessor-version":[{"id":549,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/43\/revisions\/549"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=43"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=43"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=43"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}