Commentaren voor Webflow is LIVE op Product Hunt! Ontvang 50% korting voor 12 maanden →
Wedstrijd: Bouw een SaaS-app tussen 29 mei - 14 juni en maak kans op geldprijzen, gratis plannen & meer!
#109 - Custom Multi Selects v0.1
Custom-styled multi selects with search, keyboard selection, and more.
Bekijk demo
<!-- 💙 MEMBERSCRIPT #109 v0.1 💙 - CUSTOM MULTI SELECT -->
<script>
$(document).ready(function() {
$('[ms-code-select-wrapper]').each(function() {
const $wrapper = $(this);
const isMulti = $wrapper.attr('ms-code-select-wrapper') === 'multi';
const $input = $wrapper.find('[ms-code-select="input"]');
const $list = $wrapper.find('[ms-code-select="list"]');
const $selectedWrapper = $wrapper.find('[ms-code-select="selected-wrapper"]');
const $emptyState = $wrapper.find('[ms-code-select="empty-state"]');
const options = $input.attr('ms-code-select-options').split(',').map(opt => opt.trim());
let selectedOptions = [];
let highlightedIndex = -1;
const $templateSelectedTag = $selectedWrapper.find('[ms-code-select="tag"]');
const templateSelectedTagHTML = $templateSelectedTag.prop('outerHTML');
$templateSelectedTag.remove();
const $templateNewTag = $list.find('[ms-code-select="tag-name-new"]');
const templateNewTagHTML = $templateNewTag.prop('outerHTML');
$templateNewTag.remove();
function createSelectedTag(value) {
const $newTag = $(templateSelectedTagHTML);
$newTag.find('[ms-code-select="tag-name-selected"]').text(value);
$newTag.find('[ms-code-select="tag-close"]').on('click', function(e) {
e.stopPropagation();
removeTag(value);
});
return $newTag;
}
function addTag(value) {
if (!selectedOptions.includes(value) && options.includes(value)) {
selectedOptions.push(value);
$selectedWrapper.append(createSelectedTag(value));
updateInput();
filterOptions();
}
}
function removeTag(value) {
selectedOptions = selectedOptions.filter(option => option !== value);
$selectedWrapper.find(`[ms-code-select="tag-name-selected"]:contains("${value}")`).closest('[ms-code-select="tag"]').remove();
updateInput();
if (isMulti && selectedOptions.length > 0) {
$input.val($input.val() + ', ');
}
filterOptions();
}
function updateInput() {
$input.val(selectedOptions.join(', '));
}
function toggleList(show) {
$list.toggle(show);
}
function createOptionElement(value) {
const $option = $(templateNewTagHTML);
$option.text(value);
$option.on('click', function() {
selectOption(value);
});
return $option;
}
function selectOption(value) {
if (isMulti) {
addTag(value);
$input.val(selectedOptions.join(', ') + (selectedOptions.length > 0 ? ', ' : ''));
$input.focus();
} else {
selectedOptions = [value];
$selectedWrapper.empty().append(createSelectedTag(value));
updateInput();
toggleList(false);
}
filterOptions();
}
function filterOptions() {
const inputValue = $input.val();
const searchTerm = isMulti ? inputValue.split(',').pop().trim() : inputValue.trim();
let visibleOptionsCount = 0;
$list.find('[ms-code-select="tag-name-new"]').each(function() {
const $option = $(this);
const optionText = $option.text().toLowerCase();
const matches = optionText.includes(searchTerm.toLowerCase());
const isSelected = selectedOptions.includes($option.text());
$option.toggle(matches && !isSelected);
if (matches && !isSelected) visibleOptionsCount++;
});
$emptyState.toggle(visibleOptionsCount === 0 && searchTerm !== '');
highlightedIndex = -1;
updateHighlight();
}
function cleanInput() {
const inputValues = $input.val().split(',').map(v => v.trim()).filter(v => v);
const validValues = inputValues.filter(v => options.includes(v));
selectedOptions = validValues;
$selectedWrapper.empty();
selectedOptions.forEach(value => $selectedWrapper.append(createSelectedTag(value)));
updateInput();
filterOptions();
}
function handleInputChange() {
const inputValue = $input.val();
const inputValues = inputValue.split(',').map(v => v.trim());
const lastValue = inputValues[inputValues.length - 1];
if (inputValue.endsWith(',') || inputValue.endsWith(', ')) {
inputValues.pop();
const newValidValues = inputValues.filter(v => options.includes(v) && !selectedOptions.includes(v));
newValidValues.forEach(addTag);
$input.val(selectedOptions.join(', ') + (selectedOptions.length > 0 ? ', ' : ''));
} else if (options.includes(lastValue) && !selectedOptions.includes(lastValue)) {
addTag(lastValue);
$input.val(selectedOptions.join(', ') + ', ');
}
filterOptions();
}
function initializeWithValue() {
const initialValue = $input.val();
if (initialValue) {
const initialValues = initialValue.split(',').map(v => v.trim());
initialValues.forEach(value => {
if (options.includes(value)) {
addTag(value);
}
});
updateInput();
filterOptions();
}
}
function updateHighlight() {
$list.find('[ms-code-select="tag-name-new"]').removeClass('highlighted').css('background-color', '');
if (highlightedIndex >= 0) {
$list.find('[ms-code-select="tag-name-new"]:visible').eq(highlightedIndex)
.addClass('highlighted')
.css('background-color', '#e0e0e0');
}
}
function handleKeyDown(e) {
const visibleOptions = $list.find('[ms-code-select="tag-name-new"]:visible');
const optionCount = visibleOptions.length;
switch (e.key) {
case 'ArrowDown':
e.preventDefault();
highlightedIndex = (highlightedIndex + 1) % optionCount;
updateHighlight();
break;
case 'ArrowUp':
e.preventDefault();
highlightedIndex = (highlightedIndex - 1 + optionCount) % optionCount;
updateHighlight();
break;
case 'Enter':
e.preventDefault();
if (highlightedIndex >= 0) {
const selectedValue = visibleOptions.eq(highlightedIndex).text();
selectOption(selectedValue);
}
break;
}
}
$.each(options, function(i, option) {
$list.append(createOptionElement(option));
});
$input.on('focus', function() {
toggleList(true);
if (isMulti) {
const currentVal = $input.val().trim();
if (currentVal !== '' && !currentVal.endsWith(',')) {
$input.val(currentVal + ', ');
}
this.selectionStart = this.selectionEnd = this.value.length;
}
filterOptions();
});
$input.on('click', function(e) {
e.preventDefault();
this.selectionStart = this.selectionEnd = this.value.length;
});
$input.on('blur', function() {
setTimeout(function() {
if (!$list.is(':hover')) {
toggleList(false);
cleanInput();
}
}, 100);
});
$input.on('input', handleInputChange);
$input.on('keydown', handleKeyDown);
$list.on('mouseenter', '[ms-code-select="tag-name-new"]', function() {
$(this).css('background-color', '#e0e0e0');
});
$list.on('mouseleave', '[ms-code-select="tag-name-new"]', function() {
if (!$(this).hasClass('highlighted')) {
$(this).css('background-color', '');
}
});
initializeWithValue();
toggleList(false);
});
});
</script>
Het Make.com-scenario maken
1. Download de JSON blauwdruk hieronder om het te leren.
2. Navigeer naar Make.com en maak een nieuw scenario...
3. Klik op het kleine vakje met 3 stippen en vervolgens op Import Blueprint...
4. Upload je bestand en voila! Je bent klaar om je eigen accounts te koppelen.
Hulp nodig met deze MemberScript?
Alle Memberstack-klanten kunnen om hulp vragen in de 2.0 Slack. Houd er rekening mee dat dit geen officiële functies zijn en dat ondersteuning niet kan worden gegarandeerd.
Word lid van de 2.0 SlackVersie-opmerkingen
Attributen
Beschrijving
Attribuut
Geen items gevonden.
Gidsen / Handleidingen
Les
Wat is Memberstack?
Auth & betalingen voor Webflow sites
Voeg logins, abonnementen, gated content en nog veel meer toe aan uw Webflow site - eenvoudig en volledig aanpasbaar.
Meer informatie
Probeer Memberstack gratis uit
100% gratis, onbeperkt uitproberen - upgrade alleen als je klaar bent om te lanceren. Geen creditcard nodig.
Product
Volledige lijst met functiesGebruikersaccountsGated ContentBeveiligde betalingenAPI & integratiesMemberstack & WebflowEen nieuw account aanmaken2.0 Inloggen1.0 InloggenPrijzenTaal
PrivacybeleidGebruiksvoorwaardenCookiebeleidVeiligheidsbeleid
© Memberstack Inc. 2018 - 2024. Alle rechten voorbehouden.