Utilizing objects as tags within the Form Tags component in Bootstrap Vue

Let's break down the following code snippet from the documentation:

<template>
  <div>
  <b-form-tags v-model="value" no-outer-focus class="mb-2">
    <template v-slot="{ tags, inputAttrs, inputHandlers, addTag, removeTag }">
      <b-input-group aria-controls="my-custom-tags-list">
        <input
          v-bind="inputAttrs"
          v-on="inputHandlers"
          placeholder="New tag - Press enter to add"
          class="form-control">
        <b-input-group-append>
          <b-button @click="addTag()" variant="primary">Add</b-button>
        </b-input-group-append>
      </b-input-group>
      <ul
        id="my-custom-tags-list"
        class="list-unstyled d-inline-flex flex-wrap mb-0"
        aria-live="polite"
        aria-atomic="false"
        aria-relevant="additions removals"
      >
      <!-- Always use the tag value as the :key, not the index! -->
      <!-- Otherwise screen readers will not read the tag
           additions and removals correctly -->
        <b-card
          v-for="tag in tags"
          :key="tag"
          :id="`my-custom-tags-tag_${tag.replace(/\s/g, '_')}_`"
          tag="li"
          class="mt-1 mr-1"
          body-class="py-1 pr-2 text-nowrap"
        >
          <strong>{{ tag }}</strong>
          <b-button
            @click="removeTag(tag)"
            variant="link"
            size="sm"
            :aria-controls="`my-custom-tags-tag_${tag.replace(/\s/g, '_')}_`"
            >remove</b-button>
          </b-card>
        </ul>
      </template>
    </b-form-tags>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        value: ['apple', 'orange', 'banana', 'pear', 'peach']
      }
    }
  }
</script>

The code above generates the following output: https://i.sstatic.net/hER4m.png

However, if the values are in the form of an array of objects instead of simple strings, how can we render the object properties as tag elements?

For instance, if the value is:

[{name: 'apple', color: 'red'}, {name:'mango', color: 'yellow'}]
, then how can we achieve the same output as shown above? I attempted to use
<strong>{{ tag.name }}</strong>
, but it only displays empty tags for removal, as seen below: https://i.sstatic.net/Fpx1j.png Do you have any suggestions on how to accomplish what I'm trying to achieve here?

Answer №1

It appears that the functionality you are attempting to achieve is not currently supported, as indicated in this discussion

To work around this limitation, you will need to convert your array of objects into a string array and utilize that instead.

When you are ready to utilize the tags, you can then map them back to the original objects as needed.

Below is a basic example of how this can be accomplished.

new Vue({
  el: "#app",
  computed: {
    mappedTags() {
      /* Keep in mind that this is case sensitive */
      return this.options.filter(option => this.value.includes(option.name))
    }
  },
  data: {
    value: [],
    options: [{
        name: 'Mango',
        color: 'Orange'
      },
      {
        name: 'Orange',
        color: 'Orange'
      },
      {
        name: 'Lemon',
        color: 'Yellow'
      },
      {
        name: 'Apple',
        color: 'Red'
      },
      {
        name: 'Banana',
        color: 'Yellow'
      },
    ]
  }
})
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="98faf7f7ecebeceaf9e8d8acb6acb6a9">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f0929f9f848384829180dd868595b0c2dec4dec0">[email protected]</a>/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b4d6dbdbc0c7c0c6d5c499c2c1d1f4869a869a86">[email protected]</a>/dist/bootstrap-vue.js"></script>
<style>
  /* Added for better text visibility */
  
  .text-stroke {
    text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
  }
</style>

<div id="app" class="p-3">
  Recognized (<b>Case-sensitive</b>) tags - [Banana, Apple, Orange, Mango]
  <b-form-tags v-model="value" no-outer-focus class="mb-2">
    <template v-slot="{ tags, inputAttrs, inputHandlers, addTag, removeTag }">
      <b-input-group aria-controls="my-custom-tags-list">
        <b-input
          v-bind="inputAttrs"
          v-on="inputHandlers"
          placeholder="New tag - Press enter to add"></b-input>
        <b-input-group-append>
          <b-button @click="addTag()" variant="primary">Add</b-button>
        </b-input-group-append>
      </b-input-group>
      <ul class="list-unstyled d-inline-flex flex-wrap mb-0">
        <b-card
          v-for="tag in mappedTags"
          :key="tag.name"
          :id="`my-custom-tags-tag_${tag.name.replace(/\s/g, '_')}_`"
          tag="li"
          class="mt-1 mr-1"
          body-class="py-1 pr-2 text-nowrap"
        >
          <strong :style="`color: ${tag.color}`" class="text-stroke">
            {{ tag.name }}
          </strong>
          <b-button
            @click="removeTag(tag.name)"
            variant="link"
          >
            Remove
          </b-button>
        </b-card>
      </ul>
    </template>
  </b-form-tags>
  {{ mappedTags }}
</div>

Answer №2

Substitute {{ tag.name }} with {{ JSON.parse(tag).name }}.

This should offer a solution to the issue.

Answer №3

A scenario where I required user input and selection, consolidating two input values into an array of objects.

Ensure you include a v-model in your inputs to enable passing to a custom function.

<b-form-input
  v-model="werkTagNombre"

<b-form-select
  v-model="werkTagExp"
...

"@click="addingWerkTag({werkTagNombre, werkTagExp})"

Complete template code

<b-form-tags v-model="freelance.tags.nombre">
          <template v-slot="{ inputAttrs, inputHandlers }">
            <b-input-group aria-controls="tags-list">
              <b-form-input
                v-model="werkTagNombre"
                v-bind="inputAttrs"
                v-on="inputHandlers"
                placeholder="Select"
                class="werk-input werk-shadow-input mr-2"
              >
              </b-form-input>
              <b-input-group-append>
                <b-form-select
                  v-model="werkTagExp"
                  :options="experienceOptions"
                  class="werk-input werk-shadow-input ml-2 mr-2"
                >
                </b-form-select>
              </b-input-group-append>
              <b-input-group-append>
                <b-button class="shadow-none ml-2" style="border-radius:6px;"@click="addingWerkTag({werkTagNombre, werkTagExp})"> ADD</b-button>
              </b-input-group-append>
            </b-input-group>
            <span style="font-size: 10px; color: #a5a5a5;">TAGS:</span>
            <ul id="tags-list" class="list-unstyled d-inline-flex flex-wrap mb-0 mt-1">
              <b-badge
                v-for="(werkTag, index) in freelance.tags"
                :key="index"
                tag="li"
                class="mx-1 my-1 werk-tags"
              >
              {{werkTag.nombre}} {{werkTag.experience}}
              </b-badge>
            </ul>
          </template>
        </b-form-tags>

Script

  export default {
data() {
  return {
    freelance: {
      tags: [
        {
          nombre:"Sample name",
          experience:1
        }
      ],
}
...
    werkTagNombre: '',
    werkTagExp: '0',
    experienceOptions: [
      { value: '0', text: 'Select'},
      { value: 1, text: 'less than 2 years'},
      { value: 2, text: '3 to 5 years'},
      { value: 3, text: 'more than 5 years'},
    ]
...

methods:{
 addingWerkTag(value){
    this.freelance.tags.push({nombre: value.werkTagNombre, exp: value.werkTagExp});
  },
 ...
}

If desired, pass the addTag default function in this manner:

Add the functions like "addtag" inside the template slot

<template v-slot="{ inputAttrs, inputHandlers, addTag }">
...

To include it in your custom function:

@click="addingWerkTag({ werkTagNombre, werkTagExp, addTag })"

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

The React application is experiencing difficulties in receiving the response data (JSON) from the Express server, despite the fact that

When making POST or GET requests to our Express server, served through PM2 on EC2, Postman receives the complete response with JSON data. However, our front end React app (both locally and deployed via CF) only gets the response status code and message. Th ...

I am looking for a way to hide email addresses using Regex in JavaScript

I'm looking for a way to hide an email address [email protected]=> [email protected] using JavaScript I attempted to use the /(?<=.{2}).(?=[^@]*?@)/ regex, but it is not functioning properly in Internet Explorer and Mozilla. I need a ...

Creating a versatile function for rendering content

I am working on a unique calendar feature that involves using checkboxes for filtering purposes. So far, I have managed to get all the filters functioning correctly by triggering my render event in this manner: //Initiate render event when checkbox is cli ...

The value of data in Vue.js remains stagnant even after reassignment

In my data setup, I have defined the following: data() { return { mdrender: '', markdown: '' }; }, Additionally, I am working with this function: methods: { interpretVars: function(markdown) { $.ge ...

AJAX is not meeting my expectations

Is there an issue with this code? It's supposed to insert data into the database but I'm not getting any errors. I am new to using ajax, and I found this code which I modified slightly. I thought it would work, but it's not functioning as e ...

Trigger a functional component's function in React using Chrome developer tools

function App() { const myFunction = () => { console.log('hello world!') } return <div>...</div> } After the website has fully loaded and the component is mounted, can we access the JavaScript to call myFunction()? ...

Can fog be applied from a fixed location within a three.js scene without being tied to the camera's position?

Is it feasible to render fog in such a way that an avatar on a terrain remains clear while the surrounding area gradually fades into the mist, especially when the camera is positioned overhead at a distance? ...

Passing an extra variable to the callback function in AJAX and saving the XMLHttpRequest.response as a variable

Attempting to read a local file on the server using the standard loadDoc(url, cfunc) function, my goal is to: 1) Search for a specific string in the file (getLine()); 2) If possible, save that line to a variable. For point 1, I provide a string to the c ...

Using querySelector in VueJS to concatenate variables

My challenge involves combining a Vue variable with an id in querySelector, but unfortunately it is not selecting any element as intended. The code snippet I am currently using is: document.querySelectorAll(".container:not(#`${this.id}`")); The variable ...

Assign a Value to a Hidden Input Type When a User Submits a Form

I have a straightforward form set up in the following code. I am looking to add the value entered in the rm_accounts text box to the hidden page_confirm input value at the end of the URL. I hope that explanation is clear. In simple terms, if the user type ...

When passing parameters through a URL in TypeScript, the display shows up as "[object object]" rather than as a string

Hey there! I'm trying to pass some string parameters to my URL to fetch information from an API. Everything seems fine, and when displayed in an alert, the URL looks exactly as it should (no [object, object] issue). var startDate = "2020-09-20"; var ...

Determine the total number of selected items in MagicSuggest when it loses focus

I have been working with MagicSuggest and I am currently facing an issue where I need to retrieve the length of selections on a blur event. Interestingly, my code functions perfectly fine when a new selection is added using the ENTER key, but it fails when ...

Combining Entities Using Immutable JavaScript

Currently utilizing React, Redux, and Immutable. I have a question about merging a plain JavaScript object into an Immutable Map object. Importing Immutable.js: import { List as iList, Map as iMap } from "immutable"; The content of action.paylo ...

Execute the JavaScript [ window:print() ] function once the webpage has finished loading along with any

I am facing an issue with my web page that has around 10 Google Analytics charts. I want to trigger a print dialog box once the page is fully loaded, including all the charts and JavaScript. Currently, the problem is that the print dialog box opens after t ...

The require statement in Vue.js is failing to function dynamically

Having trouble dynamically requiring an image in Vue.js and it's not functioning as expected <div class="card" :style="{ background: 'url(' + require(image) + ')',}"> export default { data() { return { ...

AngularJS faces issue with view not reflecting changes made to model

A web-based game I am developing lets players bid on cards and trade them with one another. The technology stack for this application includes Node, Express, MongoDB, and Angular. The player avatars and names, along with their connection status, are displ ...

Saving dynamic text input values to the database using asynchronous communication with AJAX

PHP: foreach ($_POST['fields'] as $fieldIndex => $fieldValue) { $stmt = $dbconnect->prepare('INSERT INTO '); <<=== How to insert values $stmt->execute(); } JQuery: $("#add").click(functio ...

Is the size of the JSON file inhibiting successful parsing?

After retrieving a large list of schools with their respective columns from the database, totaling over 1000 rows, I converted it to JSON and passed it to my view. I then attempted to parse it using $.parseJSON('@Html.Raw(Model.subChoiceJsonString)& ...

Creating a curved exponential data set with specific endpoints and a set number of data points

Struggling to create a function that involves math skills, I could really use some assistance. The task is to design a function that takes data points x and generates an array of size x with exponentially increasing values from 0 to 100. It would be ideal ...

Using jQuery, generate a dynamic form to create a multidimensional array

I've set up a form where additional dropdowns can be dynamically added if the user clicks on a specific link. Here's an example of how it looks: <div class="dynamic-sale"> <select name="sizes[]" id="sizes" class="entry-dropdown"&g ...