Commit 36e9ac3f authored by ecrombag's avatar ecrombag

Added generic functions gHint and gError. These can be used to append an error...

Added generic functions gHint and gError. These can be used to append an error or hint message to individual form values. Individual client components (in Javascript) are expected to handle 'this.errorMsg' and/or 'this.hintMsg' at initialization and implement 'this.setError(msg)' and 'this.setHint(msg)' when updating.

See 'VerifiedTest.icl' for some small code snippets. 

Still todo: 
 - Make errors and hints work for constructors, lists and tuples
 - Allow for the assignment of hints/errors to record fields by label, instead of position
 - Come up with some good examples to demonstrate the functionality in 'All Examples'

git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@1014 63da3aa8-80fd-4f01-9db8-e6ea747a3da2
parent ec135e12
......@@ -27,6 +27,7 @@
,{"text":"UsernameControl.js","path":"src/js/tui/"}
,{"text":"HiddenControl.js","path":"src/js/tui/"}
,{"text":"FormButtonControl.js","path":"src/js/tui/"}
,{"text":"TUICommon.js","path":"src/js/tui/"}
,{"text":"ListContainer.js","path":"src/js/tui/"}
,{"text":"RecordContainer.js","path":"src/js/tui/"}
......
Ext.ns("itasks");
Ext.QuickTips.init();
Ext.onReady(function(){
itasks.app = new itasks.Application();
itasks.app.start();
......
......@@ -181,6 +181,14 @@ itasks.ttc.FormContainer = Ext.extend(Ext.Panel, {
case "TUIReplaceMenu":
this.replaceToolbar(update[1]);
break;
case "TUISetError":
var ct = Ext.getCmp(update[1]);
if(ct && ct.setError) ct.setError(update[2]);
break;
case "TUISetHint":
var ct = Ext.getCmp(update[1]);
if(ct && ct.setHint) ct.setHint(update[2]);
break;
}
}
......
......@@ -6,6 +6,8 @@ itasks.tui.BoolControl = Ext.extend(Ext.form.Checkbox,{
this.autoCreate = {tag: 'span', html: this.value};
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
......@@ -17,6 +19,15 @@ itasks.tui.BoolControl = Ext.extend(Ext.form.Checkbox,{
itasks.tui.BoolControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.BoolControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update(value);
......@@ -24,6 +35,59 @@ itasks.tui.BoolControl = Ext.extend(Ext.form.Checkbox,{
if(value == "True") value = true;
itasks.tui.BoolControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.unmarkError();
else this.markError(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
},
markError : function(msg){
if(this.rendered){
if(!this.errorIcon){
this.activeError = msg;
var elp = this.el.findParent('.x-form-element',5,true) || this.el.findParent('.x-form-field-wrap',5,true);
if(!elp) return;
this.errorIcon = elp.createChild({cls: 'x-form-invalid-icon'});
if(this.ownerCt){
this.ownerCt.on('afterlayout', this.alignErrorIcon(), this);
this.ownerCt.on('expand', this.alignErrorIcon(), this);
}
this.on('resize', this.alignErrorIcon(),this);
this.on('destroy', function(){ Ext.destroy(this.errorIcon); }, this);
}
this.alignErrorIcon();
this.errorIcon.dom.qtip = msg;
this.errorIcon.dom.qclass = 'x-form-invalid-tip';
this.errorIcon.show();
}else{
this.errorIcon.show();
}
},
unmarkError: function(){
if(this.errorIcon){
this.errorIcon.dom.qtip = '';
this.errorIcon.hide();
delete this.activeError;
}
},
alignErrorIcon : function(){
this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
}
});
......
......@@ -4,11 +4,50 @@ itasks.tui.CharControl = Ext.extend(Ext.form.TextField,{
width: 40,
maxLength: 1,
initComponent: function() {
if(this.staticDisplay){
this.autoCreate = {tag: 'div', style: 'overflow: auto', html: this.value};
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
if(this.value == "") delete this.value;
itasks.tui.StringControl.superclass.initComponent.apply(this,arguments);
itasks.tui.CharControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.CharControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update(value);
}else{
itasks.tui.CharControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
......
......@@ -26,7 +26,8 @@ itasks.tui.ConstructorControl = Ext.extend(Ext.Panel,{
store: store,
value: store[(this.consSelIdx+1)][1],
hideLabel: true,
style: 'margin-bottom: 4px'
style: 'margin-bottom: 4px',
msgTarget: 'side'
});
}else{
this.consField = {
......@@ -45,7 +46,28 @@ itasks.tui.ConstructorControl = Ext.extend(Ext.Panel,{
}else{
Ext.form.ComboBox.superclass.setValue.call(this,value);
}
}
if(this.activeError) this.setError(this.activeError);
};
this.consField.afterRender = function(){
Ext.form.ComboBox.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
};
this.consField.setError = function(msg){
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
};
this.consField.setHint = function(msg){
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
};
this.items = [this.consField].concat(this.items);
......
......@@ -13,6 +13,8 @@ itasks.tui.CurrencyControl = Ext.extend(Ext.form.TextField,{
this.autoCreate = {tag: 'div', style: 'overflow: auto; padding-top: 4px', html: this.value};
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
......@@ -25,6 +27,14 @@ itasks.tui.CurrencyControl = Ext.extend(Ext.form.TextField,{
var cl = ct.createChild({tag: 'span', style: 'position: absolute;', cn: this.currencyLabel});
cl.setLocation(this.getEl().getLeft() + 5, this.getEl().getTop() + 5);
},
afterRender: function(){
itasks.tui.CurrencyControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
normalize: function(s) {
if(s == "")
return s;
......@@ -55,6 +65,20 @@ itasks.tui.CurrencyControl = Ext.extend(Ext.form.TextField,{
}else{
itasks.tui.CurrencyControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
......
......@@ -6,6 +6,8 @@ itasks.tui.DateControl = Ext.extend(Ext.form.DateField,{
if(this.staticDisplay){
this.autoCreate = {tag: 'div', style: 'padding-top: 4px', html: this.value};
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
......@@ -22,6 +24,11 @@ itasks.tui.DateControl = Ext.extend(Ext.form.DateField,{
if(this.staticDisplay){
this.el.next().remove();
}
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
......@@ -29,6 +36,22 @@ itasks.tui.DateControl = Ext.extend(Ext.form.DateField,{
}else{
itasks.tui.DateControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
......
This diff is collapsed.
......@@ -23,6 +23,15 @@ itasks.tui.FormButtonControl = Ext.extend(Ext.Button,{
itasks.tui.FormButtonControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.FormButtonControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update(value);
......@@ -31,6 +40,92 @@ itasks.tui.FormButtonControl = Ext.extend(Ext.Button,{
}else{
this.toggle(false,true);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.unmarkError();
else this.markError(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") this.clearHint();
else this.markHint(msg);
}).defer(50,this);
},
markError : function(msg){
if(this.rendered){
if(!this.errorIcon){
this.activeError = msg;
var elp = this.el.findParent('.x-form-element',5,true) || this.el.findParent('.x-form-field-wrap',5,true);
if(!elp) return;
this.errorIcon = elp.createChild({cls: 'x-form-invalid-icon'});
if(this.ownerCt){
this.ownerCt.on('afterlayout', this.alignErrorIcon(), this);
this.ownerCt.on('expand', this.alignErrorIcon(), this);
}
this.on('resize', this.alignErrorIcon(),this);
this.on('destroy', function(){ Ext.destroy(this.errorIcon); }, this);
}
this.alignErrorIcon();
this.errorIcon.dom.qtip = msg;
this.errorIcon.dom.qclass = 'x-form-invalid-tip';
this.errorIcon.show();
}
},
markHint : function(msg){
if(this.rendered){
if(!this.hintIcon){
this.activeHint = msg;
var elp = this.el.findParent('.x-form-element',5,true) || this.el.findParent('.x-form-field-wrap',5,true);
if(!elp) return;
this.hintIcon = elp.createChild({cls: 'x-form-hint-icon'});
if(this.ownerCt){
this.ownerCt.on('afterlayout', this.alignHintIcon(), this);
this.ownerCt.on('expand', this.alignHintIcon(), this);
}
this.on('resize', this.alignHintIcon(),this);
this.on('destroy', function(){ Ext.destroy(this.hintIcon); }, this);
}
this.alignHintIcon();
this.hintIcon.dom.qtip = msg;
this.hintIcon.dom.qclass = 'x-form-hint-tip';
this.hintIcon.show();
}
},
unmarkHint: function(){
if(this.hintIcon){
this.hintIcon.dom.qtip = '';
this.hintIcon.hide();
delete this.activeHint;
}
},
unmarkError: function(){
if(this.errorIcon){
this.errorIcon.dom.qtip = '';
this.errorIcon.hide();
delete this.activeError;
}
},
alignErrorIcon : function(){
this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
},
alignHintIcon : function(){
this.hintIcon.alignTo(this.el, 'tl-tr', [2,0]);
}
});
......
......@@ -11,19 +11,44 @@ itasks.tui.IntControl = Ext.extend(Ext.form.NumberField,{
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
this.msgTarget = 'side';
if(this.value == "") delete this.value;
itasks.tui.IntControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.IntControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update(value);
}else{
itasks.tui.IntControl.superclass.setValue.call(this,value);
if(this.activeError) this.setError(this.activeError);
}
}
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
Ext.reg("itasks.tui.Int",itasks.tui.IntControl);
\ No newline at end of file
......@@ -9,6 +9,8 @@ itasks.tui.NoteControl = Ext.extend(Ext.form.TextArea,{
this.autoHeight = true;
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
......@@ -16,12 +18,37 @@ itasks.tui.NoteControl = Ext.extend(Ext.form.TextArea,{
itasks.tui.NoteControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.NoteControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update(value.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2'));
}else{
itasks.tui.NoteControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
......
......@@ -9,6 +9,8 @@ itasks.tui.PasswordControl = Ext.extend(Ext.form.TextField,{
this.autoCreate = {tag: 'span', html: '***********'};
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
......@@ -17,6 +19,38 @@ itasks.tui.PasswordControl = Ext.extend(Ext.form.TextField,{
if(this.value == "") delete this.value;
itasks.tui.PasswordControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.PasswordControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update('***********');
}else{
itasks.tui.PasswordControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
......
......@@ -9,6 +9,8 @@ itasks.tui.RealControl = Ext.extend(Ext.form.NumberField,{
this.autoCreate = {tag: 'div', style: 'overflow: auto', html: this.value};
}
this.msgTarget = 'side';
this.hideLabel = this.fieldLabel == null;
this.fieldLabel = itasks.util.fieldLabel(this.optional,this.fieldLabel);
this.allowBlank = this.optional;
......@@ -16,12 +18,37 @@ itasks.tui.RealControl = Ext.extend(Ext.form.NumberField,{
itasks.tui.RealControl.superclass.initComponent.apply(this,arguments);
},
afterRender: function(){
itasks.tui.RealControl.superclass.afterRender.call(this,arguments);
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
setValue: function(value){
if(this.staticDisplay){
this.update(value);
}else{
itasks.tui.RealControl.superclass.setValue.call(this,value);
}
if(this.activeError) this.setError(this.activeError);
},
setError: function(msg){
(function() {
if(msg == "") this.clearInvalid();
else this.markInvalid(msg);
}).defer(50,this);
},
setHint: function(msg){
(function() {
if(msg == "") itasks.tui.common.clearHint(this);
else itasks.tui.common.markHint(this,msg);
}).defer(50,this);
}
});
......
......@@ -28,6 +28,11 @@ itasks.tui.RecordContainer = Ext.extend(Ext.form.FieldSet,{
this[this.hasValue?'expand':'collapse']();
this.checkbox.dom.checked = this.hasValue;
}
(function(){
this.setError(this.errorMsg);
this.setHint(this.hintMsg);
}).defer(50,this);
},
onCheckClick : function() {
......@@ -36,6 +41,62 @@ itasks.tui.RecordContainer = Ext.extend(Ext.form.FieldSet,{
var formCt = this.findParentByType(itasks.ttc.FormContainer);
formCt.addUpdate(this.name,(this.checkbox.dom.checked)?'create':'');
formCt.sendUpdates(false);
},
setError: function(msg){
if(this.staticDisplay) return;
(function() {
if(msg == "") this.clearError();
else this.markError(msg);
}).defer(50,this);
},
setHint: function(msg){
if(this.staticDisplay) return;
(function() {
if(msg == "") this.clearHint();
else this.markHint(msg);
}).defer(50,this);
},
markHint : function (msg){