mercredi 27 novembre 2019

Keep checkbox state across pagination vue-bootstrap

I am using a bootstrap table using pagination to display users. On every row a checkbox for selecting more than one at a time to perform an action. I manage to write the functions to select one and select all, keeping the array across pagination. But now I am not able to control the ui while navigating across pages using pagination. As I said, the array I created for storing the selected users stays across pages, but I 'loose the tick' on the checkboxes... It looks like the v-model binding gets lost while surfing the pages... Here the inherent parts of the code, hoping someone could help. In the template:

<b-table
            v-if="users && users.length > 0 && !isLoading"
            id="table-transition-userList"
            :key="users.id"
            responsive
            :tbody-transition-props="transProps"
            :fields="fields"
            :items="users"
            hover
            class="mx-2 py-1 tbl-user-list"
            :per-page="perPage"
            :filter="filter"
            :filterIncludedFields="filterOn"
            @filtered="onFiltered"
          > 
          <template
            v-slot:head(checkbox)="data">
            <b-form-checkbox
              size="lg"
              v-model="isSelectedAll"
              @change="selectAll(data)"
            />
          </template>
          <template
            v-slot:cell(checkbox)="data"
          >
            <b-form-checkbox
              v-model="data.item.selected"
              @change="select(data.item)"
            />
          </template>

In the script data:

fields: [
        { key: 'checkbox', label: ''},
        { key: 'fullName', label: 'Utente' },
        { key: 'user.username', label: 'Username' },
        { key: 'user.email', label: 'Email' },
        { key: 'buttons', label: 'Operazioni' }
      ],
      totalRows: 1,
      currentPage: 1,
      perPage: 5,
      pageOptions: [5, 10, 15, 20, 25],
      filter: null,
      filterOn: [],
      users: [],
      selectedUsers: [],
      isSelectedAll: false

In the methods:

selectAll() {
      this.isSelectedAll = !this.isSelectedAll
      this.users.forEach(user => user.selected = this.isSelectedAll)

      const notSelected = this.users.filter(user => !user.selected)
      const selected = this.users.filter(user => user.selected)

      // new selected users array without current page selected users
      let selectedUsersCopy = this.selectedUsers.slice().filter(user =>
        !notSelected.find(e => e.id === user.id)
      )
      if(notSelected.length > 0) {
        this.isSelectedAll = true
      }
      else {
        this.isSelectedAll = false
      }
      this.selectedUsers = [
        ...selectedUsersCopy,
        ...selected.filter(user => !selectedUsersCopy.find(e => e.id === user.id))
      ];

      console.log('selected', selected, 'this.sele', this.selectedUsers, 'copy', selectedUsersCopy, 'notSele', notSelected)
    },
    select(user) {
      user.selected = !user.selected
      this.isSelectedAll = false
      const selected = this.users.filter(user => user.selected)
      if(selected.length === this.users.length) {
        this.isSelectedAll = true
      }
      else {
        this.isSelectedAll = false
      }
      let isDouble = false
      if(this.selectedUsers.find(v => v.user.id === user.id)) isDouble = true
      if(user.selected) {
        if(isDouble) {
          console.log('double if user selected and isDouble', isDouble)
          console.log("object already exists", this.selectedUsers)
          return
        }
        else {
          this.selectedUsers.push(user)
          console.log("pushed", this.selectedUsers)
          return this.selectedUsers
        }
      }
      else {
        const index = this.selectedUsers.indexOf(user);
        this.selectedUsers.splice(index, 1);
        console.log("removed, new array: ", this.selectedUsers)
      }
    },
    async pagination(page) {
      const payload = {
        limit: this.perPage,
        offset: (page - 1) * this.perPage
      }
      this.isLoading = true
      this.isSelectedAll = false
      await this.$store.dispatch('user/setUsers', payload)
      const response = this.$store.getters.users
      this.users = response.results
      this.isLoading = false
      this.currentPage = page
    }

My pagination is calling different apis with different limits and offsets. I think the problem is to be found in the built-in checked property of the form checkbox though... Thanks to anyone who could give me a hint. xx




Aucun commentaire:

Enregistrer un commentaire