skip to Main Content

I have a selectize input and want to change its behaviour. I normally use selectize inputs from within some framework (shiny), so I hope the example that I give here is understandable and precise.

I want to change the logic, when an onChange – event is triggered. I only want this to happen when there is one element selected, not when none is selected. In case the user deletes the element and leaves the form untouched, I want to restore the value that was active before.

Have a look at the following code:

$(document).ready(function() {
  var selectize = $('#select-beast').selectize({
    delimiter: ',',
    persist: false,
    create: function(input) {
      return {
        value: input,
        text: input
      }
    }
  });

  selectize[0].selectize.on('change', function() {
    var value = selectize[0].selectize.getValue();
    console.log(value);
  });
});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Selectize Example</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/css/selectize.default.min.css">
</head>
<body>
  <select id="select-beast" multiple placeholder="Select a beast...">
    <option value="lion">Lion</option>
    <option value="tiger">Tiger</option>
    <option value="bear">Bear</option>
    <option value="elephant">Elephant</option>
    <option value="rhino">Rhino</option>
  </select>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/js/standalone/selectize.min.js"></script>
</body>
</html>

So in my case the log message should only ever print out something like Array["bear"] but never an empty array. I know that in this case one could do a if before the console.log but I am explicitly asking for changing the onChange condition because in my real problem I have no direct control on what my framework is doing. Is there a way of achieving my goal?

  • no change-event with empty selection
  • restoring the value that was there before, once the user gives focus to another element

I would claim that it is pretty natural to want something like that, so maybe there is even a plugin capable of achieving my goals?

2

Answers


  1. We can’t override the code but we can get around it. I got around it by pushing value into an array and then logging the first last (confusing I know) selected value instead of an empty array. There was a few issues I fixed with little bits and bobs but I’ve commented them out for you.

    Please upvote or comment if this helps. Accepting the answer would be nice too.

    $(document).ready(function() {
      let selectize = $('#select-beast').selectize({
        delimiter: ',',
        persist: false,
        create: function(input) {
          return {
            value: input,
            text: input
          }
        }
      });
    
    let previousLog = [];
      selectize[0].selectize.on('change', function() {
        let value = selectize[0].selectize.getValue();
    
        previousLog.push("" + value); //IDK why but the empty string + value is just what makes this work so I'm going to point this towards js behaviour
        let lastLogged = previousLog.length - 2; //Getting last selected first value. I minus 2 to not log the empty string aswell as other values.
    
        if(value.length == 0){
          console.log([previousLog[lastLogged]]) //Logging as array rather than string.
        } else {
            console.log(value); //Normal value log
        }
      });
    });
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Selectize Example</title>
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/css/selectize.default.min.css">
    </head>
    <body>
      <select id="select-beast" multiple placeholder="Select a beast...">
        <option value="lion">Lion</option>
        <option value="tiger">Tiger</option>
        <option value="bear">Bear</option>
        <option value="elephant">Elephant</option>
        <option value="rhino">Rhino</option>
      </select>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/js/standalone/selectize.min.js"></script>
    </body>
    </html>

    Upvote if this helps!

    Login or Signup to reply.
  2. I don’t quite understand what you want.
    But you can override the change event and not call your function if value.length === 0 (this will work with <select multiple> and without multiple).
    It’s a bit dirty:

    const selectize = $('#select-beast').selectize({
      delimiter: ',',
      persist: false,
      create: function(input) {
        return {
          value: input,
          text: input
        }
      }
    });
    
    /* We save the event */
    const originalOnChange = selectize[0].selectize._events.change; 
    
    selectize[0].selectize.on('change', function() {
      var value = selectize[0].selectize.getValue();
      console.log(value);
    });
    
    /* We turn off the event */
    selectize[0].selectize.off('change');
    
    selectize[0].selectize._events.change = [];
    selectize[0].selectize._events.change[0] = function(value) {
      /* If is no value - we do nothing */
      if(!value.length){
        return;
      }
      /* Or call previously saved functions */
      originalOnChange[0].call(this);
      originalOnChange[1]();
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/css/selectize.default.min.css">
    <select id="select-beast" multiple placeholder="Select a beast...">
      <option value="lion">Lion</option>
      <option value="tiger">Tiger</option>
      <option value="bear">Bear</option>
      <option value="elephant">Elephant</option>
      <option value="rhino">Rhino</option>
    </select>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/js/standalone/selectize.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search