MissKnacki
MissKnacki

Reputation: 279

Drop down list with Vue JS

I code an html page with a drop-down list with HTML CSS and VueJS. I want that if I click on a certain option in my drop-down list, it display something in console.

My html code :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="css/style.css">

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script type="text/javascript" src="js/historique.js"></script>

    <title>Historique</title>
</head>
<body>
    <select id="selectionMachines" size="1">
        <option v-for="todo in todos"  v-on:click="action">
            {{ todo.libelle }}
        </option>
    </select>
</body>
</html>

And my JS code :

window.onload = function () {
    var machines = new Vue({
        el:"#selectionMachines",
        data: {
            todos: [
                { libelle: "Machine 195", num: 195},
                { libelle: "Machine 196", num: 195}
            ]
        },
        methods: {
            action: function() {
                console.log(this.todo.num);
                if (this.todos.num == 195)
                    console.log("J'ai choisi 195");
            }
        }
    })
}

The action function doesn't work for the moment, undefined is log in console. Any idea ?

Upvotes: 1

Views: 1578

Answers (2)

muka.gergely
muka.gergely

Reputation: 8329

  1. The event should be bound to <select>.

  2. The event should pass the $event variable to the function

  3. The options' values should be bound to the options themselves (:value=""). You'll get this value with the $event ($event.target.value)

  4. Even though you literally click on a <select> and the <option>, the event is not click(), but input or change, as it's an input field. This is not VueJS question, but JavaScript.

  5. Your action() method is a function, so if you want it to get executed, then you have to call it with parantheses (action()), and not it's "string value" (action). This is unlike computed in VueJS templates, but VueJS handles the difference.

  6. Pay attention to your todos - both have a num key with value 195 (so you won't see a difference in the console, both will log 195 there), although their label (libelle) implies 195 and 196

  7. You write console.log(this.todo.num); and this.todos.num == 195 in your action() method. I guess you tried to use the single todo item that's selected in the input. The problem with this is that the input (and the todo in todos) only exist in your template, your scripts (like methods) don't know about them - you have to pass the information somehow to those scripts ($event is good for that). If you want to get the whole single todo object to work with, then I suggest find() (or filter() as your num value is not unique).

new Vue({
  el: "#selectionMachines",
  data: {
    todos: [{
        libelle: "Machine 195",
        num: 195
      },
      {
        libelle: "Machine 196",
        num: 195
      }
    ]
  },
  methods: {
    action: function(event) {
      console.log(event.target.value)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<select id="selectionMachines" size="1" @change="action($event)">
  <option v-for="todo in todos" :value="todo.num">
    {{ todo.libelle }}
  </option>
</select>

Upvotes: 2

Eugene Kramorev
Eugene Kramorev

Reputation: 28

Try this:

<option v-for="todo in todos" @click="action(todo)">
            {{ todo.libelle }} 
</option>
action(todo) { if (todo.num === 195) console.log("J'ai choisi 195"); }

Upvotes: 0

Related Questions