
2.2 组合简介
2.2.1 组合(Combo)
组合是在页面上显示一个文本框和一个下拉面板,它是创建其他复杂组件(例如:combobox、combotree、combogrid)的基础,利用组合我们也可以自定义开发一些更加复杂的组件,例如在第6章中利用组合开发起止日期框组件。本节将向读者讲解组合和组合框两个组件的使用方法。
组合的依赖关系如下:
- textbox
- panel
组合扩展于:
- textbox
组合的默认配置定义在$.fn.combo.defaults中。
1. 组合的用法
可以通过JavaScript从<input>或者<select>标记创建组合,注意使用标记创建组合是不合法的。例如:
01 <input id="cc" value="1"> 02 $('#cc').combo({ 03 required:true, 04 multiple:true 05 });
2. 组合属性
组合常用属性的说明见表2.11。
表2.11 组合常用属性说明

3. 组合的事件
组合常用事件的说明见表2.12。
表2.12 组合常用事件说明

4. 组合的方法
组合常用方法的说明见表2.13。
表2.13 组合常用方法说明

5. 深入理解EasyUI依赖关系
通过前面的学习读者可以发现组合依赖于文本框和面板,其中扩展于文本框,因此我们可以使用文本框的属性来初始化组合,但是如果需要设置面板属性的话,我们需要通过组合的panel方法先获取面板对象再设置其属性,例如:
01 <body> 02 <input id="cc" name="dept" value="aa"> 03 <div id="footer">底部</footer> 04 </body> 05 <script> 06 $(function(){ 07 $('#cc').combo({ 08 //文本框属性 09 iconCls:'icon-search', 10 onClickButton:function(){ 11 alert("11"); 12 }, 13 //组合属性 14 hasDownArrow:false, 15 }); 16 //设置面板属性 17 var panel = $('#cc').combo("panel"); 18 panel.panel({ 19 footer:"#footer" 20 }); 21 }); 22 </script>
最终运行结果如图2.11所示。
再看下面的代码,我们使用组合的textbox方法获取文本框对象,接着设置文本框属性,例如:
01 var tb = $('#cc').combo("textbox"); 02 tb.textbox({ 03 width:300 04 });
此时运行结果如图2.12所示。

图2.11 设置依赖组件属性

图2.12 设置依赖组件属性
可以发现此时并没有设置成功组合中的文本框属性,相反这段代码在原先的组合上新增了一个文本框。这是因为组合本身并没有重写或新增textbox方法,组合使用的其实是文本框的textbox方法,该方法返回的是文本框中展示值框的对象,开发者可以为其绑定指定的事件。但是如果使用展示值框来初始化文本框,就会在其基础上创建一个新的文本框。
2.2.2 组合框(ComboBox)
组合框由一个可编辑的文本框和一个下拉面板组成。用户可以在下拉面板中选中一个或者多个值,同样可以直接在文本框内输入内容或者在下拉面板中选中一个或多个值。
组合框依赖关系如下:
- combo
组合框扩展于:
- combo
组合框的默认配置定义在$.fn.combobox.defaults中。
1. 创建组合框
可以通过<select>标记创建一个组合框,此时可以将选项直接写入到<select>元素中。例如:
01 <select id="cc" class="easyui-combobox" name="dept" style="width:200px;"> 02 <option value="aa">item1</option> 03 <option>item2</option> 04 <option>item3</option> 05 <option>item4</option> 06 <option>item5</option> 07 </select>
也可以通过<input>标记创建组合框,例如:
01 <input id="cc" name="dept" value="aa"> 02 $('#cc').combobox({ 03 url:'combobox_data.json', 04 valueField:'id', 05 textField:'text' 06 });
也可以创建两个相互依赖的组合框,例如:
01 <input id="cc1" class="easyui-combobox" data-options=" 02 valueField: 'id', 03 textField: 'text', 04 url: 'get_data1.php', 05 onSelect: function(rec){ 06 var url = 'get_data2.php?id='+rec.id; 07 $('#cc2').combobox('reload', url); 08 }"> 09 <input id="cc2" class="easyui-combobox" data-options="valueField:'id',textField:'text'">
2. 组合框属性
组合框常用属性见表2.14。
表2.14 组合框常用属性说明

下面将具体讲解如何使用组合框从服务器和本地加载数据,组合框加载数据时可以接收JSON格式数据,通过如下方法加载本地数据,部分代码如下:
01 $('#cc').combobox({ 02 valueField:'id', 03 textField:'city', 04 data:[ 05 {"id":1," country":"中国","city":"北京市"}, 06 {"id":2," country":"中国","city":"上海市"}, 07 {"id":3," country":"中国","city":"重庆市"}, 08 {"id":4," country":"中国","city":"天津市"}, 09 {"id":5," country":"美国","city":"华盛顿"}, 10 {"id":6," country":"美国","city":"纽约"}, 11 {"id":7," country":"美国","city":"旧金山"}, 12 {"id":8," country":"英国","city":"伦敦"}, 13 {"id":9," country":"英国","city":"伯明翰"}, 14 {"id":10," country":"英国","city":"利兹"}, 15 {"id":11," country":"法国","city":"巴黎"}, 16 {"id":12," country":"法国","city":"马赛"}, 17 {"id":13," country":"法国","city":"里昂"}, 18 ], 19 });
我们也可以通过服务器加载数据,服务器部分代码如下:
01 $city = array( 02 array("id"=>1," country"=>"中国","city"=>"北京市"), 03 array("id"=>2," country"=>"中国","city"=>"上海市"), 04 array("id"=>3," country"=>"中国","city"=>"重庆市"), 05 array("id"=>4," country"=>"中国","city"=>"天津市"), 06 array("id"=>5," country"=>"美国","city"=>"华盛顿"), 07 array("id"=>6," country"=>"美国","city"=>"纽约"), 08 array("id"=>7," country"=>"美国","city"=>"旧金山"), 09 array("id"=>8," country"=>"英国","city"=>"伦敦"), 10 array("id"=>9," country"=>"英国","city"=>"伯明翰"), 11 array("id"=>10," country"=>"英国","city"=>"利兹"), 12 array("id"=>11," country"=>"法国","city"=>"巴黎"), 13 array("id"=>12," country"=>"法国","city"=>"马赛"), 14 array("id"=>13," country"=>"法国","city"=>"里昂") 15 ); 16 echo JSON($city);
对应的客户端部分代码如下:
01 $('#cc').combobox({ 02 valueField:'id', 03 textField:'city', 04 url:" getData.php" 05 });
最终运行结果如图2.13所示。

图2.13 使用组合框加载数据
通过本地加载数据时,需要给data属性赋予一个JSON格式的数据,使用数字1来存储数据要比使用“北京市”来存储数据更加节省磁盘空间,而且避免了编码问题,因此在这里使用id字段来表示存储值,使用city字段来表示展示值。组合框中的valueField属性指定存储值的字段,textField属性指定展示值字段。通过服务器加载数据,其实就是将数据保存在服务器端,其本质都是通过JSON格式数据来初始化组合框,url属性提供组合框初始化数据的服务器地址。
在上述例子的JSON格式数据中有一个country字段,该字段表示每个城市所在的国家,组合框可以通过groupField属性对数据进行分组,使用groupFormatter属性设置各个分组的展示值,formatter属性可以设置组合框中每一行数据的展示值。接下来我们将把数据按照国家进行分组,并将国家名格式化为该国家的国旗图标,然后再对各个国家首都进行加黑处理。部分代码如下:
01 $('#cc').combobox({ 02 //扩展自Combo的属性 03 width: 400, 04 panelHeight:450, 05 //ComboBox新增属性 06 valueField:'id', 07 textField:'city', 08 groupField:'country', 09 url:"server/getCountry.php", 10 groupFormatter:function(group){ 11 if(group == "中国"){ 12 return "<img src='img/zg.png'></img>"; 13 }else if(group == "美国"){ 14 return "<img src='img/mg.png'></img>"; 15 }else if(group == "英国"){ 16 return "<img src='img/yg.png'></img>"; 17 }else if(group == "法国"){ 18 return "<img src='img/fg.png' width='36' height='27'></img>"; 19 }else{ 20 return ""; 21 } 22 }, 23 formatter:function(row){ 24 var opts = $(this).combobox("options"); 25 var text = row[opts.textField]; 26 if(text == "北京市"||text == "华盛顿"||text == "伦敦"||text == "巴黎"){ 27 return "<b>"+text+"</b>"; 28 } 29 else{ 30 return text; 31 } 32 }, 33 });
在上述代码中groupFormatter属性的参数group代表的是各个分组的名称,例如中国、美国等,程序会自动检测有多少个分组,并将每个类型的分组都使用一次groupFormatter中的方法格式化。formatter属性中的row参数代表初始化数据中的每一行数据,例如{"id":1,"country":"中国","city":"北京市"},程序会对初始化数据使用format中的方法进行格式化,因此通过这个方法我们可以自定义组合框中每一行数据的展示格式。options方法在前面的章节中曾经提及过,它返回的是当前组件的配置,因此通过row[opts.textField]可以获取组合框textField的值。最终运行结果如图2.14所示。

图2.14 使用组合框对设计数据的展示值
【本节详细代码参见随书源码:\源码\easyui\example\c2\comboboxFormat.html】
组合框是由可编辑的文本框和下拉面板组成的。用户同样可以在文本框内输入字符串来检索数据,因为当组合框中包含世界所有的国家的主要城市时,通过下拉面板一条条地查找数据显然效率低下,此时用户更希望在文本框内中输入需要查找的城市关键字,下拉面板自动将包含关键字的数据显示出来。mode属性指定当用户在组合框内输入关键字时,组合框从何处获取数据,当设置其值为remote时,组合框会将用户输入的关键字通过http请求以参数q传输给服务器端,服务器端会将查询到的数据返回给组合框,mode属性设置为local时,可以通过filter属性自定义规则在本地进行检索。服务器端检索数据较为复杂,接下来本书先讲解如何从本地检索数据,我们对上个例子进行修改,使用户输入国家时,下拉面板只显示该国家的城市,新增代码如下:
01 mode: "local", 02 filter:function(q,row) 03 { 04 var opts = $('#cc').combobox("options");//获取该组合框全部的属性 05 var groupname =row[opts.groupField];//获取该行数据的分组值 06 if(groupname == q){ 07 return row[opts.textField]; //当用户输入的值等于分组值时则显示数据 08 } 09 else{ 10 return false; 11 } 12 }
最终运行结果如图2.15所示。

图2.15 本地检索数据
提示
filter属性默认检索规则是显示包含用户输入的关键字的数据。例如输入“北京”,将会检索到“北京市”。
下面我们将探讨服务器端检索数据的方法,使用服务器端检索数据需要用到如下属性。
- mode:设置为romote时将从服务器端检索数据。
- loader:用于从服务器检索数据。
- loadFilter:对服务器端检索后的数据进一步过滤。
部分代码如下:
01 mode: "remote", 02 loader:function(param,success,error){ 03 var q = param.q; //获取文本框中输入的数据 04 if(q.length<1){ 05 return false; 06 } 07 $.ajax({ //利用ajax请求获取数据 08 url: ' filterCountry.php?q='+q, 09 dataType: 'json', 10 type:'get', 11 success: function(data){ 12 success(data); 13 }, 14 error:function(){ 15 error(); 16 } 17 }); 18 } 19 loadFilter:function(data){ 20 //服务器端检索完毕后的回调函数,data为服务器返回的值, 21 //开发者可以进一步对数据进行过滤 22 return data; 23 }
【本节详细代码参见随书源码:\源码\easyui\example\c2\ comboboxFilter.html】
loader属性为一个函数,其参数param为需要被传输到服务器的数据,通过param.q可以得到用户输入的关键字,然后使用ajax的get方法向服务器传输用户输入的关键字,服务器将检索后的结果通过JSON格式返回,ajax传输成功后调用loader函数的success参数,该参数接收服务器返回的数据,最后会调用loadFilter属性中的方法,该方法可以对检索后的数据进一步过滤。服务器端代码如下:
01 $limit = $_GET['q']; 02 $result = db::select("select * from country where country = :country",array( 03 "country"=>$limit 04 ))->getResult(); 05 echo Data::toJson($result);
运行上述程序后读者可以发现,使用服务器检索数据在组合框初始化时,并不会加载全部的数据。因此通过服务器检索数据更适合用于数据量极大时,用户并不希望显示全部的数据,仅仅希望查找自己感兴趣的数据的情况下使用。
到目前为止组合框还有两个属性没有讲解,一个为method属性,另一个为queryParams属性。在实际项目开发中,经常会遇到权限限制的问题,例如在网站上有很多个用户,每个用户下拥有多个项目,我们希望用户只能看到自己的项目。例如我们希望用户只能看到中国下的全部城市,此时我们会通过queryParams属性增加一些参数,这些参数将会在组合框初始化时传输到服务器,服务器根据这些参数即可限制显示给用户的数据范围,method属性指定以何种方式发送这些参数,它可以是get或者post方法。如下代码限制用户仅能查看中国的城市:
01 url:" getData.php", 02 queryParams:{"c":'中国'}, 03 method: 'get'
服务器获取传输过来的参数并且进行处理,部分代码如下:
01 $limit = $_GET['c']; 02 $result = db::select("select * from country where country = :country",array( 03 "country"=>$limit 04 ))->getResult(); 05 echo Data::toJson($result);
此时组合框内将仅仅显示中国范围内的城市。
提示
loader属性中的param参数是一个包含queryParams属性和用户输入值的对象,在上例中我们也可以通过param.c获取到queryParams属性中的限制参数,这种设计保证我们在向服务器检索数据时也可以限制在指定范围内检索。
看到这里读者可能会对组合框的属性感到繁杂,其实组合框一共有三大类属性,分别是:
(1)值类属性。例如valueField属性指定存储值字段,textField属性指定展示值字段,groupField属性指定分组值字段,由于valueField、textField、groupField属性仅仅是针对JSON格式内的数据,因此展示值只能是一段字符串,并不丰富。对此组合框提供了groupFormatter属性来将分组字段内容转换成任意的展示格式,提供formatter属性将展示值字段内容进一步格式化成任意形式。
(2)获取数据属性。组合框可以接受JSON格式数据,提供本地获取数据和服务器端获取数据两种形式。本地获取数据时直接设置data属性值即可,服务器端获取数据需要设置url属性为初始化数据的服务器地址。为了只显示指定范围内的数据可以在queryParams中增加一些限制参数,通过method属性指定这些参数以何种方法传输给服务器端。
(3)检索数据属性。组合框提供本地检索和服务器检索数据两种形式。本地检索数据时,只需要在filter属性中定义一系列的检索规则即可,本地检索数据在初始化时仍然会加载全部数据。通过服务器端检索数据时,需要设置mode属性值为remote,在loader属性中向检索服务器发送ajax请求,接收到服务器返回的数据后会调用loadFilter属性对检索后的数据进一步过滤。
3. 组合框事件
组合框常用事件说明见表2.15。
表2.15 组合框常用事件说明

onBeforeLoad是在数据加载前触发,其参数param表示此次数据加载请求中包含的全部参数,通常用在向服务器发送加载数据请求前检查请求的参数。
组合框事件的record参数为用户操作的行对象,包括用户操作某行数据的存储值、展示值以及分组值。
提示
在EasyUI中很多参数都是对象,如果读者不清楚参数的具体含义,可以使用本书在2.1.2节中提供的writeObj函数打印对象。
4. 组合框方法
组合框常用方法说明见表2.16。
表2.16 组合框常用方法说明

其中setValues方法需要在组合框设置为多选模式时才能选中多个值。设置组合框的值的含义是选中面板中指定的数据,并将选中数据的展示值显示在文本框中。
01 $('#cc').combobox("setValue","1");//选中单个数据 02 $('#cc').combobox("setValues","1,2");//选中多个数据