Employing a pair of interdependent v-select components to prevent any duplicate entries

I am currently working with two v-select boxes that share similar data. In my scenario, I extract attachments from an email and load them into an array. The issue I encountered is that the first select box should only allow the selection of one document, while the second select box should only display items that have not been chosen in the first v-select box. Below is a snippet of my template code:

                            <v-select v-model="selectedResponses"
                                  :items="attachments"
                                  item-value="id"
                                  item-text="name"
                                  label="First Document"
                                  persistent-hint
                                  filled
                                  chips
                                  return-object></v-select>            
                        <v-select v-model="selectedSupportingDocs"
                                  :items="availableSupportingDocs"
                                  item-value="id"
                                  item-text="name"
                                  label="Additional Documents"
                                  persistent-hint
                                  multiple
                                  filled
                                  chips
                                  return-object></v-select>

To address this issue, I decided to make the items for the second v-select box a computed property by removing the selected value in the first v-select box. However, the problem I'm facing is that whatever I choose in the first box becomes the only available option in the second v-select box. It seems like the splice() function is not working as expected.

            computed: {
            availableSupportingDocs() {
                if (this.selectedResponses == null) return this.attachments;

                for (let i = 0; i < this.attachments.length; i++) {
                    if (this.selectedResponses.id === this.attachments[i]["id"]) {
                        console.log(this.attachments[i]["name"])
                        console.log(this.attachments.slice().splice(i, 1))
                        return this.attachments.slice().splice(i,1)
                    }
                }

                return this.attachments
            }
        },

Answer №1

When using the .splice() method, keep in mind that it will alter the original array and return a new array with the removed values:

const arr = [1,2,3,4]
const splicedOff = arr.splice(2,1)

const s = JSON.stringify
console.log('spliced:', s(splicedOff), 'remaining:', s(arr))

It is important to note that only the element you didn't want to include will be returned.

There are a couple of ways to address this issue:

  • Assign the modified array to a new variable before using .splice(), then return that variable
const newAttachments = this.attachments.slice()
newAttachments.splice(i,1)
return newAttachments
  • Alternatively, you can utilize .filter()
return this.attachments.filter((_,ix) => i !== ix)

By using filter(), you can eliminate the need for an outer loop:

availableSupportingDocs() {
  return !this.selectedResponses 
  ? this.attachments
  : this.attachments.filter((attachment) => this.selectedResponses.id !== attachment.id)
}

In your comments, you mentioned that when selectedResponses change, you may need to update the value of selectedSupportingDocs. This can be achieved through a watcher or an event handler.

A watch function would look like this:

watch: {
  selectedResponses: function () {
    if(this.selectedResponses?.id === this.selectedSupportingDocs.id) {
      this.selectedSupportingDocs = null
    }
  },
},

For an event handler approach, add a @change to the v-select:

<v-select
  v-model="selectedResponses"
  :items="attachments"
  ...
  @change="adjustSupportingDocsSelection"
/>

The corresponding method would be placed in the component methods:

methods: {
  adjustSupportingDocsSelection(){
    // same as above
  }
}

Personally, I lean towards using the event handler because it is more explicit. The watcher is advantageous if there are other mechanisms that could change selectedResponses, covering all scenarios. Choose the approach that aligns best with your preferences.

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

"Unlocking the Potential: Maximizing the Benefits of the top.gg Vote Web

My bot has been verified on top.gg, and I'm looking to offer rewards to users who vote for my bot. How can I detect when someone votes for my bot, get their ID, check if it's the weekend, and take action after the vote? Essentially, how do I util ...

Is there a way to turn off linting while utilizing vue-cli serve?

I am currently running my project using vue-cli by executing the following command: vue-cli-service serve --open Is there a way to stop all linting? It seems like it's re-linting every time I save, and it significantly slows down the process of ma ...

Utilize Jasmine's AJAX spy to intercept and inspect the error request

I am encountering an issue while trying to monitor the ajax error request and receiving the following error message. Can someone assist me with this? TypeError: e.error is not a function Code snippet for JS testing : function postSettings() { $ ...

What is the method to have the text cursor within a text field start a few pixels in?

I need a text field with the cursor starting a few pixels (let's say 4) from the left-hand side. I am aware that this can be achieved by adjusting the size of the text field using padding, but I am curious if there is a way to resize the text box with ...

Encountering an Unexpected Error in Next.js When Revalidating Paths

I'm facing an issue with my Next app where, despite editing a resource through an API endpoint following the pages-based system, the changes aren't reflected when I try to view or re-edit the resource. After checking the documentation, I discover ...

What is the best option: using a Javascript template or exploring another

Just starting out in web development. I want to include the same menu on every page of my new website, but I don't want to manually update it in each file whenever there's a change. Is there an easy template engine for JavaScript or another sol ...

The tab component is failing to load due to an issue with the Bootstrap tab

I've created a page displaying different locations with two tabs - one for Google Maps and another for weather. For example, take a look at this location: The issue I'm facing is that when switching between the tabs, they don't load fully. ...

What is the best way to automatically insert data into a database at regular intervals, while ensuring that users are unable to manipulate the timing through inspect

Is there a secure way to insert 1 point into the database every x seconds without allowing users to manipulate the interval time through inspect element? var time = 1; var interval = setInterval(function() { if (time != time + 1) { ...

Navigating and extracting nested JSON properties using JavaScript (React)

I am currently working with a nested JSON file that is being fetched through an API. The structure of the JSON file looks something like this: { "trees":{ "name":"a", "age":"9", "h ...

Troubleshooting Issue with jQuery replaceWith in Loop

Trying to make it so that when the update button is clicked, the text on the left side becomes an input box: Click the update button and the text on the left will be an input box However, instead of just one input box appearing, all the text on the left s ...

What is the best way to trigger a javascript modal to open automatically after a specific duration

Let's take an instance where my modal has the ID #modal1. It usually appears through a button-based action. ...

Utilizing jQuery for asynchronous image uploading

Just started learning jQuery and I'm having trouble uploading a jpg image file using the ajax method. It seems like it's not working properly. Can anyone guide me through this process? HTML <form action="" method="POST" enctype="multipart/fo ...

The popularity of AJAX in JavaScript is continuing to rise

I am facing an issue with my website that features a configurable 3D object with various properties. Whenever I reload the div containing the 3D object to reflect new properties, the script data keeps adding on. This not only slows down the functionality a ...

Extract information from a string to retrieve the array specifications

After making a request to the server, I received the following response: { "statusCode": 200, "body": "{\"Errors\":\"\",\"Message\":\"\",\"Output\":\"\",\"TokenID\":\"F10645774 ...

What is the best way to include JSON values for specific keys using JavaScript, jQuery, or AngularJS?

Below is a sample of the json: var json = var data = [{ "a": 150 }, { "a": 50 }, { "b": 100 }, { "b": 25 }]; I aim to combine the values of "a" and "b" in a new finaljson(the desired output json), like so: var finaljson = [{ "a": 200 ...

"Encountering a problem with posting API requests using Express

I've encountered a problem where I keep receiving a 404 error when trying to post to a specific route. Here's the code snippet: app.js (code snippet for app.js) .... module.exports = app; api.js (code snippet for api.js) .... module.export ...

"Every time an Ajax call is successful, the 'else' clause in

When it comes to using Ajax for user login in the system, I encountered an issue where the Ajax success function would always run the else statement even if the server returned a true Boolean value. This meant that even when the login credentials were vali ...

Tips for aligning actions to the right of a Vue3 Quasar horizontal card

Looking for help on getting the actions aligned to the far right side while keeping a small title using Quasar classes or Flexbox. When I try replacing the text on the right, it shifts the actions over which is not what I want. Codepen: https://codepen.io ...

Leveraging JQuery for form submission

My webpage contains a form with the following structure: <form action="/" method="post"> <select id="SelectedMonth" name="SelectedMonth"> <option>7/1/2017</option> <option>6/1/2017</option> </select> </form> ...

Retrieve the value of the following object in a loop - Vue JS

I needed to verify whether a specific property of an object matches the property of the next object in an array of objects while looping through using a v-for loop. Here's an example JSON object: [ { Date: '21-July-2017', ...}, { Date: ...