kawnah
kawnah

Reputation: 3404

v if equal to data attribute

how do you do this? I have a method that gets called on a select where on change I want to hide everything else thats not the selected attribute. When the see all option is picked, everything should be shown.

The thought process is to leverage v-model to check if its equal to a data attribute and hide everything else otherwise. If all options are selected, the v-model (in this case, "selectedDep") equals out to just nothing, show them all.

Vue.js v-if for attributes

is only talking about adding the attr which is not my problem.

I'm trying to do something like this:

Select Tag:

<select type="text" id="job-teams" @change="onDepChange($event)" placeholder="Filter By Department" name="teams" v-model="selectedDep">
   <option value="">All Departments</option>
   <option v-for="listing in listings" :value="listing.title">{{ listing.title }}</option>
</select>

Div I want to hide based on selected option (this is where I'm stuck)

<div v-for="listing in listings" :data-department="listing.title" v-if="selectedDep === '' || selectedDep === data-department">

Data

data: {
    listings: [],
    locations: [],
    message: 'job postings',
    selectedDep: '',
    error: null
  },

Method

onDepChange: function(event) {
      this.selectedDep = event.target.value
      console.log(this.selectedDep)
}
  1. the first attempt looks like this:
<div v-for="listing in listings" :data-department="listing.title" v-if="selectedDep === '' || selectedDep === data-department">

This throws multiples of the same error in the console:

Property or method "department" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

Where is it getting "department"? I don't have "department" but "data-department"? I read the documentation:

Since Vue doesn’t allow dynamically adding root-level reactive properties, you have to initialize Vue instances by declaring all root-level reactive data properties upfront, even with an empty value:

If you reference my data object above I'm doing that. The link/documentation is not helpful.

  1. The second attempt:
<div v-for="listing in listings" :data-department="listing.title" v-if="selectedDep === '' || selectedDep === :data-department">

I thought maybe adding a colon would do it but

[Vue warn]: Failed to generate render function:

SyntaxError: Unexpected token ':' in

Is apparently a syntax error so that doesn't work.

v-show based on select option data attribute value

This answer only seems to address boolean values (true/false) not comparing several data attribute values.

To conclude

In the context of vue js, how do you do: "if the selected item in a dropdown matches the data attribute of a div - show that one and hide everything else, otherwise if its empty show them all" ... ?

Upvotes: 1

Views: 1524

Answers (2)

muka.gergely
muka.gergely

Reputation: 8329

You don't need a v-if for controlling what data you want to display. Also, you shouldn't use v-if on the same tag as with v-for (more on this here).

Solution: create a computed value and list that with a v-for.

new Vue({
  el: "#app",
  data: {
    listings: [{
        title: "Listing 1",
      },
      {
        title: "Listing 2",
      },
      {
        title: "Listing 3",
      },
    ],
    locations: [],
    message: 'job postings',
    selectedDep: '',
    error: null
  },
  computed: {
    selectedListing() {
      return this.selectedDep ? this.listings.filter(({
        title
      }) => title === this.selectedDep) : this.listings
    },
  },
  methods: {
    onDepChange: function(event) {
      this.selectedDep = event.target.value
      console.log(this.selectedDep)
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <select type="text" id="job-teams" @change="onDepChange($event)" placeholder="Filter By Department" name="teams" v-model="selectedDep">
    <option value="">All Departments</option>
    <option v-for="listing in listings" :value="listing.title">{{ listing.title }}</option>
  </select>
  <div v-for="listing in selectedListing" :department="listing.title">
    {{ listing.title }}
  </div>
</div>

Upvotes: 1

kawnah
kawnah

Reputation: 3404

Ok I figured it out: vue,js doesn't like comparing something to data-department (I don't know why, if anyone reading wants to leave a comment explaining why, much appreciated) you instead have to compare to the object value (in this case, listing.title)

So:

<div v-for="listing in listings" v-if="selectedDep === '' || selectedDep === listing.title">

Upvotes: 0

Related Questions