Execute a function (with arguments) within a v-for loop in Vue.js

Currently, I am attempting to create a select element using Vue.js and Material Design that has 2 levels: categories and items. Each category can contain multiple items which may be selected or not.

<md-select v-if="categories.length > 0" name="categories" id="categories" multiple > 
    <div v-for="(category,key,index) in categories" :key="category.id">
       <md-subheader>{{category.name}}</md-subheader>
       <md-option 
          v-if="category.subItems" 
          v-for="subItem in category.subItems" 
          :key="subItem.id" 
          :value="subItem.id"
          selected="checkIsSelected(subItem.id)">
           {{subItem.name}}
       </md-option>      
     </div>
</md-select>

The resulting select would look something like this:

   Category 1
      [ ] - Item 1
      [x] - Item 2
      [ ] - Item 3
   Category 2
      ...

The issue arises when attempting to determine if an item is already selected from an API. The method being used for this purpose is:

selected="checkIsSelected(subItem.id)"

Within the methods: section:

methods: {

...

  checkIsSelected (catId) {
    this.selectedOld.map((catOld) => {
      if (catId === catOld.id) {
        return true
      }
    })
    return false
  }
}

To summarize:

How can I call a function (with parameters) within an element of a v-for loop to toggle the selection state?

However, it seems that this function is not being called at all. Any advice on where I might be going wrong? I have attempted various solutions but none seem to work as expected.

Your assistance on this matter would be greatly appreciated. Thank you!

Answer №1

After exploring various options, I decided to take a different approach that might benefit others as well.

Instead of directly calling a function within the for loop, I opted to first call the API to verify if it had been selected before and then add an attribute to the subItem element.

With @Ricardo Orellana's solution, during the initial load, it was challenging to determine which item was selected; the selection only became evident when there was a change in the select value.

I employed the v-bind:class option to confirm the selection of the subItem and highlight it:

<md-select v-if="categories.length > 0" name="categories" id="categories" multiple v-model="selectedNew">
  <md-button class="md-icon-button" md-menu-trigger slot="icon">
    <md-icon>{{icon}}</md-icon>      
  </md-button>

  <div v-for="(category,key,index) in categories" :key="category.id">
    <md-subheader>{{category.name}}</md-subheader>
    <md-option 
      v-bind:class="{ 'md-checked' : subItem.selected }"
      v-if="category.subItems" 
      v-for="subItem in category.subItems"
      :key="subItem.id" 
      :value="subItem">
        {{subItem.name}}
    </md-option>      
  </div>
</md-select>

In the method section:

...
cat.subItems = actobj                
cat.subItems.map(this.markIsSelected)
...

markIsSelected (cat, index, categories) {
  categories[index].selected = false
  this.selectedOld.forEach(function (catOld) {
    if (cat.id === catOld.optionId) {
      categories[index].selected = true
      return
    }
  })
}

Thank you for your assistance and time!

Answer №2

One possible solution is to include

v-model="currentCategorySelected"
and utilize the @change="checkIsSelected" function. This allows for the execution of code every time a new option is selected, passing the selected ID through the callback.

Here is an example implementation:

<md-select
  v-if="categories.length > 0"
  name="categories"
  id="categories"
  v-model="currentCategorySelected"
  @change="checkIsSelected"
  multiple>
    <div 
      v-for="(category,key,index) in categories"
      :key="category.id">

      <md-subheader>
        {{category.name}}
      </md-subheader>

      <md-option
        v-if="category.subItems"
        v-for="subItem in category.subItems"
        :key="subItem.id"
        :value="subItem.id"
      >
        {{subItem.name}}
      </md-option>
    </div>
</md-select>

Answer №3

To implement the necessary change, modify

selected="checkIsSelected(subItem.id)"
to use
:selected="checkIsSelected(subItem.id)"
. Don't forget the colon!

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

Utilizing dynamic data within the ng-template

As a newcomer to Angular, I am facing a challenge in passing a string into a template. My goal is to create a reusable template or component that can display instructions on how to proceed with an action. Currently, I am achieving this by using the follow ...

Unexpected token . encountered in Javascript: Uncaught Syntax Error. This error message is triggered when

As someone who is completely new to programming, I was given the task of creating a voting website for a class assignment. In order to store data locally, I managed to create variables and implement them using local storage: var eventName = document.getEl ...

Sending data from jQuery modal to the final input field

In my latest project, I have developed a modal window that features a table with rows of input boxes and buttons: <table class="datatable tablesort selectable paginate full" width="100%"> <tbody> ...

Is the Await keyword failing to properly pause execution until the promise has been fulfilled?

I'm currently working on manipulating a variable within an async function, and I've noticed that the variable is being returned before the completion of the data.map function below. Even though I have the await keyword in place to pause the code ...

What is the hierarchy of fields in package.json?

After submitting a pull request to a repository to include a typings field in the package.json file, the maintainer suggested the following modification: - "typings": "./src/index.d.ts", - "main": "./src/index.js" ...

Having trouble with Angular UI Select functionality?

I have integrated the angular ui select library from https://github.com/angular-ui/ui-select into my project. Instead of using the traditional select element, I am now utilizing the ui-select directive. This is a snippet of my code: <select class=" ...

Utilizing Javascript in Spotfire for enhanced functionality

Currently, I have a dropdown menu with two options ("START" & "END"). Depending on the selected value from this dropdown, I want to display a specific DIV element. I attempted to use the code below, but unfortunately, it is not functioning as expected ...

What could be the reason for not just removing the pseudo-class, but instead deleting the entire CSS document altogether?

var style = document.styleSheets[1] style.deleteRule(`.block__header::after`) console.log(`.block__header::after`) What is preventing it from being removed from the CSS document? The pseudo-class is still found in the console, and when trying to dele ...

What is causing the lack of updated data on the components when navigating to a different page? (Vue.JS 2)

I am working with 2 components The first component looks like this : http://pastebin.com/M8Q3au0B Due to the long code, I have used pastebin for it The first component calls the second component The second component is as follows: <template> ...

Manipulate audio files by utilizing the web audio API and wavesurfer.js to cut and paste audio

I am currently working on developing a web-based editor that allows users to customize basic settings for their audio files. To achieve this, I have integrated wavesurfer.js as a plugin due to its efficient and cross-browser waveform solution. After prior ...

Is it possible to use the same template multiple times in vue.js?

When a page form is submitted, an ajax call is made to a backend service which returns a JSON object. This object is then connected to a Vue.js template (a specific id within a div). Everything functions correctly after the initial submit. However, subsequ ...

When Electron's WebView.loadURL is called, it initiates a reloaded page

According to the documentation provided by Electron, it is necessary to wait until the webview element is available in order to utilize its respective methods. While most methods function properly, I am facing challenges in understanding how to programmati ...

Leveraging Vue.js and TypeScript: accessing the type of the child component through refs

In my parent component, I have a child component named with a reference passed to it: <child ref="childRef" /> When trying to execute a function inside the child component from the parent component, I face some challenges: mounted() { ...

I encountered a PrimeVue error while running a Vue Jest test

When working on a Vue jest test, I encountered an error message "No PrimeVue Confirmation provided!" which seemed to be related to the useToast() and useConfirm() services. "transformIgnorePatterns": [ "<rootDir>/node_modules/(?! ...

Enhancing visual aesthetics with Vuetify on v-slot label components

I am working with Vuetify code that appears like this <v-radio-group v-model="gender" column class="radio-group-full-width"> <v-radio value="Boy"> <template v-slot:label> <v-textarea v-model="answer" v-vali ...

Problem with sidebar animation: Functioning properly when open, but closes abruptly without animation in React using Tailwind CSS

When interacting with my Menu react component by clicking on the 'hamburger' icon that I created manually, the sidebar menu opens smoothly with an animation. However, the issue arises when trying to close the sidebar as it vanishes instantly with ...

Showing data retrieved from nested JSON arrays in React Native

Recently, I delved into the world of React Native and encountered a challenge in displaying nested elements from fetched JSON data. Despite utilizing react hooks in the fetch API, I couldn't quite crack the code. export default function MedProfilScre ...

I am curious about why I am unable to utilize inline functions in component props. Could you please provide a detailed explanation and perhaps give an example to illustrate? Furthermore, what is

Please take note: The component prop accepts a component, not a render function. Do not pass an inline function (e.g. component={() => }), as this will cause your component to unmount and remount, losing all state when the parent component re-renders. F ...

What is the best way to add an additional selected option after the page has been loaded?

I'm currently having trouble adding an extra option to a Chosen after the page has loaded completely. It works fine when I add values before the page loads, but once it's fully loaded, I can't seem to add values to the chosen component, as s ...

What steps can be taken to eliminate the useSearchParams() and Suspense deployment error?

I'm encountering an issue where ⨯ useSearchParams() needs to be enclosed within a suspense boundary on the page "/PaymentPage". More information can be found at: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout Although I have wra ...