Changes in Render widget is not working on the second fragment added on the same panel

rahulpandey0102 28-03-2018

Hi,

I have a scenario in Adaptive Form, in this we are trying to convert the drop down box by overriding widget JS. Things work fine if we are using this component on one fragment but if we use same component on different fragment and use that fragment on the same form panel, it does not work (widget js is not being called). even we tried to use same working fragment twice (instead of using different fragment), it does not work.

Need help to resolve this.

Thanks

Accepted Solutions (1)

Accepted Solutions (1)

rahulpandey0102 13-04-2018

I have got the cause of the issue, that is we are trying to bind event on page/form load, which is not working here . Now we are merging the event binding code within wdget.js . It works.

Answers (2)

Answers (2)

rahulpandey0102 28-03-2018

I am using this widget multiple time on a single adaptive form fragment it works fine, but when we put multiple fragments on a Adaptive form it does not work.

(function ($) {

    /*

     * As a sample the class is extending from textField, choose the required class to extend from (based on requirement):

     * - $.xfaWidget.abstractWidget: This is the parent of all the other widgets, and should be used only when any

     *                                specific widget below is not applicable.

     * - $.xfaWidget.defaultWidget: This widget extends from Abstract widget and provides the default implementation for

     *                               render, getOptionsMap and getCommitValue.

     * - $.xfaWidget.dateTimeEdit: This is Out-of-the-box widget for Date Picker.

     * - $.xfaWidget.dropDownList: This is Out-of-the-box widget for Drop-down list.

     * - $.xfaWidget.listBoxWidget: This is Out-of-the-box widget for List box (Drop-down

     *                              list with multi-select enabled).

     * - $.xfaWidget.numericInput: This is Out-of-the-box widget for Numeric fields.

     * - $.xfaWidget.signatureField: This is Out-of-the-box widget for Signature fields.

     * - $.xfaWidget.textField: This is Out-of-the-box widget for Text fields.

     * - $.xfaWidget.xfaButton: This is Out-of-the-box widget for buttons.

     * - $.xfaWidget.XfaCheckBox: This is Out-of-the-box widget for Check box and radio buttons fields.

     */

    $.widget("xfaWidget.customDropdown", $.xfaWidget.defaultWidget, {

        _widgetName: "customDropdown",

        /*

         * The render function updates the HTML widget UI by invoking the JQuery plugin.

         * Every Adaptive Forms field uses a default html element for taking input, example: for Date Field the element

         * is <input type='date'>. The render function of the abstractWidget returns that element.

         */

        render: function () {

            var control = $.xfaWidget.defaultWidget.prototype.render.apply(this, arguments);

            var $control = $(control);

            var controlObject;

            try {

                if ($control) {

                    //$control.bootstrapNumber();

                    var id = $control.attr("id");

                    controlObject = $("#" + id);

                }

            } catch (exc) {

                console.log(exc);

            }

            return controlObject;

        },

        /*

         * For reflecting the model changes the widget can register for the listeners in the getOptionsMap function.

         * For adding a listener ensure that instead of starting from scratch, get the option map from the super class.

         * The function returns a mapping which provides detail for what action to perform on change of an option. The

         * keys are the options that are provided to the widget and values are the function that should be called

         * whenever a change in that option is detected. The abstract Widget provides handlers for all the global

         * options (except value and displayValue). The various options include:

         * - tabIndex

         * - role

         * - screenReaderText

         * - paraStyles

         * - dir

         * - height

         * - width

         * - isValid

         * - access

         * - value

         * - displayValue

         * - placeholder

         * - items [ListBox, DropDownList]

         * - maxChars [TextField]

         * - multiLine [TextField]

         * - svgCaption [Button]

         * - allowNeutral [CheckBox]

         * You only need to override the options which require a behavior change (as compared to default Out-of-the-box

         * widget).

         */

        getOptionsMap: function () {

            var parentOptionsMap = $.xfaWidget.defaultWidget.prototype.getOptionsMap.apply(this, arguments),

                newMap = $.extend({}, parentOptionsMap,

                    {

                        "access": function (val) {

                            switch (val) {

                                case "open" :

                                    var selectElement = this.$userControl;

                                    var guideFieldWidget = selectElement.parent();

                                    guideFieldWidget.append('<input disabled type="text" style="position: relative;" class="border-bottom-grey">\n' +

                                        '                    <span class="dropdown-list-icon-toggle"></span>\n' +

                                        '                    <div class="dropdown-list hidden">\n' +

                                        '                      <ul class="dropdown-list-ul"></ul></div>');

                                    var defaultValue = this.options.displayValue;

                                    var options = this.options.items;

                                    var dropdownListUL = guideFieldWidget.find('.dropdown-list-ul');

                                    for (var idx = 0; idx < options.length; idx++) {

                                        var option = options[idx];

                                        if (defaultValue && defaultValue == option.save) {

                                            guideFieldWidget.children("input").val(option.display);

                                        }

                                        dropdownListUL.append('<li class="item" value="' + option.save + '">' + option.display + '</li>');

                                    }

                                    selectElement.css("display", "none");

                                    selectElement.on('change', function () {

                                        if (selectElement.attr('disabled')) {

                                            guideFieldWidget.addClass('disabled_area');

                                        } else {

                                            guideFieldWidget.removeClass('disabled_area');

                                        }

                                    });

                                    break;

                                case "nonInteractive" :

                                case "protected" :

                                    this.$userControl.attr("disabled", "disabled");

                                    this.$userControl.attr("aria-disabled", "true");

                                    this.$userControl.parent().find(".input-group-btn button").prop('disabled', true);

                                    break;

                                case "readOnly" :

                                    this.$userControl.attr("readOnly", "readOnly");

                                    this.$userControl.attr("aria-readonly", "true");

                                    this.$userControl.parent().find(".input-group-btn button").prop('disabled', true);

                                    break;

                                default :

                                    this.$userControl.removeAttr("disabled");

                                    this.$userControl.removeAttr("aria-disabled");

                                    this.$userControl.parent().find(".input-group-btn button").prop('disabled', false);

                                    break;

                            }

                        },

                    });

            return newMap;

        },

        /*

         * To enable the widget to throw XFA events that, we need to modify the getEventMap function. The function

         * returns a mapping of html events to the XFA events. The code below provides a mapping which essentially tells

         * the XFA framework that whenever html triggers focus on the datepicker element (the $userControl element)

         * execute the XFA enter event and run any script written on that event for this field.

         * In case the custom widget requires to throw an HTML blur / change event on non-default actions as well, then

         * a custom event may be dispatched, and the custom event may be mapped with the XFA event below.

         */

        getEventMap: function () {

            var parentEventMap = $.xfaWidget.defaultWidget.prototype.getEventMap.apply(this, arguments),

                newMap = $.extend({}, parentEventMap,

                    {

                        blur: "xfaexit",

                        //...

                    });

            return newMap;

        },

        /*

         * XFA provides display and edit picture clause which determines the format in which the value will be visible

         * in the UI and the input format in which the user will enter the value. The value the user enters into the

         * field is formatted after the user exits from the field and similarly when they enter the field, edit value is

         * displayed to them (As per mobile forms limitation, instead of edit Value, rawValue is displayed).

         * The framework accomplishes this by providing two values to the widget, displayValue and value. The framework

         * also calls the showDisplayValue function after the Exit event and showValue function before the Enter event

         * and it is the responsibility of the widget to implement how it wants these values to appear to the user.

         */

        showDisplayValue: function () {

            this.$userControl.val(this.options.displayValue)

        },

        showValue: function () {

            this.$userControl.val(this.options.value)

        },

        /*

         * According to the specification the value returned by the getCommitValue function of the widget is set to be

         * the value of the field. The framework calls the getCommitValue function to get the value at appropriate event

         * (The event for most fields is exit event, except for dropdown where the event can be change/exit).

         */

        getCommitValue: function () {

            return this.$userControl.val();

        }

    });

})(jQuery);

James_R_Green 28-03-2018

Hi,

Can you share some code?

My first guess would be, are you using a css class rather than id to find your widget in the render method?

If you are, these might not be unique, which would be fine with one element. But could cause a problem with two widgets.

Thanks,

James