Leveraging the capabilities of vue-select, or any other sleek select box, with ESM build of Vue 3

In my current setup, I have a client-side javascript app using Vue 3 with the following structure:

HTML (including a select box):

<html>
  <head>
    <title>Test</title>
  </head>
  <body>
    <div id="vuetest">
      <select id="assignment-select" v-model="ft_assignment">
        <optgroup v-for="optgroup in ft_assignments" :label="optgroup.text">
          <option
            v-for="option in optgroup.children"
            :value="option.id"
            :disabled="option.disabled"
          >
            {{ option.text }}
          </option>
        </optgroup>
      </select>
    </div>

    <script type="module">
      import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";

      const app = createApp({
        data() {
          return {
            ft_assignment: "a",
            ft_assignments: [
              {
                text: "hi",
                children: [
                  { id: "a", text: "a1" },
                  { id: "b", text: "b1" },
                ],
              },
              {
                text: "there",
                children: [
                  { id: "c", text: "c1" },
                  { id: "d", text: "d1" },
                ],
              },
            ],
          };
        },
        watch: {
          ft_assignment(v) {
            console.log(v);
          },
        },
      }).mount("#vuetest");
    </script>
  </body>
</html>

I am looking to enhance the select box by incorporating a more modern and feature-rich alternative like vue-select or select2. However, I'm unsure of how to integrate these components without introducing compatibility issues between jQuery and Vue.js. Therefore, I want to avoid directly implementing select2 as a jquery plugin.

Any suggestions on transforming the select box into a sleeker and contemporary select element are much appreciated!

Answer №1

While this example does not utilize the esm build of vue 3, it still relies on the UMD build which is directly supported in the browser. The reason for this approach is that the vue-select library does not offer an esm build version at the moment, but it does work with the UMD build.

To include the necessary dependencies, follow these steps:

<script src="https://unpkg.com/vue@latest"></script>
<script src="https://unpkg.com/vue-select@beta"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-select@latest/dist/vue-select.css" />

Next, import the vue component like so:

const { createApp } = Vue;

Then import the vue-select component in this manner:

const app = createApp({
  components: {
    vSelect: window["vue-select"],
  },
  ...

For a functioning code snippet, refer to the following:

<html>
  <head>
    <title>Test</title>
    <script src="https://unpkg.com/vue@latest"></script>
    <script src="https://unpkg.com/vue-select@beta"></script>
    <link
      rel="stylesheet"
      href="https://unpkg.com/vue-select@latest/dist/vue-select.css"
    />
  </head>
  <body>
    <div id="vuetest">
      <v-select :options="flattenedFtAssignemnts" label="text"></v-select>
    </div>
    
    <script type="module">
      const { createApp } = Vue;

      const app = createApp({
        components: {
          vSelect: window["vue-select"],
        },
        data() {
          return {
            ft_assignment: "a",
            ft_assignments: [
              {
                text: "hi",
                children: [
                  { id: "a", text: "a1" },
                  { id: "b", text: "b1" },
                ],
              },
              {
                text: "there",
                children: [
                  { id: "c", text: "c1" },
                  { id: "d", text: "d1" },
                ],
              },
            ],
          };
        },
        computed: {
          flattenedFtAssignments() {
            return this.ft_assignments.map(obj => obj.children).flat();
          }
        },
        watch: {
          ft_assignment(v) {
            console.log(v);
          },
        },
      });

      app.mount("#vuetest");
    </script>
  </body>
</html>

It's worth noting that vue-select presently does not support the use of <optgroup>, hence the need to flatten the children for selection purposes.

Answer №2

If you're not a fan of plugins and prefer to create it from scratch (that's how I like to do it).

To achieve this, simply create a div that contains a text input field for searching within the same div. The options are hidden anchor tags stored inside another div. Next, attach an event listener to these anchor tags with the corresponding function to be called.

Take a look at this approach, feel free to customize it to suit your needs perfectly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Component does not detect change when the same number is sent as input

Let me paint you a picture: I have this nifty component, set up with the OnPush strategy, that showcases a PDF document, sliding through pages one by one, and granting users the ability to smoothly glide through pages and jump to specific ones. It even of ...

A guide on cycling through the data within the input fields

Here's my code snippet: <div class="form-group row text-right" *ngFor='let row of vipInput'> <label class="col-sm-3 form-control-label m-t-5" for="password-h-f"></label> <div class="col-sm-9 form-control-label m-t-5 ...

jQuery is displaying fields inside the widget box that were supposed to have been removed

I am currently working on a project with a widget foldable box function called Metadata Widget. This widget displays certain fields, and I have added an import button to the side that calls upon the Metadata Widget and shows it. However, I have noticed tha ...

Issue with Google chart: The visualization type gantt is invalid

I have attempted the solution provided here but unfortunately, the issue still persists. I modified useGstaticLoader: true in this However, upon checking the view, I received an error message stating: Invalid visualization type: gantt I would appreciate ...

Sort through nested objects

Trying to filter an array of movies by genre using a function but encountering a TypeError: TypeError: movie.genres.some is not a function. (in 'movie.genres.some(function(item){return item.name === genre;})', 'movie.genres.some' is und ...

No entries found in the Nuxt/content module's array

<template> <div> <input v-model="searchQuery" type="search" autocomplete="off" placeholder="Search Articles" /> <ul v-if="articles.length"> ...

JQuery email validation failing to function

I am new to JQuery and have created a basic validation script to verify email addresses. However, it does not seem to be working properly. Can anyone provide guidance on how to correct this issue? <script> $( "#email" ).blur(function() { var ...

Prevent modal from closing when tapping outside of it

I'm currently facing a challenge in creating a popup modal that cannot be closed by clicking outside the modal window. I have explored various solutions involving backdrops but none of them seem to be effective. Any assistance would be greatly appreci ...

Avoiding the need to escape quotes in a JavaScript object created from PHP

Although I have searched extensively, I cannot seem to find a solution that addresses my specific issue. It feels like this question must have been asked before and answered countless times. My current problem involves loading data from MySQL using PHP, w ...

Using the named function and function parameter to call `preventDefault()` and avoid the default

I want to incorporate an e.preventDefault() call in my event listener. My function, "voteNoClick", needs to receive a parameter named "direction". How can I pass both the direction parameter and the event object into the function, allowing me to include e. ...

What is the best way to implement rate limiting or throttling on a Strapi API?

Our company relies on a simple strapi API implemented in node.js and hosted on Heroku. Despite our efforts, we have not been able to find a solution to implement rate limiting, as it appears that Heroku does not offer throttling add-ons and strapi lacks bu ...

JavaScript code to allow two textboxes to be enabled at the same time when a checkbox is

One question I have regarding the code snippet below : <input id="myCheckBox" type="checkbox" name="alamatCat" onClick="apply(this.checked, 'textBox3', 'textBox4')"> OT Date </td> <td> From <input id="text ...

Using NextJs Link component to wrap an Image element can lead to errors when iterating over an array, unless it is positioned within the

I am currently working on implementing NextJs's <Link /> tag to wrap a NextJs <Image /> within my application in order to iterate over an array of data. Everything functions as expected and renders correctly when I place the <Link /> ...

I am unable to select the first item when using select2.js and setting a placeholder

I am experiencing an issue with my <select> list that is styled using select2.js. Everything seems to be functioning properly, except for when a placeholder is used. Users are unable to select the first item in the list initially. If they choose any ...

Strategies for transferring all selected checkbox IDs to REST endpoint

I'm currently diving into web development and have set up a few checkboxes on my page. Right now, I have four checkboxes available. My goal is to send the IDs of the checkboxes that the user has checked to my "REST Service". Below is the code that I&a ...

Upon installation, the extension that replaces the new tab fails to detect the index.html file

edit: Check out the Chrome Extension here Edit 2: It seems that the recent update containing the index.html file was not published due to Google putting it under revision. Apologies for forgetting to include the index.html file in the upload zip, as I ...

Display the outline of a translucent image

Looking to create an image reveal effect on my website. I want to display only the outline of a transparent image using brightness, then gradually reveal the full image by removing the brightness effect. Currently, I achieve this with a black outline usi ...

Create a scrollable div within a template

After discovering a template that I want to use for my personal project, I noticed a missing element... There's a div where content can be added. That's fine, but what if I add more content than fits in the space provided? The whole website beco ...

Empty promise will be followed by an array that is empty

How can I fetch time from Firestore using a promise in Angular CLI 8, but the array is empty because the promise has not resolved yet? How can I ensure the array is only called after the getTime() function has finished executing? example.service.ts teste ...

Tips for changing SVG element style using JavaScript

After creating an inline SVG with multiple rectangle elements and applying the same color to all of them using CSS, I assigned unique IDs to each rectangle. However, when attempting to manipulate the rectangles' colors with plain JavaScript, the chang ...