Skip to content

Instantly share code, notes, and snippets.

@jdorrance
Created October 22, 2013 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdorrance/7106778 to your computer and use it in GitHub Desktop.
Save jdorrance/7106778 to your computer and use it in GitHub Desktop.
###
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: (config) ->
list = this
config.fieldConfig = {} unless config.fieldConfig
config.fieldConfig.xtype = "textfield" unless config.fieldConfig.xtype
config.allowAdd = true unless config.allowAdd?
config.allowRemove = true unless config.allowRemove?
config.fieldConfig.allowRemove = config.allowRemove
config.fieldConfig.name = config.name
@fieldConfig = config.fieldConfig
items = new Array()
if config.readOnly
#if component is defined as readOnly, apply this to all items
config.fieldConfig.readOnly = true
if config.allowAdd and not config.readOnly
items.push
xtype: "button"
cls: "cq-multifield-btn"
text: "+"
handler: ->
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
# somehow regex get broken in this.defaults, so fix it
@defaults.fieldConfig.regex = config.fieldConfig.regex if @defaults.fieldConfig.regex
###
@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
###
@addEvents "change"
@findParentByType("panel").addListener "show", ->
tmp = @findByType("multifieldmultifield")
multifield = null
multifield = tmp[0] if tmp.length > 0
if multifield?
multifield.doLayout()
itemsTmp = multifield.findByType("multifieldmultifielditem")
i = 0
while i < itemsTmp.length
item = itemsTmp[i]
if item.fields
j = 0
while j < item.fields.length
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"
j++
i++
#
###
Adds a new field to the widget.
@param value The value of the field
###
addItem: (value) ->
index = @items.getCount() - 1
item = @insert(index,
nodeIndex: index
)
@findParentByType("form").getForm().add item
@doLayout()
item.setValue value if value
###
Returns the data value.
@return {String[]} value The field value
###
getValue: ->
value = new Array()
@items.each ((item, index) -> #, length
if item instanceof CQ.form.MultiFieldMultiField.Item
value[index] = item.getValue()
index++
), this
value
###
Sets a data value into the field and validates it.
@param {Mixed} value The value to set
###
setValue: (value) ->
@fireEvent "change", this, value, @getValue()
oldItems = @items
oldItems.each ((item) -> #, index, length
if item instanceof CQ.form.MultiFieldMultiField.Item
@remove item, true
@findParentByType("form").getForm().remove item
), this
@doLayout()
if (value?) and (value isnt "")
if value instanceof Array or CQ.Ext.isArray(value)
i = 0
while i < value.length
storedItem = value[i]
valueString = null
key = 0
while key < @fieldConfig.length
if (@fieldConfig[key]) and (@fieldConfig[key].name)
fieldName = @fieldConfig[key].name
fieldName = fieldName.substring(fieldName.lastIndexOf("/") + 1) if fieldName.indexOf("/") > -1
if storedItem[fieldName]
unless valueString?
valueString = storedItem[fieldName]
else
valueString = valueString + "|" + storedItem[fieldName]
else
unless valueString?
valueString = ""
else
valueString = valueString + "|"
key++
@addItem valueString
i++
else
@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: (value) ->
if @allowBlank
@clearInvalid()
return true
else
if @items.items.length > 1
@clearInvalid()
return true
else
@markInvalid @blankText
return false
true
processRecord: (record, path) ->
rows = new Array()
index = 0
nodeName = @getName().replace("./", "")
node = record.get(nodeName)
for key of node
unless key is "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
nodePath = nodeName + "/" + key
rows[key] = record.get(nodePath)
index++
@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: (config) ->
item = this
mfConfig = config
index = config.nodeIndex
@fields = new Array()
fieldIndex = 0
key = 0
while key < config.fieldConfig.length
tempConfig = config.fieldConfig[key]
if (tempConfig) and (tempConfig.name)
fieldName = tempConfig.name
fieldName = fieldName.substring(fieldName.lastIndexOf(["/"]) + 1) if fieldName.indexOf("./") > -1
if index?
tempConfig.name = config.name + "/" + index + "/" + fieldName
else
tempConfig.name = config.name + "/" + fieldName
@fields[fieldIndex] = CQ.Util.build(tempConfig, true)
fieldIndex++
key++
items = new Array()
i = 0
while i < @fields.length
items.push
xtype: "panel"
border: false
items: @fields[i]
i++
unless config.fieldConfig.readOnly
items.push
xtype: "panel"
border: false
items:
xtype: "button"
text: "Up"
cls: "cq-multifield-btn"
handler: ->
parent = item.ownerCt
index = parent.items.indexOf(item)
item.reorder parent.items.itemAt(index - 1) if index > 0
items.push
xtype: "panel"
border: false
items:
xtype: "button"
text: "Down"
cls: "cq-multifield-btn"
handler: ->
parent = item.ownerCt
index = parent.items.indexOf(item)
item.reorder parent.items.itemAt(index + 1) if index < parent.items.getCount() - 1
if config.fieldConfig.allowRemove
items.push
xtype: "panel"
border: false
items:
xtype: "button"
text: "-"
cls: "cq-multifield-btn"
handler: ->
item.remove item
config = CQ.Util.applyDefaults(config,
layout: "table"
border: false
layoutConfig:
columns: (@fields.length + 3)
defaults:
bodyStyle: "padding:3px"
items: items
)
CQ.form.MultiField.Item.superclass.constructor.call this, config
@setValue config.value if config.value
###
Reorders the item above the specified item.
@param item The item to reorder above
###
reorder: (item) ->
vars = new Array()
i = 0
while i < item.fields.length
vars.push item.fields[i].getValue()
i++
j = 0
while j < vars.length
item.fields[j].setValue @fields[j].getValue()
@fields[j].setValue vars[j]
j++
remove: (item) ->
parent = item.ownerCt
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: ->
value = null
i = 0
while i < @fields.length
if i is 0
value = @fields[0].getValue()
else
value = value + "|" + @fields[i].getValue()
i++
value
###
Sets a data value into the field and validates it.
@param {String} value The value to set
###
setValue: (value) ->
if value
values = value.split(["|"])
i = 0
while i < values.length
@fields[i].setValue values[i]
@fields[i].wrap.setWidth @fields[i].width + "px" if @fields[i].isXType("trigger")
i++
validate: ->
isValid = true
if @fields
i = 0
while i < @fields.length and isValid
isValid = @fields[i].validate() if @fields[i]
i++
isValid
getName: ->
if mfConfig
mfConfig.name
else
""
)
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