0

I am using VueJS, and I have a list of genre buttons that are being dynamically created. These buttons have the ability to be toggled on and off, and when they are toggled on, I want to apply CSS styling (like a blue background) to show they are selected. When they're not selected, I want it to go back to how it is (white background with grey border).

My problem is that I can't achieve the toggling background color feature. I have tried to use variant="primary" as well as other variant options, but it does not work. I have also tried erasing the style="border: 2px solid darkgrey; margin:2px;" while applying variant, however that also doesn't work.

I've resorted to trying to just directly change the CSS of the buttons, using StackOverflow post, but it does not work.

This is the buttons markup in my index.html:

<ul style="list-style: none;">
    <button v-if="ShowALLButton" v-on:click="getAllGenres" class = "btn btn-success" style="left: 0px; margin:2px;">ALL</button>
        <li style="display: inline;">
          <button v-for="buttons in buttonsList" v-if="ShowALLButton" v-on:click="getGenre(buttons)" :pressed.sync="buttons.state" id="buttonID" class = "btn" style="border: 2px solid darkgrey; margin:2px;">
            {{ buttons.genre }}. 
          </button>
        </li>
</ul>

Essentially, the above is a for-loop iterating through my buttonsList, which is a structure that looks like this, containing the genre to display on the buttons, as well as whether it has been toggled on or off (indicated by state, which is initially toggled off, as represented by false). The actual toggling functionality works, because it shows the correct genre(s) results. But for those curious, this is what buttonsList looks like (a list of objects):

[
{ genre: "Folk", state: false },
{ genre: "Rap", state: false },
{ genre: "Pop", state: false },
...
]

The relevant styling from index.html:

<style>
 .am-active {
    background-color: rgb(21, 79, 202);
    color: white;
 }
 .am-not-active {
    background-color: white;
 }
</style>

The function that deals with the buttons toggling and genre selection is in my script.js. It is in the todo! that I need to apply the correct CSS styling to change the buttons, but I am unable to.

// Get Selected Genres
getGenre(button) {
  console.log("ENTERED GET GENRE!!!!!!");
  var selectedGenresItems = []

  // keep track of selected genres
  if (!this.selectedGenres.includes(button)) {
    this.selectedGenres.push(button);
    // todo!
    console.log("inside if");
    button.className += 'am-active';
    console.log(button);
    // ^ the above does not work, it just adds a key with "className" = "undefinedam-active" :(
  }
  else {
    this.selectedGenres.pop(button);
    // todo! must use .am-not-active
  }

  // you can stop reading here if you want
  // print out the list 
  console.log("selectedGenres here:");
  console.log(this.selectedGenres);

  // get only items that have the desired genre
  var num_matches= 0;
  console.log("items length:" + this.items.length);
  console.log("selectedGenres length:" + this.selectedGenres.length);
  for (var start = 0; start < this.items.length; start++) {
    for (var g = 0; g < this.selectedGenres.length; g++) {
      if (this.items[start].primaryGenreName === this.selectedGenres[g].genre) {
        console.log("we found a match!!!");
        num_matches++;
        selectedGenresItems.push(this.items[start]);
      }
    }
  }

  console.log("num_matches: " + num_matches);
  console.log("this is my final list of selectedGenreItems:")
  console.log("object: %O", selectedGenresItems);

  // assign this list to filteredItems (which renders on index.html)
  this.filteredItems = [];
  this.filteredItems = selectedGenresItems;

  // print out the items in this list
  console.log("items in filteredItems:");
  console.log(this.filteredItems);
}

1 Answer 1

1

You can bind the class attribute & enable / disable a class on basis of state key of the buttonsList state.

new Vue({
  el: '#app',
  
  data: {
    buttonsList: [
      { genre: "Folk", state: false },
      { genre: "Rap", state: false },
      { genre: "Pop", state: false },
    ]
  },
  
  methods: {
    getGenre (buttons, i) {
      this.buttonsList[i].state = !this.buttonsList[i].state
    }
  }
})
.am-active {
    background-color: rgb(21, 79, 202);
    color: white;
 }
 .am-not-active {
    background-color: white;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

  <ul>
    <li>
      <button 
        v-for="(buttons, i) in buttonsList" v-on:click="getGenre(buttons, i)"
        :class="{
          'am-active': buttons.state,
          'am-not-active': !buttons.state
        }"
        :key="i"
      >
        {{ buttons.genre }}. 
      </button>
    </li>
  </ul>

</div>

Sign up to request clarification or add additional context in comments.

1 Comment

@McFloofenbork pls accepts / upvote if you found the answer useful, this will help other users identify the correct answer with ease. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.