Bootstrap每天必学之级联下拉菜单
来源: 阅读:1192 次 日期:2016-07-15 16:21:17
温馨提示: 小编为您整理了“Bootstrap每天必学之级联下拉菜单”,方便广大网友查阅!

本文将介绍自定义的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();

    }

  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助。

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map