Pete
Pete

Reputation: 3

Vuejs checkbox child state not updating

I'm a beginner in Vue.js and I'm stuck at this:

<span>Condition</span>
<el-select style="width: 94%;" v-model="condition[index+1]">
  <el-option label="Ambient" value="Ambient">Ambient</el-option>
  <el-option label="Frozen" value="Frozen">Frozen</el-option>
</el-select>
<h4>
  <el-checkbox v-model="check[index+1]" @change="selectAllPanels(index+1, item.id)">Select All</el-checkbox>
</h4>
<div class="card-content panels-category" v-for="(category, n) in panelsCategory[item.id]" :key="category.id" style="float: left">
  <div class="panel-category" v-if="searchList[item.id][n].length > 0">
    <el-checkbox v-model="checkAll[index+1][item.id][n]" @change="checkAllPanel(index+1, item.id, n)"  :label="category.id" :key="category.id">
      <h5 class="card-title">{{ category[0].panel_category }}</h5>
    </el-checkbox>
  </div>
  <div class="panels" v-for="panels in searchList[item.id][n]" :key="panels.id">     <!-- in panelsCategory[item.id][n]-->
    <!--<el-checkbox-group class="panels-name" v-model="selectedPanels[index+1][item.id]"  @change="handelAddSample(index+1)">-->
      <el-checkbox :checked="checkAll[index+1][item.id][n]" class="panels-name" v-model="selectedPanels[index+1][item.id]"  @change="handelAddSample()" :label="panels.id" :key="panels.id" >{{panels.reportable_name}}</el-checkbox>
      <el-popover class="panel-popover"
                  trigger="hover"
                  @show="getPanelTest(panels.id)"
                  placement="bottom">
        <el-button slot="reference" class="ti-help popover-help"></el-button>
        <slot>{{panelTest}}</slot>
      </el-popover>
    <!--</el-checkbox-group>-->
  </div>
  <div class="panels" v-if="searchList[item.id][n].length > 0" v-for="i in getPanelsLength(index+1, item.id, n)" ></div>
</div>

At click on plus button from the right side-->click sth from the dropdown list-->it displays the new tab

So, here, in these tabs comes the magic: the checkboxes are not working well, I mean at click on "Select All" checkbox, all checkboxes should be selected, but this doesn't happen until one subcategory checkbox is clicked (like the third child), but the list where the selected checkboxes are stored is populated well.

I tried this.$forceUpdate() and even this.$set() inside the functions called at click on select All and category title (those with blue background) Can somebody please help?

I tried to reproduce it in this fiddle Here.

Upvotes: 0

Views: 2774

Answers (2)

James
James

Reputation: 38

<el-checkbox class="panels-name" 
  :value="!!selectedPanels[index+1][item.id].find(i=>i===panels.id)"
  @change="handelAddSample(index+1,item.id,panels.id)"
  :label="panels.id"
  :key="panels.id"
>{{panels.reportable_name}}
</el-checkbox>

bind by :value="!!selectedPanels[index+1][item.id].find(i=>i===panels.id)", it worked.

just add it to child

     handelAddSample(a,b,id) {
        let m = -1;
        if(!!this.selectedPanels[a][b].find((i,index)=>{if(i===id){m=index;return true}})){
            this.selectedPanels[a][b].splice(m,1); 
        }else {
            this.selectedPanels[a][b].push(id);
        }
        this.$forceUpdate()
      },

new demo

Upvotes: 1

Daniel
Daniel

Reputation: 35684

The issue appears to be with the chekbox

<el-checkbox
  :checked="checkAll[index+1][item.id][n]"
  class="panels-name"
  v-model="selectedPanels[index+1][item.id]"
  @change="handelAddSample()"
  :label="panels.id" :key="panels.id"
>{{panels.reportable_name}}</el-checkbox>

this element has both :checked and v-model defined, which will compete, more importantly though, you're using model on a static data (updating searchList, instead of checkAll). For an element-ui you only use v-model, and pass the checkAll instead of searchList.

<el-checkbox
  v-model="checkAll[index+1][item.id][n]"
  class="panels-name"
  @change="handelAddSample()"
  :label="panels.id" :key="panels.id"
>{{panels.reportable_name}}</el-checkbox>

another thing you should do is use this.$set when you're updating nested properties

  selectAllPanels(index, item) {
    if (this.check[index] === true) {
      this.$set(this.check, index, true) // <--- note use of $set here
    } else {
      this.$set(this.check, index, false) // <--- here
    }
    for (let i = 0; i <= this.panelsCategory[item].length; i++) {
        console.log(this.panelsCategory[item][i])
      if (this.panelsCategory[item][i] !== undefined && this.check[index]) {
        this.$set(this.checkAll[index][item], i, true) // <--- here
        this.checkAllPanel(index, item, i)
      } else {
        if (this.panelsCategory[item][i] !== undefined) {
          this.$set(this.checkAll[index][item], i, false) // <--- and here
          this.checkAllPanel(index, item, i)
        }
      }
    }
    //this.$forceUpdate()  // <--- then you don't need forceUpdate
  },

Upvotes: 0

Related Questions