DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> Bootstrap每天必學之級聯下拉菜單
Bootstrap每天必學之級聯下拉菜單
編輯:關於JavaScript     

本文將介紹自定義的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>

·兩個select組件,一個為province_code、一個為city_code。
·省級菜單上增加了兩個屬性。
      ref指定關聯菜單為市級菜單city_select
      refUrl指定菜單獲取數據的URL 
                pro_code作為獲取市級數據的關鍵因子
                {value}呢,則為通配符,稍候在介紹組件的時候繼續講到
               city_code=HSLY,主要用於選中指定的省市菜單,諸如上文中的(河南、洛陽),如果不選中,則city_code=為空
·class=”combox” 為該省級下拉框增加jquery選擇器
·頁面加載完畢後執行combox組件的關鍵方法,下面詳細介紹

②、yunm.combox.js

現在我們來看看關鍵的組件內容吧!

(function($) {
 var _onchange = function(event) {
 var $ref = $("#" + event.data.ref);
 if ($ref.size() == 0)
 return false;

 var refUrl = event.data.refUrl;
 var value = encodeURIComponent(event.data.$this.val());
 YUNM.debug(value);

 $.ajax({
 type : 'POST',
 dataType : "json",
 url : refUrl.replace("{value}", value),
 cache : false,
 data : {},
 success : function(response) {
 $ref.empty();

 addHtml(response, $ref);
 $ref.trigger("change").combox();
 },
 error : YUNM.ajaxError
 });

 };

 var addHtml = function(response, $this) {
 var json = YUNM.jsonEval(response);
 if (!json)
 return;

 var html = '';
 $.each(json, function(i) {
 if (json[i]) {

 html += '<option value="' + json[i].value + '"';

 if (json[i].selected) {
  html += ' selected="' + json[i].selected;
 }

 html += '">' + json[i].name + '</option>';
 }
 });

 $this.html(html);
 };

 $.extend($.fn, {
 combox : function() {

 return this.each(function(i) {
 var $this = $(this);

 var value = $this.val() || '';
 var ref = $this.attr("ref");

 var refUrl = $this.attr("refUrl") || "";
 if (refUrl) {
  refUrl = refUrl.replace("{value}", encodeURIComponent(value));
 }

 if (refUrl) {
  $.ajax({
  type : 'POST',
  dataType : "json",
  url : refUrl,
  cache : false,
  data : {},
  success : function(response) {
  addHtml(response, $this);

  if (ref && $this.attr("refUrl")) {
  $this.unbind("change", _onchange).bind("change", {
   ref : ref,
   refUrl : $this.attr("refUrl"),
   $this : $this,
  }, _onchange).trigger("change");
  }
  },
  error : YUNM.ajaxError
  });
 }

 });
 }
 });
})(jQuery);

·通過$.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();
 }
 }
 }

如果大家還想深入學習,可以點擊jQuery級聯菜單特效匯總、Javascript級聯菜單特效匯總進行學習。

如果大家還想深入學習Bootstrap,可以點擊這裡進行學習,再為大家附兩個精彩的專題:Bootstrap學習教程 Bootstrap實戰教程

本文系列教程整理到:Bootstrap基礎教程 專題中,歡迎點擊學習。

以上就是本文的全部內容,希望對大家的學習有所幫助。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved