Reputation: 674
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?
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?
Upvotes: 1
Views: 282
Reputation: 9993
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;
/* Your function. (By the way, value is in the first argument) */
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;
}
/* Else call previously saved functions */
if (Array.isArray(originalOnChange)) {
originalOnChange[0] && originalOnChange[0].call(this);
originalOnChange[1] && 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>
If you want to set a value after blur
when the select is empty, you need to store that value somewhere. I added this to a modified change
function:
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;
/* Your function. (By the way, value is in the first argument) */
selectize[0].selectize.on('change', function() {
var value = selectize[0].selectize.getValue();
console.log(value);
});
/* blur event */
selectize[0].selectize.on('blur', function() {
const value = selectize[0].selectize.getValue();
if(!value.length){
selectize[0].selectize.setValue(selectize.data('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;
}
/* Keep the value for `blur` */
selectize.data('value', value)
/* Else call previously saved functions */
if (Array.isArray(originalOnChange)) {
originalOnChange[0] && originalOnChange[0].call(this);
originalOnChange[1] && 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>
Upvotes: 1