There is a drop-down multy select in which I would like to click on an element to remove it from the selected ones. Out of the box chosen.js apparently can not do this, how can you modify it a bit?
I tried to bind the standard function to elements, but it didn't work. Please give me a hint
$("body").on("click", ".result-selected", function() {
let index = $(this).attr("data-option-array-index");
let container = $(this).closest(".chosen-container");
let select = container.prev();
if ( select != null && select.hasClass("chosen-select") ) {
console.log(index);
select
.find("option:eq(" + index + ")")
.prop("selected", false);
select.trigger("chosen:updated").trigger('chosen:open');
}
});
In the original code, you were triggering chosen:open after deselecting. This might not always behave as expected because if the dropdown is closed when you deselect, opening it immediately after might not be desired. In most cases, you will want to close the dropdown after making changes, not reopen it.
Working snippet:
$(function() {
// Initialize Chosen with options
$(".chosen-select").chosen({
width: "100%",
allow_single_deselect: false,
disable_search: true,
hide_results_on_select: false,
});
// Event listener for clicking a selected item to deselect
$("body").on("click", ".result-selected", function() {
let index = $(this).attr("data-option-array-index"); // Get the index of the selected option
let container = $(this).closest(".chosen-container"); // Find the container of the chosen dropdown
let select = container.prev(); // Get the original select element
if (select != null && select.hasClass("chosen-select")) {
// Check if dropdown is open before deselecting
let isDropdownOpen = container.hasClass("chosen-with-drop");
// Find the corresponding option element in the select by index
let option = select.find("option").eq(index);
if (option.length) {
// Deselect the option (remove 'selected' attribute)
option.prop("selected", false);
// Temporarily disable Chosen's internal closing behavior
select.trigger("chosen:updated");
// If the dropdown was open before deselecting, we keep it open manually
if (isDropdownOpen) {
// Manually re-open the dropdown if it's closed after deselecting
setTimeout(function() {
select.trigger("chosen:open");
}, 10); // Small delay to allow update to complete before reopening
return false;
}
}
}
});
// Handle item click to ensure dropdown opens again after deselection
$("body").on("click", ".chosen-select", function() {
let select = $(this);
let container = select.next(".chosen-container");
// If the dropdown is not open, we open it
if (!container.hasClass("chosen-with-drop")) {
select.trigger("chosen:open");
}
});
// Prevent the dropdown from closing when updating
$(document).on("chosen:updated", ".chosen-select", function() {
let select = $(this);
let container = select.next(".chosen-container");
// If the dropdown is open, we reopen it
if (container.hasClass("chosen-with-drop")) {
setTimeout(function() {
select.trigger("chosen:open");
}, 10);
}
});
});
.box{
width:300px;
margin:50px;
}
.chosen-container{
position: relative;
}
.chosen-single{
display: flex;
align-items: center;
width: 100%;
padding: 12px 24px;
border: none;
outline: none;
background-color: #FAFAFB;
font-size: 14px;
line-height: 24px;
min-height: 48px;
text-decoration: none;
color:#02013D;
position: relative;
cursor: pointer;
font-weight: 400;
b{
width: 16px;
height: 16px;
position: absolute;
top: 16px;
right: 16px;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 10L8 6L12 10' stroke='%2302013D' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
transform: rotate(180deg);
transition: transform .3s linear;
.chosen-with-drop &{
transform: rotate(0);
}
}
}
.chosen-drop{
// display: none;
margin-top: 4px;
background-clip: padding-box;
position: absolute;
top: 100%;
z-index: 1010;
width: 100%;
border-top: 0;
background: #FAFAFB;
clip: rect(0, 0, 0, 0);
-webkit-clip-path: inset(100% 100%);
clip-path: inset(100% 100%);
.chosen-with-drop &{
clip:auto;
-webkit-clip-path: none;
clip-path: none;
}
}
.chosen-search{
display: none;
}
.chosen-results{
margin: 0;
list-style: none;
padding: 6px 12px;
li{
padding: 6px 0px;
color:#02013D;
font-size: 14px;
cursor: pointer;
}
}
.chosen-default{
color:#81809E;
}
.chosen-container-multi{
list-style: none;
margin: 0;
padding: 0;
// align-items: center;
width: 100%;
padding-right: 34px;
border: none;
outline: none;
background-color: #FAFAFB;
font-size: 14px;
line-height: 24px;
min-height: 48px;
text-decoration: none;
color: #02013D;
position: relative;
cursor: pointer;
font-weight: 400;
height: 48px;
&::after {
content: '';
width: 16px;
height: 16px;
position: absolute;
top: 16px;
right: 16px;
background-repeat: no-repeat;
background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 10L8 6L12 10' stroke='%2302013D' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
transform: rotate(180deg);
transition: transform .3s linear;
}
.chosen-choices{
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
list-style: none;
padding: 12px 0px 12px 24px;
li{
&:last-child{
display: none;
}
&:first-child{
display: inline-block;
}
}
input{
border:none;
background-color: transparent;
font-size: 14px;
color:#02013D;
outline:none;
}
.search-field{
// display: none;
}
.chosen-search-input{
display: none;
}
.search-choice{
display: inline-block;
margin-right: 8px;
position: relative;
padding-right: 12px;
flex-shrink: 0;
.search-choice-close{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-image: url("data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 14 14' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13 1L1 13M1 1L13 13' stroke='%2302013D' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
background-position: top right;
background-repeat: no-repeat;
}
}
}
&.chosen-with-drop .chosen-choices:after {
transform: rotate(0);
}
.chosen-results{
.active-result, .result-selected{
position: relative;
padding-left: 28px;
&:before{
content:'';
position: absolute;
left: 0;
top: 50%;
transform:translateY(-50%);
width: 16px;
height: 16px;
border:1px solid #02013D;
}
}
.result-selected{
&:after{
content:'';
position: absolute;
left: 2px;
top: 50%;
transform: translateY(-50%);
width: 12px;
height: 12px;
background-color: #886B3E;
}
}
}
}
.chosen-drop {
margin-top: 4px;
background-clip: padding-box;
position: absolute;
top: 100%;
z-index: 1010;
width: 100%;
border-top: 0;
background: #FAFAFB;
clip: auto; /* Ensure it's visible */
-webkit-clip-path: none;
clip-path: none;
}
.chosen-container .chosen-with-drop .chosen-drop {
clip-path: none; /* When dropdown is open, clip-path should be removed */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.jquery.min.js"></script>
<div class="box">
<select name="size" class="chosen-select" multiple data-placeholder="Select size" >
<option value=""></option>
<option value="40">40 mm</option>
<option value="36">36 mm</option>
<option value="26">26 mm</option>
<option value="41">41 mm</option>
<option value="34">34 mm</option>
</select>
</div>