Angularjs checkbox filter on two arrays - javascript

I've been struggling to filter two different arrays, one with the checkbox values and another with whole data. In other terms, first array contains the field values from a sharepoint list and the second array contains the items from same sharepoint list. How can I filter based on the checkbox selected. Here is my code:
<div ng-repeat="x in processes">
<input type="checkbox" ng-model="filteredData"/>{{x}}
</div>
<div ng-repeat = "y in toBeFiltered | filter: {filteredData : true}">
<span class="title">{{y.Title}}</span>
<span class="process"> {{y.process}}</span>
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.processes = [
"Alfreds Futterkiste",
"Berglunds snabbköp",
"Centro comercial Moctezuma",
"Ernst Handel",
];
$scope.toBeFiltered = [{
"Title": "title1",
"process": ["Alfreds Futterkiste"]
}, {"Title" : "title2",
"process": ["Alfreds Futterkiste, Berglunds Snabbkop"]
},{"Title" : "title2",
"process": ["Alfreds Futterkiste, Berglunds Snabbkop,Ernst Handel,
Centro Comercial Moctezuma"]
}];
});
</script>
I tried using ng-model, but that didn't work. Please help. Thanks!

As a first step, you need to provide value to the check box inputs which will be set in the ng-model, when the check box is checked.

First of all you need to keep track of selected options, so I added checked property to each processes object, which then ng-model change it's value.
second I changed the two arrays which were like this
["Alfreds Futterkiste, Berglunds Snabbkop,Ernst Handel, Centro Comercial Moctezuma"]
from one long value to
["Alfreds Futterkiste", "Berglunds snabbköp","Ernst Handel", "Centro comercial Moctezuma"]
last you need to define custom filter function, in my case containFn which checks each toBeFiltered item and see if some of this item's processes is contained in processes array with condition that its checked == true
angular.module('myApp', []).controller('myCtrl', function($scope){
$scope.processes = [
{name: "Alfreds Futterkiste", checked: false},
{name: "Berglunds snabbköp", checked: false},
{name:"Centro comercial Moctezuma", checked: false},
{name: "Ernst Handel", checked: false}
];
$scope.toBeFiltered = [{
"Title": "title1",
"process": ["Alfreds Futterkiste"]
}, {"Title" : "title2",
"process": ["Alfreds Futterkiste", "Berglunds snabbköp"]
},{"Title" : "title2",
"process": ["Alfreds Futterkiste", "Berglunds snabbköp","Ernst Handel", "Centro comercial Moctezuma"]
}];
$scope.containFn = function(item){
var found = false;
item.process.forEach(function(element){
if($scope.processes.some(function(it) {return (it.name == element && it.checked== true) })) found = true;
});
return found;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myApp' ng-controller='myCtrl'>
<div ng-repeat="x in processes">
<input type="checkbox" ng-model="x.checked"/>{{x.name}}
</div>
<div ng-repeat = "y in toBeFiltered | filter: containFn">
<span class="title">{{y.Title}}</span>
<span class="process"> {{y.process}}</span>
</div>
</div>
run the snippet, if there is something isn't clear, or I didn't get feel free to comment

Related

AngularJS: how to give array of values to filter

How to pass array of values as filter in angularjs
My scenario
cuisines json: ["food", "Alcohol","Thai"]
catorigeres json :["home", "office","school"]
values with cuisines and categories :
[{
"_id": "1",
"businessTypeName": "Pizza Hut",
"cus_name": ["food","Thai"],
"cat_name": ["home", "school"],
}, {
"_id": "2",
"businessTypeName": "Chicken Hut",
"cus_name":["Alcohol","Thai"],
"cat_name": ["office", "home"],
}, {
"_id": "3",
"businessTypeName": "Fish Hut",
"bussiness_url": "/dist/images/loop_image_sample_3.png",
"cus_name": ["Thai"],
"cat_name": ["office", "school"],
}]
cuisines and categories are of in checkbox if i click anyone it will append the array of values to {{selected}}
my question is how to filter values in {{selected}} to listing_loop div
my plunker demo
I don't think you can do that in html alone.
You can add a filtering function to the scope:
$scope.customFilter = function(value, index, array) {
// make sure `value.id` is a string
return ["food","Thai","Alcohol"].indexOf(value.id);
}
and using like this in HTML
<div ng-repeat="set in get | filter:customFilter"></div>

Angularjs orderby on toggle and removing orderby

So I am trying to use the orderby function of angularjs. Currently I have an original data set.
$scope.customers = [
{"name" : "Bottom-Dollar Marketse" ,"city" : "Tsawassen"},
{"name" : "Alfreds Futterkiste", "city" : "Berlin"},
{"name" : "Bon app", "city" : "Marseille"},
{"name" : "Cactus Comidas para llevar", "city" : "Buenos Aires"},
{"name" : "Bolido Comidas preparadas", "city" : "Madrid"},
{"name" : "Around the Horn", "city" : "London"},
{"name" : "B's Beverages", "city" : "London"}
];
$scope.reverse= false;
$scope.toggleOrder = function(){
$scope.reverse=!$scope.reverse;
}
If I use the following to display my customers, I would get the array reverse ordered by the city. Currently I could click on the toggle button and reverse the array if wanted to.
<button ng-click="toggleOrder()">ToggleReverse</button >
<li ng-repeat="x in customers | orderBy : 'city': reverse">{{x.name + ", " + x.city}}</li>
But now the issue is if I didn't want the orderBy function at all. If I wanted to get my original customers data without any order how could I do that with the same toggleOrder function?
For instance, When I load the data it would be the original array. If 1st click of the toggleOrder button, it would sort in based on city, 2nd click of the toggleOrder button would reverse sort the city, and third click of the toggleOrder button would have no sort and give me the original array, and so on.
If the orderBy function isn't the best to go by let me know.
Any help would be great!
I'm not sure why you want to add this feature on your application, but here you go:
(function() {
'use strict';
angular
.module('app', [])
.constant('BUTTON_VALUES', {
1: 'Ascending',
2: 'Descending',
3: 'No order',
})
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', 'BUTTON_VALUES'];
function MainCtrl($scope, BUTTON_VALUES) {
$scope.customers = [
{
"name": "Bottom-Dollar Marketse",
"city": "Tsawassen"
},
{
"name": "Alfreds Futterkiste",
"city": "Berlin"
},
{
"name": "Bon app",
"city": "Marseille"
},
{
"name": "Cactus Comidas para llevar",
"city": "Buenos Aires"
},
{
"name": "Bolido Comidas preparadas",
"city": "Madrid"
},
{
"name": "Around the Horn",
"city": "London"
},
{
"name": "B's Beverages",
"city": "London"
}
];
$scope.btnValue = BUTTON_VALUES[3];
$scope.reverse = true;
$scope.orderParam = '';
var increment = 0;
$scope.toggleOrder = function() {
increment++;
$scope.btnValue = BUTTON_VALUES[increment];
switch (increment) {
case 1:
case 2:
$scope.orderParam = 'city';
$scope.reverse = !$scope.reverse;
break;
case 3:
$scope.orderParam = '';
increment = 0;
break;
}
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="toggleOrder()">{{btnValue}}</button>
<pre ng-bind-template="Order - {{orderParam}}"></pre>
<pre ng-bind-template="Reverse? {{reverse}}"></pre>
<hr>
<li ng-repeat="x in customers | orderBy : orderParam: orderParam && reverse">{{x.name + ", " + x.city}}</li>
</body>
</html>
Note: I added a constant as an example to demonstrate how you can handle your button name.
I hope it helps.
So, you want the original order the third time you click on the order by button. Seems doable but complicated. Maybe instead you should have another button that is labeled "original order" and a hidden column that lists the index of your original order. Pushing that button orders by that original index.
/edited I rather use another approach of angualrjs filters which is basically taking string as param and matching it to the object in list.
jsfiddle.net/2q14sryb
Hope it works!

AngularJS showing value based on id

How can I change data based on id that is passed from json file.
JSON:
{
"hotels": [
{
"id" : 1,
"name": "some hotel 1",
"category" : [{
"id" : 1,
"hotel_id" : 1,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
},
{
"id" : 2,
"name": "some hotel 2",
"category" : [{
"id" : 1,
"hotel_id" : 2,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
}
]
}
in my html I have ng-repeat like:
<p>Hotel names</p>
<ul>
<li ng-repeat="hotel in list.hotels">
{{hotel.name}}
<ul class="thumbnails">
<p>Category</p>
<li ng-repeat="cat in hotel.category">
{{cat.name}}
</li>
</ul>
</li>
</ul>
So this will show all what I have in that json file and I'm trying to limit it to show only data for one hotel (I know that I can do it with something like {{hotel[0].name}}) but there must be better approach, and also how can I use some kind of a switch by pressing the button to show data from hotel with id 1 to hotel with id 2 in the same div and vice versa?
Thank you.
You could use ng-repeat to create the links to display the hotel based on the click like in the following demo or in this fiddle.
For the categories you can use another ng-repeat (not added in the demo).
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController() {
this.hotels = [
{
"id" : 1,
"name": "some hotel 1",
"category" : [{
"id" : 1,
"hotel_id" : 1,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
},
{
"id" : 2,
"name": "some hotel 2",
"category" : [{
"id" : 1,
"hotel_id" : 2,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
}
];
this.selectedHotel = this.hotels[0];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
{{hotel.name}}
<div>
Hotel name: {{mainCtrl.selectedHotel.name}}
Category: {{mainCtrl.selectedHotel.category}}
</div>
</div>
To answer your question, notice ng-if added
<p>Hotel names</p>
<ul>
<li ng-repeat="hotel in list.hotels">
{{hotel.name}}
<ul class="thumbnails">
<p>Category</p>
<li ng-repeat="cat in hotel.categories" ng-if="cat.id == yourid">
{{cat.name}}
</li>
</ul>
</li>
</ul>
You can change yourid by using the current controller. And as other people suggest, you shouldn't use ng-repeat if you want to display only one element

How to show JSON as formatted view in html

I need to view JSON in my html page as formatted view. JSON come from database. I need to show it nut in Formatted view.
Just like
{
"crews": [{
"items": [
{
"year" : "2013",
"boat" : "Blue",
"position" : "1",
"name" : "Patrick Close",
"college" : "Pembroke",
"weight" : "14st 2lbs"
}, {
"year" : "2013",
"boat" : "Blue",
"position" : "2",
"name" : "Geordie Macleod",
"college" : "Christ Church",
"weight" : "13st 10lbs"
}]
}]
}
Anyone have any idea or suggestion ? or any resource that may help.
Edited: I want to create a JSON parser. User input different json and can view in formatted view.
Try JSON.stringify(data), its a Javascript function. Hope it might help.
Refer: Detail Explaination
If you are using PHP then use json_encode
Refer: json_encode manual
Since your are using angular-js, you can simply load your JSON feed from your controller then use the ng-repeat function to iterate over the items into your view page. Here down a sample where of how your HTML view can look like and you may need to style and build the blocks as per your needs:
<span>items:</span>
<span>[</span>
<br/>
<div class="item" ng-repeat="item in items">
<span>{</span><br/>
<span class="field">year : {{item.year}}</span><br/>
<span class="field">boat : {{item.boat}}</span><br/>
<span class="field">position : {{item.position}}</span><br/>
<span>}</span>
</div>
You can find a working sample in this JSFiddle.
First: your remote JSON is invalid: it's missing an ending bracket for crews.
It should be like this:
{
"crews": [{
"items": [
{
"year" : "2013",
"boat" : "Blue",
"position" : "1",
"name" : "Patrick Close",
"college" : "Pembroke",
"weight" : "14st 2lbs"
}, {
"year" : "2013",
"boat" : "Blue",
"position" : "2",
"name" : "Geordie Macleod",
"college" : "Christ Church",
"weight" : "13st 10lbs"
}]
}] // Missing this bracket
}
You didn't mention if your JSON is remote or not. I'm assuming not, so I'll use a local JavaScript var with eval function in this sample code.
<script type="text/javascript">
var content = {
"crews": [{
"items": [
{
"year" : "2013",
"boat" : "Blue",
"position" : "1",
"name" : "Patrick Close",
"college" : "Pembroke",
"weight" : "14st 2lbs"
}, {
"year" : "2013",
"boat" : "Blue",
"position" : "2",
"name" : "Geordie Macleod",
"college" : "Christ Church",
"weight" : "13st 10lbs"
}]
}]
};
var json = eval(content);
for (c in json.crews) {
var crew = json.crews[c];
for (i in crew.items) {
var item = crew.items[i];
console.log(item.year);
console.log(item.boat);
console.log(item.position);
console.log(item.name);
}
}
</script>
I'm using console.log to output, so you'll be able to see data only if you open the browser console:

How to dynamically populate display objects in Angular JS based on properties from the JSON object.?

I am reading the below json value from a module.js
.controller('home.person',['$scope','$filter','personResource',function($scope,$filter,personResource) {
$scope.searchPerson = function() {
var params = $scope.search || {};
params.skip=0;
params.take =10;
$scope.personDetails =
{
"apiversion": "0.1",
"code": 200,
"status": "OK",
"mydata": {
"myrecords": [
{
"models": [
{
"name": "Selva",
"dob": "10/10/1981"
}
],
"Address1": "ABC Street",
"Address2": "Apt 123",
"City": "NewCity1",
"State": "Georgia"
},
{
"models": [
{
"name": "Kumar",
"dob": "10/10/1982"
}
],
"Address1": "BCD Street",
"Address2": "Apt 345",
"City": "NewCity2",
"State": "Ohio",
"Country":"USA"
},
{
"models": [
{
"name": "Pranav",
"dob": "10/10/1983"
}
],
"Address1": "EFG Street",
"Address2": "Apt 678",
"City": "NewCity3",
"State": "NewYork",
"Country":"USA",
"Zipcode" :"123456"
}
]
}
}
}
}])
Now i am able to statically build the UX. But my each record set's key value pair count is different. So i want to build my html dynamically as per the current record set's count.Country & Zipcode is not exist in all records so i need to build dynamically the build and populate the html output.Most of the time, my json output is dynamic. Instead of persondetails, i may get the json output of a product details instead of PersonDetails.
<div ng-show="personDetails.mydata.myrecords.length > 0" ng-repeat="recordSingle in personDetails.mydata.myrecords">
<div >
<span >Address1: {{recordSingle.Address1}}</span>
<span >Address2: {{recordSingle.Address2}}</span>
<span>City: {{recordSingle.City}}</span>
<span>State: {{recordSingle.State}}</span>
<span>Country: {{recordSingle.Country}}</span>
<span>Zipcode: {{recordSingle.Zipcode}}</span>
</div>
</div>
One way is to use ng-if statement, for the optional span elements:
<span ng-if="recordSingle.Address1">Address1: {{recordSingle.Address1}}</span>
[Update #1: updated based on revised comments to question]
[Update #2: fixed typos in function and included plunkr]
I now understand that you want to dynamically build the display objects based on properties from the JSON object. In this case, I would iterate through the properties of the object. I would use a function to produce this array of properties for each object so that you can filter out any prototype chains. I would also remove out any unwanted propoerties, such as the internal $$hashKey and perhaps the array objects e.g.
In your controller:
$scope.getPropertyNames = getPropertyNames;
function getPropertyNames(obj) {
var props = [];
for (var key in obj) {
if (obj.hasOwnProperty(key) && !angular.isArray(obj[key]) && key !== '$$hashKey') {
props.push(key);
}
}
return props;
}
Then in your HTML view:
<div ng-repeat="record in personDetails.mydata.myrecords">
<div ng-repeat="prop in getPropertyNames(record)">
<span ng-bind="prop"></span>: <span ng-bind="record[prop]"></span>
</div>
</div>
This works for me... see this plunker. It is displaying each of the properties of the object in the array dynamically (you could have any property in the object). Is this not what you are trying to achieve?

Categories

Resources