skip to Main Content

I’d like to limit number characters of string in select2 in ten (10) characters, for example:

"apple", is valid.. has 5 characters
"book", is valid.. has 4 characters
"Incomprehensibilities", is invalid... has 21 characters, permited max 10 characters

I have the select2 code but I don’t know how to limit the number of characters

$("#customer_tag_ids").select2({
    maximumSelectionLength: 5,
    multiple: true,
    tags: true,
    tokenSeparators: [',', ' '],
    createTag: function (params) {
      if (params.term.match(/^(?![d ])[a-zd ]*$/i)) {
        // Return null to disable tag creation
        return {
          id: params.term,
          text: params.term,
          tag: true
        }
      }
      return null;
    },
    language: {
      maximumSelected: function (e) {
        return I18n.t('customers.alert.limit_max');
      },

      inputTooShort: function (e) {
        return I18n.t('customers.alert.limit_min');
      },

      noResults: function(){
        return I18n.t('customers.alert.not_result_found');
      }
    },
  });

2

Answers


  1. You can achieve this by setting the maxlength attribute of the class .select2-search__field in the select2:open event.

    e.g.

    $("#customer_tag_ids").select2({
      maximumSelectionLength: 5,
      multiple: true,
      tags: true,
      tokenSeparators: [',', ' '],
      createTag: function(params) {
        if (params.term.match(/^(?![d ])[a-zd ]*$/i)) {
          // Return null to disable tag creation
          return {
            id: params.term,
            text: params.term,
            tag: true
          }
        }
        return null;
      },
      language: {
        maximumSelected: function(e) {
          return I18n.t('customers.alert.limit_max');
        },
    
        inputTooShort: function(e) {
          return I18n.t('customers.alert.limit_min');
        },
    
        noResults: function() {
          return I18n.t('customers.alert.not_result_found');
        }
      },
    });
    
    // This limits the select2 input to 10 characters
    $('#customer_tag_ids').select2().on('select2:open', function() {
        $('.select2-search__field').attr('maxlength', 10);
    });
    #customer_tag_ids { width: 300px }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
    
    <select id="customer_tag_ids">
        <option value="text-1">Text 1</option>
        <option value="text-2">Text 2</option>
    </select>
    Login or Signup to reply.
  2. I modified your createTag option to prevent user input text that has more than 10 chars. Also I added a div tag below to give a warning message whenever the user want to create a new tag.

    Another solution

    At first I thought that we can use the event select2:selecting

    select2:selecting Triggered before a result is selected. This event can be prevented.

    That means you can catch the event $('#customer_tag_ids').on('select2:selecting, (event) => { // do something })
    and then use the method event.preventDefault() to prevent selecting the value.

    But then I realized you’ve already have some conditions inside the creatTag option, and you may want to check the condition and show the message to the new tags only, so I end up with the below solution.

    $("#customer_tag_ids").select2({
      maximumSelectionLength: 5,
      multiple: true,
      tags: true,
      tokenSeparators: [',', ' '],
      createTag: function(params) {
        let text = params.term;
        $('#warning-text').show();
        if (text.length <= 10) {
          $("#warning-text").text(`"${text}", is valid.. has ${text.length} characters`);
        } else {
          $("#warning-text").text(`"${text}", is invalid... has ${text.length} characters, permited max 10 characters
    `);
          // return null to prevent create new tag
          return null;
        }
    
        if (params.term.match(/^(?![d ])[a-zd ]*$/i)) {
          // Return null to disable tag creation
          return {
            id: params.term,
            text: params.term,
            tag: true
          }
        } else {
          $("#warning-text").text(`"${text}", is invalid... it's doesn't match the pattern /^(?![d ])[a-zd ]*$/i
    `);
        }
        return null;
      },
      language: {
        maximumSelected: function(e) {
          // return I18n.t('customers.alert.limit_max');
        },
    
        inputTooShort: function(e) {
          // return I18n.t('customers.alert.limit_min');
        },
    
        noResults: function() {
          // return I18n.t('customers.alert.not_result_found');
        }
      },
    });
    
    // Hide the warning text when open/close the dropdown
    $("#customer_tag_ids").on("select2:open, select2:close", (e) => {
      $("#warning-text").hide();
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
    
    <select id="customer_tag_ids" class="js-example-basic-single" name="state" style="width: 300px">
      <option value="text-1">Text 1</option>
      <option value="text-2">Text 2</option>
    </select>
    
    <div id="warning-text" style="margin-top: 50px">
    
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search