Description
Hi there!
I love your new AdvancedSelect, but, unfortunately, cannot get it working. Specifically, I have trouble getting the selected value and/ or detecting a change event.
What I want to build (see my try below):
Starting from your Advanced Select => Tags example, a select for several of a number of specialties (which are dynamically fetched from my api endpoint in fetchSpecialties*). The selected values shall be emitted with an 'input' emit.
It works fine if I remove the data-hs-select='{...}'
, i.e., use a usual select multiple.
[ * : To achieve that the selectable values in the Advanced Select are initialised by those fetched from my DB, I had to wrap the advanced select using a v-if="specialtiesFetched". I have removed this from the minimal example below. I also tried without and it seems not to be related to the issue. ]
What I tried (all included in my code snippet below as I tried them):
- add an onChange callback in the selection element (seems to be disabled following this discussion: AdvancedSelect change toggleClasses dynamically not working #190 (comment)_ - right?)
- Use HSStaticMethods.autoInit() + setting el.oChanges (as discussed there; same, so also disabled?)
- using v-model like in a usual select (no change to variable)
- leaving out the dynamic fetch of the selectable values and removing the v-if (did not help)
I am on preline/select v2.0.2.
Following #190 (comment), I have learnt that there shall be a v2.0.3 which addresses my issue (is that so?), but unfortunately cannot find it using npm i.
I would very much appreciate any help how to get the selected values out of this beautiful select! :)
<script lang="ts">
import {ref, onMounted} from 'vue';
import {getApiClient} from "@/apiclient/client";
import {HSSelect, HSStaticMethods} from "preline";
interface SpecialtyInputProps {
value: string[];
}
export default {
inheritAttrs: false
props: {
value: {
type: Array as () => string[],
required: false,
},
},
setup(props: SpecialtyInputProps, {emit}: { emit: (event: 'input', value: SpecialtyInputProps['value']) => void }) {
const specialties = ref<string[]>(['a', 'b', 'c']);
const specialtiesSelected = ref<string[]>([]);
onMounted(async () => {
emit('input', ['',]);
setTimeout(() => {
console.log('HSS init')
HSStaticMethods.autoInit();
const el = HSSelect.getInstance("#specialtySelect");
if (el) {
// check if the element exists on dom
el.onchange = (val: any) => {
console.log(val);
updateValue();
};
console.log('onchange:' + el.onchange);
} else {
console.log("no element found");
}
}, 100);
});
const updateValue = () => {
emit('input', specialtiesSelected.value);
};
return {
specialties,
updateValue,
specialtiesSelected
};
},
};
</script>
<template>
<div class="relative">
Selected: {{ specialtiesSelected }}.
Props: {{ value }}.
<select
id="specialtySelect"
v-model="specialtiesSelected"
@change="updateValue"
multiple
data-hs-select='{
"placeholder": "Select option...",
"toggleTag": "<button type=\"button\"></button>",
"toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative flex text-nowrap w-full cursor-pointer bg-white border border-gray-200 rounded-lg text-start text-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600",
"dropdownClasses": "mt-2 z-50 w-full max-h-[300px] p-1 space-y-0.5 bg-white border border-gray-200 rounded-lg overflow-hidden overflow-y-auto dark:bg-slate-900 dark:border-gray-700",
"optionClasses": "py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-none focus:bg-gray-100 dark:bg-slate-900 dark:hover:bg-slate-800 dark:text-gray-200 dark:focus:bg-slate-800",
"mode": "tags",
"tagsClasses": "relative ps-0.5 pe-9 min-h-[46px] flex items-center flex-wrap text-nowrap w-full border border-gray-200 rounded-lg text-start text-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600",
"tagsItemTemplate": "<div class=\"flex flex-nowrap items-center relative z-10 bg-white border border-gray-200 rounded-full p-1 m-1 dark:bg-slate-900 dark:border-gray-700\"><div class=\"h-6 w-6 me-1\" data-icon></div><div class=\"whitespace-nowrap\" data-title></div><div class=\"inline-flex flex-shrink-0 justify-center items-center h-5 w-5 ms-2 rounded-full text-gray-800 bg-gray-200 hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-400 text-sm dark:bg-gray-700/50 dark:hover:bg-gray-700 dark:text-gray-400 cursor-pointer\" data-remove><svg class=\"flex-shrink-0 w-3 h-3\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg></div></div>",
"tagsInputClasses": "absolute inset-0 w-full py-3 px-4 pe-9 flex-1 text-sm rounded-lg focus-visible:ring-0 dark:bg-slate-900 dark:text-gray-400",
"optionTemplate": "<div class=\"flex items-center\"><div class=\"h-8 w-8 me-2\" data-icon></div><div><div class=\"text-sm font-semibold text-gray-800 dark:text-gray-200\" data-title></div><div class=\"text-xs text-gray-500\" data-description></div></div><div class=\"ms-auto\"><span class=\"hidden hs-selected:block\"><svg class=\"flex-shrink-0 w-4 h-4 text-blue-600\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425a.247.247 0 0 1 .02-.022Z\"/></svg></span></div></div>"
}'
class="hidden"
>
<option v-for="specialty in specialties"
:value="specialty" data-hs-select-option='{
"description": "Lorem ipsum",
"icon": "<img class=\"inline-block rounded-full\" src=\"https://images.unsplash.com/photo-1531927557220-a9e23c1e4794?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80\" />"
}'>{{ specialty }}
</option>
</select>
<div class="absolute top-1/2 end-3 -translate-y-1/2">
<svg class="flex-shrink-0 w-3.5 h-3.5 text-gray-500 dark:text-gray-500" xmlns="http://www.w3.org/2000/svg"
width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="m7 15 5 5 5-5"/>
<path d="m7 9 5-5 5 5"/>
</svg>
</div>
</div>
</template>
Thank you very much!