Expand my Community achievements bar.

Radically easy to access on brand approved content for distribution and omnichannel performant delivery. AEM Assets Content Hub and Dynamic Media with OpenAPI capabilities is now GA.

checkbox value not saving in multifield dialog in AEM 6.4

Avatar

Level 2

Hi Team,

I am working on developing a multifield in 6.4 I have a checkbox, in the multifield. But, when I am adding some values in dialog, after clicking on TICK mark and refreshing the page. When I reopen the dialog, I see the empty one. Not even the  added nodes in dialog.

I have added acs-commons 4.2.0

--I have used coral only, not granite UI. That is shown in the screenshots below.

Goal :

1. Multifield with checkbox with JSON_STORE in AEM 6.4

2. I also need RTE fields in TOUCH UI dialog in 6.4 with JSON Store

Attached screen-shots of the dialog :

Screen-shot-1.PNGscreen-shot-2.PNG

screen-shot-3.PNG

dialog xml file :

<?xml version="1.0" encoding="UTF-8"?>

<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"

    jcr:primaryType="nt:unstructured"

    jcr:title="Check Box"

    sling:resourceType="cq/gui/components/authoring/dialog"

    helpPath="en/cq/current/wcm/default_components.html#Image">

    <content

        jcr:primaryType="nt:unstructured"

        sling:resourceType="granite/ui/components/foundation/container">

        <layout

            jcr:primaryType="nt:unstructured"

            sling:resourceType="granite/ui/components/foundation/layouts/tabs"

            margin="{Boolean}false"

            type="nav"/>

        <items jcr:primaryType="nt:unstructured">

            <overviewone

                jcr:primaryType="nt:unstructured"

                jcr:title="Overview One"

                sling:resourceType="granite/ui/components/foundation/section">

                <layout

                    jcr:primaryType="nt:unstructured"

                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>

                <items jcr:primaryType="nt:unstructured">

                    <column

                        jcr:primaryType="nt:unstructured"

                        sling:resourceType="granite/ui/components/foundation/container">

                        <items jcr:primaryType="nt:unstructured">

                            <hideMobile

                                jcr:primaryType="nt:unstructured"

                                sling:resourceType="granite/ui/components/foundation/form/checkbox"

                                name="./myValueOne"

                                text="Check By Default"

                                value="isChecked"/>

                        </items>

                    </column>

                </items>

            </overviewone>

            <overviewtwo

                jcr:primaryType="nt:unstructured"

                jcr:title="Overview Two"

                sling:resourceType="granite/ui/components/foundation/section">

                <layout

                    jcr:primaryType="nt:unstructured"

                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>

                <items jcr:primaryType="nt:unstructured">

                    <column

                        jcr:primaryType="nt:unstructured"

                        sling:resourceType="granite/ui/components/foundation/container">

                        <items jcr:primaryType="nt:unstructured">

                            <hideMobile

                                jcr:primaryType="nt:unstructured"

                                sling:resourceType="granite/ui/components/foundation/form/checkbox"

                                name="./myValue"

                                text="Check By Default"

                                value="isChecked"/>

                        </items>

                    </column>

                </items>

            </overviewtwo>

            <Careinformation

                jcr:primaryType="nt:unstructured"

                jcr:title="Care Information"

                sling:resourceType="granite/ui/components/foundation/section">

                <layout

                    jcr:primaryType="nt:unstructured"

                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>

                <items jcr:primaryType="nt:unstructured">

                    <Dispositions

                        jcr:primaryType="nt:unstructured"

                        sling:resourceType="granite/ui/components/coral/foundation/form/multifield"

                        fieldLabel="Care Information Statements">

                        <field

                            jcr:primaryType="nt:unstructured"

                            sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"

                            acs-commons-nested="JSON_STORE"

                            name="./careinfo">

                            <items jcr:primaryType="nt:unstructured">

                                <column

                                    jcr:primaryType="nt:unstructured"

                                    sling:resourceType="granite/ui/components/coral/foundation/container">

                                    <items jcr:primaryType="nt:unstructured">

                                        <hideMobile

                                            jcr:primaryType="nt:unstructured"

                                            sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"

                                            name="./option"

                                            text="Add Button?"

                                            uncheckedValue="{Boolean}false"

                                            value="{Boolean}true"/>

                                    </items>

                                </column>

                            </items>

                        </field>

                    </Dispositions>

                </items>

            </Careinformation>

        </items>

    </content>

</jcr:root>

Could someone please provide a solution.

Thanks,
Sampath.

4 Replies

Avatar

Level 3

Hi Sampath,

It is known issue with multifield (when used with ACS-Commons), you will need to add logic to set checkbox and RTE value in touchui-widgets-init.js file and set it in "setWidgetValue" method.

You can add something like as below  for example:

isCheckbox: function ($field) {

   return !_.isEmpty($field) && ($field.prop("type") === "checkbox" || $field.hasClass("coral-Checkbox"));
},

setCheckBox: function ($field, value) {

   if($field.parent().hasClass("coral-Checkbox")){

  $field.parent().prop("checked", $field.attr("value") === value);
   }else {

  $field.prop("checked", $field.attr("value") === value);
   }

},

and in setWidgetValue() -->

setWidgetValue: function ($field, value) {

   if (_.isEmpty($field)) {

   return;
   }

   if (this.isSelectOne($field)) {

   this.setSelectOne($field, value);
   } else if (this.isCheckbox($field)) {

   this.setCheckBox($field, value);
   } else if (this.isRichTextField($field)) {

   this.setRichTextField($field, value);
   }

Also you can overlay "touchui-widgets-init.js" from acs commons and add this code

Hope this helps.

Thanks,

Vipin

Avatar

Level 2

Hi Vipin,

The suggestions, which you ave provided are already available in touchui-widgets-init.js file in acs-commons-4.2.0.
For the reference, I am adding the touchui-widgets-init.js file below. Could you please let me know, if there are any other changes to be made apart from this. vipin

/*

* #%L

* ACS AEM Commons Package

* %%

* Copyright (C) 2013 Adobe

* %%

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

* #L%

*

* A sample component dialog using the Touch UI Multi Field

* Note the usage of empty valued acs-commons-nested property

*/

(function () {

    "use strict";

    if (typeof window.ACS === "undefined") {

        window.ACS = {};

    }

    if (typeof window.ACS.TouchUI === "undefined") {

        window.ACS.TouchUI = {};

    }

    ACS.TouchUI.Widget = new Class({

        toString: 'ACS TouchUI Widget Base Class',

        ACS_COMMONS_NESTED:  "acs-commons-nested",

        DATA_ACS_COMMONS_NESTED:  "data-acs-commons-nested",

        CFFW:  ".coral-Form-fieldwrapper",

        JSON_STORE: "JSON_STORE",

        NODE_STORE: "NODE_STORE",

        SELECTOR_FORM_CQ_DIALOG: "form.cq-dialog",

        SELECTOR_FORM_SITES_PROPERTIES: "form#cq-sites-properties-form",

        SELECTOR_FORM_CREATE_PAGE: "form.cq-siteadmin-admin-createpage",

        SELECTOR_FORM_PROPERTIES_PAGE: "form#propertiesform",

        nestedPluck: function(object, key) {

            if (!_.isObject(object) || _.isEmpty(object) || _.isEmpty(key)) {

                return [];

            }

            if (key.indexOf("/") === -1) {

                return object[key];

            }

            var nestedKeys = _.reject(key.split("/"), function(token) {

                return token.trim() === "";

            }), nestedObjectOrValue = object;

            _.each(nestedKeys, function(nKey) {

                if(_.isUndefined(nestedObjectOrValue)){

                    return;

                }

                if(_.isUndefined(nestedObjectOrValue[nKey])){

                    nestedObjectOrValue = undefined;

                    return;

                }

                nestedObjectOrValue = nestedObjectOrValue[nKey];

            });

            return nestedObjectOrValue;

        },

        isSelectOne: function ($field) {

            return !_.isEmpty($field) && ($field.prop("type") === "select-one");

        },

        setSelectOne: function ($field, value) {

            var select = $field.closest(".coral-Select").data("select");

            if(!select){

                var dataInit = $field.closest('.coral-Select').data('init');

                if(dataInit === 'graphiciconselect'){

                    $field.val(value);

                    $field.closest('.coral-Form-field').find('.selected-icon i').removeClass().addClass(value);

                }

            }else{

                select.setValue(value);

            }

        },

        isSelectMultiple: function ($field) {

            return !_.isEmpty($field) && ($field.prop("type") === "select-multiple");

        },

        setSelectMultiple: function ($field, value) {

            var select = $field.closest(".coral-Select").data("select");

            if (select){

                select.setValue(value);

            }

        },

    isCoralSelect: function ($field) {

            return !_.isEmpty($field) && ($field.parent().prop('tagName') === "CORAL-SELECT");

        },

        setCoralSelect: function ($field, value) {

            $field.parent().get(0).set("value",value);

        },

    // To support coral 3 UI checkbox, add property granite:class=coral-Form-fieldwrapper to the field in dialog.

        isCheckbox: function ($field) {

            return !_.isEmpty($field) && ($field.prop("type") === "checkbox" || $field.hasClass("coral-Checkbox"));

        },

        setCheckBox: function ($field, value) {

            if($field.parent().hasClass("coral-Checkbox")){

                $field.parent().prop("checked", $field.attr("value") === value);

            }else {

            $field.prop("checked", $field.attr("value") === value);

            }

        },

        isDateField: function ($field) {

            return !_.isEmpty($field) && $field.prop("type") === "hidden" && ($field.parent().hasClass("coral-DatePicker") || $field.parent().prop('tagName') === "CORAL-DATEPICKER");

        },

        setDateField: function ($field, value) {

            var date = moment(new Date(value));

            var $parent = $field.parent();

            if (date.isValid()) {

                $parent.find("input.coral-Textfield").val(date.format($parent.attr("data-displayed-format")));

                $field.val(date.format($parent.attr("data-stored-format")));

if ($parent.prop('tagName') === "CORAL-DATEPICKER") {

                $field.val(date.format($parent.attr("displayformat")));

                    $parent.get(0).set("value",date.format($parent.attr("valueformat")));

                }

            }

            else {

                $parent.find("input.coral-Textfield").val(value);

                $field.val(value);

$parent.get(0).set("value",value);

            }

        },

        isRichTextField: function ($field) {

            return !_.isEmpty($field) && $field.prop("type") === "hidden" && !$field.hasClass("coral-RichText-isRichTextFlag") && $field.parent().hasClass("richtext-container");

        },

        setRichTextField: function ($field, value) {

            $field.val(value);

            $field.parent().find(".coral-RichText-editable.coral-RichText").empty().append(value);

        },

        isAutocomplete: function($field) {

            return !_.isEmpty($field) && ($field.find("ul").hasClass("js-coral-Autocomplete-tagList") || $field.closest("ul").hasClass("js-coral-Autocomplete-tagList"));

        },

        isFoundationAutocomplete: function($field) {

            return !_.isEmpty($field) && ($field.parents('foundation-autocomplete').length > 0);

        },

        setAutocomplete: function($field,value) {

            var cmf = this;

            var tagsArray = value.split(',');

            var $tagList = CUI.Widget.fromElement(CUI.TagList,$field);

            if ($tagList) {

                $(tagsArray).each(function (i, item) {

                    var selectedItem = $field.closest(cmf.CFFW).find("li[data-value='" + item + "']");

                    $tagList._appendItem({"display": selectedItem.text(), "value": item});

                });

            }

        },

        setFoundationAutocomplete: function($field,value) {

            $field.parents('foundation-autocomplete').val(value);

        },

       

        isTagsField: function ($field) {

            return !_.isEmpty($field) && ($field.hasClass("js-TagsPickerField-tagList") || $field.closest("ul").hasClass("js-TagsPickerField-tagList"));

        },

       

        getTagsFieldName: function ($fieldWrapper) {

            return $fieldWrapper.children(".js-cq-TagsPickerField").data("property-path").substr(2);

        },

        setTagsField: function($field, value) {

        var cmf = this;

            var tagsArray = value.split(',');

            var $tagList = CUI.Widget.fromElement(CUI.TagList,$field);

            var cuiTagList = $field.data("tagList");

            if ($tagList) {

                $(tagsArray).each(function (i, item) {

                var tagPath = "/etc/tags/" + item.replace(":", "/");

                    $.get(tagPath + ".tag.json").done(function(data){

                        cuiTagList._appendItem( { value: data.tagID, display: data.titlePath} );

                    });

                });

            }

        },

        isColorField: function ($field) {

            return $field.attr("is") === "coral-textfield" && $field.hasClass("coral-ColorInput-input");

        },

        setColorField: function ($field, value) {

            if (value && value.trim() !== "") {

                value = value.trim();

                $field.val(value);

                //set value

                $field.parent().attr("value", value);

                //set background color

                $field.parent().removeClass("coral-ColorInput--novalue");

                var hexToRGB = CUI.util.color.HexToRGB(value);

                var rgbColor = "background-color: rgb(" + hexToRGB.r + ", " + hexToRGB.g + ", " + hexToRGB.b + ");";

                $field.parent().find("div[role='presentation'] button[is='coral-button']").attr("style", rgbColor);

                $field.parent().find("coral-overlay button[is='coral-button']").attr("style", rgbColor);

                //set selected

                var colorItem = $field.parent().find("coral-colorinput-item[value='#" + value.replace('#', '').toUpperCase() + "']");

                colorItem.attr("aria-selected", true);

                colorItem.attr("selected", "");

                colorItem.addClass("is-selected");

            }

        },

        setWidgetValue: function ($field, value) {

            if (_.isEmpty($field)) {

                return;

            }

            if (this.isSelectOne($field)) {

                this.setSelectOne($field, value);

            } else if (this.isSelectMultiple($field)) {

                this.setSelectMultiple($field, value);

            } else if (this.isCheckbox($field)) {

                this.setCheckBox($field, value);

            } else if (this.isRichTextField($field)) {

                this.setRichTextField($field, value);

            } else if (this.isDateField($field)) {

                this.setDateField($field, value);

            } else if (this.isAutocomplete($field)) {

                this.setAutocomplete($field,value);

            } else if (this.isTagsField($field)) {

                this.setTagsField($field,value);

            } else if (this.isFoundationAutocomplete($field)) {

                this.setFoundationAutocomplete($field,value);

            } else if (this.isCoralSelect($field)) {

                this.setCoralSelect($field, value);

            } else if (this.isColorField($field)) {

                this.setColorField($field, value);

            } else {

                $field.val(value);

            }

        },

        isJsonStore: function(name){

            return (_.isEmpty(name) || name === this.JSON_STORE);

        },

        isNodeStore: function(name){

            return (name === this.NODE_STORE);

        },

        addCompositeMultifieldRemoveListener: function($multifield){

            var cmf = this;

            $multifield.find(".js-coral-Multifield-remove").click(function(){

                setTimeout(function () {

                    cmf.addCompositeMultifieldValidator();

                }, 500);

            });

        },

        addCompositeMultifieldValidator: function(){

            var fieldErrorEl = $("<span class='coral-Form-fielderror coral-Icon coral-Icon--alert coral-Icon--sizeS' " +

                    "data-init='quicktip' data-quicktip-type='error' />"),

                cmf = this,

                selector = "[" + cmf.DATA_ACS_COMMONS_NESTED + "] >* input, [" + cmf.DATA_ACS_COMMONS_NESTED + "] >* textarea";

            $.validator.register({

                selector: selector,

                validate: validate,

                show: show,

                clear: clear

            });

            function validate($el){

                var $multifield = $el.closest(".coral-Multifield"),

                    $inputs = $multifield.find("input, textarea"),

                    $input, isRequired, message = null;

                $inputs.each(function(index, input){

                    $input = $(input);

                    isRequired = $input.attr("required") || ($input.attr("aria-required") === "true");

                    if (isRequired && $input.val().length === 0) {

                        $input.addClass("is-invalid");

                        message = "Please fill the required multifield items";

                    }else{

                        $input.removeClass("is-invalid");

                    }

                });

                if(message){

                    $(".cq-dialog-submit").attr("disabled", "disabled");

                }else{

                    $(".cq-dialog-submit").removeAttr("disabled");

                }

                return message;

            }

            function show($el, message){

                /* jshint validthis: true */

                clear($el);

                var $multifield = $el.closest(".coral-Multifield"),

                    arrow = $el.closest("form").hasClass("coral-Form--vertical") ? "right" : "top";

                fieldErrorEl.clone()

                    .attr("data-quicktip-arrow", arrow)

                    .attr("data-quicktip-content", message)

                    .insertAfter($multifield);

            }

            function clear($el){

                var $multifield = $el.closest(".coral-Multifield");

                $multifield.nextAll(".coral-Form-fielderror").tooltip("hide").remove();

            }

            validate($($(selector)[0]));

        },

        isPropertiesPage: function($document) {

            return $document.find(this.SELECTOR_FORM_SITES_PROPERTIES).length === 1;

        },

        isPropertiesFormPage: function($document) {

            return $document.find(this.SELECTOR_FORM_PROPERTIES_PAGE).length === 1;

        },

        isCreatePageWizard: function($document) {

            return $document.find(this.SELECTOR_FORM_CREATE_PAGE).length == 1;

        },

        getPropertiesFormSelector: function() {

            return this.SELECTOR_FORM_CQ_DIALOG + "," + this.SELECTOR_FORM_SITES_PROPERTIES + "," +

                this.SELECTOR_FORM_CREATE_PAGE + "," + this.SELECTOR_FORM_PROPERTIES_PAGE;

        },

    });

    if (!ACS.TouchUI.extendedMultfield) {

        //extend otb multifield for adjusting event propagation when there are nested multifields

        //for working around the nested multifield add and reorder

        CUI.Multifield = 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.Multifield);

        ACS.TouchUI.extendedMultfield = true;

    }

}());

Avatar

Level 3

Hi Sampath,

For this to work you will need to add "granite:class=coral-Form-fieldwrapper" property on checkbox in dialog.

Example :

<hideMobile

                                            jcr:primaryType="nt:unstructured"

                                            sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"

                                            name="./option"

                                            text="Add Button?"

                                             granite:class=coral-Form-fieldwrapper

                                            uncheckedValue="{Boolean}false"

                                            value="{Boolean}true"/>

Thanks,

Vipin

Avatar

Level 4

You do not need ACS-Commons to work with a granite-based Multifield. There is a checkbox in this MF example:

Building Experience Manager Components using Granite/Coral Resource Types