filter multiple checkbox angular - javascript

I am trying to filter my results on multiple checkboxes.
Here is my JSFIDDLE
How do i write dynamic ng-model for the checkboxes for the filter to take reflect?
function MainCtrl($scope) {
$scope.languages = [
{ name: 'persian', _id : 0 },
{ name: 'English', _id : 1 },
{ name: 'spanish', _id : 2 }
];
$scope.bu = [
{ name: 'A', _id : 1 },
{ name: 'B', _id : 2 },
{ name: 'C', _id : 3 },
{ name: 'D', _id : 4 },
{ name: 'E', _id : 5 }
];
$scope.array = [
{
"id": 910,
"language": {
"_id": "333",
"name": "Persian",
"abbreviation": "PE"
},
"business_unit": {
"_id": "2",
"name": "B"
}
},
{
"id": 909,
"language": {
"_id": "456",
"name": "English",
"abbreviation": "EN"
},
"business_unit": {
"_id": "3",
"name": "C"
}
},
{
"id": 908,
"language": {
"_id": "456",
"name": "Spanish",
"abbreviation": "SP"
},
"business_unit": {
"_id": "4",
"name": "D"
}
},
{
"id": 911,
"language": {
"_id": "343",
"name": "German",
"abbreviation": "GE"
},
"business_unit": {
"_id": "5",
"name": "E"
}
},
{
"id": 912,
"language": {
"_id": "696",
"name": "Russian",
"abbreviation": "RU"
},
"business_unit": {
"_id": "1",
"name": "A"
}
}]
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="MainCtrl">
<li ng-repeat="o in languages" ng-model="lang.language.name">
<input type="checkbox">
{{o.name}},
`</li>
<br><br><br>
<li ng-repeat="o in bu">
<input type="checkbox" ng-model="bu.business_unit.name">
{{o.name}},
`</li>
<br><br><br>
<div ng-repeat="arr in array filter : lang | filter : bu">
{{arr.language.name}} "and" {{arr.business_unit.name}}
</div>
<div>

You can use custom filter to achieve your goal:
custom fileter:
filter('myFilter', function() {
return function(items, search) {
var filterItems = {
search: search,
result: []
};
if (!search.needFilter) {
return items;
}
angular.forEach(items, function(value, key) {
if (this.search.language[value.language.name] === true || this.search.business_unit[value.business_unit.name] === true) {
this.result.push(value);
}
}, filterItems);
return filterItems.result;
};
})
HTML:
<p>Search by Language:</p>
<li ng-repeat="o in languages">
<input type="checkbox" ng-model="search.language[o.name]"> {{o.name}}
</li>
<p>Search by Unit:</p>
<li ng-repeat="o in bu">
<input type="checkbox" ng-model="search.business_unit[o.name]"> {{o.name}}
</li>
<p><b>Result:</b></p>
<div ng-repeat="arr in array | myFilter : search:false ">
{{arr.language.name}} "and" {{arr.business_unit.name}}
</div>
For more details see PLUNKER DEMO

Related

Compare values over components / BootstrapVue

I'm working with BootstrapVue. I have following problem - I have a select dropdown in my parent.vue where I select my ID (as you can see it's my props) and I want to compare this with my json file...
Now I need to do following:
Check my selected ID (from parent.vue) with my json file and find the correct ID
Put all Articel in my dropdown selection
emit Rank of selected Articel back to parent
I don't have any clue how to solve that with a nested JSON File.. I think I have to use a v-for loop..
Thanks in advance for helping me out!
my code:
<template>
<b-card>
<div class="mt-2">CLOTHING ITEM</div>
<b-form-select type="text"></b-form-select>
</b-card>
</template>
<script>
import json from './json/ID.json'
export default {
name: "customerChoice",
data() {
return {
json: json,
}
},
props: ["ID"]
}
</script>
my nested json:
[
{
"ID": "1111",
"Product": {
"1": {
"Articel": "Jeans",
"Rank": "1"
},
"2": {
"Articel": "T-Shirt",
"Rank": "2"
}
}
},
{
"ID": "2222",
"Product": {
"1": {
"Articel": "Hoodie",
"Rank": "2"
},
"2": {
"Articel": "Jeans",
"Rank": ""
}
}
},
{
"ID": "3333",
"Product": {
"1": {
"Articel": "Socks",
"Rank": "1"
}
}
}
]
If I understand you correctly, take a look at following snippet:
Vue.component('Child', {
template: `
<b-card>
<div class="mt-2">CLOTHING ITEM</div>
<b-form-select type="text"
v-model="selected"
:options="articles"
text-field="Articel"
value-field="Rank"
>
</b-form-select>
</b-card>
`,
data() {
return {
json: [
{ID: "1111", "Product": {"1": {"Rank": "1", "Articel": "Jeans"}, "2": {"Articel": "T-Shirt", "Rank": "2"}}},
{ID: "2222", "Product": {"1": {"Articel": "Hoodie","Rank": "2"}, "2": {"Articel": "Jeans", "Rank": ""}}},
{ID: "3333", "Product": {"1": {"Articel": "Socks", "Rank": "1"}}}
],
selected: null,
}
},
props: ["id"],
computed: {
articles() {
const res = []
const art = this.json.find(j => j.ID === this.id)
for(let key in art.Product) {
res.push(art.Product[key])
}
return res
}
},
watch: {
selected() {
this.$emit('changed', this.selected)
}
}
})
new Vue({
el: '#demo',
data() {
return {
parentId: '1111',
rank: ''
}
},
methods: {
rankReceived(val) {
console.log(val)
this.rank = val
}
}
})
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<div id="demo">
<h3>{{rank}}</h3>
<Child :id="parentId" #changed="rankReceived" />
</div>

filter the items inside *ngFor based on the category on button click - Angular

I have a list of items which I am looping through with *ngFor. I have category buttons above the list like in the HTML shown below. What I need to implement is when clicking on the button, I want to filter the list based on the category of the button clicked.
I am not sure what approach is better, whether to go for a pipe or just a function
<div class="quick-filter-container">
<button class="quick-filter-button active" [class.active]="isActive('cat1')" (click)="setActive('cat1')"
type="button">Category1</button>
<button class="quick-filter-button" [class.active]="isActive('cat2')" (click)="setActive('cat2')"
type="button">Category2</button>
<button class="quick-filter-button" [class.active]="isActive('cat3')" (click)="setActive('cat3')"
type="button">Category3</button>
<button class="quick-filter-button" [class.active]="isActive('cat4')" (click)="setActive('cat4')"
type="button">Category4</button>
</div>
<div class="meter-reading-list-conatiner" *ngFor="let data of filteredList">
<h1>{{data.address.addressName}}</h1>
<div *ngFor="let header of data.premiseMeters">
<span> ID: {{header.meterNumber}}</span>
</div>
</div>
setActive(buttonName) {
this.activeButton = buttonName;
}
isActive(buttonName) {
return this.activeButton === buttonName;
}
JSON
this.filteredList = {
"meterReadPanelReportList": [
{
"premiseId": 674052,
"address": {
"addressName": "CHILDRENS ROAD, LIMERICK, CO. LIMERICK"
},
"premiseMeters": [
{
"meterNumber": "Y00001410",
"utilType": "elec",
"category": "category1",
"meters": [
{
"lastReadingDate": "23/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
},
{
"lastReadingDate": "24/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
}
]
},
{
"meterNumber": "Z00001410",
"utilType": "gas",
"category": "category3",
"meters": [
{
"lastReadingDate": "23/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
},
{
"lastReadingDate": "23/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
}
]
}
]
},
{
"premiseId": 674052,
"address": {
"addressName": "CHILDRENS ROAD, LIMERICK, CO. LIMERICK"
},
"premiseMeters": [
{
"meterNumber": "Y00001410",
"utilType": "gas",
"category": "category2",
"meters": [
{
"lastReadingDate": "23/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
},
{
"lastReadingDate": "24/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
}
]
},
{
"meterNumber": "Z00001410",
"utilType": "gas",
"category": "category3",
"meters": [
{
"lastReadingDate": "23/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
},
{
"lastReadingDate": "23/09/2020",
"lastReadingMethod": "E",
"lastReadingStatus": "Pending"
}
]
}
]
}
]
}
Call the function from html and pass the category name as an argument
<button class="quick-filter-button active" [class.active]="isActive('cat1')" (click)="myClickFunction('category1')"
type="button">Category1</button>
Filter the data in components on a common function. Expecting the unfiltered dataset named as data here.
myClickFunction(category){
this.filteredList = data.filter(item => item.category === category );
}

How to access items from array

I want to display the name and photoUrl in the HTML template of an Angular 6 app, how do I access the name and photoUrl elements only in the below array:
{
"key":"key0",
"value":[
{
"id":567657,
"name":"Jess",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating":30
},
{
"id":3243242,
"name":"Ryan",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/male-29.jpg",
"rating":5
}
]
}
{
"key":"key1",
"value":[
{
"id":567657,
"name":"Jess",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating":30
},
{
"id":6757587,
"name":"Sarah",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-70.jpg",
"rating":16
}
]
}
You can use *ngFor directive provided by Angular
.component.html
<div *ngFor="let user of users">
<div *ngFor="let value of values;i = index">
<div>{{value.name}}</div>
<div>{{value.photoUrl}}</div>
</div>
<div>
.component.ts
users = [
{
"key":"key0",
"value":[
{
"id":567657,
"name":"Jess",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating":30
},
{
"id":3243242,
"name":"Ryan",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/male-29.jpg",
"rating":5
}
]
}.
{
"key":"key1",
"value":[
{
"id":567657,
"name":"Jess",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating":30
},
{
"id":6757587,
"name":"Sarah",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-70.jpg",
"rating":16
}
]
}
]
Your JSON is not valid, however i made few adjustments
[ {
"key": "key0",
"value": [
{
"id": 567657,
"name": "Jess",
"photoUrl": "https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating": 30
},
{
"id": 3243242,
"name": "Ryan",
"photoUrl": "https://d3iw72m71ie81c.cloudfront.net/male-29.jpg",
"rating": 5
}
] }, {
"key": "key1",
"value": [
{
"id": 567657,
"name": "Jess",
"photoUrl": "https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating": 30
},
{
"id": 6757587,
"name": "Sarah",
"photoUrl": "https://d3iw72m71ie81c.cloudfront.net/female-70.jpg",
"rating": 16
}
] } ]
and you just need nested ngFor as follows,
<ul>
<li *ngFor="let group of myArray">
{{group.name}}
<ul>
<li *ngFor="let light of group.value">
<h1>Photo </h1> {{light.photoUrl}}
<h1>Name </h1> {{light.name}}
</li>
</ul>
</li>
</ul>
STACKBLITZ DEMO
component.ts
user_Array = [
{
"key":"key0",
"value":[
{
"id":567657,
"name":"Jess",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating":30
},
{
"id":3243242,
"name":"Ryan",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/male-29.jpg",
"rating":5
}
]
}.
{
"key":"key1",
"value":[
{
"id":567657,
"name":"Jess",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-50.jpeg",
"rating":30
},
{
"id":6757587,
"name":"Sarah",
"photoUrl":"https://d3iw72m71ie81c.cloudfront.net/female-70.jpg",
"rating":16
}
]
}
]
component.html
<div *ngFor="let user of user_Array">
<span>{{user?.name}}</span>
<img src="{{user?.photoUrl}}">
<div>
comment
by adding '?' html file will not generate error if that specific variable is not present.
it is always safe to add "?" while accessing ts variable

Generate dynamic data field using child component

I want to generate dynamic data field using value of prop passed in child component.
Code:
...
<datafieldcheckbox :categories="abc" #call-method="callfilteredproducts"></datafieldcheckbox>
new Vue({
el: "#app",
data: {
abc: null, // this will generate based on a value of prop passed in child component.
products: [
{
"id": "1",
"name": "Product1",
"abc": "EEE",
"skill": "Easy",
"color": "blue",
"price": 100.00
},
{
"id": 2,
"name": "Product2",
"abc": "EEE",
"skill": "Intermediate",
"color": "red",
"price": 120.00
},
{
"id": 3,
"name": "Product3",
"abc": "Office",
"skill": "Intermediate",
"color": "green",
"price": 190.00
}
]
...
const dfCheckBox = Vue.component('datafieldcheckbox', {
template: `<div id="one">
<h4><strong>Categories</strong></h4>
<ul class="categoriesFilter">
<li v-for="category in categories"><label><input type="checkbox" :id="category" :value="category" v-model="selectedFilters.categories" #click="filterProducts()"><span class="categoryName">{{category}}</span></label></li>
</ul>
</div>`,
data() {
return{
products : null,
selectedFilters: {
categories: [],
colors: [],
minPrice: null,
maxPrice: null
}
}
},
props : ['categories'],
methods: {
filterProducts(){
this.$emit('call-method', this.selectedFilters);
}
}
});
like in above code If I write abc then it will generate this kinda code in parent data:
Now let's say I have data in products and I want to find unique values of a key that is passed from child props.
Just pass the product array to child component and filter the category by checkbox. pls try this
template
<!-- child -->
<script type="text/x-template" id="grid-template">
<div>
<h2>
category list:
</h2>
<ul>
<li v-for="category in categories">
<label>{{category.abc}}</label>
<input type="checkbox" :value="category" v-model="selectedCategory" #change="emitback(selectedCategory)"/>
</li>
</ul>
</div>
</script>
<!-- parent -->
<div id="demo">
<h2>
selected category:
</h2>
<ul>
<li v-for="category in selectedCategory">
{{category.abc}}
</li>
</ul>
<datafieldcheckbox :categories="product" #call="callfilteredproducts"></datafieldcheckbox>
</div>
script
Vue.component('datafieldcheckbox', {
template: '#grid-template',
props: {
categories: Array,
},
created(){
console.log(this.categories);
},
data: function () {
return {
selectedCategory:[]
}
},
methods: {
emitback(selectedVal){
this.$emit('call',selectedVal);
}
}
})
// bootstrap the demo
var demo = new Vue({
el: '#demo',
data: {
selectedCategory:[],
product:[
{
"id": "1",
"name": "Product1",
"abc": "EEE",
"skill": "Easy",
"color": "blue",
"price": 100.00
},
{
"id": 2,
"name": "Product2",
"abc": "EEE",
"skill": "Intermediate",
"color": "red",
"price": 120.00
},
{
"id": 3,
"name": "Product3",
"abc": "Office",
"skill": "Intermediate",
"color": "green",
"price": 190.00
}
]
},
methods:{
callfilteredproducts(event){
console.log(event);
this.selectedCategory = event
}
}
})
demo Jsfiddle

Angular material chips md-autocomplete not working on ng-repeat

I using Angular 1.5.5, and angular-material 1.1.0 here.
When I adding md-chips in ng-repeat loop it do not working, I got follow error:
angular.js:13550 TypeError: this.items.some is not a function
at e.appendChip (http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js:13:28477)....
md-template do not what that should (as return i go value from md-item-text, which is _id, but i need $chip.text);
it don't addind an item even if i changing md-item-text="item.text" (which is wrong but for test).
It do working well for a single item (with out ng-repeat).
<md-list-item ng-repeat="i in dialogueItems track by $index">
<md-chips ng-model="i.text" md-removable="true" md-enable-chip-edit="true" md-autocomplete-snap="true" md-require-match="true">
<md-autocomplete md-min-length="0" md-match-case-insensitive="true" md-selected-item="i.selectedItem" md-search-text="i.searchText" md-items="item in loadItems(i.searchText, i.tagId)" md-item-text="i.selectedItem._id" md-autoselect="true" md-no-cache="true"
placeholder="Words">
<span md-highlight-text="i.searchText">{{item.text}}</span>
</md-autocomplete>
<md-chip-template>
{{$chip.text}}
</md-chip-template>
</md-chips>
</md-list-item>
JS
$scope.dialogueItems = [{
tagId: 1,
text: [],
searchText: null,
selectedItem: null
}];
$scope.loadItems = function(query, tagId) {
return $http({
method: 'POST',
url: '/api/wordsapi/searchwords',
data: {
text: query,
tagId: tagId,
count: 10
}
}).then(function(d) {
return d.data.words;
});
};
And example of api result:
{
"words": [{
"text": "you",
"_id": "030423b3-99ed-42a2-bab7-7efd10a68cfa"
}, {
"text": "i",
"_id": "a833abe2-c602-4cd7-b765-5b14229ecc7d"
}, {
"text": "god",
"_id": "724766b6-c83c-4679-bf28-827ad1a516eb"
}, {
"text": "a",
"_id": "c2b7920b-7541-42f1-9b61-84a1d7c42930"
}, {
"text": "bless",
"_id": "6ea9b56f-b47b-4453-b97c-0b5ba4311992"
}, {
"text": "am",
"_id": "ab12f90d-9b40-4e33-af13-14e75fbb405a"
}, {
"text": "your",
"_id": "55910a38-4435-4db4-8498-6cddaf4b0059"
}, {
"text": "with",
"_id": "7c5a2627-777f-443e-9f58-83c62e4fae11"
}, {
"text": "are",
"_id": "befa650c-e894-477b-9e67-2f7fb24e40b5"
}, {
"text": "good",
"_id": "90ee8243-630f-4f91-9ecf-0a6469716e0d"
}],
"allCount": 1024
}

Categories