-
20 Feb 2008 10:14 AM #1
Form Enhancements (maxLength, defaulting combobox, + others)
Form Enhancements (maxLength, defaulting combobox, + others)
The following override will apply the maxLength property to the textfield DOM element.
PHP Code:
Ext.override(Ext.form.TextField, {
initComponent : function(){
if (this.maxLength!=Number.MAX_VALUE && !this.autoCreate) {
this.autoCreate = Ext.apply(this.getAutoCreate, {maxlength:this.maxLength});
}
Ext.form.TextField.superclass.initComponent.call(this);
this.addEvents(
'autosize'
);
}
});
Last edited by DigitalSkyline; 28 Feb 2008 at 9:46 AM. Reason: updated title
-
20 Feb 2008 11:04 PM #2
More Form Enhancements
More Form Enhancements
A couple more bits...
- Added MixedCollection of form fields.
- Fields gain getForm() method
- Fields can be managed using mapTo:
- {
- xtype:'textfield',
- mapTo:'MyDataName' //no need for id/name property
- }
PHP Code:
// Forms probably should not rely on ID/NAME for data population,
// in large applications this becomes unmanageable.
Ext.override(Ext.form.FormPanel, {
//We'll create a MixedCollection with references to each contained field
allFields : new Ext.util.MixedCollection(false, function(o){
return o.id || (o.id = Ext.id());
}),
afterRender : function(){
Ext.form.FormPanel.superclass.afterRender.call(this);
if (this.items) {
this.items.each(this.traverseFields, this);
}
},
traverseFields : function(f){
if(f.isFormField){
//add parent form reference
f.formId=this.getId();
//allFields will use mapTo, or name, for easy access.
this.allFields.add((f.mapTo||f.getName()),f);
} else {
if (f.items) {
//make recursive call
f.items.each(this.traverseFields, this);
}
}
}
});
Ext.override(Ext.form.Field, {
mapTo:'',
initComponent : function(){
//manage id's and name properties
if (this.mapTo) {
this.name = this.mapTo;
this.id = Ext.id(this.el,'managed-form');
}
Ext.form.Field.superclass.initComponent.call(this);
this.addEvents(
'focus',
'blur',
'specialkey',
'change',
'invalid',
'valid'
);
},
//give fields reference to the parent formPanel
getForm : function(){
if (this.formId) return Ext.getCmp(this.formId);
}
});
-
20 Feb 2008 11:23 PM #3
you'll probably want to state somewhere though that the dom's maxLength property will render the TextField's maxLength config useless since the user will never be able to type past maxLength no. of characters.
Sencha Docs / Ext 3.x - ( Docs | Examples )
Learning Center / Saki's Examples (for 2.x) / HOWTO - ( Report Bugs | Post Proper Code )
-
21 Feb 2008 12:26 PM #4
Mystix, that's the whole point!

I don't know what the use case is of allowing typing beyond the character limit, I think the browser's behavior is what is expected in 99% of the cases out there (who knows maybe there is a 1% reason to allow it?)
In any case as you point out, and to anyone that this is not obvious to, the override in the first post will make the ~2 pieces of code in Ext that detects maxLength for validation, redundant.
For those who want the browser's behavior, this matters naught. For those who want the Ext behavior of allowing typing beyond the limit, but to simply invalidate the field, need not apply.
I supply this fix for those that need it; for those users who expected the browser's behavior (I think that's probably quite a few people).
Cheers!
-
24 Feb 2008 9:10 PM #5
I guess it is a matter of preference. For me I think the ideal use case is to have a combination of the two. While keystrokes are being entered that exceed the maximum length, the best case it to hover a validation message for a second or two. In that case you would probably trap the keydown, but you will still need the normal validation message in the event that it was bypassed by a cut and paste action.
Btw, I don't intend on causing any rioting or the sort but is anyone else sick of having to validate every field two or three times between the client and server interaction?
-
28 Feb 2008 9:44 AM #6
Another override for presetting combobox values loaded from JSON via nested object. This override allows you to preset a combobox without loading its entire store.
Thanks to milanz for original code, while it didn't work for me, it pointed me in the right direction. Original post: http://extjs.com/forum/showthread.php?t=20803
Example JSON:
{sucess:true, items:{normalfield:'normalvalue', mycombo:{value:'..', display:'...'}}
Improvements are welcome!
PHP Code:
Ext.override(Ext.form.BasicForm, {
setValues : function(values){
var v, f, d;
if(Ext.isArray(values)){ // array of objects
for(var i = 0, len = values.length; i < len; i++){
v = values[i];
f = this.findField(v.id);
if(f){
if(typeof v == 'object' && f.mode == 'remote'){
d = v[f.displayField];
v = v[f.valueField];
} else {
v = v.value;
d = v; //default
}
if (f.getXType()=='combo'){
f.lastSelectionText = d;
if (f.hiddenField) {
f.hiddenField.value = v;
}
Ext.form.ComboBox.superclass.setValue.call(f, d);
f.value = v;
}else{
f.setValue(v);
}
if(this.trackResetOnLoad){
f.originalValue = f.getValue();
}
}
}
}else{ // object hash
var id;
for(id in values){
v = values[id];
if(typeof v != 'function' && (f = this.findField(id))){
if(typeof v == 'object' && f.mode == 'remote'){
d = v[f.displayField];
v = v[f.valueField];
} else {
d = v; //default
}
if (f.getXType()=='combo'){
f.lastSelectionText = d;
if (f.hiddenField) {
f.hiddenField.value = v;
}
Ext.form.ComboBox.superclass.setValue.call(f, d);
f.value = v;
} else {
f.setValue(v);
}
if(this.trackResetOnLoad){
f.originalValue = f.getValue();
}
}
}
}
return this;
}
});
Last edited by DigitalSkyline; 29 Feb 2008 at 5:49 AM. Reason: fixed tabulation
-
28 Feb 2008 11:17 AM #7
It probably didn't work because I was using Ext v1.02 and posted the code in a v.2 topic area.Thanks to milanz for original code, while it didn't work for me, it pointed me in the right direction. Original post:
DigitalSkyline, absolutely brilliant -- thanks for taking the time to make improvements.
-
29 Feb 2008 4:53 AM #8
How different would this be for XML loads?
-
29 Feb 2008 5:48 AM #9
As far as I'm aware there really should not be a difference, as long as your using a standard Ext.record to populate the form. The record object supplied to the form should be the same.
However the built in form action.Load requires a JSON result, with a success property.




Reply With Quote