5

I have problem with checkboxes and vue filter of array.

new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript"},
      { text: "Learn Vue"},
      { text: "Play around in JSFiddle"},
      { text: "Build something awesome"}
    ],
    search: '',
  },
  methods: {
  	
  },
  computed: {
  	filtered() {
      return this.todos.filter(todo => {
        return todo.text.toLowerCase().includes(this.search.toLowerCase())
      })
    },
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="text" v-model="search">
  <ol>
    <li v-for="todo in filtered">
      <label>
        <input type="checkbox">

        <del v-if="todo.done">
          {{ todo.text }}
        </del>
        <span v-else>
          {{ todo.text }}
        </span>
      </label>
    </li>
  </ol>
</div>

If you check first from array and search for any of others:

Check -> Learn javascript

Search -> Learn Vue

Vue appear to be checked..

Is that suppose to work like that?

How can I remove all from displayed list and append same time?

4
  • 1
    Vue apears to be checked because of vue's optimization. Use v-model for each checkbox to avoid that. Commented Mar 1, 2019 at 9:11
  • Can you produce a working example? Commented Mar 1, 2019 at 9:12
  • The real question is, why is this happening, I'm also curious. Commented Mar 1, 2019 at 9:23
  • 1
    @Deda Because of vue's optimization proccess. It uses virtual DOM to do as little changes to DOM as possible. Commented Mar 1, 2019 at 9:29

2 Answers 2

3

Use v-model to bind in filtered array

new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript"},
      { text: "Learn Vue"},
      { text: "Play around in JSFiddle",done:true},
      { text: "Build something awesome"}
    ],
    search: '',
  },
  methods: {
  	
  },
  computed: {
  	filtered() {
      return this.todos.filter(todo => {
        return todo.text.toLowerCase().includes(this.search.toLowerCase())
      })
    },
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="text" v-model="search">
  <ol>
    <li v-for="todo in filtered">
      <label>
        <input v-model="todo.done" type="checkbox">
          <del v-if="todo.done">{{ todo.text }}</del>
          <span v-if="!todo.done">{{ todo.text }}</span>
          
      </label>
    </li>
  </ol>
</div>

Here is put checked by default for Play around in JSFiddle

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

7 Comments

This works but, I am fetching 'todos' as data from database.... I need to append additional field for each...
@Learner : what additional field ? can you share ?
That one for v model, like when I return data I return id, name and in todos array i have objects with id and name and for each I need to add done for v model
can you add this in your question so that we can understand better.
you answered my question and it works, but I need to add custom field for each result from database for v-model, or to add it on client side but I need to go throught all and add like: todo[done] = false or something like that, seems like too much work for something like this...
|
1

Simply just add done: false in todos and add v-model="todo.done" to input in v-for.

Example on JSFiddle

Differences from your code:

// added `done`
todos: [
  { done: false, text: "Learn JavaScript"},
  { done: false, text: "Learn Vue"},
  { done: false, text: "Play around in JSFiddle"},
  { done: false, text: "Build something awesome"}
]
<!-- added `v-model="todo.done"` -->
<input v-model="todo.done" type="checkbox">

2 Comments

How to add done: false to your data (array of JSON objects): for (var i in data) { data[i]['done'] = false; } OR for (var i in data) { data[i].done = false; }
Both ways should work. Btw, it's better to create a computed method in your component with mutated (modified) array and use array's map function. Something like this computed: { todosWithMark() { return this.todos.map(todo => ({ ...todo, done: false})) } } and use it.

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.