/**
* Adapted from Brian Kotek's FormUtilities.cfc
*/
component {
/**
* I convert form field names containing dots and / or brackets into structs and / or arrays
* for convenient form variable processing on submission of nested trees of values
*/
public struct function buildFormCollections( struct formScope ) {
var local = {};
local.tempStruct = {};
local.tempStruct['formCollectionsList'] = "";
for (local.thisField in arguments.formScope) {
local.thisField = trim(local.thisField);
// if the fieldname has a dot or a bracket ...
if ( hasFormCollectionSyntax(local.thisField) ) {
// add collection to list if not present
local.tempStruct['formCollectionsList'] = addCollectionNameToCollectionList(local.tempStruct['formCollectionsList'], local.thisField);
local.currentElement = local.tempStruct;
// loop over the field using . as the delimiter
local.delimiterCounter = 1;
for (var i = 1; i <= ListLen( local.thisField, '.' ); i++ ) {
local.thisElement = ListGetAt( local.thisField, i, '.' );
local.tempElement = local.thisElement;
local.tempIndex = 0;
// if the current portion of the field has a bracket, determine the index and the element name
if ( local.tempElement contains "[" ) {
local.tempIndex = ReReplaceNoCase(local.tempElement, '.+\[|\]', '', 'all');
local.tempElement = ReReplaceNoCase(local.tempElement, '\[.+\]', '', 'all');
}
// if there is a temp element defined, this field is an array or struct
if ( !StructKeyExists( local.currentElement, local.tempElement ) ) {
// if tempIndex is 0, it's a struct, otherwise it's an array
if ( local.tempIndex eq 0 ) {
local.currentElement[local.tempElement] = {};
} else {
local.currentElement[local.tempElement] = [];
}
}
// if this is the last element defined by dots in the form field name, assign the form field value to the variable
if ( local.delimiterCounter eq ListLen(local.thisField, '.') ) {
if ( local.tempIndex eq 0 ) {
local.currentElement[local.tempElement] = arguments.formScope[local.thisField];
} else {
local.currentElement[local.tempElement][local.tempIndex] = arguments.formScope[local.thisField];
}
// otherwise, keep going through the field name looking for more structs or arrays
} else {
// if this field was a Struct, make the next element the current element for the next loop iteration
if ( local.tempIndex eq 0 ) {
local.currentElement = local.currentElement[local.tempElement];
} else {
if ( ArrayIsEmpty(local.currentElement[local.tempElement])
or ArrayLen(local.currentElement[local.tempElement]) lt local.tempIndex
or not ArrayIsDefined(local.currentElement[local.tempElement], local.tempIndex) ) {
local.currentElement[local.tempElement][local.tempIndex] = {};
}
// Make the next element the current element for the next loop iteration
local.currentElement = local.currentElement[local.tempElement][local.tempIndex];
}
local.delimiterCounter = local.delimiterCounter + 1;
}
}
}
}
return local.tempStruct;
}
/**
* I determine if the field has the form collection syntax, meaning it contains a dot or a bracket
*
*/
private boolean function hasFormCollectionSyntax( fieldName ) {
return arguments.fieldName contains "." or arguments.fieldName contains "[";
}
/**
* I add the collection name to the list of collection names if it isn't already there
*
*/
private string function addCollectionNameToCollectionList( string formCollectionsList, string fieldName ) {
if ( !ListFindNoCase( arguments.formCollectionsList, ReReplaceNoCase( arguments.fieldName, '(\.|\[).+', '' ) ) ) {
arguments.formCollectionsList = ListAppend( arguments.formCollectionsList, ReReplaceNoCase( arguments.fieldName, '(\.|\[).+', '' ) );
}
return arguments.formCollectionsList;
}
}