Home > Enterprise >  vue - uncheck all child checkboxes when parent is unchecked
vue - uncheck all child checkboxes when parent is unchecked

Time:09-27

I am working on a menu permission project using vue.js. I have some submenus which are child of different menus. I want to uncheck all the checked submenus if the menu is unchecked

// New VueJS instance
var app = new Vue({
  el: "#app",
  data() {
    return {
      menus: [{
        id: 1,
        menuName: "Tech 1"
      }, {
        id: 2,
        menuName: "Tech 2"
      }, {
        id: 3,
        menuName: "Tech 3"
      }],
      selectedMenu: [{
        id: 1,
        menuName: "Tech 1"
      }],
      selectedSubMenu: [{
        id: 1,
        menuId: 1,
        subMenuName: "architecture"
      }, {
        id: 2,
        menuId: 1,
        subMenuName: "Electrical"
      }],
      selectedAllSubMenu: [],
      submenus: [{
        id: 1,
        menuId: 1,
        subMenuName: "architecture"
      }, {
        id: 2,
        menuId: 1,
        subMenuName: "Electrical"
      }, {
        id: 3,
        menuId: 1,
        subMenuName: "Electronics"
      }, {
        id: 4,
        menuId: 2,
        subMenuName: "IEM"
      }, {
        id: 5,
        menuId: 3,
        subMenuName: "CIVIL"
      }]
    }
  },
  computed: {
    isUserInPreviousUsers() {
      return this.previousUsers.indexOf(this.userId) >= 0;
    },
  },
  methods: {
    filteredProduct(id) {
      return this.submenus.filter(s => s.menuId === id)
    },
    selectSubMenu(id) {
      if (this.selectedSubMenu.filter(s => s.menuId === id).length === this.submenus.filter(s => s.menuId === id).length) {
        this.selectedAllSubMenu.push(id)
      } else {
        this.selectedAllSubMenu = this.selectedAllSubMenu.filter(s => s !== id)
      }
    },
    selectAllSubMenu(id) {
      const checked = this.selectedAllSubMenu.some(s => s === id)
      if (this.selectedSubMenu.filter(s => s.menuId === id).length === this.submenus.filter(s => s.menuId === id).length && !checked) {
        this.selectedSubMenu = this.selectedSubMenu.filter(s => s.menuId !== id)
      } else if (checked) {
        this.selectedSubMenu = [...new Set([...this.selectedSubMenu].concat(this.submenus.filter(s => s.menuId === id)))]
      }
    },
  }
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <table >
    <thead>
      <tr>
        <th>Menu</th>
        <th>Submenu</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(menu,index) in menus" :key="menu.id">
        <td>
          <label>
            <input type="checkbox" :value="menu" v-model="selectedMenu" />{{ menu.menuName }}
          </label>
        </td>
        <td>
          <ul>
            <label>
              <input
                type="checkbox"
                :value="menu.id"
                v-model="selectedAllSubMenu"
                @change="selectAllSubMenu(menu.id)"
              />
             Select all
            </label>
            <li v-for="submenu in filteredProduct(menu.id)" :key="submenu.id">
              <input type="checkbox" :value="submenu" v-model="selectedSubMenu" @change="selectSubMenu(menu.id)" />
              <label>{{ submenu.subMenuName }} </label>
            </li>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Here the tech 1 menu & architecture, electrical submenus are already selected. I want to uncheck the submenus when the tech 1 menu is unchecked. How do do this?

CodePudding user response:

Like with submenus, you can just filter selectedMenu array:

// New VueJS instance
var app = new Vue({
  el: "#app",
  data() {
    return {
      menus: [{id: 1, menuName: "Tech 1"}, {id: 2, menuName: "Tech 2"}, {id: 3, menuName: "Tech 3"}],
      selectedMenu: [{id: 1, menuName: "Tech 1" }],
      selectedSubMenu: [{id: 1,  menuId: 1, subMenuName: "architecture"}, {id: 2, menuId: 1, subMenuName: "Electrical"}],
      selectedAllSubMenu: [],
      submenus: [{id: 1, menuId: 1, subMenuName: "architecture"}, {id: 2, menuId: 1, subMenuName: "Electrical"}, {id: 3, menuId: 1, subMenuName: "Electronics"}, {id: 4, menuId: 2, subMenuName: "IEM"}, {        id: 5, menuId: 3, subMenuName: "CIVIL"}]
    }
  },
  computed: {
    isUserInPreviousUsers() {
      return this.previousUsers.indexOf(this.userId) >= 0;
    },
  },
  methods: {
    filteredProduct(id) {
      return this.submenus.filter(s => s.menuId === id)
    },
    handleMenu(id) {
      if (!this.selectedMenu.find(s => s.id === id)) {
        this.selectedSubMenu = this.selectedSubMenu.filter(s => s.menuId !== id)
        this.selectedAllSubMenu = this.selectedAllSubMenu.filter(s => s !== id)
      }
    },
    selectSubMenu(id) {
      if (this.selectedSubMenu.filter(s => s.menuId === id).length === this.submenus.filter(s => s.menuId === id).length) {
        this.selectedAllSubMenu.push(id)
      } else {
        this.selectedAllSubMenu = this.selectedAllSubMenu.filter(s => s !== id)
      }
    },
    selectAllSubMenu(id) {
      const checked = this.selectedAllSubMenu.some(s => s === id)
      if (this.selectedSubMenu.filter(s => s.menuId === id).length === this.submenus.filter(s => s.menuId === id).length && !checked) {
        this.selectedSubMenu = this.selectedSubMenu.filter(s => s.menuId !== id)
      } else if (checked) {
        this.selectedSubMenu = [...new Set([...this.selectedSubMenu].concat(this.submenus.filter(s => s.menuId === id)))]
      }
    },
  }
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <table >
    <thead>
      <tr>
        <th>Menu</th>
        <th>Submenu</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(menu,index) in menus" :key="menu.id">
        <td>
          <label>
            <input type="checkbox" :value="menu" v-model="selectedMenu" @change="handleMenu(menu.id)" />{{ menu.menuName }}
          </label>
        </td>
        <td>
          <ul>
            <label>
              <input
                type="checkbox"
                :value="menu.id"
                v-model="selectedAllSubMenu"
                @change="selectAllSubMenu(menu.id)"
              />
             Select all
            </label>
            <li v-for="submenu in filteredProduct(menu.id)" :key="submenu.id">
              <input type="checkbox" :value="submenu" v-model="selectedSubMenu" @change="selectSubMenu(menu.id)" />
              <label>{{ submenu.subMenuName }} </label>
            </li>
          </ul>
        </td>
      </tr>
    </tbody>
  </table>
</div>

  • Related