论坛首页 Web前端技术论坛

ExtJS Menu嵌套combo等控件时,自动隐藏/遮盖等bug的解决方案

浏览 6358 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-06   最后修改:2010-07-08

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
    ]
});
  • 大小: 32.1 KB
  • 大小: 49.8 KB
   发表时间:2010-01-13  
太感谢啦~~~
最近我也出现这个问题,正愁找不到方法呢。

另:请问如何看Ext.menu.MenuMgr中的代码啊,我怎么在3.0的api中找不到。。。
    本人还在学习中,请见谅。
0 请登录后投票
   发表时间:2010-01-14  
菜鸟的弟弟 写道
太感谢啦~~~
最近我也出现这个问题,正愁找不到方法呢。

另:请问如何看Ext.menu.MenuMgr中的代码啊,我怎么在3.0的api中找不到。。。
    本人还在学习中,请见谅。


ext-3.0.0\src\widgets\menu\MenuMgr.js
0 请登录后投票
   发表时间:2010-01-15  
晕了,3.1中下拉还是会被挡住.
0 请登录后投票
   发表时间:2010-02-17  
问题解决了,饮水思源,特地完成测试后来这回复,感谢高手的分享。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics