text: /*
  * @version: 1.2
  * @Author:  tomato
  * @Date:    2018-4-24 22:56:00
  * @Last Modified by:   tomato
  * @Last Modified time: 2018-5-26 18:08:43
  */
  //无限级下拉框
  layui.define(['jquery', 'form'], function (exports) {
      var MOD_NAME = 'selectN';
      var $ = layui.jquery;
      var form = layui.form;
      var obj = function (config) {
          //当前选中数据值名数据
          this.selected = [];
          //当前选中的值
          this.values = [];
          //当前选中的名
          this.names = [];
          //当前选中最后一个值
          this.lastValue = '';
          //当前选中最后一个值
          this.lastName = '';
          //是否已选
          this.isSelected = false;
          //初始化配置
          this.config = {
              //选择器id或class
              elem: '',
              //无限级分类数据
              data: [],
              //默认选中值
              selected: [],
              //空值项提示，可设置为数组['请选择省','请选择市','请选择县']
              tips: '请选择',
              //是否允许搜索，可设置为数组[true,true,true]
              search: false,
              //选择项宽度，可设置为数组['80','90','100']
              width: null,
              //为真只取最后一个值
              last: false,
              //值验证，与lay-verify一致
              verify: '',
              //事件过滤器，lay-filter名
              filter: '',
              //input的name 不设置与选择器相同(去#.)
              name: '',
              //数据分隔符
              delimiter: ',',
              //数据的键名 status=0为禁用状态
              field: { idName: 'id', titleName: 'name', statusName: 'status', childName: 'children' },
              //多表单区分 form.render(type, filter); 为class="layui-form" 所在元素的 lay-filter="" 的值
              formFilter: null
          }
  
          //实例化配置
          this.config = $.extend(this.config, config);
  
          //“请选择”文字
          this.setTips = function () {
              var o = this, c = o.config;
              if (Object.prototype.toString.call(c.tips) != '[object Array]') {
                  return c.tips;
              }
              else {
                  var i = $(c.elem).find('select').length;
                  return c.tips.hasOwnProperty(i) ? c.tips[i] : '请选择';
              }
          }
  
          //设置是否允许搜索
          this.setSearch = function () {
              var o = this, c = o.config;
              if (Object.prototype.toString.call(c.search) != '[object Array]') {
                  return c.search === true ? 'lay-search ' : ' ';
              }
              else {
                  var i = $(c.elem).find('select').length;
                  if (c.search.hasOwnProperty(i)) {
                      return c.search[i] === true ? 'lay-search ' : ' ';
                  }
              }
              return ' ';
          }
  
          //设置是否允许搜索
          this.setWidth = function () {
              var o = this, c = o.config;
              if (Object.prototype.toString.call(c.width) != '[object Array]') {
                  return /^\d+$/.test(c.width) ? 'style="width:' + c.width + 'px;" ' : ' ';
              }
              else {
                  var i = $(c.elem).find('select').length;
                  if (c.width.hasOwnProperty(i)) {
                      return /^\d+$/.test(c.width[i]) ? 'style="width:' + c.width[i] + 'px;" ' : ' ';
                  }
              }
          }
  
          //创建一个Select
          this.createSelect = function (optionData) {
              var o = this, c = o.config, f = c.field;
              var html = '';
              html += '<div class="layui-input-inline" ' + o.setWidth() + '>';
              html += ' <select ' + o.setSearch() + 'lay-filter="' + c.filter + '">';
              html += '  <option value="">' + o.setTips() + '</option>';
              for (var i = 0; i < optionData.length; i++) {
                  var disabled = optionData[i][f.statusName] == 0 ? 'disabled="" ' : '';
                  html += '  <option ' + disabled + 'value="' + optionData[i][f.idName] + '">' + optionData[i][f.titleName] + '</option>';
              }
              html += ' </select>';
              html += '</div>';
              return html;
          };
  
          //获取当前option的数据
          this.getOptionData = function (catData, optionIndex) {
              var f = this.config.field;
              var item = catData;
              for (var i = 0; i < optionIndex.length; i++) {
                  if ('undefined' == typeof item[optionIndex[i]]) {
                      item = null;
                      break;
                  }
                  else if ('undefined' == typeof item[optionIndex[i]][f.childName]) {
                      item = null;
                      break;
                  }
                  else {
                      item = item[optionIndex[i]][f.childName];
                  }
              }
              return item;
          };
  
          //初始化
          this.set = function (selected) {
              var o = this, c = o.config;
              $E = $(c.elem);
              //创建顶级select
              var verify = c.verify == '' ? '' : 'lay-verify="' + c.verify + '" ';
              var html = '<div style="height:0px;width:0px;overflow:hidden"><input ' + verify + 'name="' + c.name + '"></div>';
              html += o.createSelect(c.data);
              $E.html(html);
              selected = typeof selected == 'undefined' ? c.selected : selected;
              var index = [];
              for (var i = 0; i < selected.length; i++) {
                  //设置最后一个select的选中值
                  $E.find('select:last').val(selected[i]);
                  //获取该选中值的索引
                  var lastIndex = $E.find('select:last').get(0).selectedIndex - 1;
                  index.push(lastIndex);
                  //取出下级的选项值
                  var childItem = o.getOptionData(c.data, index);
                  //下级选项值存在则创建select
                  if (childItem) {
                      var html = o.createSelect(childItem);
                      $E.append(html);
                  }
              }
              form.render('select', c.formFilter);
              o.getSelected();
          };
  
          //下拉事件
          this.change = function (elem) {
              var o = this, c = o.config;
              var $thisItem = elem.parent();
              //移除后面的select
              $thisItem.nextAll('div.layui-input-inline').remove();
              var index = [];
              //获取所有select，取出选中项的值和索引
              $thisItem.parent().find('select').each(function () {
                  index.push($(this).get(0).selectedIndex - 1);
              });
  
              var childItem = o.getOptionData(c.data, index);
              if (childItem) {
                  var html = o.createSelect(childItem);
                  $thisItem.after(html);
                  form.render('select', c.formFilter);
              }
              o.getSelected();
          };
  
          //获取所有值-数组 每次选择后执行
          this.getSelected = function () {
              var o = this, c = o.config;
              var values = [];
              var names = [];
              var selected = [];
              $E = $(c.elem);
              $E.find('select').each(function () {
                  var item = {};
                  var v = $(this).val()
                  var n = $(this).find('option:selected').text();
                  item.value = v;
                  item.name = n;
                  values.push(v);
                  names.push(n);
                  selected.push(item);
              });
              o.selected = selected;
              o.values = values;
              o.names = names;
              o.lastValue = $E.find('select:last').val();
              o.lastName = $E.find('option:selected:last').text();
  
              o.isSelected = o.lastValue == '' ? false : true;
              var inputVal = c.last === true ? o.lastValue : o.values.join(c.delimiter);
              $E.find('input[name="' + c.name + '"]').val(inputVal);
          };
          //ajax方式获取候选数据
          this.getData = function (url) {
              var d;
              $.ajax({
                  url: url,
                  dataType: 'json',
                  async: false,
                  success: function (json) {
                      d = json;
                  },
                  error: function () {
                      console.error(MOD_NAME + ' hint：候选数据ajax请求错误 ');
                      d = false;
                  }
              });
              return d;
          }
      };
  
      //渲染一个实例
      obj.prototype.render = function () {
          var o = this, c = o.config;
          $E = $(c.elem);
          if ($E.length == 0) {
              console.error(MOD_NAME + ' hint：找不到容器 ' + c.elem);
              return false;
          }
          if (Object.prototype.toString.call(c.data) != '[object Array]') {
              var data = o.getData(c.data);
              if (data === false) {
                  console.error(MOD_NAME + ' hint：缺少分类数据');
                  return false;
              }
              o.config.data = data;
          }
  
          c.filter = c.filter == '' ? c.elem.replace('#', '').replace('.', '') : c.filter;
          c.name = c.name == '' ? c.elem.replace('#', '').replace('.', '') : c.name;
          o.config = c;
  
          //初始化
          o.set();
  
          //监听下拉事件
          form.on('select(' + c.filter + ')', function (data) {
              o.change($(data.elem));
          });
          //验证失败样式
          $E.find('input[name="' + c.name + '"]').focus(function () {
              var t = $(c.elem).offset().top;
              $('html,body').scrollTop(t - 200);
              $(c.elem).find('select:last').addClass('layui-form-danger');
              setTimeout(function () {
                  $(c.elem).find('select:last').removeClass('layui-form-danger');
              }, 3000);
          });
      }
  
      //输出模块
      exports(MOD_NAME, function (config) {
          var _this = new obj(config);
          _this.render();
          return _this;
      });
  });