解决jq.autocomplete.js插件在三级联动中由于异步请求表单验证卡顿出错问题

效果如下图所示:

 html布局:

<div class="form-group">
  <label class="col-sm-3 control-label"><span class="must">*</span>&nbsp;所属景区:</label>
  <div class="col-sm-8">
    <!-- 省份 -->
    <select class="form-control m-b city-selsect small" style=" 20%;margin-right: 5px;" name="prov_id" id="prov_id">
      <option value="0" selected style="display:none;" disabled>省份</option>
      <{foreach from=$prov item="vo"}>
      <option value="<{$vo.id}>"><{$vo.name}></option>
      <{/foreach}>
    </select>
    <!-- 城市 -->
    <select class="form-control m-b city-selsect small" style=" 20%;margin-right: 5px;" name="city_id" id="city_id">
      <option value="0" selected style="display:none;" disabled>城市</option>
      <{foreach from=$city item="vo"}>
      <option value="<{$vo.id}>"><{$vo.name}></option>
      <{/foreach}>
    </select>
    <!-- 景区 -->
    <input type="hidden" name="scenic_id" id="scenic_id">
    <input type="text" name="scenic_name" id="scenic_name" style=" 20%;margin-right: 5px;" placeholder="请输入景区"  class="form-control m-b city-selsect small" style=" 18%;"  required>
    <a id="goAddScenic" class="unshow" href="javascrip:void(0)" onclick="goAddScenic()">前往添加景区</a>
    <span class="tip"></span>
  </div>
</div>

 表单验证自定义规则:

// 所属景区验证
jQuery.validator.addMethod('isSenic',function(value,element){
  var flag = false
  // 根据请求结果进行景区是否已添加的判断
  for(var i = 0;i<scenicArr.length;i++){
    if(scenicArr[i].name == '暂无相关景区'){
      flag = false
      break
    } if(scenicArr[i].name == $('#scenic_name').val()){       flag = true       break     }     flag = false   }   if(flag==false){     $('#goAddScenic').removeClass('unshow')   }else{     $('#goAddScenic').addClass('unshow')   }   return flag },'暂无相关景区,请先添加景区')

$('#addTicketBaseForm').validate({
  errorPlacement: function (error, element) {
    error.appendTo(element.parents(".form-group").find("span.tip"));
  },
  ignore: '',
  rules:{
    scenic_name:{
      required: true,
      isSenic: true
    }
  },
  messages:{
    scenic_name:{
      required:'<i class="fa fa-exclamation"></i> 请输入所属景区',
      isSenic:'<i class="fa fa-exclamation"></i> 暂无相关景区,请先添加景区'
    }
  }
})

省市联动

//省份城市联动
$("#prov_id").change(function(){
  var prov_id=$("#prov_id").find("option:selected").val();
  $.ajax({
    type: "post",
    url: "__APP__/Public/getCityList",
    data: "prov_id=" + prov_id,
    dataType: "json",
    success: function(json){
      if(json.status==1){
        $("#city_id").empty();
        var str='<option value="0" selected style="display:none" disabled>城市</option>';
        for(var i=0; i<json.data.length; i++){
          str+='<option value="'+json.data[i]['id']+'">'+json.data[i]['name']+'</option>';
        }
        $("#city_id").append(str);
        //清空景区
        $("#scenic_name").empty();
        var str='<option value="0">景区</option>';
        $("#scenic_name").append(str);
      }
    }
  });
});

城市景区联动:

var scenicArr = [] // 全局保存当前匹配的所有景区
//城市景区联动
$('#city_id').change(function(){
  $('#scenic_name').val('')
  $('#scenic_id').val('')
  var prov_id = $("#prov_id").find("option:selected").val();
  var city_id = $("#city_id").find("option:selected").val();
  $.ajax({
    type: "post",
    url: "__APP__/Public/getScenicList",
    data: "prov_id=" + prov_id + '&city_id=' + city_id,
    dataType: "json",
    success: function(json){
      if(json.status==1){
        scenicArr = json.data
        autoComplete(scenicArr)
      }
    }
  });
});

景区自动填充:

// 自动填充本地获取数据
function autoComplete(params){
  $('#scenic_name').autocomplete(scenicArr, {
    minChars: 0,
     '12.5%',
    matchCase:false,//不区分大小写
    scroll: true,
    dataType: 'json',    
    scrollHeight: 400,
    delay:100,
    matchContains: true,//是否只要包含文本框里的就可以
    formatItem: function(data, i, total) {  // 格式化列表中的条目;row:条目对象,i:当前条目数,total:总条目数
      // 没有景区时,修改默认提示词 undefined
      if
(data[0]== "No Records."){         return `<button data-id="${data.scenic_id}" disabled>暂无相关景区</button>`;       }else{         return `<p data-id="${data.scenic_id}">${data.name}</p>`;       }     },     formatMatch: function(data, i, total) {       return data.name;     },     formatResult: function(data, value) {       return data.name;     }
  }).result(
function(event, data, formatted) { //回调       $("#scenic_name").val(data.name);       $("#scenic_id").val(data.scenic_id);       // 选中时进行表单验证       $('#addTicketBaseForm').validate().element($("#scenic_name"))     }); }

总结:

城市景区联动时全局保存当前城市所有景区,避免每次都要重新请求获取景区,减少请求次数

原文地址:https://www.cnblogs.com/plb2307/p/11753632.html