Bootstrap每天必学之级联下拉菜单
前端之家 收集整理的这篇文章主要介绍了
Bootstrap每天必学之级联下拉菜单 ,
前端之家 小编觉得挺不错的,现在分享给大家,也给大家做个参考。
本文将介绍自定义 的bootstrap级联下拉菜单 ,主要应用场合有省市级关联菜单 等等,那么就先拿这个例子来讲,当然其他场景的关联菜单 也同样适用。说实话,封装好一个通用的组件还是需要花费很多精力的和时间的,所谓通用,自然要考虑周全,叹!这次整理的Bootstrap关联select,里面也涉及到了很多jquery、ajax、springMVC等等知识点,可谓包罗万象!
首先,请允许我代表该自定义 组件做一番小小的介绍。
“hi,你好,我叫yunm.comBox .js,主人给我起的名字,其实呢,挺俗的。我主要通过为select组件增加 两个自定义 属性 来完成相应的数据加载,数据请求使用了ajax,后端数据处理使用了springMVC(当然其他方式也可以,只需要返回对应的json数据即可),使用起来呢,就非常非常简单了!”
当然了,从界面上完全看不出来一个组件封装的好坏,但至少,你感觉很简洁漂亮,那么好了,有了这层印象,你是否有兴趣继续看下去?我想答案是肯定的。
①、procity.jsp
首先呢,在页面 上加载yunm.comBox .js(稍候介绍,至于其他的bootstrap的css和js,不在本章介绍范围内,略过),同时呢,创建两个select,具体格式见如下:
Box.js">
Box" ref="city_select"
refUrl="${ctx}/procity?pro_code={value}&city_code=HSLY">
·两个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
现在我们来看看关键的组件内容 吧!
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 + '';
}
});
$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',url : refUrl,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这种方法 获取 ,那么先预览一下代码 吧!
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 citys = CityService.getInstance().getCitysByProvincialId(pro_id);
List coptions = new ArrayList (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 provincials = ProvincialService.getInstance().getProvincials();
// 转换成标准的option属性 (name,value,selected)
List options = new ArrayList (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
只贴出来代码 例子,不做详细解释,毕竟不是本章重点。
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();
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 provincials = null;
public List 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方法
404
*/
protected void renderJson(HttpServletResponse response,Object respon
SEO bject) {
PrintWriter out = null;
try {
if (respon
SEO bject == null) {
response.sendError(
404 );
return;
}
// 将实体对象转换为JSON Object转换
String responseStr = JsonUtil.toJson(respon
SEO bject);
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();
}
}
}
如果大家还想深入学习,可以点击、 进行学习。
如果大家还想深入学习Bootstrap,可以点击进行学习,再为大家附两个精彩的专题:
本文系列教程整理到: 专题中,欢迎点击学习。
以上就是本文的全部内容 ,希望对大家的学习有所帮助。