I have a multi input made with alpine js, is not mine, I search for one on Google and like this one. So, the problem is that 3 inputs on my form needs to be multi-options available, but the first input options repeat for all inputs (They should be different for each input).
I know is because that the input was implemented for 1 multi input per form, but I need to adapt it and I don’t know have any idea of what to do. (I’m a Django dev, I don’t have knowledge in alpine js at all and my knowledge of JavaScript is pretty basic).
If a pure soul can help me to adapt it or, at least, guide me how to do it, it would help. Thanks.
Dependencies: Tailwind (lasted stable), Alpine JS (lasted stable)
<section class="w-full">
<select x-cloak id="select" style="display:none" class="text-gray-400">
<option value="Preescolar">Preescolar</option>
<option value="Educ. Básica">Educ. Básica</option>
<option value="Educ. Media">Educ. Media</option>
</select>
<label class="w-full text-sm">
<span class="text-gray-700 dark:text-gray-400">Nivel/es</span>
<div x-data="dropdown()" x-init="loadOptions()" class="h-fit w-full flex flex-col items-center mx-auto">
<input name="values" type="hidden" x-bind:value="selectedValues()" readonly="readonly">
<div class="inline-block relative w-full">
<div class="flex flex-col items-center relative">
<div x-on:click="open" class="w-full svelte-1l8159u">
<div class="mt-1 p-2 flex rounded border dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-400 dark:focus:shadow-outline-gray svelte-1l8159u">
<div class="flex flex-auto flex-wrap grow gap-1">
<template x-for="(option,index) in selected" :key="options[option].value">
<div
class="flex justify-center gap-1 items-center font-medium pl-1 pr-0.5 rounded text-purple-700 bg-purple-100 border border-purple-300">
<div class="text-xs font-normal leading-none max-w-full flex-initial" x-model="options[option]" x-text="options[option].text"></div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click="remove(index,option)">
<svg xmlns="http://www.w3.org/2000/svg" role="button" viewBox="0 0 20 20" fill="currentColor" class="size-4 fill-current">
<path d="M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z" />
</svg>
</div>
</div>
</div>
</template>
<div x-show="selected.length == 0" class="flex-1">
<input placeholder="..."
class="bg-transparent p-0 border-none appearance-none outline-none h-full w-full text-gray-400 text-sm"
x-bind:value="selectedValues()" readonly="readonly">
</div>
</div>
<div
class="w-fit pl-2 border-l flex items-center border-gray-600 svelte-1l8159u">
<button type="button" x-show="isOpen() === true" x-on:click="open"
class="cursor-pointer outline-none focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 cursor-pointer outline-none focus:outline-none">
<path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
</svg>
</button>
<button type="button" x-show="isOpen() === false" @click="close"
class="cursor-pointer outline-none focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 cursor-pointer outline-none focus:outline-none">
<path fill-rule="evenodd" d="M9.47 6.47a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 1 1-1.06 1.06L10 8.06l-3.72 3.72a.75.75 0 0 1-1.06-1.06l4.25-4.25Z" clip-rule="evenodd" />
</svg>
</button>
</div>
</div>
</div>
<div class="w-full px-4">
<div x-show.transition.origin.top="isOpen()"
class="absolute shadow top-100 text-gray-400 bg-gray-700 z-40 w-full left-0 rounded max-h-select overflow-y-auto svelte-5uyqqj"
x-on:click.away="close">
<div class="flex flex-col w-full">
<template x-for="(option,index) in options" :key="option">
<div>
<div class="cursor-pointer w-full border-gray-600 rounded-b border-b hover:bg-purple-700"
@click="select(index,$event)">
<div x-bind:class="option.selected ? 'border-purple-600' : ''"
class="flex w-full items-center p-2 pl-2 hover:text-gray-100 relative">
<div class="w-full items-center flex">
<div class="mx-2 leading-6" x-model="option" x-text="option.text"></div>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</label>
</section>
<section class="w-full">
<select x-cloak id="select" style="display:none" class="text-gray-400">
{% for course in courses %}
<option value="1">{{course.grade}}</option>
{% endfor %}
</select>
<label class="w-full text-sm">
<span class="text-gray-700 dark:text-gray-400">Sección/es</span>
<div x-data="dropdown()" x-init="loadOptions()" class="h-fit w-full flex flex-col items-center mx-auto">
<input name="values" type="hidden" x-bind:value="selectedValues()">
<div class="inline-block relative w-full">
<div class="flex flex-col items-center relative">
<div x-on:click="open" class="w-full svelte-1l8159u">
<div class="mt-1 p-2 flex rounded border dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-400 dark:focus:shadow-outline-gray svelte-1l8159u">
<div class="flex flex-auto flex-wrap grow gap-1">
<template x-for="(option,index) in selected" :key="options[option].value">
<div
class="flex justify-center gap-1 items-center font-medium pl-1 pr-0.5 rounded text-purple-700 bg-purple-100 border border-purple-300">
<div class="text-xs font-normal leading-none max-w-full flex-initial" x-model="options[option]" x-text="options[option].text"></div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click="remove(index,option)">
<svg xmlns="http://www.w3.org/2000/svg" role="button" viewBox="0 0 20 20" fill="currentColor" class="size-4 fill-current">
<path d="M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z" />
</svg>
</div>
</div>
</div>
</template>
<div x-show="selected.length == 0" class="flex-1">
<input placeholder="..."
class="bg-transparent p-0 border-none appearance-none outline-none h-full w-full text-gray-400 text-sm"
x-bind:value="selectedValues()">
</div>
</div>
<div
class="w-fit pl-2 border-l flex items-center border-gray-600 svelte-1l8159u">
<button type="button" x-show="isOpen() === true" x-on:click="open"
class="cursor-pointer outline-none focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 cursor-pointer outline-none focus:outline-none">
<path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
</svg>
</button>
<button type="button" x-show="isOpen() === false" @click="close"
class="cursor-pointer outline-none focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 cursor-pointer outline-none focus:outline-none">
<path fill-rule="evenodd" d="M9.47 6.47a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 1 1-1.06 1.06L10 8.06l-3.72 3.72a.75.75 0 0 1-1.06-1.06l4.25-4.25Z" clip-rule="evenodd" />
</svg>
</button>
</div>
</div>
</div>
<div class="w-full px-4">
<div x-show.transition.origin.top="isOpen()"
class="absolute shadow top-100 text-gray-400 bg-gray-700 z-40 w-full left-0 rounded max-h-select overflow-y-auto svelte-5uyqqj"
x-on:click.away="close">
<div class="flex flex-col w-full">
<template x-for="(option,index) in options" :key="option">
<div>
<div class="cursor-pointer w-full border-gray-600 rounded-b border-b hover:bg-purple-700"
@click="select(index,$event)">
<div x-bind:class="option.selected ? 'border-purple-600' : ''"
class="flex w-full items-center p-2 pl-2 hover:text-gray-100 relative">
<div class="w-full items-center flex">
<div class="mx-2 leading-6" x-model="option" x-text="option.text"></div>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</label>
</section>
<section class="w-full">
<select x-cloak id="select" style="display:none" class="text-gray-400">
<option value="1">Option 2</option>
<option value="2">Option 3</option>
<option value="3">Option 4</option>
<option value="4">Option 5</option>
</select>
<label class="w-full text-sm">
<span class="text-gray-700 dark:text-gray-400">Materia/s</span>
<div x-data="dropdown()" x-init="loadOptions()" class="h-fit w-full flex flex-col items-center mx-auto">
<input name="values" type="hidden" x-bind:value="selectedValues()">
<div class="inline-block relative w-full">
<div class="flex flex-col items-center relative">
<div x-on:click="open" class="w-full svelte-1l8159u">
<div class="mt-1 p-2 flex rounded border dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-400 dark:focus:shadow-outline-gray svelte-1l8159u">
<div class="flex flex-auto flex-wrap grow gap-1">
<template x-for="(option,index) in selected" :key="options[option].value">
<div
class="flex justify-center gap-1 items-center font-medium pl-1 pr-0.5 rounded text-purple-700 bg-purple-100 border border-purple-300">
<div class="text-xs font-normal leading-none max-w-full flex-initial" x-model="options[option]" x-text="options[option].text"></div>
<div class="flex flex-auto flex-row-reverse">
<div x-on:click="remove(index,option)">
<svg xmlns="http://www.w3.org/2000/svg" role="button" viewBox="0 0 20 20" fill="currentColor" class="size-4 fill-current">
<path d="M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z" />
</svg>
</div>
</div>
</div>
</template>
<div x-show="selected.length == 0" class="flex-1">
<input placeholder="..."
class="bg-transparent p-0 border-none appearance-none outline-none h-full w-full text-gray-400 text-sm"
x-bind:value="selectedValues()">
</div>
</div>
<div
class="w-fit pl-2 border-l flex items-center border-gray-600 svelte-1l8159u">
<button type="button" x-show="isOpen() === true" x-on:click="open"
class="cursor-pointer outline-none focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 cursor-pointer outline-none focus:outline-none">
<path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
</svg>
</button>
<button type="button" x-show="isOpen() === false" @click="close"
class="cursor-pointer outline-none focus:outline-none">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5 cursor-pointer outline-none focus:outline-none">
<path fill-rule="evenodd" d="M9.47 6.47a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 1 1-1.06 1.06L10 8.06l-3.72 3.72a.75.75 0 0 1-1.06-1.06l4.25-4.25Z" clip-rule="evenodd" />
</svg>
</button>
</div>
</div>
</div>
<div class="w-full px-4">
<div x-show.transition.origin.top="isOpen()"
class="absolute shadow top-100 text-gray-400 bg-gray-700 z-40 w-full left-0 rounded max-h-select overflow-y-auto svelte-5uyqqj"
x-on:click.away="close">
<div class="flex flex-col w-full">
<template x-for="(option,index) in options" :key="option">
<div>
<div class="cursor-pointer w-full border-gray-600 rounded-b border-b hover:bg-purple-700"
@click="select(index,$event)">
<div x-bind:class="option.selected ? 'border-purple-600' : ''"
class="flex w-full items-center p-2 pl-2 hover:text-gray-100 relative">
<div class="w-full items-center flex">
<div class="mx-2 leading-6" x-model="option" x-text="option.text"></div>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</label>
</section>
<script>
function dropdown() {
return {
options: [],
selected: [],
show: false,
open() { this.show = true },
close() { this.show = false },
isOpen() { return this.show === true },
select(index, event) {
if (!this.options[index].selected) {
this.options[index].selected = true;
this.options[index].element = event.target;
this.selected.push(index);
} else {
this.selected.splice(this.selected.lastIndexOf(index), 1);
this.options[index].selected = false
}
},
remove(index, option) {
this.options[option].selected = false;
this.selected.splice(index, 1);
},
loadOptions() {
const options = document.getElementById('select').options;
for (let i = 0; i < options.length; i++) {
this.options.push({
value: options[i].value,
text: options[i].innerText,
selected: options[i].getAttribute('selected') != null ? options[i].getAttribute('selected') : false
});
}
},
selectedValues() {
return this.selected.map((option) => {
return this.options[option].value;
})
}
}
}
</script>