• sencha touch Button Select(点击按钮进行选择)扩展


    此扩展基于官方selectfield控件修改而来,变动并不大,使用方法类似。

    代码如下:

      1 Ext.define('ux.SelectBtn', {
      2     extend: 'Ext.Button',
      3     xtype: 'selectBtn',
      4     alternateClassName: 'selectBtn',
      5     requires: [
      6         'Ext.Panel',
      7         'Ext.picker.Picker',
      8         'Ext.data.Store',
      9         'Ext.data.StoreManager',
     10         'Ext.dataview.List'
     11     ],
     12     config: {
     13         /**
     14          * @cfg
     15          * @inheritdoc
     16          */
     17         ui: 'select',
     18 
     19 
     20         /**
     21          * @cfg {String/Number} valueField The underlying {@link Ext.data.Field#name data value name} (or numeric Array index) to bind to this
     22          * Select control.
     23          * @accessor
     24          */
     25         valueField: 'value',
     26 
     27         /**
     28          * @cfg {String/Number} displayField The underlying {@link Ext.data.Field#name data value name} (or numeric Array index) to bind to this
     29          * Select control. This resolved value is the visibly rendered value of the available selection options.
     30          * @accessor
     31          */
     32         displayField: 'text',
     33 
     34         /**
     35          * @cfg {Ext.data.Store/Object/String} store The store to provide selection options data.
     36          * Either a Store instance, configuration object or store ID.
     37          * @accessor
     38          */
     39         store: null,
     40 
     41         /**
     42          * @cfg {Array} options An array of select options.
     43          *
     44          *     [
     45          *         {text: 'First Option',  value: 'first'},
     46          *         {text: 'Second Option', value: 'second'},
     47          *         {text: 'Third Option',  value: 'third'}
     48          *     ]
     49          *
     50          * __Note:__ Option object member names should correspond with defined {@link #valueField valueField} and {@link #displayField displayField} values.
     51          * This config will be ignored if a {@link #store store} instance is provided.
     52          * @accessor
     53          */
     54         options: null,
     55 
     56         /**
     57          * @cfg {String} hiddenName Specify a `hiddenName` if you're using the {@link Ext.form.Panel#standardSubmit standardSubmit} option.
     58          * This name will be used to post the underlying value of the select to the server.
     59          * @accessor
     60          */
     61         hiddenName: null,
     62 
     63         /**
     64          * @cfg {Object} component
     65          * @accessor
     66          * @hide
     67          */
     68         component: {
     69             useMask: true
     70         },
     71 
     72 
     73         /**
     74          * @cfg {String/Boolean} usePicker
     75          * `true` if you want this component to always use a {@link Ext.picker.Picker}.
     76          * `false` if you want it to use a popup overlay {@link Ext.List}.
     77          * `auto` if you want to show a {@link Ext.picker.Picker} only on phones.
     78          */
     79         usePicker: 'auto',
     80 
     81         /**
     82          * @cfg {Boolean} autoSelect
     83          * `true` to auto select the first value in the {@link #store} or {@link #options} when they are changed. Only happens when
     84          * the {@link #value} is set to `null`.
     85          */
     86         autoSelect: true,
     87 
     88         /**
     89          * @cfg {Object} defaultPhonePickerConfig
     90          * The default configuration for the picker component when you are on a phone.
     91          */
     92         defaultPhonePickerConfig: null,
     93 
     94         /**
     95          * @cfg {Object} defaultTabletPickerConfig
     96          * The default configuration for the picker component when you are on a tablet.
     97          */
     98         defaultTabletPickerConfig: null,
     99 
    100         /**
    101          * @cfg
    102          * @inheritdoc
    103          */
    104         name: 'picker',
    105 
    106         /**
    107          * @cfg {String} pickerSlotAlign
    108          * The alignment of text in the picker created by this Select
    109          * @private
    110          */
    111         pickerSlotAlign: 'center',
    112         value:null
    113     },
    114 
    115     platformConfig: [
    116         {
    117             theme: ['Windows'],
    118             pickerSlotAlign: 'left'
    119         },
    120         {
    121             theme: ['Tizen'],
    122             usePicker: false
    123         }
    124     ],
    125 
    126     // @private
    127     initialize: function () {
    128         var me = this;
    129         me.callParent();
    130         //监听按钮点击事件
    131         this.on({
    132             scope: me,
    133             tap: "showPicker"
    134         });
    135     },
    136 
    137     /**
    138      * @private
    139      */
    140     updateDefaultPhonePickerConfig: function (newConfig) {
    141         var picker = this.picker;
    142         if (picker) {
    143             picker.setConfig(newConfig);
    144         }
    145     },
    146 
    147     /**
    148      * @private
    149      */
    150     updateDefaultTabletPickerConfig: function (newConfig) {
    151         var listPanel = this.listPanel;
    152         if (listPanel) {
    153             listPanel.setConfig(newConfig);
    154         }
    155     },
    156 
    157     /**
    158      * @private
    159      * Checks if the value is `auto`. If it is, it only uses the picker if the current device type
    160      * is a phone.
    161      */
    162     applyUsePicker: function (usePicker) {
    163         if (usePicker == "auto") {
    164             usePicker = (Ext.os.deviceType == 'Phone');
    165         }
    166 
    167         return Boolean(usePicker);
    168     },
    169 
    170     /**
    171      * @private
    172      */
    173     applyValue: function (value) {
    174         var record = value,
    175             index, store;
    176 
    177         //we call this so that the options configruation gets intiailized, so that a store exists, and we can
    178         //find the correct value
    179         this.getOptions();
    180 
    181         store = this.getStore();
    182 
    183         if ((value != undefined && !value.isModel) && store) {
    184             index = store.find(this.getValueField(), value, null, null, null, true);
    185 
    186             if (index == -1) {
    187                 index = store.find(this.getDisplayField(), value, null, null, null, true);
    188             }
    189 
    190             record = store.getAt(index);
    191         }
    192 
    193         return record;
    194     },
    195 
    196     updateValue: function (newValue, oldValue) {
    197         this.record = newValue;
    198     },
    199 
    200     getValue: function () {
    201         var record = this.record;
    202         return (record && record.isModel) ? record.get(this.getValueField()) : null;
    203     },
    204 
    205     /**
    206      * Returns the current selected {@link Ext.data.Model record} instance selected in this field.
    207      * @return {Ext.data.Model} the record.
    208      */
    209     getRecord: function () {
    210         return this.record;
    211     },
    212 
    213     // @private
    214     getPhonePicker: function () {
    215         var config = this.getDefaultPhonePickerConfig();
    216 
    217         if (!this.picker) {
    218             this.picker = Ext.create('Ext.picker.Picker', Ext.apply({
    219                 slots: [
    220                     {
    221                         align: this.getPickerSlotAlign(),
    222                         name: this.getName(),
    223                         valueField: this.getValueField(),
    224                         displayField: this.getDisplayField(),
    225                         value: this.getValue(),
    226                         store: this.getStore()
    227                     }
    228                 ],
    229                 listeners: {
    230                     change: this.onPickerChange,
    231                     scope: this
    232                 }
    233             }, config));
    234         }
    235 
    236         return this.picker;
    237     },
    238 
    239     // @private
    240     getTabletPicker: function () {
    241         var config = this.getDefaultTabletPickerConfig();
    242 
    243         if (!this.listPanel) {
    244             this.listPanel = Ext.create('Ext.Panel', Ext.apply({
    245                 left: 0,
    246                 top: 0,
    247                 modal: true,
    248                 cls: Ext.baseCSSPrefix + 'select-overlay',
    249                 layout: 'fit',
    250                 hideOnMaskTap: true,
    251                  Ext.os.is.Phone ? '14em' : '18em',
    252                 height: (Ext.os.is.BlackBerry && Ext.os.version.getMajor() === 10) ? '12em' : (Ext.os.is.Phone ? '12.5em' : '22em'),
    253                 items: {
    254                     xtype: 'list',
    255                     store: this.getStore(),
    256                     itemTpl: '<span class="x-list-label">{' + this.getDisplayField() + ':htmlEncode}</span>',
    257                     listeners: {
    258                         select: this.onListSelect,
    259                         itemtap: this.onListTap,
    260                         scope: this
    261                     }
    262                 }
    263             }, config));
    264         }
    265 
    266         return this.listPanel;
    267     },
    268 
    269     /**
    270      * 显示选择器, whether that is a {@link Ext.picker.Picker} or a simple
    271      * {@link Ext.List list}.
    272      */
    273     showPicker: function () {
    274         var me = this,
    275             store = me.getStore(),
    276             value = me.getValue();
    277         //check if the store is empty, if it is, return
    278         if (!store || store.getCount() === 0) {
    279             return;
    280         }
    281 
    282         if (me.getUsePicker()) {
    283             var picker = me.getPhonePicker(),
    284                 name = me.getName(),
    285                 pickerValue = {};
    286 
    287             pickerValue[name] = value;
    288             picker.setValue(pickerValue);
    289 
    290             if (!picker.getParent()) {
    291                 Ext.Viewport.add(picker);
    292             }
    293 
    294             picker.show();
    295         } else {
    296             var listPanel = me.getTabletPicker(),
    297                 list = listPanel.down('list'),
    298                 index, record;
    299 
    300             if (!listPanel.getParent()) {
    301                 Ext.Viewport.add(listPanel);
    302             }
    303             //基于按钮显示
    304             listPanel.showBy(me);
    305 
    306             if (value || me.getAutoSelect()) {
    307                 store = list.getStore();
    308                 index = store.find(me.getValueField(), value, null, null, null, true);
    309                 record = store.getAt(index);
    310 
    311                 if (record) {
    312                     list.select(record, null, true);
    313                 }
    314             }
    315         }
    316     },
    317 
    318     // @private
    319     onListSelect: function (item, record) {
    320         var me = this;
    321         if (record) {
    322             me.setValue(record);
    323             //选择成功触发事件
    324             this.fireEvent('selecSuccess', this, this.getValue(), record);
    325         }
    326     },
    327 
    328     onListTap: function () {
    329         this.listPanel.hide({
    330             type: 'fade',
    331             out: true,
    332             scope: this
    333         });
    334     },
    335 
    336     // @private
    337     onPickerChange: function (picker, value) {
    338         var me = this,
    339             newValue = value[me.getName()],
    340             store = me.getStore(),
    341             index = store.find(me.getValueField(), newValue, null, null, null, true),
    342             record = store.getAt(index);
    343 
    344         me.setValue(record);
    345         //选择成功触发事件
    346         this.fireEvent('selecSuccess', this, this.getValue(), record);
    347     },
    348 
    349     onChange: function (component, newValue, oldValue) {
    350         var me = this,
    351             store = me.getStore(),
    352             index = (store) ? store.find(me.getDisplayField(), oldValue, null, null, null, true) : -1,
    353             valueField = me.getValueField(),
    354             record = (store) ? store.getAt(index) : null;
    355 
    356         oldValue = (record) ? record.get(valueField) : null;
    357 
    358         me.fireEvent('change', me, me.getValue(), oldValue);
    359     },
    360 
    361     /**
    362      * Updates the underlying `<options>` list with new values.
    363      *
    364      * @param {Array} newOptions An array of options configurations to insert or append.
    365      *
    366      *     selectBox.setOptions([
    367      *         {text: 'First Option',  value: 'first'},
    368      *         {text: 'Second Option', value: 'second'},
    369      *         {text: 'Third Option',  value: 'third'}
    370      *     ]).setValue('third');
    371      *
    372      * __Note:__ option object member names should correspond with defined {@link #valueField valueField} and
    373      * {@link #displayField displayField} values.
    374      *
    375      * @return {Ext.field.Select} this
    376      */
    377     updateOptions: function (newOptions) {
    378         var store = this.getStore();
    379 
    380         if (!store) {
    381             this.setStore(true);
    382             store = this._store;
    383         }
    384 
    385         if (!newOptions) {
    386             store.clearData();
    387         }
    388         else {
    389             store.setData(newOptions);
    390             this.onStoreDataChanged(store);
    391         }
    392         return this;
    393     },
    394 
    395     applyStore: function (store) {
    396         if (store === true) {
    397             store = Ext.create('Ext.data.Store', {
    398                 fields: [this.getValueField(), this.getDisplayField()],
    399                 autoDestroy: true
    400             });
    401         }
    402 
    403         if (store) {
    404             store = Ext.data.StoreManager.lookup(store);
    405 
    406             store.on({
    407                 scope: this,
    408                 addrecords: 'onStoreDataChanged',
    409                 removerecords: 'onStoreDataChanged',
    410                 updaterecord: 'onStoreDataChanged',
    411                 refresh: 'onStoreDataChanged'
    412             });
    413         }
    414 
    415         return store;
    416     },
    417 
    418     updateStore: function (newStore) {
    419         if (newStore) {
    420             this.onStoreDataChanged(newStore);
    421         }
    422 
    423         if (this.getUsePicker() && this.picker) {
    424             this.picker.down('pickerslot').setStore(newStore);
    425         } else if (this.listPanel) {
    426             this.listPanel.down('dataview').setStore(newStore);
    427         }
    428     },
    429 
    430     /**
    431      * Called when the internal {@link #store}'s data has changed.
    432      */
    433     onStoreDataChanged: function (store) {
    434         var initialConfig = this.getInitialConfig(),
    435             value = this.getValue();
    436 
    437         if (value || value == 0) {
    438             this.updateValue(this.applyValue(value));
    439         }
    440 
    441         if (this.getValue() === null) {
    442             if (initialConfig.hasOwnProperty('value')) {
    443                 this.setValue(initialConfig.value);
    444             }
    445 
    446             if (this.getValue() === null && this.getAutoSelect()) {
    447                 if (store.getCount() > 0) {
    448                     this.setRecord(store.getAt(0));
    449                 }
    450             }
    451         }
    452     },
    453 
    454     /**
    455      * Resets the Select field to the value of the first record in the store.
    456      * @return {Ext.field.Select} this
    457      * @chainable
    458      */
    459     reset: function () {
    460         var store = this.getStore(),
    461             record = (this.originalValue) ? this.originalValue : store.getAt(0);
    462 
    463         if (store && record) {
    464             this.setValue(record);
    465         }
    466 
    467         return this;
    468     },
    469 
    470     destroy: function () {
    471         this.callParent(arguments);
    472         var store = this.getStore();
    473 
    474         if (store && store.getAutoDestroy()) {
    475             Ext.destroy(store);
    476         }
    477 
    478         Ext.destroy(this.listPanel, this.picker);
    479     }
    480 });

    使用示例

    引用:

        requires: ['ux.SelectBtn'],

    使用(可以参考官方selectfield控件用法):

     1 {
     2                 xtype: 'selectBtn',
     3                 text: '分享',
     4                 align: 'right',
     5                 ui: 'decline',
     6                 valueField: 'name',
     7                 displayField: 'name',
     8                 action:'share',
     9                 store: 'shareList'
    10 }

    控制层监听

    引用:

    1 refs: {
    2             shareBtn: 'button[action=share]'
    3         }

    监听(选择成功):

    1 control: {
    2             shareBtn: {
    3                 selecSuccess: function (t, value, record) {
    4                     console.log(value,record);
    5                 }
    6             }
    7 }

    效果图(点击按钮后):

     

  • 相关阅读:
    3. Image Structure and Generation
    STM32F103
    10.2 External interrupt/event controller (EXTI)
    10.1 Nested vectored interrupt controller (NVIC) 嵌套矢量中断控制器
    ibatis 使用 in 查询的几种XML写法
    文字纵向打印
    oracle每天清理归档日志
    使用语句查询mssql死锁
    Xml序列化UTF-8格式错误
    Nginx的优点
  • 原文地址:https://www.cnblogs.com/mlzs/p/3560234.html
Copyright © 2020-2023  润新知