本文將介紹自訂的bootstrap級聯下拉選單,主要應用場合有省市級關聯選單等等,那麼就先拿這個例子來講,當然其他場景的關聯選單也同樣適用。說實話,封裝好一個通用的組件還是需要花費很多精力的和時間的,所謂通用,自然要考慮周全,嘆!這次整理的Bootstrap關聯select,裡面也牽涉到了許多jquery、ajax、springMVC等等知識點,可謂包羅萬象!
首先,請容許我代表該自訂元件做一番小小的介紹。
「hi,你好,我叫yunm.combox.js,主人給我起的名字,其實呢,挺俗的。我主要透過為select元件增加兩個自訂屬性來完成對應的資料加載,資料請求使用了ajax,後端資料處理使用了springMVC(當然其他方式也可以,只需要返回對應的json資料即可),使用起來呢,就非常非常簡單了!
一、介面效果
當然了,從介面上完全看不出來一個組件封裝的好壞,但至少,你感覺很簡潔漂亮,那麼好了,有了這層印象,你是否有興趣繼續看下去?我想答案是肯定的。
二、使用方法
①、procity.jsp
首先呢,在頁面上載入yunm.combox.js(稍候介紹,至於其他的bootstrap的css和js,不在本章介紹範圍內,略過),同時呢,創建兩個select,具體格式見如下:
<script type="text/javascript" src="${ctx}/components/yunm/yunm.combox.js"></script> <div class="form-group"> <div class="row"> <div class="col-md-6"> <select name="province_code" class="form-control combox" ref="city_select" refUrl="${ctx}/procity?pro_code={value}&city_code=HSLY"> </select> </div> <div class="col-md-6"> <select name="city_code" id="city_select" class="form-control"> </select> </div> </div> </div> <script type="text/javascript"> <!-- $(function() { if ($.fn.combox) { $("select.combox", $p).combox(); } }); //--> </script>
·省級菜單上增加了兩個屬性。
ref指定關聯選單為市級選單city_select
refUrl指定選單取得資料的URL
pro_code作為市級資料的關鍵因素
{value}呢,則為通配符,請稍候在介紹組件的時候繼續講到呢,則為通配符,稍候在介紹組件的時候繼續講到
Sharp
·class=”combox” 為此省級下拉框增加jquery選擇器
·頁面載入完畢後執行combox組件的關鍵方法,以下詳細介紹
②、yunm.combox.js
現在我們來看看關鍵的元件內容吧!
·通过$.extend($.fn, { combox : function() {为jquery增加一个叫combox的底层(可以查询jquery帮助文档)方法。
·通过(function($){_onchange、addHtml})(jQuery);为该组件在页面初始加载时创建两个方法onchange和addHtml,至于(function($) {})(jQuery);我想你如果不了解的话,赶紧百度吧!
·先来看combox 方法
获取ref、refUrl,通过ajax向refUrl请求省级菜单数据,当获取成功后,通过addHtml方法将json转换后的option绑定到省级菜单select上
然后呢,为省级菜单select绑定change事件,传递的参数为ref(市级菜单)、refUrl(市级数据获取的url)、$this(省级菜单,便于change事件获取对应选中项,如效果图中的河南)
通过trigger方法立即执行change事件,便于获取对应的市级菜单内容。
·再来看_onchange方法,主要是点击省级菜单时触发,用于获取市级菜单列表
refUrl,向服务端请求的URL
value,用于获取省级菜单的选中项目,然后通过该value值获取省级对应的市级菜单
$ref.empty();用于清空市级菜单
通过ajax继续获取市级菜单内容,然后通过addHtml方法添加到市级菜单中。
·addHtml方法
通过jsonEval方法对服务端传递回来的数据进行eval(eval('(' + data + ')'),如有不懂,可百度)方法处理,否则会出错。
$.each(json, function(i) {遍历json,通过jquery创建option对象,然后加入到select中。
③、ProcityController
前端介绍完了,我们回到后端进行介绍,当然了,你也可以忽略本节,因为不是所用的关联数据都通过springMVC这种方法获取,那么先预览一下代码吧!
package com.honzh.spring.controller; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.honzh.biz.database.entity.City; import com.honzh.biz.database.entity.Option; import com.honzh.biz.database.entity.Provincial; import com.honzh.common.util.JsonUtil; import com.honzh.spring.service.CityService; import com.honzh.spring.service.ProvincialService; @Controller @RequestMapping(value = "/procity") public class ProcityController extends BaseController { private static Logger logger = Logger.getLogger(ProcityController.class); /** * 当传递city_code,则表明下拉框要被选中,否则不选中 */ @RequestMapping("") public void index(@RequestParam(value = "city_code", required = false) String city_code, @RequestParam(value = "pro_code", required = false) String pro_code, HttpServletResponse response) { try { logger.debug("获取所在地区" + city_code + ", 省" + pro_code); // 如果pro_code为””,则表明要获取城市菜单,否则获取市级菜单 if (!pro_code.equals("")) { Integer pro_id = ProvincialService.getInstance().getByProvincialcode(pro_code).getId(); List<City> citys = CityService.getInstance().getCitysByProvincialId(pro_id); List<Option> coptions = new ArrayList<Option>(citys.size()); for (City city : citys) { Option coption = new Option(); coption.setId(city.getId()); coption.setName(city.getCname()); coption.setValue(city.getCode()); // 市级菜单被选中 if (city_code != null && !city_code.equals("")) { if (city.getCode().equals(city_code)) { coption.setSelected("selected"); } } coptions.add(coption); } renderJson(response, coptions); } else { List<Provincial> provincials = ProvincialService.getInstance().getProvincials(); // 转换成标准的option属性(name,value,selected) List<Option> options = new ArrayList<Option>(provincials.size()); // 被选中的省市 // 则说明是展示页面,此时需要为省级菜单和市级菜单设置选择项 if (city_code != null && !city_code.equals("")) { Provincial selected_provincial = ProvincialService.getInstance().getProvincialByCitycode(city_code); pro_code = selected_provincial.getProcode(); } else { pro_code = provincials.get(0) == null ? "" : provincials.get(0).getProcode(); } for (Provincial provincial : provincials) { Option option = new Option(); option.setId(provincial.getId()); option.setName(provincial.getProname()); option.setValue(provincial.getProcode()); if (!pro_code.equals("") && provincial.getProcode().equals(pro_code)) { option.setSelected("selected"); } options.add(option); } renderJson(response, JsonUtil.toJson(options)); } } catch (Exception e) { logger.error(e.getMessage()); logger.error(e.getMessage(), e); renderJson(response, null); } } }
@RequestParam(value = "city_code", required = false) String city_code,对于RequestParam注解,其实非常好用,这里就不多做解释,只是推广一下,固定个数的参数,用该注解更易于代码的维护。
ProvincialService类、CityService类就是两个单例,尽量把数据放置在内存当中,减少查询数据库的次数,稍候贴出来一个例子。
Option类就是单纯的封装前端option组件的关键属性,便于组件的通用化。
renderJson(response, JsonUtil.toJson(options));将数据json化后返回,稍候贴上详细代码。
④、ProvincialService.java
只贴出来代码例子,不做详细解释,毕竟不是本章重点。
package com.honzh.spring.service; import java.util.ArrayList; import java.util.List; import com.honzh.biz.database.entity.City; import com.honzh.biz.database.entity.Provincial; import com.honzh.biz.database.mapper.ProvincialMapper; import com.honzh.common.spring.SpringContextHolder; public class ProvincialService { private static Object lock = new Object(); private static ProvincialService config = null; private ProvincialService() { provincials = new ArrayList<Provincial>(); ProvincialMapper mapper = SpringContextHolder.getBean(ProvincialMapper.class); provincials.addAll(mapper.getProvincials()); } public static ProvincialService getInstance() { synchronized (lock) { if (null == config) { config = new ProvincialService(); } } return (config); } public Provincial getByProvincialcode(String provincial_code) { for (Provincial provincial : provincials) { if (provincial.getProcode().equals(provincial_code)) { return provincial; } } return null; } private List<Provincial> provincials = null; public List<Provincial> getProvincials() { return provincials; } public Provincial getProvincialByCitycode(String city_code) { City city = CityService.getInstance().getCityByCode(city_code); for (Provincial provincial : provincials) { if (provincial.getId().intValue() == city.getProid().intValue()) { return provincial; } } return null; } public Provincial getProvincialByCode(String province_code) { for (Provincial provincial : provincials) { if (provincial.getProcode().equals(province_code)) { return provincial; } } return null; } }
⑤、renderJson方法
/** * 如果出错的话,response直接返回404 */ protected void renderJson(HttpServletResponse response, Object responseObject) { PrintWriter out = null; try { if (responseObject == null) { response.sendError(404); return; } // 将实体对象转换为JSON Object转换 String responseStr = JsonUtil.toJson(responseObject); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); out = response.getWriter(); out.append(responseStr); logger.debug("返回是:" + responseStr); } catch (IOException e) { logger.error(e.getMessage()); logger.error(e.getMessage(), e); } finally { if (out != null) { out.close(); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助。