Last active
March 29, 2019 09:49
-
-
Save sgaem/f15e7aa6615d142fbb30aba5888a06f1 to your computer and use it in GitHub Desktop.
This Multifield.js is working with all the widgets like drop-down and checkbox functionality.
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
(function ($, $document) { | |
var DATA_EAEM_NESTED = "data-eaem-nested"; | |
var CFFW = ".coral-Form-fieldwrapper"; | |
function isSelectOne($field){ | |
return !_.isEmpty($field) && ($field.prop("type") === "select-one"); | |
} | |
function setSelectOne($field, value){ | |
var select = $field.closest(".coral-Select").data("select"); | |
if(select){ | |
select.setValue(value); | |
} | |
} | |
function isCheckbox($field){ | |
return !_.isEmpty($field) && ($field.prop("type") === "checkbox"); | |
} | |
function setCheckBox($field, value){ | |
$field.prop( "checked", $field.attr("value") == value); | |
} | |
function setWidgetValue($field, value){ | |
if(_.isEmpty($field)){ | |
return; | |
} | |
if(isSelectOne($field)){ | |
setSelectOne($field, value); | |
}else if(isCheckbox($field)){ | |
setCheckBox($field, value); | |
}else{ | |
$field.val(value); | |
} | |
} | |
//reads multifield data from server, creates the nested composite multifields and fills them | |
function addDataInFields() { | |
$(document).on("dialog-ready", dlgReadyHandler); | |
function dlgReadyHandler() { | |
var $fieldSets = $("[" + DATA_EAEM_NESTED + "][class='coral-Form-fieldset']"); | |
if(_.isEmpty($fieldSets)){ | |
return; | |
} | |
var mNames = []; | |
$fieldSets.each(function (i, fieldSet) { | |
mNames.push($(fieldSet).data("name")); | |
}); | |
mNames = _.uniq(mNames); | |
var actionUrl = $fieldSets.closest("form.foundation-form").attr("action") + ".json"; | |
$.ajax(actionUrl).done(postProcess); | |
function postProcess(data){ | |
_.each(mNames, function(mName){ | |
buildMultiField(data, mName); | |
}); | |
} | |
//creates & fills the nested multifield with data | |
function fillNestedFields($multifield, valueArr){ | |
_.each(valueArr, function(record, index){ | |
$multifield.find(".js-coral-Multifield-add").click(); | |
//a setTimeout may be needed | |
_.each(record, function(value, key){ | |
setWidgetValue($($multifield.find("[name='./" + key + "']")[index]), value); | |
}) | |
}) | |
} | |
function buildMultiField(data, mName){ | |
if(_.isEmpty(mName)){ | |
return; | |
} | |
$fieldSets = $("[data-name='" + mName + "']"); | |
//strip ./ | |
mName = mName.substring(2); | |
var mValues = data[mName], $field, name; | |
if(_.isString(mValues)){ | |
mValues = [ JSON.parse(mValues) ]; | |
} | |
_.each(mValues, function (record, i) { | |
if (!record) { | |
return; | |
} | |
if(_.isString(record)){ | |
record = JSON.parse(record); | |
} | |
_.each(record, function(rValue, rKey){ | |
$field = $($fieldSets[i]).find("[name='./" + rKey + "']"); | |
if(_.isArray(rValue) && !_.isEmpty(rValue)){ | |
fillNestedFields( $($fieldSets[i]).find("[data-init='multifield']"), rValue); | |
}else{ | |
var select = $field.closest(".coral-Select").data("select"); | |
if(select){ | |
select.setValue(rValue); | |
} | |
else{ | |
setWidgetValue($field, rValue); | |
} | |
} | |
}); | |
}); | |
} | |
} | |
} | |
function fillValue($field, record){ | |
var name = $field.attr("name"), value; | |
if (!name) { | |
return; | |
} | |
//strip ./ | |
if (name.indexOf("./") == 0) { | |
name = name.substring(2); | |
} | |
value = $field.val(); | |
if( isCheckbox($field) ){ | |
value = $field.prop("checked") ? $field.val() : ""; | |
} | |
record[name] = value; | |
//remove the field, so that individual values are not POSTed | |
$field.remove(); | |
} | |
//for getting the nested multifield data as js objects | |
function getRecordFromMultiField($multifield){ | |
var $fieldSets = $multifield.find("[class='coral-Form-fieldset']"); | |
var records = [], record, $fields, name; | |
$fieldSets.each(function (i, fieldSet) { | |
$fields = $(fieldSet).find("[name]"); | |
record = {}; | |
$fields.each(function (j, field) { | |
fillValue($(field), record); | |
}); | |
if(!$.isEmptyObject(record)){ | |
records.push(record) | |
} | |
}); | |
return records; | |
} | |
//collect data from widgets in multifield and POST them to CRX as JSON | |
function collectDataFromFields(){ | |
$(document).on("click", ".cq-dialog-submit", function () { | |
var $form = $(this).closest("form.foundation-form"); | |
var $fieldSets = $("[" + DATA_EAEM_NESTED + "][class='coral-Form-fieldset']"); | |
var record, $fields, $field, name, $nestedMultiField; | |
$fieldSets.each(function (i, fieldSet) { | |
$fields = $(fieldSet).children().children(CFFW); | |
record = {}; | |
$fields.each(function (j, field) { | |
$field = $(field); | |
//may be a nested multifield | |
$nestedMultiField = $field.find("[data-init='multifield']"); | |
if($nestedMultiField.length == 0){ | |
fillValue($field.find("[name]"), record); | |
}else{ | |
name = $nestedMultiField.find("[class='coral-Form-fieldset']").data("name"); | |
if(!name){ | |
return; | |
} | |
//strip ./ | |
name = name.substring(2); | |
record[name] = getRecordFromMultiField($nestedMultiField); | |
} | |
}); | |
if ($.isEmptyObject(record)) { | |
return; | |
} | |
//add the record JSON in a hidden field as string | |
$('<input />').attr('type', 'hidden') | |
.attr('name', $(fieldSet).data("name")) | |
.attr('value', JSON.stringify(record)) | |
.appendTo($form); | |
}); | |
}); | |
} | |
$document.ready(function () { | |
addDataInFields(); | |
collectDataFromFields(); | |
}); | |
//extend otb multifield for adjusting event propagation when there are nested multifields | |
//for working around the nested multifield add and reorder | |
CUI.CustomMultifield = new Class({ | |
toString: "Multifield", | |
extend: CUI.Multifield, | |
construct: function (options) { | |
this.script = this.$element.find(".js-coral-Multifield-input-template:last"); | |
}, | |
_addListeners: function () { | |
this.superClass._addListeners.call(this); | |
//otb coral event handler is added on selector .js-coral-Multifield-add | |
//any nested multifield add click events are propagated to the parent multifield | |
//to prevent adding a new composite field in both nested multifield and parent multifield | |
//when user clicks on add of nested multifield, stop the event propagation to parent multifield | |
this.$element.on("click", ".js-coral-Multifield-add", function (e) { | |
e.stopPropagation(); | |
}); | |
this.$element.on("drop", function (e) { | |
e.stopPropagation(); | |
}); | |
} | |
}); | |
CUI.Widget.registry.register("multifield", CUI.CustomMultifield); | |
}(jQuery, jQuery(document))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 53 function fillNestedFields .Once addbutton is clicked All multifield items aren't ready. Use the CoralUI ready event handler in this case to prepopulate the multiflied items.Below is the sample code