/** * A field that can be clicked to bring up the color picker. * The selected color is configurable via {@link #value} and * The Format is configurable via {@link #format}. * * @example * Ext.create({ * xtype: 'colorfield', * renderTo: Ext.getBody(), * * value: '#993300', // initial selected color * format: 'hex6', // by default it's hex6 * * listeners : { * change: function (field, color) { * console.log('New color: ' + color); * } * } * }); */Ext.define('Ext.ux.colorpick.Field', { extend: 'Ext.field.Picker', xtype: 'colorfield', mixins: [ 'Ext.ux.colorpick.Selection' ], requires: [ 'Ext.window.Window', 'Ext.ux.colorpick.Selector', 'Ext.ux.colorpick.ColorUtils' ], editable: false, focusable: true, matchFieldWidth: false, // picker is usually wider than field // "Color Swatch" shown on the left of the field html: [ '<div class="' + Ext.baseCSSPrefix + 'colorpicker-field-swatch">' + '<div class="' + Ext.baseCSSPrefix + 'colorpicker-field-swatch-inner"></div>' + '</div>' ], cls: Ext.baseCSSPrefix + 'colorpicker-field', config: { /** * @cfg {Object} popup * This object configures the popup window and colorselector component displayed * when this button is clicked. Applications should not need to configure this. * @private */ popup: { lazy: true, $value: { xtype: 'window', closeAction: 'hide', modal: Ext.platformTags.phone ? true : false, referenceHolder: true, width: Ext.platformTags.phone ? '100%' : 'auto', layout: Ext.platformTags.phone ? 'hbox' : 'vbox', header: false, resizable: true, scrollable: true, items: { xtype: 'colorselector', reference: 'selector', flex: '1 1 auto', showPreviousColor: true, showOkCancelButtons: true } } } }, /** * @event change * Fires when a color is selected. * @param {Ext.ux.colorpick.Field} this * @param {String} color The value of the selected color as per specified {@link #format}. * @param {String} previousColor The previous color value. */ afterRender: function() { this.callParent(); this.updateValue(this.value); }, // override as required by parent pickerfield createFloatedPicker: function() { var me = this, popup = me.getPopup(), picker; // the window will actually be shown and will house the picker me.colorPickerWindow = popup = Ext.create(popup); picker = me.colorPicker = popup.lookupReference('selector'); picker.setColor(me.getColor()); picker.setHexReadOnly(!me.editable); picker.on({ ok: 'onColorPickerOK', cancel: 'onColorPickerCancel', close: 'onColorPickerCancel', scope: me }); me.colorPicker.ownerCmp = me; return me.colorPickerWindow; }, // override as required by parent pickerfield for mobile devices createEdgePicker: function() { var me = this, popup = me.getPopup(), picker; // the window will actually be shown and will house the picker me.colorPickerWindow = popup = Ext.create(popup); picker = me.colorPicker = popup.lookupReference('selector'); me.pickerType = 'floated'; picker.setColor(me.getColor()); picker.on({ ok: 'onColorPickerOK', cancel: 'onColorPickerCancel', close: 'onColorPickerCancel', scope: me }); me.colorPicker.ownerCmp = me; return me.colorPickerWindow; }, collapse: function() { var picker = this.getPicker(); if (this.expanded) { picker.hide(); } }, showPicker: function() { var me = this, alignTarget = me[me.alignTarget], picker = me.getPicker(), color = this.getColor(); // Setting up previous selected color if (this.colorPicker) { this.colorPicker.setColor(this.getColor()); this.colorPicker.setPreviousColor(color); } // TODO: what if virtual keyboard is present if (me.getMatchFieldWidth()) { picker.setWidth(alignTarget.getWidth()); } if (Ext.platformTags.phone) { picker.show(); } else { picker.showBy(alignTarget, me.getFloatedPickerAlign(), { minHeight: 100 }); } // Collapse on touch outside this component tree. // Because touch platforms do not focus document.body on touch // so no focusleave would occur to trigger a collapse. me.touchListeners = Ext.getDoc().on({ // Do not translate on non-touch platforms. // mousedown will blur the field. translate: false, touchstart: me.collapseIf, scope: me, delegated: false, destroyable: true }); }, onFocusLeave: function(e) { if (e.type !== 'focusenter') { this.callParent(arguments); } }, // When the Ok button is clicked on color picker, preserve the previous value onColorPickerOK: function(colorPicker) { this.setColor(colorPicker.getColor()); this.collapse(); }, onColorPickerCancel: function() { this.collapse(); }, onExpandTap: function() { var color = this.getColor(); if (this.colorPicker) { this.colorPicker.setPreviousColor(color); } this.callParent(arguments); }, // Expects value formatted as per "format" config setValue: function(color) { var me = this, c; if (Ext.ux.colorpick.ColorUtils.isValid(color)) { c = me.mixins.colorselection.applyValue.call(me, color); me.callParent([c]); } }, // Sets this.format and color picker's setFormat() updateFormat: function(format) { var cp = this.colorPicker; if (cp) { cp.setFormat(format); } }, updateValue: function(color) { var me = this, swatchEl = this.element.down('.x-colorpicker-field-swatch-inner'), c; // If the "value" is changed, update "color" as well. Since these are always // tracking each other, we guard against the case where we are being updated // *because* "color" is being set. if (!me.syncing) { me.syncing = true; me.setColor(color); me.syncing = false; } c = me.getColor(); Ext.ux.colorpick.ColorUtils.setBackground(swatchEl, c); if (me.colorPicker) { me.colorPicker.setColor(c); } me.inputElement.dom.value = me.getValue(); }, validator: function(val) { if (!Ext.ux.colorpick.ColorUtils.isValid(val)) { return this.invalidText; } return true; }, updateColor: function(color) { var me = this, cp = me.colorPicker, swatchEl = this.element.down('.x-colorpicker-field-swatch-inner'); me.mixins.colorselection.updateColor.call(me, color); Ext.ux.colorpick.ColorUtils.setBackground(swatchEl, color); if (cp) { cp.setColor(color); } }});