Created
October 22, 2013 15:20
-
-
Save jdorrance/7102579 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The <code>CQ.form.MultiFieldMultiField</code> class represents an editable list | |
* of form fields for editing multi value properties. | |
* | |
* @class CQ.form.MultiFieldMultiField | |
* @extends CQ.form.CompositeField | |
*/ | |
CQ.form.MultiFieldMultiField = CQ.Ext.extend(CQ.form.CompositeField, { | |
/** | |
* @cfg {Object} fieldConfig | |
* The configuration options for the fields (optional). | |
*/ | |
fieldConfig: null, | |
/** | |
* @cfg {Object} globalConfig | |
* The configuration options for the fields, to create a new field for the form. | |
*/ | |
globalConfig: null, | |
/** | |
* Creates a new <code>CQ.form.MultiFieldMultiField</code>. | |
* @constructor | |
* @param {Object} config The config object | |
*/ | |
constructor: function(config) { | |
var list = this; | |
if (!config.fieldConfig) { | |
config.fieldConfig = {}; | |
} | |
if (!config.fieldConfig.xtype) { | |
config.fieldConfig.xtype = "textfield"; | |
} | |
config.fieldConfig.name = config.name; | |
this.fieldConfig = config.fieldConfig; | |
var items = new Array(); | |
if(config.readOnly) { | |
//if component is defined as readOnly, apply this to all items | |
config.fieldConfig.readOnly = true; | |
} else { | |
items.push({ | |
"xtype":"button", | |
"cls": "cq-multifield-btn", | |
"text":"+", | |
"handler":function() { | |
list.addItem(); | |
} | |
}); | |
} | |
items.push({ | |
"xtype":"hidden", | |
"name":config.name + CQ.Sling.DELETE_SUFFIX | |
}); | |
config = CQ.Util.applyDefaults(config, { | |
"defaults":{ | |
"xtype":"multifieldmultifielditem", | |
"name":config.name, | |
"fieldConfig":config.fieldConfig | |
}, | |
"items":[ | |
{ | |
"xtype":"panel", | |
"border":false, | |
"bodyStyle":"padding:4px", | |
"items":items | |
} | |
] | |
}); | |
CQ.form.MultiFieldMultiField.superclass.constructor.call(this,config); | |
if (this.defaults.fieldConfig.regex) { | |
// somehow regex get broken in this.defaults, so fix it | |
this.defaults.fieldConfig.regex = config.fieldConfig.regex; | |
} | |
this.addEvents( | |
/** | |
* @event change | |
* Fires when the value is changed. | |
* @param {CQ.form.MultiFieldMultiFieldNodes} this | |
* @param {Mixed} newValue The new value | |
* @param {Mixed} oldValue The original value | |
*/ | |
"change" | |
); | |
this.findParentByType("panel").addListener("show", function() { | |
var tmp = this.findByType("multifieldmultifield"); | |
var multifield = null; | |
if ( tmp.length > 0 ) multifield = tmp[0]; | |
if (multifield != null) { | |
multifield.doLayout(); | |
var itemsTmp = multifield.findByType("multifieldmultifielditem"); | |
for ( var i = 0; i < itemsTmp.length; i ++ ) { | |
var item = itemsTmp[i]; | |
if(item.fields) { | |
for (var j=0; j<item.fields.length; j++) { | |
if (item.fields[j]) { | |
if (item.fields[j].isXType("trigger")) { | |
if (item.fields[j].getWidth() > 15) { | |
item.fields[j].setWidth(item.fields[j].getWidth()); | |
} else { | |
//arbitrary width value | |
item.fields[j].setWidth(134); | |
} | |
item.fields[j].wrap.setWidth(item.fields[j].getWidth()+"px"); | |
} | |
} | |
} | |
} | |
} | |
} | |
/**/ | |
}); | |
}, | |
/** | |
* Adds a new field to the widget. | |
* @param value The value of the field | |
*/ | |
addItem: function(value) { | |
var index = this.items.getCount()-1; | |
var item = this.insert(index, {"nodeIndex": index}); | |
this.findParentByType("form").getForm().add(item); | |
this.doLayout(); | |
if (value) { | |
item.setValue(value); | |
} | |
}, | |
/** | |
* Returns the data value. | |
* @return {String[]} value The field value | |
*/ | |
getValue: function() { | |
var value = new Array(); | |
this.items.each(function(item, index/*, length*/) { | |
if (item instanceof CQ.form.MultiFieldMultiField.Item) { | |
value[index] = item.getValue(); | |
index++; | |
} | |
}, this); | |
return value; | |
}, | |
/** | |
* Sets a data value into the field and validates it. | |
* @param {Mixed} value The value to set | |
*/ | |
setValue: function(value) { | |
this.fireEvent("change", this, value, this.getValue()); | |
var oldItems = this.items; | |
oldItems.each(function(item/*, index, length*/) { | |
if (item instanceof CQ.form.MultiFieldMultiField.Item) { | |
this.remove(item, true); | |
this.findParentByType("form").getForm().remove(item); | |
} | |
}, this); | |
this.doLayout(); | |
if ((value != null) && (value != "")) { | |
if (value instanceof Array || CQ.Ext.isArray(value)) { | |
for (var i = 0; i < value.length; i++) { | |
var storedItem = value[i]; | |
var valueString = null; | |
for (var key=0; key < this.fieldConfig.length;key++) { | |
if ( (this.fieldConfig[key]) && (this.fieldConfig[key].name) ) { | |
var fieldName = this.fieldConfig[key].name; | |
if (fieldName.indexOf("/") > -1) { | |
fieldName = fieldName.substring(fieldName.lastIndexOf("/")+1); | |
} | |
if (storedItem[fieldName]) { | |
if (valueString == null) { | |
valueString = storedItem[fieldName]; | |
} else { | |
valueString = valueString + "|" + storedItem[fieldName]; | |
} | |
} else { | |
if (valueString == null) { | |
valueString = ""; | |
} else { | |
valueString = valueString + "|"; | |
} | |
} | |
} | |
} | |
this.addItem(valueString); | |
} | |
} else { | |
this.addItem(value); | |
} | |
} | |
}, | |
/** | |
/* ValidateValue function | |
/* | |
/* This validateValue enforces user to click on + initially when content is being first created. | |
/* | |
/* How to add validation: Add allowBlank="{Boolean}false" on the same level where | |
/* xtype="multifieldmultifield" is defined in dialog.xml | |
/* | |
/* Note: You still have to put allowBlank="{Boolean}false" on the fields under | |
/* multifield where you want to strictly enforce editors to provide values. If not provided | |
/* than users will click on + and this validation will skip. | |
/* EXAMPLE to add allowBlank on multifieldmultifield: | |
/* | |
/* <links | |
/* jcr:primaryType="cq:Widget" | |
/* fieldLabel="Links" | |
/* name="./links" | |
/* allowBlank="{Boolean}false" | |
/* xtype="multifieldmultifield"> | |
/* <fieldConfig jcr:primaryType="cq:WidgetCollection"> | |
/* <field1 | |
/* jcr:primaryType="cq:Widget" | |
/* fieldLabel="Link Title" | |
/* name="linkTitle" | |
/* xtype="textfield" | |
/* allowBlank="{Boolean}false" | |
/* emptyText="Link Title"/> | |
/* </field1> | |
/* </fieldConfig> | |
/* </links> | |
/* | |
/* | |
*/ | |
validateValue: function(value) { | |
if(this.allowBlank){ | |
this.clearInvalid(); | |
return true; | |
}else{ | |
if(this.items.items.length > 1){ | |
this.clearInvalid(); | |
return true; | |
} | |
else{ | |
this.markInvalid(this.blankText); | |
return false; | |
} | |
} | |
return true; | |
}, | |
processRecord: function(record, path) { | |
var rows = new Array(); | |
var index = 0; | |
var nodeName = this.getName().replace("./", ""); | |
var node = record.get(nodeName); | |
for (var key in node) { | |
if (key != 'jcr:primaryType') { | |
//the nodes are saved in no particular order, so using the key (name) of the node | |
//to add to the right index of the array so they populate the form correctly | |
//the order can be maintained by adding isUpload ="true" to the dialog config | |
var nodePath = nodeName + "/" + key; | |
rows[key] = record.get(nodePath); | |
index++; | |
} | |
} | |
this.setValue(rows); | |
} | |
}); | |
CQ.Ext.reg("multifieldmultifield", CQ.form.MultiFieldMultiField); | |
/** | |
* The <code>CQ.form.MultiFieldMultiField.Item</code> class represents an item in a | |
* <code>CQ.form.MultiFieldMultiField</code>. This class is not intended for direct use. | |
* | |
* @private | |
* @class CQ.form.MultiFieldMultiField.Item | |
* @extends CQ.Ext.Panel | |
*/ | |
CQ.form.MultiFieldMultiField.Item = CQ.Ext.extend(CQ.form.MultiField.Item, { | |
mfConfig: null, | |
/** | |
* Creates a new <code>CQ.form.MultiFieldMultiField.Item</code>. | |
* @constructor | |
* @param {Object} config The config object | |
*/ | |
constructor: function(config) { | |
var item = this; | |
mfConfig = config; | |
var index = config.nodeIndex; | |
this.fields = new Array(); | |
var fieldIndex = 0; | |
for (var key = 0; key < config.fieldConfig.length;key++) { | |
var tempConfig = config.fieldConfig[key]; | |
if ( (tempConfig) && (tempConfig.name) ) { | |
var fieldName = tempConfig.name; | |
if (fieldName.indexOf("./") > -1) { | |
fieldName = fieldName.substring(fieldName.lastIndexOf(['/']) + 1); | |
} | |
if (index != null) { | |
tempConfig.name = config.name + "/" + index + "/" + fieldName; | |
} else { | |
tempConfig.name = config.name + "/" + fieldName; | |
} | |
this.fields[fieldIndex] = CQ.Util.build(tempConfig, true); | |
fieldIndex++; | |
} | |
} | |
var items = new Array(); | |
for (var i=0; i< this.fields.length; i++) { | |
items.push({ | |
"xtype":"panel", | |
"border":false, | |
"items": this.fields[i] | |
}); | |
} | |
if(!config.fieldConfig.readOnly) { | |
items.push({ | |
"xtype":"panel", | |
"border":false, | |
"items":{ | |
"xtype":"button", | |
"text":"Up", | |
"cls": "cq-multifield-btn", | |
"handler":function() { | |
var parent = item.ownerCt; | |
var index = parent.items.indexOf(item); | |
if (index > 0) { | |
item.reorder(parent.items.itemAt(index - 1)); | |
} | |
} | |
} | |
}); | |
items.push({ | |
"xtype":"panel", | |
"border":false, | |
"items":{ | |
"xtype":"button", | |
"text":"Down", | |
"cls": "cq-multifield-btn", | |
"handler":function() { | |
var parent = item.ownerCt; | |
var index = parent.items.indexOf(item); | |
if (index < parent.items.getCount() - 1) { | |
item.reorder(parent.items.itemAt(index + 1)); | |
} | |
} | |
} | |
}); | |
items.push({ | |
"xtype":"panel", | |
"border":false, | |
"items":{ | |
"xtype":"button", | |
"text":"-", | |
"cls": "cq-multifield-btn", | |
"handler":function() { | |
item.remove(item); | |
} | |
} | |
}); | |
} | |
config = CQ.Util.applyDefaults(config, { | |
"layout":"table", | |
"border":false, | |
"layoutConfig":{ | |
"columns": (this.fields.length + 3) | |
}, | |
"defaults":{ | |
"bodyStyle":"padding:3px" | |
}, | |
"items":items | |
}); | |
CQ.form.MultiField.Item.superclass.constructor.call(this, config); | |
if (config.value) { | |
this.setValue(config.value); | |
} | |
}, | |
/** | |
* Reorders the item above the specified item. | |
* @param item The item to reorder above | |
*/ | |
reorder: function(item) { | |
var vars = new Array(); | |
for (var i=0; i<item.fields.length; i++) { | |
vars.push(item.fields[i].getValue()); | |
} | |
for (var j=0; j<vars.length; j++) { | |
item.fields[j].setValue(this.fields[j].getValue()); | |
this.fields[j].setValue(vars[j]); | |
} | |
}, | |
remove: function(item) { | |
var parent = item.ownerCt; | |
var index = parent.items.indexOf(item); | |
if (index < parent.items.getCount() - 2) { | |
item.reorder(parent.items.itemAt(index + 1)); | |
item.remove(parent.items.itemAt(index + 1)); | |
} else { | |
parent.remove(item); | |
} | |
}, | |
/** | |
* Returns the data value. | |
* @return {String} value The field value | |
*/ | |
getValue: function() { | |
var value = null; | |
for (var i=0; i<this.fields.length; i++) { | |
if (i == 0) { | |
value = this.fields[0].getValue(); | |
} else { | |
value = value + "|" + this.fields[i].getValue(); | |
} | |
} | |
return value; | |
}, | |
/** | |
* Sets a data value into the field and validates it. | |
* @param {String} value The value to set | |
*/ | |
setValue: function(value) { | |
if (value) { | |
var values = value.split(["|"]); | |
for (var i=0; i<values.length; i++) { | |
this.fields[i].setValue(values[i]); | |
if (this.fields[i].isXType("trigger")) { | |
this.fields[i].wrap.setWidth(this.fields[i].width +"px"); | |
} | |
} | |
} | |
}, | |
validate: function() { | |
var isValid = true; | |
if(this.fields) { | |
for (var i=0; i<this.fields.length&&isValid; i++) { | |
if (this.fields[i]) { | |
isValid = this.fields[i].validate(); | |
} | |
} | |
} | |
return isValid; | |
}, | |
getName: function() { | |
if (mfConfig) { | |
return mfConfig.name; | |
} else { | |
return ''; | |
} | |
} | |
}); | |
CQ.Ext.reg("multifieldmultifielditem", CQ.form.MultiFieldMultiField.Item); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment