自己编写jQuery插件 之 无限级联下拉框

因为是级联,所以数据必须是树型结构的,我这里的测试数据如下:

看下效果图:

1.>图一:

2.>图二:

3.>图三:

  由图可知,下拉框的个数并不是写死的,而是动态加载的。每当下拉框选择改变的时候,会发送一次ajax请求,请求成功返回json格式数据,当返回的数据不为空时(即有子节点时),则会向页面中添加一个下拉框,没有则不添加。

插件的实现代码如下:

(function ($) {
    $.fn.CascadingSelect = function (options) {

        //默认参数设置
        var settings = {
            url: "/Handler.ashx",   //请求路径
            data: "0",              //初始值(字符串格式)
            split: ",",             //分割符
            cssName: "select",      //样式名称
            val: "id",              //<option value="id">name</option>
            text: "name",           //<option value="id">name</option>
            hiddenName: "selVal"    //隐藏域的name属性的值
        }

        //合并参数
        if (options)
            $.extend(settings, options);

        //链式原则
        return this.each(function () {

            init($(this), settings.data);

            /*
            初始化
            @param container    容器对象
            @param data         初始值
            */
            function init(container, data) {

                //创建隐藏域对象,并赋初始值
                var _input = $("<input type=‘hidden‘ name=‘" + settings.hiddenName + "‘ />").appendTo(container).val(settings.data);

                var arr = data.split(settings.split);
                for (var i = 0; i < arr.length; i++) {
                    //创建下拉框
                    createSelect(container, arr[i], arr[i + 1] || -1);
                }
            }

            /*
            创建下拉框
            @param container    容器对象
            @param parentid     父ID号
            @param id           自身ID号
            */
            function createSelect(container, parentid, id) {

                //创建select对象,并将select对象放入container内
                var _select = $("<select></select>").appendTo(container).addClass(settings.cssName);

                //如果parentid为空,则_parentid值为0
                var _parentid = parentid || 0;

                //发送AJAX请求,返回的data必须为json格式
                $.getJSON(settings.url, { parentid: _parentid }, function (data) {

                    //添加子节点<option>
                    addOptions(container, _select, data).val(id || -1)

                });
            }

            /*
            为下拉框添加<option>子节点
            @param container    容器对象
            @param select       下拉框对象
            @param data         子节点数据(要求数据为json格式)
            */
            function addOptions(container, select, data) {

                select.append($(‘<option value="-1">=请选择=</option>‘));

                for (var i = 0; i < data.length; i++) {
                    select.append($(‘<option  value="‘ + data[i][settings.val] + ‘">‘ + data[i][settings.text] + ‘</option>‘));
                }

                //为select绑定change事件
                select.bind("change", function () { _onchange(container, $(this), $(this).val()) });

                return select;
            }

            /*
            select的change事件函数
            @param container    容器对象
            @param select       下拉框对象
            @param id           当前下拉框的值
            */
            function _onchange(container, select, id) {

                var nextAll = select.nextAll("select");

                //如果当前select对象的值是空或-1(即:==请选择==),则将其后面的select对象全部移除
                if (!id || id == "-1") {
                    nextAll.remove();
                }

                $.getJSON(settings.url, { parentid: id }, function (data) {
                    if (data.length > 0) {
                        var _html = $("<select class=‘" + settings.cssName + "‘></select>");
                        var _select = addOptions(container, _html, data);

                        //判断当前select对象后面是否跟有select对象
                        if (nextAll.length < 1) {

                            select.after(_select); //没有则直接添加

                        } else {

                            nextAll.remove(); //有则先移除再添加
                            select.after(_select);
                        }
                    }
                    else {
                        nextAll.remove(); //没有子项则后面的select全部移除
                    }            saveVal(container); //进行数据保存,此方法必须放在回调函数里面
                });
         //saveVal(container); //如果放在这里,则会出现bug
            }

            /*
            将选择的值保存在隐藏域中,用于表单提交保存
            @param container 容器对象
            */
            function saveVal(container) {

                var arr = new Array();
                arr.push(0); //为数组arr添加元素0,父节点从0开始,所以添加0

                $("select", container).each(function () {
                    if ($(this).val() > 0) {
                        arr.push($(this).val()); //获取container下每个select对象的值,并添加到数组arr
                    }
                });

                //为隐藏域对象赋值
                $("input[name=‘" + settings.hiddenName + "‘]", container).val(arr.join(settings.split));
            }

        });
    }
})(jQuery);

注释我已经尽量写的详细了,但还是要对一些东西做下讲解。

1.> 我这里后台语言用的是C#,因此你看到的请求路径是这样的(url:"/Handler.ashx"),你用其它语言是没有问题的,但是通过ajax请求返回的数据必须是json格式的数据。

  

2.>在初始化方法 init() 中,我们向容器中放入了一个隐藏域,这个隐藏域是用来存值的,我们通过一个 saveVal() 方法为其赋值。之所以要加隐藏域,是因为我们选择的数据最终  是要保存到数据库中的,这样就会有表单提交操作,因此加个隐藏域。

  

3.>默认参数设置(settings)里面的split分割符。这里用的是逗号(,) 你也可以改用其它的,比如(-)或者(|)。它主要是用来拆分和组合所有下拉框的值的。

  拆分主要是在初始化(init)的时候,比如你给的初始值(data)不是0,而是 0,1,4  这时就会将其拆分,逐一执行创建下拉框方法 createSelect()

  组合主要是在给隐藏域赋值的时候,用分割符将各个下拉框的值拼接成一个字符串,然后赋给隐藏域。

4.>默认参数设置(settings)里面的 {val: "id", text: "name" }  。它们对应的是你返回的json对象中对应的属性名。

5.>在_onchange()方法里面有写到saveVal()执行位置的问题。之所以写在回调函数外面会出现bug,是因为$.getJSON()默认是异步的,在回调方法还没执行完时,就执行了   saveVal()方法。我们来看来bug所在:

  

  

  此时隐藏域的值是错误的,正确的值应该是 0,1,5 。由于回调函数还没执行完,也就是nextAll.remove()这个还没执行的时候,就是执行了saveVal()

DEMO的Html部分的代码:

<html>
<head>
    <title></title>
    <style type="text/css">
        *{margin:0;padding:0;}
        #box{ width:500px; margin:100px auto;}
        .select{ width:120px; height:30px; margin-right:5px;}
    </style>
</head>
<body>
    <!--容器-->
    <div id="box"></div>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.similar.cascadingselect.js" type="text/javascript"></script>
    <script type="text/javascript">
        $("#box").CascadingSelect({data:"0,1,4"});  //设置初始值为0,1,4
    </script>
</body>
</html>

运行结果:

后台代码这里就不给了,毕竟又不是每个人都用的C#....

时间: 2024-08-25 13:16:12

自己编写jQuery插件 之 无限级联下拉框的相关文章

jquery级联下拉框

$(document).ready(function(){     //找到三个下拉框     var carnameSelect = $(".carname").children("select");     var cartypeSelect = $(".cartype").children("select");     var wheeltypeSelect = $(".wheeltype").chi

JQuery和ASP.NET分别实现级联下拉框效果

在学习JQuery之前知道下拉框的级联效果可以通过asp.net控件实现,现在学习了JQuery,知道了JQuery和select也能实现.我分别举两个小例子说明这两种方法如何实现. 1.用JQuery和select来实现汽车厂商和汽车类型的联动 效果图:       逻辑分析图: html代码: [html] view plain copy <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "

Jquery+json绑定带层次下拉框(select控件)

一.实现的效果图 二.主要代码 html代码 <select id="pid" runat="server"> <option value="0" data="|0|">不选父级类</option> </select> Jquery代码 var html = ['<option value="0">不选父级模块</option>'];

本示例演示如何通过Struts2框架提供的标签,简单地实现【级联下拉框】

1.发布房屋表单页面的级联下拉框如下: 2.     进入发布页面前需要查询下拉框数据,Action代码如下: 3.     房屋发布页面JSP代码如下: <s:doubleselect>标签的属性说明: list:                     一级下拉框的数据来源集合,和Action中集合名称一样 listKey:              一级下拉框数据集合中的实体,作为value的属性名 listValue:           一级下拉框数据集合中实体,作为text的属性名

jquery模拟可输入的下拉框

//页面html <div id="select" class="select" > <ul> <c:forEach items="${movieCityList}" var="cy" varStatus="st"> <li> <a href="javascript:void(0)" onclick="selectOptio

Struts2 &lt;s:doubleselect&gt;级联下拉框 详解析

运行环境:myeclipse8.6+jboss5.1+jvm1.6 先看最后目录结构: 直接上源码: complexFormTag.jsp: <%@ page language="java" contentType="text/html; charset=gb2312"pageEncoding="gb2312"%> <%@ taglib prefix="s" uri="/struts-tags&qu

jquery的隐藏和显示——下拉框式

下拉框定义value值 后面写上onchange方法(onchange 事件会在域的内容改变时发生) 然后定义方法, 然后两个span解决.

JavaScript实现级联下拉框

<!DOCTYPE html> <html> <head> <meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title> 级联菜单 </tit

js基于json的级联下拉框

级联下拉列表是项目中常用到的.比如省市县,比如企业性质等,做成一个js通用组件, 在静态页出来后可以直接插入,将数据和html静态页做一个解耦. 贴出来抛砖引玉吧. <html> <script type="text/javascript"> /** 基于json的级联下拉列表,支持初始化 调用eg: var comboselect = ComboSelectFactory(data, 'p1', 'p2', 'p3', 'p4'); 设定下拉列表value,t