view class doc
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717/// FOURJS_START_COPYRIGHT(D,2015)
/// Property of Four Js*
/// (c) Copyright Four Js 2015, 2023. All Rights Reserved.
/// * Trademark of Four Js Development Tools Europe Ltd
///   in the United States and elsewhere
///
/// This file can be modified by licensees according to the
/// product manual.
/// FOURJS_END_COPYRIGHT

'use strict';

modulum('ButtonEditWidget', ['FieldWidgetBase', 'WidgetFactory'],
  function(context, cls) {

    /**
     * ButtonEdit widget.
     * @class ButtonEditWidget
     * @memberOf classes
     * @extends classes.FieldWidgetBase
     * @publicdoc Widgets
     */
    cls.ButtonEditWidget = context.oo.Class(cls.FieldWidgetBase, function($super) {
      return /** @lends classes.ButtonEditWidget.prototype */ {
        __name: 'ButtonEditWidget',
        /**
         * Edit part of the widget
         * @type {classes.EditWidget}
         */
        _edit: null,

        /**
         * Button part of the widget
         * @type {classes.ButtonWidget}
         */
        _button: null,

        /**
         * Redefine where the data is located
         * @type {string}
         */
        __dataContentPlaceholderSelector: '.gbc_dataContentPlaceholder',

        /**
         * Handler for click
         * @function
         */
        _clickHandler: null,

        /**
         * Handler for focus
         * @function
         */
        _focusHandler: null,

        /**
         * Handler for blur
         * @function
         */
        _blurHandler: null,

        /**
         * Handler for change
         * @function
         */
        _changeHandler: null,

        /**
         * Handler for image ready
         * @function
         */
        _imageReadyHandler: null,

        /**
         * Flag to manage if button has been clicked
         * @type {boolean}
         */
        _buttonClicked: false,

        /**
         * Handler for virtualKeyboardDisplayed event
         * @function
         */
        _virtualKeyboardDisplayedHandler: null,

        /**
         * @inheritDoc
         */
        constructor: function(opts) {
          $super.constructor.call(this, opts);
          this.setFocusable(true);
        },

        /**
         * @inheritDoc
         */
        _initLayout: function() {
          if (!this._ignoreLayout) {
            this._layoutInformation = new cls.LayoutInformation(this);
            this._layoutEngine = new cls.LeafLayoutEngine(this);
            this._layoutInformation.setReservedDecorationSpace(2);
          }
        },

        /**
         * @inheritDoc
         */
        _initElement: function() {
          $super._initElement.call(this);

          this._edit = cls.WidgetFactory.createWidget('EditWidget', this.getBuildParameters());
          this._button = cls.WidgetFactory.createWidget('ButtonWidget', this.getBuildParameters());
          // layout engine can be null if _ignoreLayout is true, which happens for widget being in table and not in first row. (cf constructor of WidgetBase)
          // in that case, we do not want to measure image once loaded
          if (!this._ignoreLayout) {
            this._imageReadyHandler = this._button.when(context.constants.widgetEvents.ready, this._imageLoaded.bind(this));
          }
          this._element.appendChild(this._edit.getElement());
          this._element.appendChild(this._button.getElement());
          this._edit.setParentWidget(this);
          this._button.setParentWidget(this);
          this._clickHandler = this._button.when(context.constants.widgetEvents.click, this._onButtonClick.bind(this));
          this._focusHandler = this._edit.when(context.constants.widgetEvents.requestFocus, this._onEditRequestFocus.bind(this));
          this._blurHandler = this._edit.when(context.constants.widgetEvents.blur, this._onEditBlur.bind(this));
          this._changeHandler = this._edit.when(context.constants.widgetEvents.change, this._onEditChange.bind(this));

          // Manage virtual keyboard on Mobile
          if (context.__wrapper.isGMA()) {
            // On GMA skip the first VM Focus after a dialogType change.
            this._virtualKeyboardDisplayedHandler = this._appWidget.when(context.constants.widgetEvents.virtualKeyboardDisplayed,
              function() {
                if (this._edit) {
                  this._edit._canShowVirtualKeyboard = true;
                }
              }.bind(this));
          }
        },

        /**
         * Handler called when the button image is loaded
         */
        _imageLoaded: function(event, src) {
          this._layoutEngine.invalidateMeasure();
          this.emit(context.constants.widgetEvents.ready);
        },

        /**
         * @inheritDoc
         */
        destroy: function() {
          this._clickHandler();
          this._clickHandler = null;
          this._focusHandler();
          this._focusHandler = null;
          this._blurHandler();
          this._blurHandler = null;
          this._changeHandler();
          this._changeHandler = null;
          this._edit.destroy();
          this._edit = null;
          this._button.destroy();
          this._button = null;

          if (this._completerWidget) {
            this._completerWidget.destroy();
            this._completerWidget = null;
          }
          if (this._imageReadyHandler) {
            this._imageReadyHandler();
            this._imageReadyHandler = null;
          }
          if (this._virtualKeyboardDisplayedHandler) {
            this._virtualKeyboardDisplayedHandler();
            this._virtualKeyboardDisplayedHandler = null;
          }

          $super.destroy.call(this);
        },

        /**
         * @inheritDoc
         */
        managePriorityKeyDown: function(keyString, domKeyEvent, repeat) {
          return this._edit.managePriorityKeyDown(keyString, domKeyEvent, repeat);
        },

        /**
         * @inheritDoc
         */
        manageKeyDown: function(keyString, domKeyEvent, repeat) {
          return this._edit.manageKeyDown(keyString, domKeyEvent, repeat);
        },

        /**
         * @inheritDoc
         */
        manageKeyUp: function(keyString, domKeyEvent) {
          this._edit.manageKeyUp(keyString, domKeyEvent);

          this.emit(context.constants.widgetEvents.keyUp, domKeyEvent, true);
        },

        /**
         * return true if the backup value has been restored
         * @return {boolean}
         */
        isValueRestored: function() {
          return this._edit.isValueRestored();
        },

        /**
         * Handler when click on button
         * @param {Object} event - DOM event
         * @param sender
         * @param domEvent
         */
        _onButtonClick: function(event, sender, domEvent) {
          if (this.isEnabled()) {
            if (this.getApplicationWidget() && context.__wrapper.isGMA()) {
              this.getApplicationWidget().virtualKeyboardIsDisplayed();
            }

            this.emit(context.constants.widgetEvents.requestFocus, domEvent);
            this.emit(context.constants.widgetEvents.click, domEvent, !this.hasDOMFocus());
          }
        },

        /**
         * Handler when focus is requested
         * @param event
         * @param sender
         * @param domEvent
         */
        _onEditRequestFocus: function(event, sender, domEvent) {
          this.emit(context.constants.widgetEvents.requestFocus, domEvent);
        },

        /**
         * Handler when edit is blured
         * @param event
         * @param sender
         * @param domEvent
         */
        _onEditBlur: function(event, sender, domEvent) {
          this.emit(context.constants.widgetEvents.blur, domEvent);
        },

        /**
         * Handler when edit content changes
         * @param event
         * @param sender
         * @param isTextEntry
         */
        _onEditChange: function(event, sender, isTextEntry) {
          this.emit(context.constants.widgetEvents.change, isTextEntry);
        },

        /**
         * Get the input field of the widget
         * @return {HTMLElement} The input element
         * @publicdoc
         */
        getInputElement: function() {
          return this._edit.getInputElement();
        },

        /**
         * @inheritDoc
         */
        setTitle: function(title) {
          this._edit.setTitle(title);
        },

        /**
         * Set button title from localized text of corresponding action
         * @param actionTitle
         */
        setActionTitle: function(actionTitle) {
          if (actionTitle && actionTitle.length <= 0) {
            this._button.setTitle(this.getTitle());
          } else {
            this._button.setTitle(actionTitle);
          }
        },

        /**
         * @inheritDoc
         */
        getTitle: function() {
          return this._edit.getTitle();
        },

        /**
         * @inheritDoc
         */
        setReadOnly: function(readonly) {
          this._edit.setReadOnly(readonly);
        },

        /**
         * @inheritDoc
         */
        isReadOnly: function() {
          return this._edit.isReadOnly();
        },

        /**
         * @return {boolean} true if we must ignore the scroll attribute
         */
        isDataTypeWithNoScroll: function() {
          return this._edit.isDataTypeWithNoScroll();
        },

        /**
         * Set to true if we must ignore the scroll attribute
         * @param {boolean} checkDisplayValue
         */
        setDataTypeWithNoScroll: function(checkDisplayValue) {
          this._edit.setDataTypeWithNoScroll(checkDisplayValue);
        },

        /**
         * Define the maximum number of characters allowed
         * @param {number} maxlength - maximum number of characters allowed in the field
         * @publicdoc
         */
        setMaxLength: function(maxlength) {
          this._edit.setMaxLength(maxlength);
        },

        /**
         * Defines if we can take more char than the widget width
         * @param {boolean} scroll true if the widget can 'scroll' his content (take more char than the widget width)
         * @publicdoc
         */
        setScroll: function(scroll) {
          this._edit.setScroll(scroll);
        },

        /**
         * Widget width
         * @param {number} width
         */
        setVMWidth: function(width) {
          this._edit.setVMWidth(width);
        },

        /**
         * @return {boolean} true if we can trigger the autonext
         */
        canAutoNext: function() {
          return this._edit.canAutoNext();
        },

        /**
         * Get the maximum number of characters allowed
         * @returns {number} the maximum number of characters allowed in the field
         * @publicdoc
         */
        getMaxLength: function() {
          return this._edit.getMaxLength();
        },

        /**
         * Set Default TTF color
         * @param {string} color - rgb formatted or css name
         */
        setDefaultTTFColor: function(color) {
          if (this._button) {
            this._button.setDefaultColor(color);
          }
        },

        /**
         * @inheritDoc
         */
        setTextAlign: function(align) {
          this._edit.setTextAlign(align);
        },

        /**
         * @inheritDoc
         */
        getTextAlign: function() {
          return this._edit.getTextAlign();
        },

        /**
         * When cursor2 === cursor, it is a simple cursor set
         * @param {number} cursor - starting cursor position
         * @param {number} cursor2 - ending cursor position
         * @publicdoc
         */
        setCursors: function(cursor, cursor2) {

          if (this._edit) {
            this._edit.setCursors(cursor, cursor2);
          }
        },

        /**
         * Get cursors
         * @return {{start: number, end: number}} object with cursors
         * @publicdoc
         */
        getCursors: function() {
          return this._edit.getCursors();
        },

        /**
         * Get the display format of the edit part
         * @return {string} the display format
         * @publicdoc
         */
        getDisplayFormat: function() {
          return this._edit.getDisplayFormat();
        },

        /**
         * Set the display format of the edit part
         * @param {string} format the display format
         * @publicdoc
         */
        setDisplayFormat: function(format) {
          this._edit.setDisplayFormat(format);
        },

        /**
         * @inheritDoc
         */
        setValue: function(value, fromVM) {
          this._edit.setValue(value, fromVM);
        },

        /**
         * @inheritDoc
         */
        getValue: function() {
          return this._edit.getValue();
        },

        /**
         * Set the image of the button part
         * @param {string} image - URL of the image to display
         * @publicdoc
         */
        setImage: function(image) {
          this._button.setImage(image);
        },

        /**
         * Get the image of the button part
         * @returns {string} the URL of the image displayed in the button part
         * @publicdoc
         */
        getImage: function() {
          return this._button.getImage();
        },

        /**
         * Defines the widget as autoscalable
         * @param {boolean} enabled the wanted state
         * @publicdoc
         */
        setAutoScale: function(enabled) {
          this._button.setAutoScale(enabled);
        },

        /**
         * @inheritDoc
         */
        setEnabled: function(enabled) {
          $super.setEnabled.call(this, enabled);
          this._edit.setEnabled(enabled);
        },

        /**
         * @inheritDoc
         */
        isEnabled: function() {
          return this._edit.isEnabled();
        },
        /**
         * Enable the button
         * @param {boolean} enabled - true if the button should be enabled, false otherwise
         * @publicdoc
         */
        setButtonEnabled: function(enabled) {
          this._button.setEnabled(enabled);
        },

        /**
         * returns whether or not the button is enabled
         * @returns {boolean} true if the button is enabled, false otherwise
         * @publicdoc
         */
        isButtonEnabled: function() {
          return this._button.isEnabled();
        },

        /**
         * sets 'password' mode
         * @param {boolean} isPassword - true if the widget should be in 'password' mode, false otherwise
         * @publicdoc
         */
        setIsPassword: function(isPassword) {
          this._edit.setIsPassword(isPassword);
        },

        /**
         * returns whether or not the widget should be in 'password' mode
         * @returns {boolean} true if the widget is in 'password' mode, false otherwise
         * @publicdoc
         */
        isPassword: function() {
          return this._edit.isPassword();
        },

        /**
         * Used to manage the keyboardHint.
         * @param {string} valType - the type attribute value to set
         * @publicdoc
         */
        setType: function(valType) {
          this._edit.setType(valType);
        },

        /**
         * Get the keyboardHint method
         * @returns {string} this Edit current type
         * @publicdoc
         */
        getType: function() {
          return this._edit.getType();
        },

        /**
         * @inheritDoc
         */
        loseFocus: function() {
          $super.loseFocus.call(this);
          if (this._completerWidget) {
            this._completerWidget.loseFocus();
          }
        },

        /**
         * @inheritDoc
         */
        setDialogType: function(dialogType) {
          $super.setDialogType.call(this, dialogType);

          this._edit.setDialogType(dialogType);
        },

        /**
         * @inheritDoc
         */
        setFocus: function(fromMouse) {
          var inputElement = this._edit.getInputElement();

          if (inputElement) {
            if (context.__wrapper.isGMA() && !this._edit._showVirtualKeyboardOnFocus) {
              if (this._edit._canShowVirtualKeyboard) {
                this._edit._setElementAttribute('readonly', this._edit._realReadOnly ? 'readonly' : null, "_inputElement");
              } else {
                this._edit._setElementAttribute('readonly', 'readonly', "_inputElement");
              }
            }

            inputElement.domFocus();
          }
          this.getUserInterfaceWidget().setFocusedWidget(this); // TODO why don't call super.setFocus ?
        },

        /**
         * @inheritDoc
         */
        flash: function() {
          if (this._edit) {
            this._edit.flash();
          }
        },

        /**
         * Get the Completer widget
         * @return {classes.CompleterWidget}
         */
        getCompleterWidget: function() {
          return this._edit.getCompleterWidget();
        },

        /**
         * Will add a completer to the edit
         */
        addCompleterWidget: function() {
          this._edit.addCompleterWidget();
        },

        /**
         * @inheritDoc
         */
        setColor: function(color) {
          this._edit.setColor(color);
        },

        /**
         * @inheritDoc
         */
        getColor: function() {
          return this._edit.getColor();
        },

        /**
         * @inheritDoc
         */
        getColorFromStyle: function() {
          return this._edit.getColorFromStyle();
        },

        /**
         * @inheritDoc
         */
        setTextTransform: function(transform) {
          this._edit.setTextTransform(transform);
        },

        /**
         * @inheritDoc
         */
        removeTextTransform: function() {
          this._edit.removeTextTransform();
        },

        /**
         * @inheritDoc
         */
        getTextTransform: function() {
          return this._edit.getTextTransform();
        },

        /**
         * @inheritDoc
         */
        setEditing: function(editing) {
          if (this._edit) {
            this._edit.setEditing(editing);
          }
        },

        /**
         * @inheritDoc
         */
        getEditingTime: function() {
          return this._edit.getEditingTime();
        },

        /**
         * @inheritDoc
         */
        isEditing: function() {
          return this._edit.isEditing();
        },

        /**
         * @inheritDoc
         */
        setPlaceHolder: function(placeholder) {
          this._edit.setPlaceHolder(placeholder);
        },

        /**
         * @inheritDoc
         */
        setNotEditable: function(notEditable) {
          this._edit.setNotEditable(notEditable);
        },

        hasDOMFocus: function() {
          return this._edit.hasDOMFocus() || this._button.hasDOMFocus();
        },

        /**
         * @inheritDoc
         */
        isNotEditable: function() {
          return this._edit.isNotEditable();
        },

        /**
         * @inheritDoc
         */
        _preventEditAllowNavigation: function(evt, keyString) {
          this._edit._preventEditAllowNavigation(evt, keyString);
        },

        /**
         * True if you want to always show the virtual keyboard on GMA
         * @param {boolean} show
         */
        setShowVirtualKeyboardOnFocus: function(show) {
          this._edit._showVirtualKeyboardOnFocus = show;
        },

        /**
         * Get the element state
         * @return {cls.InputTextState}
         */
        getElementState: function() {
          return this._edit.getElementState();
        }

      };
    });
    cls.WidgetFactory.registerBuilder('ButtonEdit', cls.ButtonEditWidget);
  });