bootstrap-select动态加载数据和多级联动

最近使用bootstrap-select在做了一个地址的联动,效果图如下

在这里插入图片描述

环境相关

bootstrap 3.3.7
jquery 3.3.1
bootstrap-select 1.13.9

1、数据表结构如下

-- 地址配置表(address_config)
create table address_config
(
	option_value varchar(20) not null comment '地址编号',
	parent_id varchar(60) not null comment '父级编号',
	option_text varchar(30) comment '地址描述',
	description varchar(100) comment '描述',
	primary key (option_value, parent_id)
) COMMENT='地址配置表';

-- 初始化数据
-- 广东省
insert into address_config values('广东省','PARENT','广东省','省份');

insert into address_config values('广州市','广东省','广州市','广东省市级');

insert into address_config values('天河区','广州市','天河区','广州市县或区');
insert into address_config values('长兴街道','天河区','长兴街道','天河区街道');
insert into address_config values('元岗街道','天河区','元岗街道','天河区街道');

insert into address_config values('海珠区','广州市','海珠区','广州市县或区');

-- 云南省
insert into address_config values('云南省','PARENT','云南省','省份');

insert into address_config values('昆明市','云南省','昆明市','云南省市级');
insert into address_config values('东川区','昆明市','东川区','昆明市县或区');
insert into address_config values('嵩明县','昆明市','嵩明县','昆明市县或区');

2、Mybatis配置如下

实体

package com.flashsale.model;

public class AddressConfig {
    /**
     * 地址编号
     */
    private String optionValue;

    /**
     * 父级编号
     */
    private String parentId;

    /**
     * 地址描述
     */
    private String optionText;

    /**
     * 描述
     */
    private String description;

    /**
     * 地址编号
     * @return option_value 地址编号
     */
    public String getOptionValue() {
        return optionValue;
    }

    /**
     * 地址编号
     * @param optionValue 地址编号
     */
    public void setOptionValue(String optionValue) {
        this.optionValue = optionValue;
    }

    /**
     * 父级编号
     * @return parent_id 父级编号
     */
    public String getParentId() {
        return parentId;
    }

    /**
     * 父级编号
     * @param parentId 父级编号
     */
    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    /**
     * 地址描述
     * @return option_text 地址描述
     */
    public String getOptionText() {
        return optionText;
    }

    /**
     * 地址描述
     * @param optionText 地址描述
     */
    public void setOptionText(String optionText) {
        this.optionText = optionText;
    }

    /**
     * 描述
     * @return description 描述
     */
    public String getDescription() {
        return description;
    }

    /**
     * 描述
     * @param description 描述
     */
    public void setDescription(String description) {
        this.description = description;
    }

	@Override
	public String toString() {
		return "AddressConfig [optionValue=" + optionValue + ", parentId=" + parentId + ", optionText=" + optionText
				+ ", description=" + description + "]";
	}
}

Mapper接口

package com.flashsale.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.flashsale.model.AddressConfig;

public interface AddressConfigMapper {
	
	List<AddressConfig> selectByParentId(String parentId);
}

Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.flashsale.mapper.AddressConfigMapper">
	<resultMap id="AddressConfigMap" type="com.flashsale.model.AddressConfig">
		<id column="option_value" jdbcType="VARCHAR" property="optionValue" />
		<id column="parent_id" jdbcType="VARCHAR" property="parentId" />
		<result column="option_text" jdbcType="VARCHAR" property="optionText" />
		<result column="description" jdbcType="VARCHAR" property="description" />
	</resultMap>

	<select id="selectByParentId" resultMap="AddressConfigMap">
		select option_value, option_text
		from address_config
		where parent_id = #{parentId}
		order by description, option_value
	</select>
</mapper>

3、Service和Controller如下

Service类

package com.flashsale.service;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.flashsale.model.AddressConfig;

public interface AddressConfigService {

	List<AddressConfig> selectByParentId(String parentId);
}

Service实现类

package com.flashsale.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.flashsale.mapper.AddressConfigMapper;
import com.flashsale.model.AddressConfig;
import com.flashsale.service.AddressConfigService;

@Service("addressConfigService")
public class AddressConfigServiceImpl implements AddressConfigService {
	@Autowired
	private AddressConfigMapper addressConfigMapper;

	@Override
	public List<AddressConfig> selectByParentId(String parentId) {
		return addressConfigMapper.selectByParentId(parentId);
	}
}

Controller类

package com.flashsale.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.flashsale.helper.JsonResult;
import com.flashsale.model.AddressConfig;
import com.flashsale.service.AddressConfigService;

@RestController
@RequestMapping("/address")
public class AddressConfigController {
	@Autowired
	private AddressConfigService addressConfigService;
	
	/**
	 * 根据父级加载地址初始化数据
	 * @param parentId
	 */
	@GetMapping("/{parentId}")
	public JsonResult<AddressConfig> selectByParentId(@PathVariable("parentId") String parentId) {
		return JsonResult.success(addressConfigService.selectByParentId(parentId));
	}
}

JsonResult类

package com.flashsale.helper;

import java.util.ArrayList;
import java.util.List;

public class JsonResult<T> {
	// 状态
	private boolean success;

	// 错误码
	private String error;

	// 错误信息
	private String errorMessage;

	// 数据
	private List<T> data = new ArrayList<T>();

	// 数据总条数
	private Integer total = data != null ? data.size() : 0;

	public JsonResult() {
		super();
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public String getError() {
		return error;
	}

	public void setError(String error) {
		this.error = error;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public List<T> getData() {
		return data;
	}

	public void setData(List<T> data) {
		this.data = data;
	}

	public Integer getTotal() {
		return total;
	}

	public void setTotal(Integer total) {
		this.total = total;
	}
	
	public static <T> JsonResult<T> success() {
		return success(null);
	}
	
	public static <T> JsonResult<T> success(List<T> data) {
		JsonResult<T> jsonResult = new JsonResult<T>();
		jsonResult.success = true;
		jsonResult.error = null;
		jsonResult.errorMessage = null;
		jsonResult.data = data;
		return jsonResult;
	}
	
	public static <T> JsonResult<T> success(T row) {
		JsonResult<T> jsonResult = new JsonResult<T>();
		jsonResult.success = true;
		jsonResult.error = null;
		jsonResult.errorMessage = null;
		jsonResult.data.add(row);
		jsonResult.total = 1;
		return jsonResult;
	}
	
	public static <T> JsonResult<T> error(String error, String errorMessage) {
		JsonResult<T> jsonResult = new JsonResult<T>();
		jsonResult.success = false;
		jsonResult.error = error;
		jsonResult.errorMessage = errorMessage;
		jsonResult.data = null;
		return jsonResult;
	}
}

4、返回的JSON数据格式如下

在这里插入图片描述

5、前端页面及JS

引入相关的CSS和JS

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>用户管理</title>
		
		<link rel="stylesheet" type="text/css" href="css/plugins/bootstrap.min.css">
		<link rel="stylesheet" type="text/css" href="css/plugins/bootstrap-select.min.css">
	</head>
	<body>
        <div class="btn-group">
			<button id="btn_add" class="btn btn-primary btn-sm" data-toggle="modal" 
				data-target="#addUserModal" data-whatever="新增">
				<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
				新增
			</button>
		</div>
        <!-- 模态框(Modal) -->
		<div class="modal fade" id="addUserModal" tabindex="-1" role="dialog" aria-labelledby="addUserModalLabel" 
			aria-hidden="true" data-backdrop="static" data-keyboard="false">
		    <div class="modal-dialog" style="width:800px">
		        <div class="modal-content">
		            <div class="modal-header">
		                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
		                <h4 class="modal-title" id="addUserModalLabel"></h4>
		            </div>
		            <div class="modal-body">
		            	<form class="form-horizontal" id="userForm" method="POST" role="form" autocomplete="off">
							<div class="form-group form-inline">
								<label class="col-sm-2 control-label">地址</label>
								<div class="col-sm-8">
									<select class="selectpicker form-control" onchange="initCity()" id="province" name="province">
										<option value="">--省份--</option>
			    					</select>
			    					<select class="selectpicker form-control" onchange="initRegion()" id="city" name="city">
			    						<option value="">--城市--</option>
			    					</select>
			    					<select class="selectpicker form-control" onchange="initStreet()" id="region" name="region">
			    						<option value="">--县区--</option>
			    					</select>
			    					<select class="selectpicker form-control" id="street" name="street">
			    						<option value="">--街道--</option>
			    					</select>
								</div>
							</div>
							
							<div class="form-group">
								<label for="userEmail" class="col-sm-2 control-label"></label>
								<div class="col-sm-8">
									<input type="text" class="form-control" id="userArea" name="userArea" placeholder="输入详细地址" />
								</div>
							</div>
						</form>
		            </div>
		        </div><!-- /.modal-content -->
		    </div><!-- /.modal -->
		</div>
		
		<script src="js/plugins/jquery-3.3.1.min.js"></script>
		<script src="js/plugins/bootstrap.js"></script>
		<script src="js/plugins/bootstrap-select.min.js"></script>
		<script src="js/userInfo.js"></script>
	</body>
</html>

userInfo.js

$(document).ready(function(){
	// 地区下拉框初始化
	$("#province").selectpicker({width:130, liveSearch: true, liveSearchPlaceholder: "搜索" });
	$("#city").selectpicker({width:120, liveSearch: true, liveSearchPlaceholder: "搜索" });
	$("#region").selectpicker({width:120, liveSearch: true, liveSearchPlaceholder: "搜索" });
	$("#street").selectpicker({width:120});
	
	// 动态加载省份选项数据
	initSelectOptions("province", "PARENT");
});// onReady

/**
 * 动态生成select选项
 * @param selectId
 * @param parentId
 * @returns
 */
function initSelectOptions(selectId, parentId) {
	var selectObj = $("#" + selectId);
	$.ajax({
        url : "/flashsale/address/" + parentId,
        async : false,
        type : "GET",
        success : function(result) {
        	if (result.success) {
        		var configs = result.data;
        		selectObj.find("option:not(:first)").remove();
        		for (var i in configs) {
        			var addressConfig = configs[i];
        			var optionValue = addressConfig.optionValue;
        			var optionText = addressConfig.optionText;	
        			selectObj.append(new Option(optionText, optionValue));
        		}
        		
        		// 刷新select
    			selectObj.selectpicker('refresh');
        	} else {
        		toastr.error('获取['+ parentId + ']信息失败,原因:' + result.errorMessage);
        	}
        },
        error : function(result) {
        	toastr.error('获取['+ parentId + ']信息失败,原因:' + result.errorMessage);
        }
	});// ajax
}

/**
 * 根据选择的省份动态初始化城市options
 * @returns
 */
function initCity() {
	// 当省份变动时,初始化城市和清空县区和街道
	var provinceSel = $("#province").val();
	initSelectOptions("city", provinceSel);
	$("#region").find("option:not(:first)").remove();
	$("#region").selectpicker('refresh');
	$("#street").find("option:not(:first)").remove();
	$("#street").selectpicker('refresh');
}

/**
 * 根据选择的城市动态初始化区域options
 * @returns
 */
function initRegion() {
	// 选择城市
	var citySel = $("#city").val();
	initSelectOptions("region", citySel);
}

/**
 * 根据选择的县区动态初始化街道options
 * @returns
 */
function initStreet() {
	// 选择县区
	var regionSel = $("#region").val();
	initSelectOptions("street", regionSel);
}
  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!对于Bootstrap-select.js分组联动的实现,您可以按照以下步骤进行操作: 1. 引入必要的依赖文件:在HTML文件中引入Bootstrap-select.js和Bootstrap-select.css文件。 ```html <link rel="stylesheet" href="path/to/bootstrap-select.css"> <script src="path/to/bootstrap-select.js"></script> ``` 2. 创建下拉菜单的HTML结构:使用`<select>`元素创建下拉菜单,并为其添`data-live-search="true"`和`data-size="5"`属性,以启用搜索和设置可见选项的数量。 ```html <select class="selectpicker" data-live-search="true" data-size="5"> <option value="">请选择</option> <optgroup label="分组1"> <option value="1">选项1</option> <option value="2">选项2</option> </optgroup> <optgroup label="分组2"> <option value="3">选项3</option> <option value="4">选项4</option> </optgroup> </select> ``` 3. 初始化插件:在页面完成后,通过JavaScript代码初始化Bootstrap-select插件。 ```javascript $(document).ready(function() { $('.selectpicker').selectpicker(); }); ``` 4. 实现分组联动效果:根据您的需求,您可以使用JavaScript代码来实现下拉菜单的分组联动效果。例如,当选择某个选项时,根据该选项的值动态改变其他下拉菜单的选项。 ```javascript $('.selectpicker').on('changed.bs.select', function(e) { var selectedValue = $(this).val(); // 根据选中的值进行相应的处理 }); ``` 这样,您就可以使用Bootstrap-select.js实现分组联动的下拉菜单了。记得根据您的实际需求进行相应的调整和处理。希望对您有帮助!如果有任何问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值