VueJS: Getting dynamic checkbox values in VueJS 2 - javascript

I am using VueJS 2 and Vuetify to build the subscription form below. Where all the preferences applicable for a subscription are fetched from the server and displayed. Preferences in the image are for digital magazine subscription. For a print magazine subscription preferences might be different.
The data fetched from server looks like this
preferences: [
{
id: "1",
title: "Subscription frequence",
options: ["Daily", "Weekly", "Fortnight", "Monthly"]
},
{
id: "2",
title: "Topics",
options: ["Sports", "Politics", "Art", "Music", "Health", "Tech"]
},
{
id: "3",
title: "Promotional Offers",
options: ["Daily", "Weekly", "Fortnight", "Monthly", "Never"]
}
]
I have used v-for to display preferences like below:
<v-col
v-for="pref in preferences"
:key="pref.id"
>
<span>{{ pref.title }}</span>
<v-checkbox
v-for="option in pref.options"
:key="option"
:v-model="pref.options"
:label="option"
color="red"
value="option"
hide-details
>
</v-checkbox>
</v-col>`
Now, since all the preferences have the same options array, I am not able figure how to differentiate one checkbox group from another. And therefore get the selected checkbox for each preference group.
Any tips much appreciated. Thanks.
UPDATE
This works for input type as shown in #palash answer. But is not working for Vuetify v-checkbox.

Add a selectedOption key in preferences objects.
preferences: [
{
id: "1",
title: "Subscription frequence",
options: ["Daily", "Weekly", "Fortnight", "Monthly"],
selectedOption: []
},
{
id: "2",
title: "Topics",
options: ["Sports", "Politics", "Art", "Music", "Health", "Tech"],
selectedOption: []
},
{
id: "3",
title: "Promotional Offers",
options: ["Daily", "Weekly", "Fortnight", "Monthly", "Never"],
selectedOption: []
}
]
<v-checkbox
v-for="option in pref.options"
:key="option"
:v-model="pref.selectedOption"
:label="option"
color="red"
value="option"
hide-details
>

First, try to add an empty selected array to each object inside preferences array:
preferences: [{
id: "1",
title: "Subscription frequence",
options: ["Daily", "Weekly", "Fortnight", "Monthly"],
selected: []
},
{
id: "2",
title: "Topics",
options: ["Sports", "Politics", "Art", "Music", "Health", "Tech"],
selected: []
},
{
id: "3",
title: "Promotional Offers",
options: ["Daily", "Weekly", "Fortnight", "Monthly", "Never"],
selected: []
}
]
Next, in the template update the v-checkbox model from:
:v-model="pref.options"
to
:v-model="pref.selected"
Now, you can easily see the selected options in each preference like:
For Subscription frequence:
this.preferences[0].selected
For Topics:
this.preferences[1].selected
For Promotional Offers:
this.preferences[2].selected
Simple Demo:
new Vue({
el: '#app',
data: {
selected: [],
roles: [{id:1,name:"Client"},{id:2,name:"Admin"},{id:3,name:"Guest"}]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<div v-for="role in roles" :key="role.id">
<label>{{role.name}}</label>
<input type="checkbox" v-model="selected" :value="role"/>
</div>
<p>Selected Roles:</p>
{{selected}}
</div>
Complex Demo:
new Vue({
el: '#app',
data: {
preferences: [{
id: "1",
title: "Subscription frequence",
options: ["Daily", "Weekly", "Fortnight", "Monthly"],
selected: []
},
{
id: "2",
title: "Topics",
options: ["Sports", "Politics", "Art", "Music", "Health", "Tech"],
selected: []
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<div v-for="pref in preferences" :key="pref.id">
<h3>{{pref.title}}:</h3>
<div v-for="option in pref.options" :key="option">
<label>{{option}}</label>
<input type="checkbox" v-model="pref.selected" :value="option" /><br>
</div>
<p>Selected {{pref.title}}:</p>
{{pref.selected}}
<br><br><hr/>
</div>
</div>

Related

How do I check an array of objects for a specific property within those objects? React

if i have data that has an array with objects, how do i check each object if it contains a specific property and value? Then creating the possibility to use the data of the ones that do or dont contain the specified property?
This is what i am working with but would like to filter the shoes to the specific rows
project:
Row.js
import React from "react";
import "./Row.css";
import { shoes } from "./data";
function Row({ title }) {
return (
<div className="row">
<h2 className="row__title">{title}</h2>
<div className="row__productsContainer">
{shoes.map((shoe) => {
return (
<div className="row__product">
<img
className="row__productImage"
src={shoe.displayImagesLink}
alt=""
/>
<h3 className="row__productName">
{shoe.brand} {shoe.productName} {shoe.gender}
</h3>
<p>${shoe.price}</p>
</div>
);
})}
</div>
</div>
);
}
export default Row;
Shoe data
export const shoes = [
{
productName: "Air Force One",
brand: "Jordan",
price: "110.00",
trending: true,
gender: "womens",
onSale: false,
origPrice: "",
newArrival: false,
displayImagesLink: [
"https://images.dsw.com/is/image/DSWShoes/498043_100_ss_01?impolicy=qlt-medium-high&imwidth=640&imdensity=2",
"https://i.ebayimg.com/thumbs/images/g/fG8AAOSwsAtd16dg/s-l300.jpg",
"https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/dc844cd51f00b98aff6e6488362ab325-1622582608.jpeg?crop=1.00xw:0.653xh;0,0.347xh&resize=640:*",
],
},
{
productName: "Color Vintage Canvas Chuck 70",
brand: "Converse",
price: "85.00",
trending: true,
gender: "unisex",
onSale: false,
origPrice: "",
newArrival: false,
displayImagesLink: [
"https://www.converse.com/dw/image/v2/BCZC_PRD/on/demandware.static/-/Sites-cnv-master-catalog/default/dw7116f8fa/images/d_107/171566C_D_107X1.jpg?sw=2000",
"https://www.converse.com/dw/image/v2/BCZC_PRD/on/demandware.static/-/Sites-cnv-master-catalog/default/dw22858a53/images/f_107/171566C_F_107X1.jpg?sw=2000",
"https://www.converse.com/dw/image/v2/BCZC_PRD/on/demandware.static/-/Sites-cnv-master-catalog/default/dwb698b526/images/j_107/171566C_J_107X1.jpg?sw=2000",
],
},
{
productName: "Cap Toe Boot",
brand: "Crown Vintage",
gender: "Mens",
trending: false,
price: "59.99",
onSale: true,
origPrice: "79.00",
newArrival: true,
displayImagesLink: [
"https://images.dsw.com/is/image/DSWShoes/500544_225_ss_01?impolicy=qlt-medium-high&imwidth=640&imdensity=2",
"https://i.ebayimg.com/thumbs/images/g/fG8AAOSwsAtd16dg/s-l300.jpg",
"https://i.pinimg.com/550x/b5/f4/93/b5f493eeb58458253e9a10ab258e8a9c.jpg",
],
},
{
productName: "Classic Lined Clog",
brand: "Crocs",
price: "59.99",
trending: true,
gender: "Womens",
onSale: false,
origPrice: "",
newArrival: true,
displayImagesLink: [
"https://images.dsw.com/is/image/DSWShoes/438702_547_ss_01?impolicy=qlt-medium-high&imwidth=640&imdensity=2",
"https://images.dsw.com/is/image/DSWShoes/438702_433_ss_02?impolicy=qlt-medium-high&imwidth=640&imdensity=2",
"https://images.dsw.com/is/image/DSWShoes/438702_433_ss_08?impolicy=qlt-medium-high&imwidth=640&imdensity=2",
],
},
];
thank you for the help.
before map you can add a filter something like this
shoes.filter(shoe => shoe["propertyName"] != undefined).map(...
accessing a property that doesnt exist will give you undefined so u can filter objects without that property and similarly for a value check you can do
shoe["propertyName"] == <desired value>
for multiple lists with multiple options you can just run different filters and then map on them.

Why ng2-tree is showing undefined

I'm using ng2-tree https://angular2-tree.readme.io/v3.2.0/docs/inputs plugin
When i input below json it is showing as undefined
[
{
"value": "helper",
"name": "helper",
"children": []
},
{
"value": "taxi",
"name": "taxi",
"children": []
},
{
"value": "Cake",
"name": "Cake",
"children": [
{
"name": "Chocolate Fudge Cake",
"value": "Chocolate Fudge Cake"
},
{
"name": "Carrot & Walnut Cake",
"value": "Carrot & Walnut Cake"
}
]
}
]
with above json my result is as undefined you can see them in my provided link below
here is the stackblitz link: https://stackblitz.com/edit/angular-ng2-tree-aouyza?file=app/app.component.ts
Please help me thanks in advance!!
Your data structure is wrong. The tree component received as input param a TreeModel and you're having an array of TreeModels at the moment.
Either you adjust your data structure and use a parent TreeModel to wrap your current ones as its children, like following:
tree: TreeModel = {
value: 'Parent Model',
children: [
{
value: 'helper',
name: 'helper',
children: [],
},
{
value: 'taxi',
name: 'taxi',
children: [],
},
{
value: 'Cake',
name: 'Cake',
children: [
{
name: 'Chocolate Fudge Cake',
value: 'Chocolate Fudge Cake',
},
{
name: 'Carrot & Walnut Cake',
value: 'Carrot & Walnut Cake',
},
],
}
]
};
Or you iterate over the array in the HTML and use multiple tree components. That would look like following:
<tree [tree]="t" *ngFor="let t of tree"></tree>
For more information see the Github page of ng2-tree ;)
Update:
You still need to adjust the data model the way I suggested but you can hide the empty root node. To do so, you need to do following:
HTML
<tree [tree]="tree" [settings]="{ rootIsVisible: false }"></tree>
Due to this setting a class rootless is applied which hides the empyt root node but only if you've added node_modules/ng2-tree/styles.css to your angular.json or you've added a custom implementation for that class.
You can find the settings doc here.

ng-repeat and ng-if not working

I want to do following:
Show all the html elements on the page based on some conditions,
my understanding was i can use ng-if.
If employeeList is empty then do i need to create another copy of the inner elements to make sure it shows on the page
ng-if prints both divs and spans which only one should be printed my html is this
html:
<div class="container" ng-controller="profileController" ng-init="loadProfilesData()">
<div ng-repeat="p in profileData">
<div>{{p.company}}</div>
<div>{{p.department}}</div>
<div ng-repeat="emp in p.employeeList"></div>
<div ng-if="emp.Tag== 'Devo100'" gauge-chart class="gauge" id="Devo100-{{p.Id}}" value=p.Value*100></div>
<div ng-if="emp.Tag!= 'Devo100'" gauge-chart class="gauge" id="Devo100-{{p.Id}}" value=0></div>
<span ng-if="emp.Tag== 'Devo102'">
{{ p.Value | date: "hh:mm:ss" }}
</span>
<span ng-if="emp.Tag== 'Devo102'">
0
</span>
</div>
</div>
</div>
my json is following
profileData: [
{
ID: "1",
metricStatList: [{"Value":0.003,"Stat":{"parameter":0,"Name":"test0","Tag":"Devo100"}},
{"Value":0.004,"Stat":{"parameter":0,"Name":"test1","Tag":"Devo101"}},
{"Value":0.005,"Stat":{"parameter":0,"Name":"test2","Tag":"Devo102"}}],
comapny: "MSDFT",
department: "Sales"
},
{
ID: "2",
metricStatList: null,
comapny: "MSDFT",
department: "HR"
},
{
ID: "3",
metricStatList: [{"Value":0.003,"Stat":{"parameter":0,"Name":"test0","Tag":"Devo100"}},
{"Value":0.004,"Stat":{"parameter":0,"Name":"test1","Tag":"Devo101"}}],
comapny: "MSDFT",
department: "Development"
},
{
ID: "4",
metricStatList: [{"Value":0.1,"Stat":{"parameter":0,"Name":"test2","Tag":"Devo102"}},
{"Value":0.25,"Stat":{"parameter":0,"Name":"test1","Tag":"Devo101"}}],
comapny: "MSDFT",
department: "Finance"
},
{
ID: "5",
metricStatList: [{"Value":0.233,"Stat":{"parameter":0,"Name":"test0","Tag":"Devo100"}}],
comapny: "MSDFT",
department: "Accounts"
}
]

Setting preselected values in multiple select with Ractive

I render a select multiple in Ractive with a computed list of all options possible, which works great. But I could not find a proper way of preselecting values.
So far I have something like:
data = [{
type: "Person",
Name: "John",
worksFor: [
"1",
"2"
]},{
type: "department",
id: "1",
Name: "Sales"
},{
type: "department",
id: "2",
Name: "Marketing"
},{
type: "department",
id: "3",
Name: "Accounting"
}]
new Ractive({
el: '#list',
template: DataTpl,
data: {myData: data},
computed: {
DepartmentList () {
//some code
return list_of_all_Departments;
},
PersonsList () {
//some Code
return list_of_persons
});
So in my Template I tried
{{#PersonsList}}
<select multiple>
{{#DepartmentList}}
<option value="{{id}}"
{{#if _.includes(PersonsList.worksFor, id)}} selected{{/if}}>{{Name}}
</option>
{{/DepartmentList}}
</select>
{{/PersonsList}}
But this just gave me a failed to compute. Does anyone know how to get those preselects?
This is one of the things where Ractive deviates from standards. You need to put a value attribute on <select>. The selected <option>'s value becomes <select>'s value. The kind of data you'll get from <select> depends if it's multiple or not. If it's a single-select, you get a single value. If it's multiple-select, you'll get an array.
Setting a pre-selected value is simply the other way around. Assign a value from your data to <select>'s value and, assuming those values exist on the <option>s, they'll be selected. No template mangling required.
Ractive.DEBUG = false;
var data = [{
type: "Person",
Name: "John",
worksFor: [
"1",
"2"
]
}, {
type: "department",
id: "1",
Name: "Sales"
}, {
type: "department",
id: "2",
Name: "Marketing"
}, {
type: "department",
id: "3",
Name: "Accounting"
}];
new Ractive({
el: '#list',
template: '#template',
data: {
selectedDepartments: [],
myData: data
},
computed: {
DepartmentList() {
return this.get('myData').filter(v => v.type === 'department');
},
PersonsList() {
return this.get('myData').filter(v => v.type === 'Person');
}
}
});
<script src="https://unpkg.com/ractive#0.8.11/ractive.min.js"></script>
<div id="list"></div>
<script type="template/ractive" id="template">
{{#PersonsList}}
{{ Name }}
<select multiple value="{{ worksFor }}">
{{#DepartmentList}}
<option value="{{id}}">{{Name}}</option>
{{/DepartmentList}}
</select>
{{/PersonsList}}
</script>
you must give the select a value and set the value to whatever is the default value

Dynatree- Get Div ID

I have 2 same dynatrees in the same page as shown in this js fiddle http://jsfiddle.net/37ppf/3/.
$("#tree1").dynatree({
onSelect : function(select,node){},
checkbox: true,
children: [
{title: "Item 1",key:"1"},
{title: "Folder 2", isFolder: true, key:"2",
children: [
{title: "Sub-item 2.1", },
{title: "Sub-item 2.2", }
]
},
{title: "Item 3",key:"5"}
]
});
$("#tree2").dynatree({
onSelect : function(select,node){},
checkbox: true,
children: [
{title: "Item 1",key:"1"},
{title: "Folder 2", isFolder: true, key:"2",
children: [
{title: "Sub-item 2.1", },
{title: "Sub-item 2.2", }
]
},
{title: "Item 3",key:"5"}
]
});
<div id="tree1"> </div>
<div id="tree2"> </div>
Now When a user selects any node in any of the dynatree I want to get the div id in which the tree from which the user has selected the node is loaded.i.e if user selects from first tree I want to get output as tree1(div id) and if a node is selected from second tree i want to get tree2. Is this possible. I tried
$(this).closest(".dynatree-container").parent("div").attr("id")
But its coming undefined.
It feels super hacky, but you can do it this way:
onSelect : function(select,node){
alert(node.tree.$tree[0].id);
},
node.tree.$tree[0] will return the javascript object of its parent tree.
See the working code at
JSFiddle
Try this
$(document).on('click','span',function(){
console.log($(this).parents('div').attr('id'))
})
DEMO

Categories

Resources