Open Timwillems opened 2 years ago
You can achieve this with CSS, e.g.:
.choices__list--multiple:not(:empty) + .choices__input::placeholder {
opacity: 0;
}
Should you want to achieve something similar with a single select, you could do it like so:
.choices__list--dropdown > .choices__list > .choices__placeholder {
display: none;
}
@ggsp Thanks for the css magic. it does indeed hide the placeholder. This only kind of worked for me as the placeholder is still taking up space. For me both the base implementation and this workaround do not function like a normal element placeholder would which is what I am going for. I'm sure there's a way to do it in css but for those who want to handle via JS this is how I ended up handling it:
const element = document.querySelector('#test');
const choices = new Choices(element,{
allowHTML: true,
placeholder: true,
placeholderValue: "This is my Placeholder"
});
const Inner = document.querySelector("div.choices__inner"); //Get the inner Container
const search = document.querySelector("div.choices__inner input[name='search_terms']"); //Get the search element (this is where the placeholder is)
const Width = Inner.offsetWidth;
element.addEventListener('change', (evnet)=> {
//Add or remove the placeholder
element.selectedOptions.length ? search.removeAttribute('placeholder') : search.setAttribute('placeholder',choices.config.placeholderValue);
//optionally keep the initial width of the container
Inner.style.minWidth = `${Width}px`;
search.removeAttribute('style');
});
<select id='test' multiple>
<option></option>
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
</select>
You can achieve this with CSS, e.g.:
.choices__list--multiple:not(:empty) + .choices__input::placeholder { opacity: 0; }
Should you want to achieve something similar with a single select, you could do it like so:
.choices__list--dropdown > .choices__list > .choices__placeholder { display: none; }
Thanks @ggsp You saved a tone of time ❤️
dphaas2004's solution did not work for me but it did put me on the path towards finding it (for my project) so I thought I'd include it on this post
HTML Filter:
<div class="c-filter">
<label for="datum">Datum</label>
<select class="js-filter-date js-searchfield" id="datum" multiple>
</select>
</div>
JS code:
const listenToSearchFields = function () {
const searchFields = document.querySelectorAll('.js-searchfield');
for (const field of searchFields) {
field.addEventListener('change', function () {
handleSearchFields(); // search request for my api
const inner = field.closest('.choices__inner'); // get the container of the current filter selected
const search = inner.querySelector('input[name="search_terms"]'); // in that container, get the placeholder
const arrSelections = inner.querySelectorAll('.choices__item'); // array of selected filters
if (arrSelections.length > 0) {
// if there are filters detected, hide placeholder
search.style = 'display:none;';
} else {
// else show the placeholder again
search.style = 'display:inline-block;';
}
});
}
};
Hopefully this is helpful to anyone else!
My solution:
let formSelects = document.querySelectorAll('select.form-select-choices')
choices = []
formSelects.forEach((item) => {
let choicesItem = new Choices(item, {
allowHTML: true,
removeItems: true,
removeItemButton: true,
placeholder: true,
placeholderValue: item.dataset.formPlaceholder
});
choicesItem.passedElement.element.addEventListener('addItem', () => {
choicesRemovePlaceholder(choicesItem)
}, false,
);
choicesItem.passedElement.element.addEventListener('removeItem', () => {
choicesRemovePlaceholder(choicesItem)
}, false,
);
choices.push(choicesItem)
})
function choicesRemovePlaceholder(choicesItem) {
let selected = choicesItem.passedElement.element.selectedOptions.length
let placeholder = choicesItem.containerInner.element.querySelector('input[type=search]')
if (selected > 0) {
placeholder.style.display = 'none'
} else {
placeholder.style.display = 'inline-block'
}
}
Using scss:
.#{$choices-selector}__list--multiple {
&:not(:empty) + .#{$choices-selector}__input {
min-width: auto !important;
&::placeholder {
opacity: 0;
}
}
}
Whenever there is an item selected in the "multiple" dropdown, i'd like to have the placeholder option removed from the list.
This is to have a indicator like "Please select your ...."
Now it always shows this placeholder, even if there are selected items