使用原生js动态生成Select,根据前面的Select的option生成二级Select

来源:互联网 发布:零起点学算法 编辑:程序博客网 时间:2024/05/18 05:44

使用原生JS动态生成Select,根据前面的Select的option生成二级Select

需求描述:

  1. 后台数据会把第一层的Select的option数据 传递给前台页面,页面根据数据的有无创建第一个Select
  2. 如果后台有数据,则根据第一个Select选中的option 下面是否有数据 生成第二个Select。当点击第一个个Select的option的时候会想后台发送数据请求,后台根据数据库的返回给前台。
  3. 点击第二个Select的option的逻辑和点击第一个Select是一样的
  4. 如果存在3个select,点击第一级的select中的某一个option,如果该option没有请求到数据,则第二个和第三个select会消失

    代码步骤

    在请求这个页面的时候就会查询出数据返回给当前的页面,页面是使用vm模版的,以下是使用的标签

   <div class="col-xs-4">                            <select id="rootId" onchange="getTypData()">                                <option>                                    ==请选择类型==                                </option>                                #foreach ($root in $!{roots})                                    <option id="${root.route}" name="${root.name}" value="$!{root.route}">                                        $!{root.name}                                    </option>                                #end                            </select>    </div>   </select>

监听Select的onChange事件,实现getTypeData()

function getTypData(route) {        var params = {};        if (typeof(route) == "undefined" || route.length == 0) {            var objS = document.getElementById("rootId");            var index = objS.selectedIndex;            if (index == 0) {                params.isNull = true;                params.route = objS.options[objS.selectedIndex + 1].id;            } else {                params.route = objS.options[objS.selectedIndex].id;            }        } else {            params.route = route;        }        var url = "/doceditor/nextParentType";        jQuery.ajax({            url: url,            type: "POST",            cache: false,            async: true,            dataType: "json",            data: params,            success: function (data) {                if (data != null && data.ok) {                    var types = data.context.types;                    var level = data.context.level;                    createSelect(types, level);                }            }, ajaxError: function () {                bapBase.alert("文本类型", "接口调用失败!");            },            complete: function () {                hideWaiting();                query();            },            beforeSend: function () {                showWaiting();            }        });    }

因为第一个option是 “ ==请选择类型==”所以不会携带参数过来,所以后台就会认定此前请求是第几层的第一个元素,此方法的作用就是为了点击option发送请求然后获取后台数据。判断是否生成下一个select。

在接收到数据之后就要考虑是否创建下一个select。实现createSelect()方法

function createSelect(types, level) {        //level 作为class的标记        if (types !== null && types !== undefined && types !== '' && types.length > 2) {            //获取父控件div            var divParentContext = document.getElementById("divContext");            //获取所有的子节点            var allDivChild = divParentContext.childNodes;            //获取当前div所在的下标            var index;            if (level != null && level.length > 0) {                //获取到当前的index                index = level;            } else {                //定义div,非创建的                index = 0;            }            //删除当前div以后的 div            for (var i = allDivChild.length, len = index; i > len; i--) {                divParentContext.removeChild(allDivChild[i - 1]);            }            //创建包裹select的div            var divChidContext = document.createElement("div");            var claz = "";            //拼接class的值            for (var i = 0; i < level; i++) {                claz = i;            }            divChidContext.setAttribute("class", claz);            //创建Select控件            var mySelect = document.createElement("select");            mySelect.setAttribute("class", claz);            //子div添加select            divChidContext.appendChild(mySelect);            //父div 添加子节点div            divParentContext.appendChild(divChidContext);            var type = JSON.parse(types);            var firstChild = new Option(" ==请选择类型==", "");            mySelect.options.add(firstChild);            for (var i in type) {                //创建slect的option                var optionChild = new Option(type[i].name, type[i].route);                mySelect.options.add(optionChild);            }            mySelect.addEventListener("change", function () {//onchange改为change                var index = this.selectedIndex; // 选中索引                var route = this.options[index].value; // 选中值                getTypData(route);            }, false);        } else if (types.length == 2) {            //获取父控件div            var divParentContext = document.getElementById("divContext");            //获取所有的子节点            var allDivChild = divParentContext.childNodes;            //获取当前div所在的下标            var index;            if (level != null && level.length > 0) {                //切割最后一个获取到当前的index                index = level;            } else {                //定义div,非创建的                index = 0;            }            //删除当前div以后的 div            for (var i = allDivChild.length, len = index; i > len; i--) {                divParentContext.removeChild(allDivChild[i - 1]);            }        }    }

逻辑很简单,就是判断type的有无,type是后台处理此次请求返回的数据,如果没有数据和有数据的两种处理方式。
1.有数据,就开始创建Select,创建逻辑也很简单,一层一层的创建,获取父div,在获取父div下所有的div,然后删除当前div以后的所有的div,然后在创建新的div,在div 里面创建select,在select里面填充携带的数据创建option.唯一特别的一点就是这个clazz,这个clazz,就是为了和type挂钩,能够清楚简单的获取到当前所处的div的位置,从而删除当前div以后的所有div。这个程序的唯一点就是这里。这个标识在后台已经定义好了,比如说,第一层的select的第一个option的clazz 就是1或者2或者3。点击第一个option请求数据,假如有数据则第二个select的clazz就是1-4,一次类推
这里写图片描述

不这样也可以,随便你只要每次请求有动态生成而且你知道的clazz就可以了

2.没有数据就认定这个是 “ ==请选择类型==”那就删除以后的div就可以了

本来没想写这个博客的,我自己的JS不是很熟练,而且也可以看出来,我不擅长使用JQury。之所以写是因为这个需求,因为网上基本上不是啥级联表什么的,就是使用ztree什么库就可以搞定的,如果你要是遇见我这样的需求,直接拿过去用,思路很简单,而且代码都是原生的js,不怕你看不懂

原创粉丝点击