skip to Main Content

I am developing a vue-component based on vue-select within which I am adding a custom info Icon, on click of the Icon I want to trigger my custom method getInfo but for some reason clicking on it does not trigger the method rather opens the search box the options search.

I want to trigger the getInfo function when the user clicks on the Icon, rest elsewhere when user clicks then I want the Input search bar to come into picture and accept user inputs.

I tried adding various z-index and other approaches from tailwind css but its not working. Following is the nuxt 3 component I have:

<template>
    <Field :name="name" v-model="item.value">
      <vSelect
        v-model="item"
        :options="options"
        :getOptionLabel="option.text"
        class="w-full bg-gray-50 dark:bg-gray-700 rounded p-1 z-10"
        appendToBody
      >
        <template #search="{ attributes, events }" class="z-10">
          <Icon
            v-if="displayInfoIcon"
            icon="ph:info"
            width="18"
            height="18"
            @click.native.stop.prevent="getInfo"
            class="absolute right-1 top-1/2 transform -translate-y-1/3 cursor-pointer z-100"
          />
          <input
            class="vs__search w-full z-10"
            v-bind="attributes"
            v-on="events"
          />
        </template>
      </vSelect>
    </Field>

    <div class="text-center">
      <ErrorMessage :name="name" class="text-red-500 mt-2 italic" />
    </div>
</template>
          
<script setup>
import { Icon } from "@iconify/vue";
import { Field, ErrorMessage } from "vee-validate";
import vSelect from "vue-select";

const props = defineProps({
  modelValue: {
    type: [String, Boolean, Number, Object, null], 
    required: false,
  },
  defaultSelection: {
    type: [Object, null], 
    required: false,
  },
  options: {
    type: Array,
    required: false,
  },
  name: {
    type: String,
    required: false,
  },
  displayInfoIcon: {
    type: Boolean,
    required: false,
    default: false,
  },
});

const emits = defineEmits([
  "update:modelValue"
]);

const defaultSelectionRef = computed(() => {
  return props.modelValue
});
const item = ref(defaultSelectionRef.value);

// Watch the modelValue prop and update field when it changes
watch(
  () => props.modelValue,
  (newVal) => {
    const selectedValue =
      newVal !== undefined
        ? props.options.find((obj) => obj.value === newVal)
        : props.options[0];
    item.value = selectedValue;
  }
);

// Emit the updated modelValue when the item changes
watchEffect(() => {
  const selectedValue = item.value ?? props.options[0];
  const selected =
    selectedValue.value != undefined ? selectedValue.value : selectedValue;
  emits("update:modelValue", selected);
  emits("onItemChange", selectedValue, props.additionalParam);
});

//On click of the info icon navigate to respective Ontology link
const getInfo = () => {
  console.log("Select Dropdown With Search");
  console.log("Name : " + props.name);
  console.log("Model Value : " + item.value);
};
</script>
        
<style src="vue-select/dist/vue-select.css"></style>
  

2

Answers


  1. Chosen as BEST ANSWER

    I used the @mousedown.native.stop.prevent and that worked fine for me.

    <Icon
    icon="ph:info"
    @mousedown.native.stop.prevent="getInfo"
    class="absolute right-1 top-1/2 transform -translate-y-1/3 cursor-pointer z-10 pointer-events-auto"
    />
    

  2. You can try using the @mousedown.native event, which should work for triggering your getInfo method.

    <template>
      <Field :name="name" v-model="item.value">
        <vSelect
          v-model="item"
          :options="options"
          :getOptionLabel="option.text"
          class="w-full bg-gray-50 dark:bg-gray-700 rounded p-1 z-10"
          appendToBody
        >
          <template #search="{ attributes, events }" class="z-10">
            <Icon
              v-if="displayInfoIcon"
              icon="ph:info"
              width="18"
              height="18"
              @mousedown.native.stop.prevent="getInfo"
              class="absolute right-1 top-1/2 transform -translate-y-1/3 cursor-pointer z-100"
            />
            <input
              class="vs__search w-full z-10"
              v-bind="attributes"
              v-on="events"
            />
          </template>
        </vSelect>
      </Field>
    
      <div class="text-center">
        <ErrorMessage :name="name" class="text-red-500 mt-2 italic" />
      </div>
    </template>
    
    <script setup>
    import { Icon } from "@iconify/vue";
    import { Field, ErrorMessage } from "vee-validate";
    import vSelect from "vue-select";
    
    const props = defineProps({
      modelValue: {
        type: [String, Boolean, Number, Object, null],
        required: false,
      },
      defaultSelection: {
        type: [Object, null],
        required: false,
      },
      options: {
        type: Array,
        required: false,
      },
      name: {
        type: String,
        required: false,
      },
      displayInfoIcon: {
        type: Boolean,
        required: false,
        default: false,
      },
    });
    
    const emits = defineEmits(["update:modelValue"]);
    
    const defaultSelectionRef = computed(() => {
      return props.modelValue;
    });
    const item = ref(defaultSelectionRef.value);
    
    // Watch the modelValue prop and update field when it changes
    watch(
      () => props.modelValue,
      (newVal) => {
        const selectedValue =
          newVal !== undefined
            ? props.options.find((obj) => obj.value === newVal)
            : props.options[0];
        item.value = selectedValue;
      }
    );
    
    // Emit the updated modelValue when the item changes
    watchEffect(() => {
      const selectedValue = item.value ?? props.options[0];
      const selected =
        selectedValue.value != undefined ? selectedValue.value : selectedValue;
      emits("update:modelValue", selected);
      emits("onItemChange", selectedValue, props.additionalParam);
    });
    
    // On click of the info icon navigate to respective Ontology link
    const getInfo = () => {
      console.log("Select Dropdown With Search");
      console.log("Name : " + props.name);
      console.log("Model Value : " + item.value);
    };
    </script>
    
    <style src="vue-select/dist/vue-select.css"></style>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search