欢迎进入Wiki » FAQ » 在JQuery UI的Dialog、Tabs界面中实现combobox?

在JQuery UI的Dialog、Tabs界面中实现combobox?

在2013-11-26 10:32上被李小翔修改
评论 (0) · 附件 (0) · 记录 · 信息

问题描述

    bro-framework中,基于jquery ui以及第三方代码,实现了一个combobox组件。

    通常情况下,jqui的dialog内容会采用ajax的方式(load)加载html文本、或者提前加载但是隐藏到页面上,当需要的时候再调用api将其显示出来;如果dialog页面上需要combobox之类的控件,若生成combobox的时机不正确时,会发现输入框和右侧的下拉箭头的位置严重偏离,或者根本就不显示为combobox,还是默认的下拉框形式。

    下面是导致出现该问题的几段问题代码。

  • 示例代码1
var dlg = $j("#foobar").dialog({
    autoOpen:false, ......
});

dlg.load( "http://xxxx/yyyy/zzzz", function(){
    dlg.dialog('open');
    $j("select[name='foobar']").combobox({minLength:1, delay:300});
});
  • 示例代码2
var dlg = $j("#foobar").dialog({
    autoOpen:false, .....
    , open: function() {
        $j("select[name='foobar']").combobox({minLength:1, delay:300});
    }
});

dlg.load( "http://xxxx/yyyy/zzzz", function(){
    dlg.dialog('open');
});
  • 示例代码3
<html>
<head>
   <script>
   // 页面加载完成后就提前设置combobox!!!
   $j(function(){
        $j("#foobar").combobox({minLength:1, delay:300});
    })
   
   // 显示dialog
   function showDialog() {
        $j("#dialog").dialog({....})
    }
   </script>
</head>
<body>
   <div id="dialog" style="display:none">
       <select id="foobar">...</select>
   </div>
   <button onclick="showDialog()">
        show dialog
   </button>
</body>
  • 示例代码4
<html>
<head>
   <script>
    $j(function(){
        $j("#tabs").tabs();    // 生成tab页签
       $j("#foobar").combobox({minLength:1, delay:300});
    })
   
   function showDialog() {
        $j("#dialog").dialog({....})
    }
   </script>
</head>
<body>
   <div id="tabs">
       <ul>
           <li><a href="#tabs-1">tab1</li>
           <li><a href="#tabs-2">tab2-combobox</li>
       </ul>
       <div id="tabs-1">....</div>
       <div id="tabs-2">
            <select id="foobar">...</select>
       </div>
   </div>
   <button onclick="showDialog()">
        show dialog
   </button>
</body>

原因分析

    示例代码1和2中,虽然都在相关的事件中渲染combobox,但实际上偶尔会出现不生成combobox的问题。原因是jquery的ajax方法load显然做了延迟渲染的处理,在load成功的回调方法里调用dialog方法来显示窗口时,HTML内容并未真正渲染到页面上。

    示例代码3中,虽然html内容已渲染,但是select此时并不可见,导致渲染出来的combobox输入框和右侧的下拉箭头的位置严重偏离。

    实例代码4中,由于有tab页签,并且默认显示tab1,而下拉框在tab2中,此时也是不可见的,因此切换到页签tab2时,combobox的显示效果仍然错位。

解决方案

    对于示例代码1和2,由于jquery目前没有提供渲染完成的事件,因此只好写点看比较罗嗦的异步代码,如下所示:

var dlg = $j("#foobar").dialog({
    autoOpen:false, .....
    , open: function() {
       // 异步渲染combobox
       function setCombobox() {
            $j.doTimeout(50, function() {
               if ( $j("select[name='foobar']:visible").length == 0 ) return setCombobox();
                $j("select[name='foobar']").combobox({minLength:1, delay:300});
            })
        };
        setCombobox();
    }
});

dlg.load( "http://xxxx/yyyy/zzzz", function(){
    dlg.dialog('open');
});

    对于示例代码3,将对combobox的调用改到dialog的open事件(见上面的open事件)中即可,代码略。

    对于示例代码4,将对combobox的调用改到对应页签激活的事件中即可,如下所示:

$j("#tabs").tabs({
    activate: function(event, ui) {
       if ( ui.newPanel.attr("id") == "tabs-2" ) {
            $j("select[name='foobar']").combobox({minLength:1, delay:300});
        }
    }
});

适用于

    BroFramework 2.8+

参考资料

  http://api.jqueryui.com/dialog/
   http://api.jqueryui.com/tabs/

在2013-10-17 09:44上被李小翔创建

Copyright © 2013 北京博瑞开源软件有限公司
京ICP备12048974号