Expand my Community achievements bar.

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