ExtJS Menu嵌套combo等控件時,自動隱藏/遮蓋等bug的解決方案

2010-07-08補充:

DateField隱藏的解決方案,詳見本文底部.

 

2010-07-04補充:

ExtJS3.2的combo文檔中更新的一種新的解決方案,詳見本文底部.

 

 

續前文: http://atian25.iteye.com/blog/431545

 

上篇只解決了combo下拉框被遮蓋的問題,但是如果選擇como的某項,或者點擊下拉菜單就會自動隱藏menu,如下圖.

 

 

初步猜測是該item的點擊被判斷不屬於menu的範圍,所以隱藏掉了.

翻了半天的源碼,終於找到此句:

   // Ext.menu.MenuMgr
   function onMouseDown(e){
       if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
           hideAll();
       }
   }

 

覺得應該是這個class的問題,於是給combo加個樣式就搞定了,如下源碼:

var combo = new Ext.form.ComboBox({
    fieldLabel: '修復後的Combo',
    store: data,
    mode: 'local',
    triggerAction:'all',
    /*
     * 關鍵點
     * 1. x-menu使combo在選擇的時候不會隱藏掉menu,看Ext.menu.MenuMgr.onMouseDown源碼即知
     * 2. x-menu裏面的"z-index: 15000;",因爲menu裏面的layer的z-index是15000,則這裏大於15000即可.. 
     * 3.因爲這個cls已經有個z-index,所以前文中我們自定義的那個class可以去掉了
     */
    listClass:' x-menu '
  });
 

 

完整的測試代碼和截圖如下:


Ext.onReady(function(){
  Ext.BLANK_IMAGE_URL = '/images/s.gif';
  Ext.QuickTips.init();
  fixMenuBug()
});

function fixMenuBug(){
  //Defined combo
  var data = [];
  for(var i=0;i<20;i++){
    data.push('option'+i);
  }
  var combo = new Ext.form.ComboBox({
    fieldLabel: '修復後的Combo',
    store: data,
    mode: 'local',
    triggerAction:'all',
    /*
     * 關鍵點
     * 1. x-menu使combo在選擇的時候不會隱藏掉menu,看Ext.menu.MenuMgr.onMouseDown源碼即知
     * 2. x-menu裏面的"z-index: 15000;",因爲menu裏面的layer的z-index是15000,則這裏大於15000即可.. 
     */
    listClass:' x-menu '
  });
  var bugcombo = new Ext.form.ComboBox({
    fieldLabel: '菜單被遮蓋住的Combo',
    store: data,
    mode: 'local',
    triggerAction:'all',
    listClass:''
  });
  var bugcombo2 = new Ext.form.ComboBox({
    fieldLabel: '點擊下拉滾動條/選擇子項會隱藏的Combo',
    store: data,
    mode: 'local',
    triggerAction:'all',
    listClass:' comboInMenu '
  });
  var combo2 = new Ext.form.ComboBox({
    fieldLabel: 'fixedCombo2',
    store: ['選我,不隱藏'].concat(data),
    value:'選我,不隱藏',
    mode: 'local',
    triggerAction:'all',
    listClass:' x-menu '
  });
  var noHideText=new Ext.form.TextField({
    value: '點我,不會被隱藏',
    //關鍵點:讓組件被選中的時候不隱藏掉menu
    hideOnClick:false
  });
  var hideText=new Ext.form.TextField({
    value: '點我,隱藏'
  });
  var form = new Ext.FormPanel({
    labelWidth: 250,
    frame:true,
    width: 550,
    height:150,
    items: [
      {xtype:'textfield',fieldLabel:'輸入框'},
      bugcombo,
      bugcombo2,
      combo
    ],
    buttons: [{text: 'Save'},{text: 'Cancel'}]
  });
  
  var btn = new Ext.SplitButton({
    renderTo: document.body,
    text: 'Options',
    menu: new Ext.menu.Menu({
      items: [
        form,combo2,noHideText,hideText,
        /* 2.2版本中需要對Adapter的第二個參數中加入hideOnClick:false
        new Ext.menu.Adapter(form,{hideOnClick:false}),
        new Ext.menu.Adapter(combo2,{hideOnClick:false}),
        new Ext.menu.Adapter(noHideText),
        new Ext.menu.Adapter(hideText),
        */
        {text:'點擊我,不隱藏',hideOnClick:false},
        {text:'點擊我,2.0隱藏,3.0不隱藏'}
      ]
    })
  });
}
 

 

2010-07-08 更新:

 

DateField隱藏的解決方法:

因爲DF裏面還有個datemenu,所以需要設置該屬性allowOtherMenus: true

 

var dateField = new Ext.form.DateField({
    fieldLabel:'日期1',
    menu: new Ext.menu.DateMenu({
      hideOnClick: false,
      allowOtherMenus: true
    })
  })
 

2010-07-04 更新:

ExtJS 3.2.0 文檔中提到的一種解決方法:

 

getListParent() : void    ComboBox
Returns the element used to house this ComboBox's pop-up list. Defaults to the document body. A custom implementation...

Returns the element used to house this ComboBox's pop-up list. Defaults to the document body.
A custom implementation may be provided as a configuration option if the floating list needs to be rendered to a different Element. An example might be rendering the list inside a Menu so that clicking the list does not hide the Menu:

var store = new Ext.data.ArrayStore({
    autoDestroy: true,
    fields: ['initials', 'fullname'],
    data : [
        ['FF', 'Fred Flintstone'],
        ['BR', 'Barney Rubble']
    ]
});

var combo = new Ext.form.ComboBox({
    store: store,
    displayField: 'fullname',
    emptyText: 'Select a name...',
    forceSelection: true,
    getListParent: function() {
        return this.el.up('.x-menu');
    },
    iconCls: 'no-icon', //use iconCls if placing within menu to shift to right side of menu
    mode: 'local',
    selectOnFocus: true,
    triggerAction: 'all',
    typeAhead: true,
    width: 135
});

var menu = new Ext.menu.Menu({
    id: 'mainMenu',
    items: [
        combo // A Field in a Menu
    ]
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章