How do you bind to name of array in object array? - angularjs

I have an object with an array:
{
People: [
{
label: 'label1',
type: 'type1'
},
{
label: 'label2',
type: 'type2'
}],
Places: [
{
label: 'label1',
type: 'type1'
},
{
label: 'label2',
type: 'type2'
}]
}
I have an ng-repeat to create a list. I can bind to the properties inside People and Places but cannot bind to the name 'People' and 'Places'.
My html is something like this:
<div ng-repeat="category in vm.categories">
<button>{{category}}</button>
<ul>
<li ng-repeat="subcategory in category">
{{subcategory.label}}
</li>
</ul>
</button>
</div>
so subcategories are all fine but {{category}} doesn't return People/Places. How do I bind to the name of the array in the object?

Try this by using iterate over the keys and values with ng-repeat in AngularJS?
angular.module("test",[]).controller("testc",function($scope) {
$scope.categories = {
People: [
{
label: 'label1',
type: 'type1'
},
{
label: 'label2',
type: 'type2'
}],
Places: [
{
label: 'label1',
type: 'type1'
},
{
label: 'label2',
type: 'type2'
}]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="testc">
<div ng-repeat="(key, value) in categories">
<button>{{key}}</button>
<ul>
<li ng-repeat="subcategory in value">
{{subcategory.label}}
</li>
</ul>
</button>
</div>
</div>

Related

Change Computed Property on Click

Is it possible to add/change the computed property inside the "v-for" with a click event?
I would like to be able to display the list of food based on their category when I click on the proper button.
If I click on the "fruit" button it will be
<div v-for="food in fruitCategory" :key="food.name" class="card">
<p>{{ food.name }}</p>
</div>
and "candy" button it would be
<div v-for="food in candyCategory" :key="food.name" class="card">
<p>{{ food.name }}</p>
</div>
Is this a good approach?
Actual code below
<template>
<div class="layout">
<button>all</button>
<button>fruit</button>
<button>candy</button>
<div v-for="food in foods" :key="food.name" class="card">
<p>{{ food.name }}</p>
</div>
</div>
</template>
export default {
name: 'Food',
data() {
return {
foods: [
{ name: 'banana', category: 'fruit' },
{ name: 'orange', category: 'fruit' },
{ name: 'strawberry', category: 'fruit' },
{ name: 'gum', category: 'candy' },
{ name: 'fuzzy peach', category: 'candy' },
]
}
},
computed: {
fruitCategory: function() {
return this.foods.filter(function(food) {
return food.category === 'fruit'
})
}
},
candyCategory: function() {
return this.foods.filter(function(food) {
return food.category === 'candy'
})
}
}
You just need to store the category in data and then you can use the filter dynamically.
here as a working example with a cat array that checks if the category is included.
new Vue({
el: "#app",
name: 'Food',
data() {
return {
cat: ['fruit','candy'],
foods: [
{ name: 'banana', category: 'fruit' },
{ name: 'orange', category: 'fruit' },
{ name: 'strawberry', category: 'fruit' },
{ name: 'gum', category: 'candy' },
{ name: 'fuzzy peach', category: 'candy' },
]
}
},
computed: {
filtered: function() {
var cat = this.cat;
return this.foods.filter(function(food) {
return cat.indexOf(food.category) >= 0;
})
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<div class="layout">
<button #click="cat=['fruit', 'candy']">all</button>
<button #click="cat=['fruit']">fruit</button>
<button #click="cat=['candy']">candy</button>
<div v-for="food in filtered" :key="food.name" class="card">
<p>{{ food.name }}</p>
</div>
</div>
</div>

arrange search filters using angular js

Problem: when i input "K", it filters both name and country that contain character "K".
Question: How can i filter the input characters only in "names.name"?
var app = angular.module("myApp", []);
app.controller("namesCtrl", function($scope) {
$scope.names = [
{ name:'Jani', country:'Norway' },
{ name:'Carl', country:'Sweden' },
{ name:'Margareth', country:'England' },
{ name:'Hege', country:'Norway' },
{ name:'Joe', country:'Denmark' },
{ name:'Gustav', country:'Sweden' },
{ name:'Birgit', country:'Denmark' },
{ name:'Mary', country:'England' },
{ name:'Kai', country:'Norway' }
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>
<input type="text" ng-model="test">
</p>
<ul>
<li ng-repeat="name in names | filter:test">
{{ name.name }}
</li>
</ul>
</div>
Try this
var app = angular.module("myApp", []);
app.controller("namesCtrl", function($scope) {
$scope.names = [
{ name:'Jani', country:'Norway' },
{ name:'Carl', country:'Sweden' },
{ name:'Margareth', country:'England' },
{ name:'Hege', country:'Norway' },
{ name:'Joe', country:'Denmark' },
{ name:'Gustav', country:'Sweden' },
{ name:'Birgit', country:'Denmark' },
{ name:'Mary', country:'England' },
{ name:'Kai', country:'Norway' }
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>
<input type="text" ng-model="test">
</p>
<ul>
<li ng-repeat="name in names | filter:{'name':test}">
{{ name.name }}
</li>
</ul>
</div>
Could you please use custom filter like below.
var app = angular.module("myApp", []);
app.controller("namesCtrl", function($scope) {
$scope.names = [{
name: 'Jani',
country: 'Norway'
},
{
name: 'Carl',
country: 'Sweden'
},
{
name: 'Margareth',
country: 'England'
},
{
name: 'Hege',
country: 'Norway'
},
{
name: 'Joe',
country: 'Denmark'
},
{
name: 'Gustav',
country: 'Sweden'
},
{
name: 'Birgit',
country: 'Denmark'
},
{
name: 'Mary',
country: 'England'
},
{
name: 'Kai',
country: 'Norway'
}
];
});
app.filter('searchTerm', function() {
return function(items, text) {
if (text) {
return items.filter(item => {
return item.name.toLowerCase().includes(text)
})
}
return items;
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>
<input type="text" ng-model="test">
</p>
<ul>
<li ng-repeat="name in names | searchTerm:test">
{{ name.name }}
</li>
</ul>
</div>

Dynamic Value Checkbox Vuejs 2

I can't get the value of the checkbox.
<li v-for="mainCat in mainCategories">
<input type="checkbox" :value="mainCat.merchantId" v-model="mainCategories.merchantId" id="mainCat.merchantId" #click="merchantCategoryId">
</li>
My Methods:
methods: {
merchantCategoryId: function() {
console.log(this.mainCategories.merchantId)
}
}
When it clicks I only get true and false for uncheck. TY
<div id="demo" >
<ul>
<li v-for="mainCat in mainCategories">
<input type="checkbox" :value="mainCat.merchantId" :id="mainCat.merchantId" v-model="checkedCategories" #click="check($event)"> {{mainCat.merchantId}}
</li>
</ul>
{{ checkedCategories }}
</div>
And in your script:
var demo = new Vue({
el: '#demo',
data: {
checkedCategories: [],
mainCategories: [{
merchantId: '1'
}, {
merchantId: '2'
}]
},
methods: {
check: function(e) {
if (e.target.checked) {
console.log(e.target.value)
}
}
}
})
Check this: https://v2.vuejs.org/v2/guide/forms.html#Checkbox
Working fiddle: http://jsfiddle.net/yMv7y/9206/
new Vue({
el: '#app',
data() {
return {
mainCategory: {
merchantIds: []
},
mainCategories: [{
merchantId: 1,
category: 'first category'
},
{
merchantId: 2,
category: 'second category'
}]
}
},
methods: {
merchantCategoryId: function() {
console.log(this.mainCategory.merchantIds)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<li v-for="mainCat in mainCategories">
<input type="checkbox"
:value="mainCat.merchantId"
v-model="mainCategory.merchantIds"
id="mainCat.merchantId"
#click="merchantCategoryId">
</li>
</div>
OR
new Vue({
el: '#app',
data() {
return {
mainCategories: [{
merchantId: 1,
category: 'first category'
},
{
merchantId: 2,
category: 'second category'
}]
}
},
methods: {
merchantCategoryId: function(event) {
console.log(event.target.value, event.target.checked)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<li v-for="mainCat in mainCategories">
<input type="checkbox"
:value="mainCat.merchantId"
id="mainCat.merchantId"
#change="merchantCategoryId($event)">
</li>
</div>
1.I observed both the mainCategories and v-model value v-model="mainCategories.merchantId" are the same.
You cannot access the marchantId of mainCategories, this is the mistake what you did apart from that nothing is wrong in the code sample to get the value of marchantId.
2 When your using $event in the click or change event function no need to use the v-model value.

Multi selectable checkbox groups using angularjs

Some time back I was looking for multi select checkbox group option in angularjs. I could not able to find my self on stackoverflow, Since i have developed it and sharing here js fiddle link.
<div ng-app="check">
<div ng-controller="controller">
<ul>
<li ng-repeat="(key, item) in basket"> {{item.type}}
<ul>
<li ng-repeat="(sub_catkey, sub_catval) in item.fields">
<label>
<input type="checkbox" ng-model="sub_catval.checked" /> {{sub_catval.name}} -- {{sub_catval.checked}} | json
</label>
</li>
</ul>
</li>
</ul>
Selected show here
<li ng-repeat="(key, item) in basket"> {{item.type}}
<ul>
<li ng-repeat="(sub_catkey, sub_catval) in item.fields | filter: true">
<label>
{{sub_catval.name}} -- {{sub_catval.checked}}
</label>
</li>
</ul>
</li>
{Manager: {Name: filter.key}}
{{basket}}
angular.module('check', [])
.controller('controller', function($scope) {
$scope.basket = [
{
"type": "fruits",
"fields": [
{name: 'Apple', checked:false},
{name: 'Mango', checked:true},
{name: 'Banana', checked:false},
{name: 'Guava', checked:false},
{name: 'Orange', checked:false}
]
},
{
"type": "flowers",
"fields": [
{name: 'rose', checked:true},
{name: 'lilly', checked:false},
{name: 'tulip', checked:false},
{name: 'marigold', checked:false},
{name: 'sunflower', checked:false}
]
}
];
$scope.selected = {
fruits: ["Apple"],
flowers: []
};
$scope.checkAll = function() {
$scope.basket = angular.copy($scope.basket);
};
$scope.uncheckAll = function() {
$scope.selected.fruits = [];
};
});
http://jsfiddle.net/42y83eLb/

AngularJS ngrepeat - filter based on scope data

I am trying to create a dropdown menu using angular ng-repeat.
I have a jd object with a field called parent_id which indicates parent node under which this node should show up. Help I need is to create filter based on previous filtered data as shown in the markup
My markup code:
<div >
<ul class="nav nav-pills" data-ng-controller= "MenuController" >
<li data-ng-class="{'active':getClass('/customers')}"
data-ng-repeat="menuItem in menuItems | filter: { ParentId: '0' }" >
{{ menuItem.Name }}
**<ul>
<li data-ng-repeat="menuItem1 in menuItems | filter: { ParentId: {{ menuItem1.ParentId }} }">
{{ menuItem1.Name }}
</li>
</ul>**
</li>
</ul>
</div>
My Service:
app.service('menuService', function () {
this.getMenuItems = function () {
return menuItems;
};
var menuItems = [
{
id: 'ABCDFER1', Name: 'Apperal', ParentId: 0, description: 'Beautifull Apparels'
},
{
id: 'ABCDFER2', Name: 'Electronics', ParentId: 0, description: 'Electronic bargains'
},
{
id: 'ABCDFER3', Name: 'Home & Kitchen', ParentId: 0, description: 'For your kitchen'
},
{
id: 'ABCDFER4', Name: 'Services', ParentId: 0, description: 'Services for you'
},
{
id: 'ABCDFER5', Name: 'Men', ParentId: 'ABCDFER1', description: 'Men Apperal'
},
{
id: 'ABCDFER6', Name: 'Women', ParentId: 'ABCDFER1', description: 'Women Apperal'
}
];
My controller:
$scope.menuItems = menuService.getMenuItems();
If I correctly understand what you're trying to accomplish, I believe you want this:
<div >
<ul class="nav nav-pills" data-ng-controller= "MenuController" >
<li data-ng-class="{'active':getClass('/customers')}"
data-ng-repeat="menuItem in menuItems | filter: { ParentId: '0' }" >
{{ menuItem.Name }}
<ul>
<li data-ng-repeat="menuItem1 in menuItems | filter: { ParentId: menuItem.id }">
{{ menuItem1.Name }}
</li>
</ul>
</li>
</ul>
</div>
Changes of note:
You want to filter on the id of the parent item, not the parentId of
the current item.
You don't need {{ }} around the filter value, because this is interpreted as code, not a template.

Resources