0

I have these checkboxes which always stay checked but I only want to check them if the object they are associated with's property called include is set to true.


right now my issue is that all the boxes stay checked, then when I click them they uncheck and then exclude students. I need to make the boxes unchecked unless I check them.

I don't have a checked attribute set on the template so I don't know why they would be checked by default? I'm hoping someone can point out my mistake.

my absent students data:

absentStudents: [{
                    "id": 207,
                    "first_name": "Gabriel De Manuel",
                    "include": false,
                    "avatar": null,
                    "group_id": 24,
                    "full_name": ", Gabriel De Manuel",
                    "exclude": false ,
                    "isGrouped": false, 
                }, {
                    "id": 208,
                    "first_name": "Francisco",
                    "include": false,
                    "avatar": null,
                    "group_id": 24,
                    "full_name": ", Francisco",
                    "exclude": false, 
                    "isGrouped": false, 
                }, {
                    "id": 209,
                    "first_name": "Rosa",
                    "include": false,
                    "avatar": null,
                    "group_id": 24,
                    "full_name": ", Rosa",
                    "exclude": false,
                    "isGrouped": false,  
                }],
            excludeAbsent: false,

//my v-model is created by the following function
 created() {
                this.absentStudentsSelected = this.absentStudents.map(x => x.id);
            },

I have rendered these checkboxes for my list

 <ul>
                    <li v-for="absentStudent in absentStudents" class="list-unstyled">
                        <input type="checkbox" @click="check($event)" v-model="absentStudentsSelected" :value="absentStudent.id">
                        {{ absentStudent.first_name }}
                    </li>
                </ul>

check the boxes for each student as long as this.excludeAbsent is true

check: function(e){  
                    if(this.excludeAbsent === true){ //if we want to include absent students

                    for(var i = 0; i< this.absentStudents.length; i++){
                        if(e.target.value == this.absentStudents[i].id){

                                this.absentStudents[i].include = true 
                            }else{
                                this.absentStudents[i].include = false 
                            }
                        }
                    }
8
  • It looks like you're tying the checkbox values to the following absentStudentsSelected with v-model but I don't see this data anywhere? Commented Apr 12, 2020 at 23:06
  • 1
    they are checked by default ? that's the issue? Commented Apr 12, 2020 at 23:11
  • Yes I understood but what is absentStudentsSelected referencing in your data as if it is referencing an empty array your checkboxes should be deselected on load, if you have something like: absentStudentsSelected:[208,207,209] based on the above the boxes would be checked Commented Apr 12, 2020 at 23:36
  • 1
    @RBowen you are correct, it is rendering the absentStudents.id I have updated my code to include create() where this happens. Do you know how I should render these values different so I can set the boxes to unchecked? Commented Apr 13, 2020 at 0:04
  • 1
    As below if you set as an empty array in your data option and remove the created function this should fix Commented Apr 13, 2020 at 0:16

2 Answers 2

2

absentStudentsSelected should be initialized as an empty array in your data option :

let app = new Vue({
  el: "#app",
  data() {
    return {
      absentStudents: [{
        "id": 207,
        "first_name": "Gabriel De Manuel",
        "include": false,
        "avatar": null,
        "group_id": 24,
        "full_name": ", Gabriel De Manuel",
        "exclude": false,
        "isGrouped": false,
      }, {
        "id": 208,
        "first_name": "Francisco",
        "include": false,
        "avatar": null,
        "group_id": 24,
        "full_name": ", Francisco",
        "exclude": false,
        "isGrouped": false,
      }, {
        "id": 209,
        "first_name": "Rosa",
        "include": false,
        "avatar": null,
        "group_id": 24,
        "full_name": ", Rosa",
        "exclude": false,
        "isGrouped": false,
      }],
      excludeAbsent: false,
      absentStudentsSelected: []
    }
  },
  methods: {
    check: function(e) {
      if (this.excludeAbsent === true) {
        for (var i = 0; i < this.absentStudents.length; i++) {
          if (e.target.value == this.absentStudents[i].id) {

            this.absentStudents[i].include = true
          } else {
            this.absentStudents[i].include = false
          }
        }
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <ul>
    <li v-for="absentStudent in absentStudents" class="list-unstyled">
      <input type="checkbox" @click="check($event)" v-model="absentStudentsSelected" :value="absentStudent.id"> {{ absentStudent.first_name }}
    </li>
  </ul>
 
</div>

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

Comments

0

You should use the checked attributes on the input elements appropriately. Unfortunately, the WhatWG Html standard now says that boolean attributes evaluating to false must be omitted altogether. As vue does not have a mechanism to conditionally include attributes, you need to fall back to a seemingly redundant solution and conditionally render the element:

<ul>
    <li v-for="absentStudent in absentStudents" class="list-unstyled">
        <input
            v-if="excludeAbsent && absentStudent.include"
            type="checkbox"
            @click="check($event)"
            v-model="absentStudentsSelected"
            :value="absentStudent.id"
            checked
        />
        <input
            v-else
            type="checkbox"
            @click="check($event)"
            v-model="absentStudentsSelected"
            :value="absentStudent.id"
        />
        {{ absentStudent.first_name }}
    </li>
</ul>

You may have to adjust the expression in the v-if directive, I am not 100% sure about the condition on which you check or don't check the checkboxes.

As an alternative you could manipulate the dom directly in the click handler but that defies the declarative nature of frameworks like vue.

2 Comments

your v-if condtion would be accurate but still some reason the v-else has no effect. I tried changing the v-if to only reflect if absentStudent.include was true or false but that still had no effect. my condition for checking or unchecking the boxes is based on this.excludeStudents which lives in my data. I will update my code to reflect this
I have made some updates as to how my code is initially rendered another comment mentioned that if the array was full of id value's (which they are to serve as a reference to which student is checked ) the checkboxes would be automatically checked. I'm not sure why this renders them as checked though?

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.