PDA

View Full Version : EditorGrid validation plugin



jsakalos
18 Dec 2007, 10:29 AM
Hi folks,

I've just finished coding of an EditorGrid validation plugin and I decided to give it some lifetime on this forum before I'll post it to Ext wiki.

Test and comment it please. Thanks.

Code:


Ext.namespace('Ext.ux', 'Ext.ux.plugins');

/**
* EditorGrid validation plugin
* Adds validation functions to the grid
*
* @author Jozef Sakalos, aka Saki
* @version 0.1
*
* Usage:
* grid = new Ext.grid.EditorGrid({plugins:new Ext.ux.plugins.GridValidator(), ...})
*/
Ext.ux.plugins.GridValidator = function(config) {

// initialize plugin
this.init = function(grid) {
Ext.apply(grid, {
/**
* Checks if a grid cell is valid
* @param {Integer} col Cell column index
* @param {Integer} row Cell row index
* @return {Boolean} true = valid, false = invalid
*/
isCellValid:function(col, row) {
if(!this.colModel.isCellEditable(col, row)) {
return true;
}
var ed = this.colModel.getCellEditor(col, row);
if(!ed) {
return true;
}
var record = this.store.getAt(row);
if(!record) {
return true;
}
var field = this.colModel.getDataIndex(col);
ed.field.setValue(record.data[field]);
return ed.field.isValid(true);
} // end of function isCellValid

/**
* Checks if grid has valid data
* @param {Boolean} editInvalid true to automatically start editing of the first invalid cell
* @return {Boolean} true = valid, false = invalid
*/
,isValid:function(editInvalid) {
var cols = this.colModel.getColumnCount();
var rows = this.store.getCount();
var r, c;
var valid = true;
for(r = 0; r < rows; r++) {
for(c = 0; c < cols; c++) {
valid = this.isCellValid(c, r);
if(!valid) {
break;
}
}
if(!valid) {
break;
}
}
if(editInvalid && !valid) {
this.startEditing(r, c);
}
return valid;
} // end of function isValid
});
}; // end of function init
}; // GridValidator plugin end

wanclark
27 Dec 2007, 9:34 PM
nice!

shane.fox
4 Mar 2008, 11:07 PM
Thanks, this was useful.

linizou
25 Mar 2008, 12:59 AM
useful

cassioam
7 Apr 2008, 7:20 AM
Thank you!:D

jschick
7 Apr 2008, 1:18 PM
This plugin is just what I was looking for. Thanks!

Because I only allow editing of one row at a time I added the following function to the plugin.



/**
* Checks if row has valid data
* @param {Integer} row index
* @param {Boolean} editInvalid true to automatically start editing of the first invalid cell
* @return {Boolean} true = valid, false = invalid
*/
,isRowValid:function(row, editInvalid) {
var cols = this.colModel.getColumnCount();
var c;
var valid = true;
for(c = 0; c < cols; c++) {
valid = this.isCellValid(c, row);
if(!valid) {
break;
}
}
if(editInvalid && !valid) {
this.startEditing(row, c);
}
return valid;
} // end of function isRowValid

spectrus
11 Apr 2008, 6:02 AM
Thanks a lot, looks like a very useful plugin!

Tried to get it working, but can't quite get it yet. My invalid test cell is not getting assigned the 'invalid' CSS class because its preventMark value is being set to 'true'. What is this parameter and where can I control it in the grid config (if anywhere)?



markInvalid : function(msg){
if(!this.rendered || this.preventMark){ return; }
...
}


Edit: Never mind, it's me. It's not the this.preventMark (which I see you're just passing in as 'true' - stupid me!), it's the !this.rendered check. I'm running the check at grid's 'show' event. Are the cells still not rendered at that point?

And one more: when the plugin's working (hope to see it myself), after it's done then all the invalid cells on the grid are being displayed as invalid (i.e. with red border) without being clicked on, correct?

Thanks!

jsakalos
11 Apr 2008, 6:35 AM
Cells will be marked invalid only if you start editing. To tell truth, I've more-the-less temporarily abandoned devel of this plugin as it was not the most important part of my project. There is still a lot of space for improvement... ;)

spectrus
11 Apr 2008, 7:01 AM
I see. But wouldn't that be taken care of by the grid anyway? For example an empty mandatory cell is being marked as invalid when clicked even without running the plugin. The usefullness of the plugin escapes me then, and please correct me if I'm wrong. Or will the plugin prove to be more useful for more complex cell editors/column model definitions?

Thank you for a quick response!

jsakalos
11 Apr 2008, 7:54 AM
The original idea was to prevent submit of invalid grid to server and/or forcing user to edit the invalid fields. Of course, if invalid cells were visually marked it would add a lot of value...

spectrus
11 Apr 2008, 1:42 PM
Of course, if invalid cells were visually marked it would add a lot of value...

Definitely. That's what I'm pounding my head on for a while now. :)

One more question: in your opinion, where would it be best to call the isValid() from if one wanted to validate the data which was just loaded into the grid? I think I just call it from the wrong place (right after grid.store.load() in grid's 'load' listener), and that's why it's not working properly.

jsakalos
11 Apr 2008, 1:47 PM
GridView refresh event?

manojo
8 May 2008, 10:31 AM
Hi,

thanks for this piece of code. I've added a bit of code that would help me. I have a grid with a checkboxSelectionModel, and the grid will be valid if there is at least one selected value : so here it is :


isValid:function(){
return (grid.sm.getSelections().length > 0);
}


I put the grid in a formpanel, but I don't see this method being called. Am I missing something?

Thanks,
Manojo

jsakalos
8 May 2008, 11:14 AM
It's fine if it suits you. Best is if you just override the function from outside and you do not change existing code. Upgrades are easier then...

manojo
8 May 2008, 11:53 AM
Hi jsakalos,

I'm sorry but I didn't completely understand what you said. Do you suggest that I override isValid function for forms ?

Thanks,
Manojo

jsakalos
8 May 2008, 12:25 PM
Sorry, it I've overlooked that you're asking... I thought you've posted your change...

isValid is function that is called from outside when you want to check if the grid contains valid data. It is not automatically called.

raviext
8 May 2008, 12:32 PM
Hi Jack

I am not sure if there is anyway i can post a query apart from replying to a post. Wanted some tips from you as i have been following from and past fews days and found you have been a great helping hand. Appreciate your diection.

I am basically a Java developers and trying Ext JS. Need some suggestion on how should i start. Following are things where i face the difficulties.

Sorry if the following question is a quite silly

a) My object oriented javascript is little patchy, though from past couple of days learning it actively. So i find difficulties in little bit of understanding the syntax.

Following is an excerpt from one of the forum.

Ext.extend(Ext.ux.grid.RecordForm, Ext.util.Observable, {


,initComponent:function() {
this.recordForm = new Ext.ux.grid.RecordForm({
title:'Ext.ux.grid.RowRecord Example'

,iconCls:'icon-edit-record'

,columnCount:2
,ignoreFields:{compID:true}
,formConfig:{
labelWidth:80
,buttonAlign:'right'

,bodyStyle:'padding-top:10px'

}
});

});

I couldn't under stand the way of defining the config parameters "initComponent:" , i was more confused with notation of ":" after the variable. I was expecting "=" instead of ":".

Here what is "initComponent" ? . Is it a function , object or variable.

Thanks
-Rave

jsakalos
8 May 2008, 1:11 PM
I guess this is addressed to me (Saki) and not to Jack (Jack Slocum?).

Anyway, it seems that you're dealing with understanding of basic Javascript syntax (: is used to define object properties, e.g. var o = {p1:1, p2:2};).

The best advice I can give you at this stage is to buy (download, get a hold of) a good book on JavaScript language syntax, watch Dough Crockford videos (google for them, should be found somewhere at Yahoo) and try to locally install some examples from extjs.com site. Not extensions or plugins yet as they may create more confusions.

There are also good tutorials for beginners on how to install Ext and how to start to play with Ext easy way. http://extjs.com/learn

Good luck!

mjlecomte
8 May 2008, 1:26 PM
I couldn't under stand the way of defining the config parameters "initComponent:" , i was more confused with notation of ":" after the variable. I was expecting "=" instead of ":".

Here what is "initComponent" ? . Is it a function , object or variable.
initComponent is a property / member of an object. When you're inside an object literal the "{" and "}" the syntax for specifying properties / members is to use a ":" instead of "=". Also note you separate with "," (comma), and you do not close with ";" (semi-colon).

manojo
8 May 2008, 1:44 PM
Hi Saki,

thanks for that. Is there a mean anyhow to call this function when isValid for a form is called ? I had a look at the code for SimpleForm, and basically what is does is, call the validate() method for each of its elements.
Then I went and had a look at TextField, but there is no validate() method, rather a validateValue()

I'm a bit confused here. Is the validate method really called?
Moreover, for my grid, is it possible to have that nice exclamation mark if it is invalid ?

How do I do that?

thanks,
Manojo

PS : If I'm deviating from the main topic of the post, I can transfer the discussion somewhere

jsakalos
8 May 2008, 1:56 PM
validate is different from isValid. isValid of BasicForm calls validate of each field. validate also marks/clears field invalid mark.

raviext
8 May 2008, 11:14 PM
Hi Saki and MJ

Thanks for the quick response. This is one of the quickest, polite and helping response i ever got. Appreciate it.

I am in the process of going through all the study materials you have suggested. I did go through the Yahoo Vedio's by Dough Crockford and was reading couple of good tutorials.

I feel that i am somewhere mixing java language with the javascript. There is a clear definition of object and functions in java, and which is mixed in javascript. The "context and scope" are quite different in both and it is quite confusing in javascript. I did try few examples and successfully ran. But as a programmer i kind of get frustrated when i don't code with the ease at which i do it in Java. And when i see the plugin's that you guys have written , they are simply awesome.

And right now i use firebug, though it is a very nice tool, but i still feel that it doesn't indicate the problem very clearly. Most of the time undefined (i think the scope understanding problem or my poor javascript problem :))

I am using the spket eclipse plugin, but i kind of felt that it doesn't deal with the scope of the object. When i was studying your plugin, when i do alt space after certain objects i expected it to show me the functions and variables/properties. But it doesn't show any but your plugin works perfect.


Regards
Rave

jsakalos
9 May 2008, 1:23 AM
I thing you're headed veeeeeery good direction!

Re scope: Have you seen this: What is that Scope all about (http://extjs.com/forum/../learn/Tutorial:What_is_that_Scope_all_about) ?
Re firebug: Just get used to it, there is nothing better.
Re eclipse: I don't know, I use vim.

Good luck!

raviext
10 May 2008, 8:52 PM
Thanks Saki for the info.

One dumb question. I couldn't find an option to start a new thread. Please let me know how can i do that, so that i can maintain the sanctity of the threads. If there is no way then i will continue on this thread.

Here is my question.

I am trying to use Ext.XTemplate() and few other renderes. In the following code "editlink" is a renderer and i am trying to call the javascript from that URL. I get an exception in the firebug
"callAlert is undefined" . Please let me know how can i call any javascipt function from the HTML code written inside renderer or from inside Ext.XTemplate()





function editlink(value, p ,record)
{
return String.format('<a href="javascript:callAlert()">Edit</a>',
record.data.id)
}



function callAlert()
{
alert(" Need to take care of other stuff");
}


var cm = new xg.ColumnModel([
expander,
{header: "Company Name", width: 120, sortable: true, dataIndex: 'name', renderer:renderTopic},
{header: "Website", width: 120, sortable: true, dataIndex: 'website'},
{header: "Status", width: 120, sortable: true, dataIndex: 'status.value' },
{header: "Created By", width: 120, sortable: true, dataIndex: 'createdby'},
{header: "Created Date", width: 120, sortable: true, dataIndex: 'createddate'},
{width: 60, sortable: true, dataIndex: 'createddate', renderer:editlink}
]);

~Rave

jsakalos
11 May 2008, 1:22 AM
Go to forum you want to create a new thread in, not existing thread but Forum, and click new thread button at the top.

(X)Template are meant to generate html code not to call functions or create object. They are very well documented:
http://extjs.com/deploy/dev/docs/?class=Ext.XTemplate

raviext
11 May 2008, 2:00 PM
Hi Saki

Thanks for the response. So we cann't call javascript functions in from the "renderer" and Xtemplate. The reason for asking this question was, i had seen couple of threads having javascript in Xtemplate

http://extjs.com/forum/showthread.php?p=147036

Regards
~Rave

jsakalos
11 May 2008, 3:55 PM
Renderer is one thing - you can call anything from there and XTemplate is another thing. XTemplate supports arbitrary code execution but is not designed to create Ext components, but to generate html output.

raviext
27 May 2008, 9:43 PM
Hi Saki

As per your suggestion, I have been working for last couple of weeks with the help of forums and few tutorials and been able to do quite some stuff in ExtJS. Now i think i would like to explore doing Extensions on ExtJS. Sometimes i hit to a requirement where i would have to Extend a component so wanted some suggestions from you.

a) What should be the starting point to write extensions ?
b) Any tutorials or links useful to start on this ?

~Rave

jsakalos
28 May 2008, 1:58 AM
Here you are:

Extensions: Extending Classes in Ext (the "Ext 2.0 way"): IconCombo (http://extjs.com/forum/../learn/Tutorial:Extending_Ext2_Class)
http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/
http://blog.extjs.eu/know-how/xtype-defined/
http://blog.extjs.eu/know-how/events-explained/

And for plugins:
http://blog.extjs.eu/know-how/extension-or-plugin/
Plugins: Writing a Plugin (http://extjs.com/forum/../learn/Tutorial:Writing_Ext_2_Plugins)

mjlecomte
28 May 2008, 3:25 AM
Hi Saki

As per your suggestion, I have been working for last couple of weeks with the help of forums and few tutorials and been able to do quite some stuff in ExtJS. Now i think i would like to explore doing Extensions on ExtJS. Sometimes i hit to a requirement where i would have to Extend a component so wanted some suggestions from you.

a) What should be the starting point to write extensions ?
b) Any tutorials or links useful to start on this ?

~Rave
You may also want to review:

the tutorials (2) on scope
overview (http://extjs.com/learn/Manual:Component:Extending_Ext_Components)
component life cycle
forum thread on extending (http://extjs.com/forum/showthread.php?t=28085)
object oriented overview (http://extjs.com/learn/Manual:Intro)

Item 3 is linked in Item 2. Several of Saki's and others are linked in Item 2. Item 2 compiles and summarizes nicely.
Item 5 may be good if you are new to OO js along with Item 1.

raviext
28 May 2008, 9:03 PM
Hi Saki & MJ

Thanks a lot for the information. I will go through these tuturials starting today.

~Rave

wolf
9 Oct 2008, 1:01 PM
Back to the GridValidator ;)

I changed the isCellValid function so that it ignores a currently focused field in the grid. Otherwise the line within the "if" clears out any typed in value. I am catching the "clientvalidation" event in FormPanel and using FormPanel's monitorResize (gray out submit button until valid). I extended both FormPanel and GridValidator. The code below could not be extended. I'll give more details if anyone has interest.


isCellValid:function(col, row) {
if(!this.colModel.isCellEditable(col, row)) {
return true;
}
var ed = this.colModel.getCellEditor(col, row);
if(!ed) {
return true;
}
var record = this.store.getAt(row);
if(!record) {
return true;
}
var field = this.colModel.getDataIndex(col);
var isValid = false; // if hasFocus, assume not yet valid
if ( !ed.field.hasFocus ) {
ed.field.setValue(record.data[field]);
isValid = ed.field.isValid(true);
}
return isValid;
} // end of function isCellValid

mjlecomte
9 Oct 2008, 1:47 PM
and using FormPanel's monitorResize (gray out submit button until valid).
Do you mean monitorValid (http://extjs.com/deploy/dev/docs/?class=Ext.form.FormPanel&member=monitorValid)?



The code below could not be extended.

I don't understand that comment?



I'll give more details if anyone has interest.

Sure, post what you got. Any criticism only helps everyone? ;)

mestrona
2 Jul 2010, 3:47 AM
i added "validateModifiedOnly" for those who want check editet fields only:


/**
* EditorGrid validation plugin
* Adds validation functions to the grid
*
* @author Jozef Sakalos, aka Saki
* @version 0.1
*
* Usage:
* grid = new Ext.grid.EditorGrid({plugins:new Ext.ux.plugins.GridValidator(), ...})
*/
Ext.ux.plugins.GridValidator = function(config) {

// initialize plugin
this.init = function(grid) {
Ext.apply(grid, {
/**
* Checks if a grid cell is valid
* @param {Integer} col Cell column index
* @param {Integer} row Cell row index
* @param {Boolean} validateModifiedOnly true to validate modified fields only
* @return {Boolean} true = valid, false = invalid
*/
isCellValid:function(col, row, validateModifiedOnly) {
if(!this.colModel.isCellEditable(col, row)) {
return true;
}
var ed = this.colModel.getCellEditor(col, row);
if(!ed) {
return true;
}
var record = this.store.getAt(row);
if(!record) {
return true;
}
var field = this.colModel.getDataIndex(col);
if(!record.isModified(field)) {
return true;
}
ed.field.setValue(record.data[field]);
return ed.field.isValid(true);
} // end of function isCellValid

/**
* Checks if grid has valid data
* @param {Boolean} editInvalid true to automatically start editing of the first invalid cell
* @param {Boolean} validateModifiedOnly true to validate modified fields only
* @return {Boolean} true = valid, false = invalid
*/
,isValid:function(editInvalid, validateModifiedOnly) {
var cols = this.colModel.getColumnCount();
var rows = this.store.getCount();
var r, c;
var valid = true;
for(r = 0; r < rows; r++) {
for(c = 0; c < cols; c++) {
valid = this.isCellValid(c, r, validateModifiedOnly);
if(!valid) {
break;
}
}
if(!valid) {
break;
}
}
if(editInvalid && !valid) {
this.startEditing(r, c);
}
return valid;
} // end of function isValid
});
}; // end of function init
}; // GridValidator plugin end

rameshP87
12 Jul 2012, 6:11 AM
any one please help me.

rameshP87
12 Jul 2012, 6:13 AM
Can i use this file as separate file ?