PDA

View Full Version : Basic Hide/When Functionality



Zakaroonikov
14 Aug 2008, 5:37 PM
Hi all,

I have written a plugin for a form panel to offer javascript-based show/hide when functionality. It is only written at a basic level but it might be a good starting point for further development.

Code:


/**
* Plugin to handle hide/when formulas
*/
JCW.Form.Plugins.HideWhen = Ext.extend(Ext.util.Observable, {
init : function(jcwForm) {
this.form = jcwForm;
},

/**
*
**/
setHideWhen : function (field) {
var rules = field.setClassWhenRules || this.getClassWhenRules(field);
if (rules) {
this.formContainerEl = this.form.container;
if (field.isXType('textfield')) {
field.el.on('change', this.fireHideWhenRules.createDelegate(this, [rules, field]));
} else if (field.isXType('checkbox')) {
field.el.on('click', this.fireHideWhenRules.createDelegate(this, [rules, field]));
}
this.fireHideWhenRules(rules, field);
}
},

fireHideWhenRules : function (rules, field) {
if (typeof rules === 'array') {
Ext.each(rules, this.setClassWhen.createDelegate(this, [field], 1));
} else if (typeof rules === 'object') {
this.setClassWhen(rules, field);
}
},

getClassWhenRules : function (field) {
var xPath = this.getAttribute(field, 'xpath');
var matchCls = this.getAttribute(field, 'matchcls');
var matchStyle = this.getAttribute(field, 'matchstyle');
var matchAction = this.getAttribute(field, 'matchaction');

var noMatchCls = this.getAttribute(field, 'nomatchcls');
var noMatchStyle = this.getAttribute(field, 'nomatchstyle');
var noMatchAction = this.getAttribute(field, 'nomatchaction');

var matchValue = this.getAttribute(field, 'matchval');

var matchQuery = this.getAttribute(field, 'matchquery');

var matchFieldNames = this.getAttribute(field, 'matchfieldnames');


if (xPath) {

var rules = {
matchCls : matchCls,
matchStyle : matchStyle,
matchAction : matchAction,
noMatchCls : noMatchCls,
noMatchStyle : noMatchStyle,
noMatchAction : noMatchAction,
matchVal : matchValue,
matchQuery : matchQuery,
matchFieldNames : matchFieldNames
};
if (typeof xPath === 'string') {
rules.xPath = xPath;
return rules;
} else {
var rulesArr = [];
for(var i=0; i < xPath.length; i++) {
rulesArr[rulesArr.length] = this._getClassWhenRule(xPath[i], rules, i);
}
return rulesArr;
}

} else {
return false;
}

},

_getClassWhenRule : function(xPath, rules, index) {
var rule = { xPath : xPath};
for (var rulePropertyName in rules) {
var ruleProperty = rules[rulePropertyName];
if (typeof ruleProperty === 'string' || typeof ruleProperty === 'boolean') {
rule[rulePropertyName] = ruleProperty;
} else if (typeof ruleProperty !== 'function') {
if (ruleProperty.length >= index) {
rule[rulePropertyName] = ruleProperty[index];
} else {
rule[rulePropertyName] = ruleProperty.length ? ruleProperty[ruleProperty.length -1] : null;
}
}
}
return rule;
},

getAttribute : function(field, attribute, index) {
if (attribute && field.el) {
var el;
if (field.isXType('combo') && field.hiddenField) {
el = Ext.fly(field.hiddenField);
} else {
el = field.el;
}
var attributeVal = el.getAttributeNS('cwo', attribute);
if (attributeVal) {
// If there is a comma in the attribute then there are multiple values so split them
if (attributeVal.indexOf(',') !== -1) {
return attributeVal.split(',');
} else {
return attributeVal;
}
}
}
return false;
},

setClassWhen : function (rules, field) {
try {
if (this.formContainerEl) {
if (rules) {
Ext.each(rules, this.processRule.createDelegate(this, [field], 1), this);
}
}
} catch (e) {

}
},


processRule : function (rule, field) {
var destEls = this.formContainerEl.select(rule.xPath, true);
if (destEls) {
if(rule.matchVal === (field.getGroupValue ? field.getGroupValue() : field.getValue())) {
if (rule.matchCls) {
destEls.addClass(rule.matchCls);
}
if (rule.noMatchCls) {
destEls.removeClass(rule.noMatchCls);
}
if (rule.matchStyle) {
destEls.applyStyles(rule.matchStyle);
}
} else {
if (rule.matchCls) {
destEls.removeClass(rule.matchCls);
}
if (rule.noMatchCls) {
destEls.addClass(rule.noMatchCls);
}
if (rule.noMatchStyle) {
destEls.applyStyles(rule.noMatchStyle);
}
}
}
}
});


Example usage place the following code in your HTML Attribute for your field:


xpath := ".cwo-MER-hideIT,.cwo-MER-showIT,.cwo-MER-strikeThroughIT,.cwo-MER-showCorporate,.cwo-MER-hideCorporate,.cwo-MER-strikeThroughCorporate";
matchVal := "Corporate IT,Corporate IT,Corporate IT,Corporate,Corporate,Corporate";
matchStyle := "display:none;,display:block;,text-decoration:line-through;,display:;,display:none;,text-decoration:line-through;";
noMatchStyle := "display:block;,display:none;,text-decoration:none;,display:none;,display:;,text-decoration:none;";


"cwo:xpath=\"" + xpath+ "\" cwo:matchval=\"" + matchVal + "\" cwo:matchstyle=\"" + matchStyle + "\" cwo:nomatchstyle=\"" + noMatchStyle + "\""


This code uses custom namespaced tag attributes. This is similar to how the Dojo integration will work with 8.5. Here is a brief explanation of these attributes:

cwo:xpath -> css selector to use to apply show/hide style
matchVal -> Value to compare fields value (the field with these attributes)
matchStyle -> What css style to apply to the dom elements selected by the css selector if the field is equal to the matchVal
noMatchStyle -> What css style to apply to the dom elements selected by the css selector if the field is not equal to the matchVal

In my example if the the field is set to 'Corporate IT' then:
1. All dom elements with css class .cwo-MER-hideIT will have a style display:none; added to them
2. All dom elements with css class .cwo-MER-showIT will have a style display:block; added to them
3. All dom elements with the css class .cwo-MER-strikeThroughIT will have the style text-decoration: strikethrough; added to them
Since the value is not 'Corporate' the following will also occur
1. All dom elements with the css class .cwo-MER-showCorporate will have the style display:none; added to them
2. All dom elements with the css class .cwo-MER-hideCorporate will have the display style cleared from them
3. All dom elements with the css class .cwo-MER-strikeThroughCorporate will have the display style text-decoration: none; added to them

In my example if the the field is set to just 'Corporate' then:
1. All dom elements with css class .cwo-MER-hideIT will have a style display:block; added to them
2. All dom elements with css class .cwo-MER-showIT will have a style display:none; added to them
3. All dom elements with the css class .cwo-MER-strikeThroughIT will have the style text-decoration: none; added to them
Since the value is 'Corporate' the following will also occur
1. All dom elements with the css class .cwo-MER-showCorporate will have the style display cleared from them
2. All dom elements with the css class .cwo-MER-hideCorporate will have the style display:none; added to them
3. All dom elements with the css class .cwo-MER-strikeThroughCorporate will have the display style text-decoration: strikethrough; added to them

Finally in the case where the field is neither 'Corporate IT' or 'Corporate' then the following would occur:
1. All dom elements with css class .cwo-MER-hideIT will have a style display:block; added to them
2. All dom elements with css class .cwo-MER-showIT will have a style display:none; added to them
3. All dom elements with the css class .cwo-MER-strikeThroughIT will have the style
4. All dom elements with the css class .cwo-MER-showCorporate will have the style display:none; added to them
5. All dom elements with the css class .cwo-MER-hideCorporate will have the display style cleared from them
6. All dom elements with the css class .cwo-MER-strikeThroughCorporate will have the display style text-decoration: none; added to them