I am working on menu-permissions using vue. I want assign "Edit", "create", "delete" on different menus. Now If I click on "create" checkbox of some menu, It is triggering other "create" checkboxes.
What I am trying is demonstrated on this codepen
How can I assign separate functionalities to separate menus?
console.clear();
// New VueJS instance
var app = new Vue({
el: "#app",
data: {
menus: [
{ id: 1, menuName: "Tech 1" },
{ id: 2, menuName: "Tech 2" },
{ id: 3, menuName: "Tech 3" }
],
selectedActions: [],
selectedMenu: [],
selectedSubMenu: [],
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;
},
filteredProduct: function () {
const app = this,
menu = app.selectedMenu;
if (menu.includes("0")) {
return app.submenus;
} else {
return app.submenus.filter(function (item) {
return menu.indexOf(item.menuId) >= 0;
});
}
}
},
methods: {
setSelectedMenu: function (event, menu_id) {
if (event.target.checked) {
this.selectedMenu.push(menu_id);
} else {
var index = this.selectedMenu.indexOf(menu_id);
this.selectedMenu.splice(index, 1);
}
}
}
});
<!-- Include the library in the page -->
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<!-- App -->
<div id="app">
<table >
<thead>
<tr>
<th>Menu</th>
<th>Submenu</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="menu in menus" :key="menu.id">
<td>
<label>
<input type="checkbox" :value="menu.id" v-model="selectedMenu" />{{ menu.menuName }}
</label>
</td>
<td>
<ul>
<li v-for="submenu in filteredProduct" :key="submenu.id" v-if="menu.id == submenu.menuId">
<input type="checkbox" :value="submenu.id" v-model="selectedSubMenu" />
<label>{{ submenu.subMenuName }} </label>
</li>
</ul>
</td>
<td >
<label >
<input type="checkbox" name="action[]" v-model="selectedActions" value="Create" />Create</label><br />
<label >
<input type="checkbox" name="action[]" v-model="selectedActions" value="Edit" />Edit</label><br />
<label >
<input type="checkbox" name="action[]" v-model="selectedActions" value="Delete" />Delete</label>
</td>
</tr>
</tbody>
</table>
</div>
CodePudding user response:
You can do it like in the snippet below.
The only thing changed is the value attribute of the Create, Edit and Delete inputs. Change it to :value="{name: 'Create', menu: index}"
and then read the object as per need.
console.clear();
// New VueJS instance
var app = new Vue({
el: "#app",
data: {
menus: [
{ id: 1, menuName: "Tech 1" },
{ id: 2, menuName: "Tech 2" },
{ id: 3, menuName: "Tech 3" }
],
selectedActions: [],
selectedMenu: [],
selectedSubMenu: [],
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;
},
filteredProduct: function () {
const app = this,
menu = app.selectedMenu;
if (menu.includes("0")) {
return app.submenus;
} else {
return app.submenus.filter(function (item) {
return menu.indexOf(item.menuId) >= 0;
});
}
}
},
methods: {
setSelectedMenu: function (event, menu_id) {
if (event.target.checked) {
this.selectedMenu.push(menu_id);
} else {
var index = this.selectedMenu.indexOf(menu_id);
this.selectedMenu.splice(index, 1);
}
}
},
watch: {
selectedActions() {
console.log(this.selectedActions)
}
}
});
<!-- Include the library in the page -->
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<!-- App -->
<div id="app">
<table >
<thead>
<tr>
<th>Menu</th>
<th>Submenu</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(menu, index) in menus" :key="menu.id">
<td>
<label>
<input type="checkbox" :value="menu.id" v-model="selectedMenu" />{{ menu.menuName }}
</label>
</td>
<td>
<ul>
<li v-for="submenu in filteredProduct" :key="submenu.id" v-if="menu.id == submenu.menuId">
<input type="checkbox" :value="submenu.id" v-model="selectedSubMenu" />
<label>{{ submenu.subMenuName }} </label>
</li>
</ul>
</td>
<td >
<label >
<input type="checkbox" name="action[]" v-model="selectedActions" :value="{name: 'Create', menu: index}" />Create</label><br />
<label >
<input type="checkbox" name="action[]" v-model="selectedActions" :value="{name: 'Edit', menu: index}" />Edit</label><br />
<label >
<input type="checkbox" name="action[]" v-model="selectedActions" :value="{name: 'Delete', menu: index}" />Delete</label>
</td>
</tr>
</tbody>
</table>
</div>