I would like to check permissions of a role using checkbox in vue. For example if an admin can create, view, delete a checkbox will be selected, if not checkbox will not be selected. So far i have the table created with proper roles and permissions that below to each role but don't know how to check checkbox based on permission in role.
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
permissions: [
{
id: 1,
name: "view posts"
},
{
id: 2,
name: "create posts"
},
{
id: 3,
"name": "edit posts"
},
{
id: 4,
name: "delete posts"
}
],
roles: [
{
id: 1,
name: "admin",
description: "Full admin access to all the areas of the blog.",
permissions: [
{
id: 1,
name: "view posts",
},
{
id: 2,
name: "create posts",
},
{
id: 3,
name: "edit posts",
},
{
id: 4,
name: "delete posts",
}
]
},
{
id: 2,
name: "executive",
description: "Limited access to critical areas of the blog",
permissions: [
{
id: 1,
name: "view posts",
},
{
id: 2,
name: "create posts",
}
]
},
{
id: 3,
name: "user",
description: "Basic view access to some areas of the blog",
permissions: [
{
id: 1,
name: "view posts",
}
]
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.js"></script>
<div id="app">
<template>
<div>
<div id='permissionsTable'>
<v-row class='headerRow'>
<v-col cols='3'>Permissions</v-col>
<v-col v-for="role in roles" v-bind:key="role.id">{{role.name}}</v-col>
</v-row>
<v-row v-for="permission in permissions" v-bind:key="permission.id" class="bodyRow">
<v-col cols='3'>{{permission.name}}</v-col>
<v-col v-for="(role, index) in roles" v-bind:key="role.name">
{{roles[index].permissions}}
<v-checkbox :input-value="roles[index].permissions.includes(permission.id)" #change="onItemClick($event,role.name,permission.id)">
</v-checkbox>
</v-col>
</v-row>
</div>
</div>
</template>
</div>
Let me know if this help.
new Vue({
el: "#app",
vuetify: new Vuetify(),
methods: {
onItemClick(e, role, permissionId) {
const index = this.roles.findIndex((r) => r.name === role);
const found=this.roles[index].permissions.find(perm=> perm.id === permissionId)
if (
found
) {
this.roles[index].permissions.splice(
this.roles[index].permissions.findIndex(perm=>perm.id===permissionId),
1
);
} else {
this.roles[index].permissions.push(this._permissions[permissionId]);
}
}
},
computed: {
_permissions() {
return this.permissions.reduce((acc, curr) => {
const id = curr.id;
acc[id] = curr;
return acc;
}, {});
},
_roles() {
return this.roles.reduce((acc, curr) => {
const id = curr.id;
acc[id] = curr;
return acc;
}, {});
}
},
data() {
return {
permissions: [
{
id: 1,
name: "view posts"
},
{
id: 2,
name: "create posts"
},
{
id: 3,
name: "edit posts"
},
{
id: 4,
name: "delete posts"
}
],
roles: [
{
id: 1,
name: "admin",
description: "Full admin access to all the areas of the blog.",
permissions: [
{
id: 1,
name: "view posts"
},
{
id: 2,
name: "create posts"
},
{
id: 3,
name: "edit posts"
},
{
id: 4,
name: "delete posts"
}
]
},
{
id: 2,
name: "executive",
description: "Limited access to critical areas of the blog",
permissions: [
{
id: 1,
name: "view posts"
},
{
id: 2,
name: "create posts"
}
]
},
{
id: 3,
name: "user",
description: "Basic view access to some areas of the blog",
permissions: [
{
id: 1,
name: "view posts"
}
]
}
]
};
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.js"></script>
<div id="app">
<template>
<div>
<div id='permissionsTable'>
<v-row class='headerRow'>
<v-col cols='3'>Permissions</v-col>
<v-col v-for="role in roles" v-bind:key="role.id">{{role.name}}</v-col>
</v-row>
<v-row v-for="permission in permissions" v-bind:key="permission.id" class="bodyRow">
<v-col cols='3'>{{permission.name}}</v-col>
<v-col v-for="(role, index) in roles" v-bind:key="role.name">
{{roles[index].permissions}}
<v-checkbox :input-value="_roles[role.id].permissions.find(perm=>perm.id===permission.id)" #change="onItemClick($event,role.name,permission.id)">
</v-checkbox>
</v-col>
</v-row>
</div>
</div>
</template>
</div>
v-checkbox has a v-model prop that you can use to pass Boolean and select or deselect it accordingly ! try adding that Boolean in your roles array and use it inside the v-for. you can also check your condition inside v-for on v-model like :v-model="role.permissions.includes(1)" but it's up to you to use the one that suit your case best.
Related
...
<b-table
class="table table-bordered"
id="my-table"
striped hover
:items="items"
:per-page="perPage"
...
></b-table>
items: [
{ id : 1, name : "Taylor", status: "passive" },
{ id : 2, name : "Tom", status: "passive" },
{ id : 3, name : "Arthur", status: "passive" },
...
İ want name or more details when i click it will transfer to new page. How can i do that ?
You can use slots to customize your b-table. I prepared a code snippet to show you how you can add a detail button in your table and redirect the user to a new page after clicking on it.
new Vue({
el: '#app',
data() {
return {
fields: ['id', 'name', 'status', 'details'],
items: [{
id: 1,
name: "Taylor",
status: "passive"
},
{
id: 2,
name: "Tom",
status: "passive"
},
{
id: 3,
name: "Arthur",
status: "passive"
},
]
}
},
methods: {
},
mounted() {},
})
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap#4.5.3/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/vue#2.6.12/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.22.0/dist/bootstrap-vue.min.js"></script>
<div id="app">
<b-table bordered id="my-table" striped hover :items="items" :fields="fields">
<template #cell(details)="row">
<b-link :to="`/items/${row.item.id}`">Details</b-link>
</template>
</b-table>
</div>
I have this select menu:
<v-select
dense
outlined
item-text="name"
item-value="id"
:items="frequencies"
v-model="frequency"
label="Frequency"
></v-select>
& I kept seeing this:
If I print it out it seems to contain correct value:
{{ frequency }} {{ frequencies }}
Hourly
[
{
"id": 1,
"name": "Hourly"
},
{
"id": 2,
"name": "Daily"
},
{
"id": 3,
"name": "Weekly"
},
{
"id": 4,
"name": "Monthly"
},
{
"id": 5,
"name": "Perpetual"
}
]
Why my select didn’t select Hourly as selected value?
Here's a live, working demo using your example.
Or, for a shortened version here:
// Hide Vue dev warnings, just for the demo
Vue.config.devtools = false;
Vue.config.productionTip = false;
// Demo Vue app, using vuetify
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
frequency: null, // ID of currently selected frequenct
frequencies: [ // List of values to display in the dropdown
{ id: 1, name: "Hourly" },
{ id: 2, name: "Daily" },
{ id: 3, name: "Weekly" },
{ id: 4, name: "Monthly" },
{ id: 5, name: "Perpetual" },
{ id: "XX", name: "Broken" },
],
}),
})
p.demo { font-size: 1.5rem; text-align: center; background: yellow; }
p.demo.init { background: aqua; }
p.demo.broke { background: hotpink; }
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.5/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.5/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/#mdi/font#6.x/css/materialdesignicons.min.css"/>
<div id="app">
<v-app id="inspire">
<v-container fluid>
<!-- v-select, from your question -->
<v-select
dense
outlined
item-text="name"
item-value="id"
:items="frequencies"
v-model="frequency"
label="Frequency"
></v-select>
Selected Frequency : {{ frequency }}
<!-- Display what's selected, just for the demo -->
<p class="demo" v-if="frequency && frequencies[frequency - 1]">
Frequency: {{ frequency }} ({{ frequencies[frequency - 1].name }})
</p>
<p class="demo broke" v-else-if="frequency">
Invalid Frequency Selected ({{ frequency }})
</p>
<p class="demo init" v-else>No value selected yet</p>
</v-container>
</v-app>
</div>
I am not sure what issue you are facing but label is not showing on select any option from the <v-select>. I created a sample code snippet for the reference, Can you please have a look and let me know if any further assistance required.
Demo :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
frequency: null,
frequencies: [
{
"id": 1,
"name": "Hourly"
},
{
"id": 2,
"name": "Daily"
},
{
"id": 3,
"name": "Weekly"
},
{
"id": 4,
"name": "Monthly"
},
{
"id": 5,
"name": "Perpetual"
}
]
}),
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.5/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.5/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/#mdi/font#6.x/css/materialdesignicons.min.css"/>
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-select
:items="frequencies"
item-text="name"
item-value="id"
label="Frequency"
v-model="frequency"
outlined
></v-select>
Selected Frequency : {{ frequency }}
</v-container>
</v-app>
</div>
What I want to achieve is put "-" on every empty cell value. Like this (see the "Name" row):
How do I do that? Thanks
You can use add a formatter if you use the fields prop.
Here you can create a method which either returns your name if there is one, or - if there's none.
new Vue({
el: '#app',
data() {
return {
fields: [
{ key: "name", formatter: 'formatName' },
{ key: "age" }
],
items: [
{ age: 40, name: 'Dickerson Macdonald' },
{ age: 21, name: '' },
{ age: 89, name: 'Geneva Wilson' },
{ age: 38, name: 'Jami Carney'}
]
}
},
methods: {
formatName(value) {
return value || '-'
}
}
})
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/vue#2.6.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.js"></script>
<div id="app">
<b-table :items="items" :fields="fields"></b-table>
</div>
Alternatively, you can use slots to create the logic in your template, or maybe render something else if there's no name. But if it's simply displaying a -, I'd stick with a formatter.
new Vue({
el: '#app',
data() {
return {
fields: [
{ key: "name" },
{ key: "age" }
],
items: [
{ age: 40, name: 'Dickerson Macdonald' },
{ age: 21, name: '' },
{ age: 89, name: 'Geneva Wilson' },
{ age: 38, name: 'Jami Carney'}
]
}
}
})
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/vue#2.6.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.js"></script>
<div id="app">
<b-table :items="items" :fields="fields">
<template #cell(name)="{ value }">
{{ value || '-' }}
</template>
</b-table>
</div>
I have an option array which is shown in the multi-select options. But I need to select a default option which id is provided. In my code I need to select the default option which id = 2 . How to do that with multi-select in vue.js?
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<div id="vue-app2">
<div>
<label class="typo__label">Single select / dropdown</label>
<multiselect v-model="value" deselect-label="Can't remove this value" track-by="id" label="name"
placeholder="Select one" :options="options" :searchable="false" :allow-empty="false">
<template slot="singleLabel" slot-scope="{ option }"><strong>{{ option.name }}</strong> is written
in<strong> {{ option.language }}</strong></template>
</multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
</div>
<script >
Vue.component('multiselect', window.VueMultiselect.default);
new Vue({
el: '#vue-app2',
data: {
id:2,
value:null,
options: [
{ id:1, name: 'Vue.js', language: 'JavaScript' },
{ id:2, name: 'Rails', language: 'Ruby' },
{ id:3,name: 'Sinatra', language: 'Ruby' },
{ id:4,name: 'Laravel', language: 'PHP', $isDisabled: true },
{ id:5,name: 'Phoenix', language: 'Elixir' }
]
}
});
</script>
If you need to take default value id from data then find and set default value on mounted;
new Vue({
el: '#vue-app2',
data: {
id: 2,
value: null,
options: [
{ id: 1, name: 'Vue.js', language: 'JavaScript' },
{ id: 2, name: 'Rails', language: 'Ruby' },
{ id: 3, name: 'Sinatra', language: 'Ruby' },
{ id: 4, name: 'Laravel', language: 'PHP', $isDisabled: true },
{ id: 5, name: 'Phoenix', language: 'Elixir' }
]
},
mounted() {
this.value = this.options.find(option => option.id === this.id);
}
});
I'm trying to show "locations" in a vuetify select component, but my current code renders "[object Object]" instead of Location 1, Location 2, etc.
My select component:
<v-select
:items="locations"
v-model="location"
label="Choose Location"
bottom
autocomplete
></v-select>
Locations:
locations () {
return this.$store.getters.getLocationsForEvent(this.event.id)
}
Vuex Getter:
getLocationsForEvent: (state) => (id) => {
return state.loadedLocations.filter(function (location) {
return location.eventId === id;
});
}
Here is a screenshot of what the location data looks like:
Thanks!
For custom objects you have to specify the item-text. The item-text is what each option will display.
From your screenshot, for instance, title is a possible property:
<v-select
:items="locations"
v-model="location"
label="Choose Location"
item-text="title"
bottom
autocomplete
></v-select>
Demos below.
Without item-text:
new Vue({
el: '#app',
data () {
return {
location: null,
locations: [
{ id: "1111", manager: 'Alice', title: 'Water Cart 1' },
{ id: "2222", manager: 'Bob', title: 'Water Cart 2' },
{ id: "3333", manager: 'Neysa', title: 'Water Cart 3' }
]
}
}
})
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link rel='stylesheet' href='https://unpkg.com/vuetify#1.0.10/dist/vuetify.min.css'>
<script src='https://unpkg.com/vue/dist/vue.js'></script>
<script src='https://unpkg.com/vuetify#1.0.10/dist/vuetify.min.js'></script>
<div id="app">
<v-app>
<v-container>
<v-select
:items="locations"
v-model="location"
label="Choose Location"
bottom
autocomplete
>
</v-select>
</v-container>
</v-app>
</div>
With item-text:
new Vue({
el: '#app',
data () {
return {
location: null,
locations: [
{ id: "1111", manager: 'Alice', title: 'Water Cart 1' },
{ id: "2222", manager: 'Bob', title: 'Water Cart 2' },
{ id: "3333", manager: 'Neysa', title: 'Water Cart 3' }
]
}
}
})
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link rel='stylesheet' href='https://unpkg.com/vuetify#1.0.10/dist/vuetify.min.css'>
<script src='https://unpkg.com/vue/dist/vue.js'></script>
<script src='https://unpkg.com/vuetify#1.0.10/dist/vuetify.min.js'></script>
<div id="app">
<v-app>
<v-container>
<v-select
:items="locations"
v-model="location"
label="Choose Location"
item-text="title"
bottom
autocomplete
>
</v-select>
</v-container>
</v-app>
</div>
implemeneted a watch to have a low level Array of objects
watch: {
groupInfo: function(groupInfo) {
if (groupInfo.teams !== undefined) {
var newArray = [];
for (var key in groupInfo.teams) {
var obj = groupInfo.teams[key];
newArray.push(obj);
}
console.log("wagwan" newArray)
this.teams = newArray;
}
}
},