bro-framework中,基于jquery ui以及第三方代码,实现了一个combobox组件。
通常情况下,jqui的dialog内容会采用ajax的方式(load)加载html文本、或者提前加载但是隐藏到页面上,当需要的时候再调用api将其显示出来;如果dialog页面上需要combobox之类的控件,若生成combobox的时机不正确时,会发现输入框和右侧的下拉箭头的位置严重偏离,或者根本就不显示为combobox,还是默认的下拉框形式。
下面是导致出现该问题的几段问题代码。
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});
});
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');
});
<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>
<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/