Imitating bootstrap tagsinput autocomplete function

Posted by iacataca on Wed, 01 Jan 2020 06:33:49 +0100

Demand analysis:

1. Independent function, that is, a page can have multiple input boxes with the same function

2. There are various functional requirements, and there are differences in the maximum number and data form

3. After completion of input, data interaction with the background (pass id)

4. Click delete or delete to remove the target

Train of thought:

1. Page structure: in a div, there are four parts: the selected element, input input box, hidden info (used in the background, hidden), and select drop-down box (hidden / displayed, JS controlled). There is at most one select drop-down box in the page.

<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. When the input gets the focus, the value changes, does not exceed the maximum number, and always guarantees that the value is not empty, the data source is requested.

3. After checking, check whether the selected value is in the selected list (ids is an array of all tags, use ids. Indexof (hidden ID) = = - 1 to judge). If it is, give a prompt; otherwise, it becomes a non string dom node, which is filled in the div. to be specific, it is inserted in front of the input input box ($(new node). innerBefore (target node)), and hide the select drop-down Box. Remember to always read what is already on the page, rather than temporarily adding new content.

JavaScript code:

  //The onpropertychange event is added for ie compatibility
  //As an event agent, the dynamically added dom node can also realize the binding function
  //Autocomplete by name only display name
  //Mul autocomplete can fill in multiple elements
  $(".autocomplete").on('input onpropertychange', function () {
    var $this = $(this),
        val = $this.val();

    //Remove other drop-down options from the page
    if ($('.select-box').length > 0) {
      $('.select-box').remove();
    }

    //The input is not empty and less than the allowed number of inputs
    if (val.length > 0 && maxnum($this, $this.data('num'))) {
      $.ajax({
        url: "/tool/getpy/",
        type: 'get',
        datatype: 'json',
        data: {
          py: $this.val()
        },
        success: function (data) {
          //Add dropdown node
          $this.parent().append('<ul class="select-box u-menu u-menu-max"></ul>');

          //Adjust dropdown style
          $('.select-box').css('width', $this.closest('.ui-autocomplete').width())

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

          //The drop-down box is initialized (cleared) every time the input changes
          $selectBox.html('');

          //Traverse all dropdown options
          $.map(data, function (item) {
            var $this = $(this);

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

              //Determine the type of 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) {//Keyboard control
    if (e.keyCode == 8 && $(this).val().length == 0) {
      //Remove target, method 1: delete key
      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);
    }
  });

  //Remove the target by clicking '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();
  });

  //When the dropdown box option is selected
  $('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 empties
    $autoInput.val('');

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

      ids.push(hiddenID);
    });

    //Judge whether it has been added according to the hiddenID. If yes, it will prompt that it has been selected. Otherwise, change the selected data into a label element and add it to the 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+'Already in the list!');
    }

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

  //Number of control options
  function maxnum(ele, num) {
    var ids = ele.closest('.ui-autocomplete').find('.autocomplete-tags');

    if (num && ids.length >= num) {//Maximum quantity limit set and exceeded
      alert('Most choice' + num + 'Options');
      $('.autocomplete').val('');
      return false;
    } else {
      return true;
    }
  }

 

Topics: Javascript IE less JSON