仿bootstrap tagsinput autocomplete功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41355260/article/details/82663136

需求分析:

1、功能独立,即一个页面可以有多个功能相同的输入框

2、功能需求多样,存在最大数目、数据形式的区别

3、完成输入后,与后台的数据交互问题(传id)

4、点击删除键或者删除按钮都能移除目标

思路:

1.页面结构:在一个div中,包含已经选择的元素、input输入框、hidden-info(后台用,隐藏)、select下拉框(隐藏/显示,JS控制)四部分。页面中至多有一个select下拉框。

<div class="ui-autocomplete">
  <div class="autocomplete-box">
    <input type="text" class="autocomplete autocomplete-by-name  mul-autocomplete" data-num="4" />
    <input class="hidden-info hide hidden" type="text" value="" />
  </div>
</div>

2.input获得焦点,值有变化,未超过最大数量,且始终保证值不为空时,请求数据源  。

3.选中后,检查选中的值是否在已经选过的列表中(ids为所有tags组成的数组,使用ids.indexOf(hiddenID)==-1判断),若在,给出提示;否则,变成非字符串的dom节点,填充在div中,确切的说,是插入在input输入框的前面($(新节点).innerBefore(目标节点)),隐藏select下拉框。切记,永远读取页面已有的内容,而不是临时添加新内容。

JavaScript代码:


  //添加onpropertychange事件是为了兼容ie
  //做事件代理,使得动态添加的dom节点也能实现绑定的功能
  //autocomplete-by-name 只显示名称
  //mul-autocomplete  可填写多个元素
  $(".autocomplete").on('input onpropertychange', function () {
    var $this = $(this),
        val = $this.val();

    //去掉页面其他的下拉选项框
    if ($('.select-box').length > 0) {
      $('.select-box').remove();
    }

    //输入不为空且少于允许的输入数目
    if (val.length > 0 && maxnum($this, $this.data('num'))) {
      $.ajax({
        url: "/tool/getpy/",
        type: 'get',
        datatype: 'json',
        data: {
          py: $this.val()
        },
        success: function (data) {
          //添加下拉框节点
          $this.parent().append('<ul class="select-box u-menu u-menu-max"></ul>');

          //调整下拉框样式
          $('.select-box').css('width', $this.closest('.ui-autocomplete').width())

          var $selectBox = $this.siblings('.select-box');

          //每一次input变化下拉框都会初始化(清空)
          $selectBox.html('');

          //遍历所有下拉框选项
          $.map(data, function (item) {
            var $this = $(this);

            if ($this.length > 0) {
              $selectBox.show();

              //判断autocomplete的类型
              if ($('.autocomplete').hasClass('autocomplete-by-name')) {
                $selectBox.append(('<li class="ui-menu-item" id=' + item.unid + '>' + item.name + '</li>'));
              } else {
                $selectBox.append(('<li class="ui-menu-item" id=' + item.unid + '>' + item.name + '(' + item.sex + '/' + item.dw + ')' + '</li>'));
              }
            }
          });;

        }
      });
    }
  }).on('keydown', function (e) {//键盘控制
    if (e.keyCode == 8 && $(this).val().length == 0) {
      //移除目标,方法一:删除键
      var ids = [];

      $(this).prev().remove();
      $(this).closest('.ui-autocomplete').find('.autocomplete-tags').each(function () {
        var $this = $(this),
            hiddenID = $this.attr('id');

        ids.push(hiddenID);
        console.log(ids);
      });
      // console.log(ids);
      $(this).closest('.ui-autocomplete').find('.hidden-info').val(ids);
    }
  });

  //移除目标,方法二:点击'x'
  $('.autocomplete-box').on('click', '.remove', function () {
    var $this = $(this),
        ids = [];
   
    $this.parent().siblings('.autocomplete-tags').each(function () {
      var $this = $(this),
          hiddenID = $this.attr('id');

      ids.push(hiddenID);
      //console.log(ids);
    });

    $this.closest('.ui-autocomplete').find('.hidden-info').val(ids);
    $this.parent().remove();
  });

  //当下拉框选项被选中
  $('body').on('click', '.select-box .ui-menu-item', function () {
    var $this = $(this),
        $selectBox = $('.select-box'),
        $autoInput = $this.parent().siblings('.autocomplete'),
        current = $this.text(),
        hiddenID = $this.attr('id'),
        ids = [];

    //input清空
    $autoInput.val('');

    $this.closest('.ui-autocomplete').find('.autocomplete-tags').each(function () {
      var $this = $(this),
          current = $this.text(),
          hiddenID = $this.attr('id');

      ids.push(hiddenID);
    });

    //根据hiddenID判断是否已经被添加过,若有,提示已选择,否则再将选择的数据变成label元素添加到div中 
    if (ids.indexOf(hiddenID) == -1) {
      $('<label class="autocomplete-tags" id="' + hiddenID + '">' + current + '<a class="remove">x</a></label>').insertBefore($autoInput);
      ids.push(hiddenID);
      $this.closest('.ui-autocomplete').find('.hidden-info').val(ids);
    } else {
      alert(current+'已在列表中!');
    }

    $selectBox.hide();
    return false;
  });

  //控制选项数目
  function maxnum(ele, num) {
    var ids = ele.closest('.ui-autocomplete').find('.autocomplete-tags');

    if (num && ids.length >= num) {//设置了最大数量限制且超过
      alert('最多选择' + num + '个选项');
      $('.autocomplete').val('');
      return false;
    } else {
      return true;
    }
  }

注意:

1、移除元素放在与该元素有关操作的最后一步操作

2、insertBefore()

猜你喜欢

转载自blog.csdn.net/weixin_41355260/article/details/82663136
今日推荐