How to sort the dropdown using Bootstrap Tagsinput?

1.6k views Asked by At

I'm using bootstrap tagsinput to display some values, but I'm not being able to order them once the user start searching. It's showing the values ascending, but I need it descending.

I didn't find any method or any way to sort it there.

Is it possible to sort using tagsinput?

1

There are 1 answers

0
Phani Kumar M On

The below will sort the tags input once an item is added. The HTML element sorting code is taken from Link. OnItemAdded event will sort the relevant spans. You can update the relevant code to sort based on user searching.

$(function () {
  $('#name').tagsinput({
    tagClass: 'label label-default label-slow',
    trimValue: true,
    allowDuplicates: true,
    freeInput: true
  });

  $('input').on('itemAdded', function () {
    $('.bootstrap-tagsinput > span').sortElements(function (a, b) {
      return $(a).text() < $(b).text() ? 1 : -1;
    });
  });
});

/**
 * jQuery.fn.sortElements
 * --------------
 * @param Function comparator:
 *   Exactly the same behaviour as [1,2,3].sort(comparator)
 *   
 * @param Function getSortable
 *   A function that should return the element that is
 *   to be sorted. The comparator will run on the
 *   current collection, but you may want the actual
 *   resulting sort to occur on a parent or another
 *   associated element.
 *   
 *   E.g. $('td').sortElements(comparator, function(){
 *      return this.parentNode; 
 *   })
 *   
 *   The <td>'s parent (<tr>) will be sorted instead
 *   of the <td> itself.
 */
    jQuery.fn.sortElements = (function () {
      var sort = [].sort;
      return function (comparator, getSortable) {
        getSortable = getSortable || function () { return this; };
        var placements = this.map(function () {
          var sortElement = getSortable.call(this),
            parentNode = sortElement.parentNode,
            // Since the element itself will change position, we have
            // to have some way of storing its original position in
            // the DOM. The easiest way is to have a 'flag' node:
            nextSibling = parentNode.insertBefore(
              document.createTextNode(''),
              sortElement.nextSibling
            );
          return function () {
            if (parentNode === this) {
              throw new Error(
                "You can't sort elements if any one is a descendant of another."
              );
            }
            // Insert before flag:
            parentNode.insertBefore(this, nextSibling);
            // Remove flag:
            parentNode.removeChild(nextSibling);
          };
        });

        return sort.call(this, comparator).each(function (i) {
          placements[i].call(getSortable.call(this));
        });
      };
    })();
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-tagsinput/0.8.0/bootstrap-tagsinput.min.js"></script>
<style type="text/css">
.bootstrap-tagsinput {
  background-color: #ffffff;
  border: 1px solid #cccccc;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  transition: border linear 0.2s, box-shadow linear 0.2s;
  display: inline-block;
  padding: 4px 6px;
  margin-bottom: 10px;
  color: #555555;
  vertical-align: middle;
  border-radius: 4px;
  max-width: 100%;
  line-height: 22px; }
  .bootstrap-tagsinput input {
    border: none;
    box-shadow: none;
    background-color: transparent;
    padding: 0;
    margin: 0;
    width: auto !important;
    max-width: inherit; }
    .bootstrap-tagsinput input:focus {
      border: none;
      box-shadow: none; }
  .bootstrap-tagsinput .tag {
    margin-right: 5px;
    color: white; }
    .bootstrap-tagsinput .tag [data-role="remove"] {
      margin-left: 8px;
      cursor: pointer; }
      .bootstrap-tagsinput .tag [data-role="remove"]:after {
        content: "x";
        padding: 0px 2px; }
      .bootstrap-tagsinput .tag [data-role="remove"]:hover {
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); }
        .bootstrap-tagsinput .tag [data-role="remove"]:hover:active {
          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); }
  .bootstrap-tagsinput .icon-white {
    margin-left: 5px; }
</style>

<input type="text" value="Amsterdam,Washington,Sydney,Beijing,Cairo" data-role="tagsinput" />