I am trying to implement chips style.
Adding tags and remove tags like chips style to an item, for that I need to split string and bind separately based on length of array of split.
How to split comma speared dynamic length string while binding data.
how can I use angular filters here
Please check following code.
JS: Controller:
var app = angular.module('myApp',[]);
app.controller('myCtrl', function($scope) {
var temp= {
"values": [
{
"id": "1",
"tags": "Design research, UI Frameworks, Wireframes"
},
{
"id": "2",
"tags": "Hockey, basketball, Cricket, Football, Baseball"
},
{
"id": "3",
"tags": "Sensors, maps, Location Service, Studio"
},
],
"count": "3"
};
// I have json like this
$scope.items = temp.values;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" >
<div ng-controller ="myCtrl">
<p ng-repeat="item in items">
<span>{{item.tags}}</span>
</p>
</div>
<hr>
<!-- here I am trying implement chips style -->
<!-- Requieremrnt-->
<span style="background:#ddd;">{{item.tags[0]}}</span>
<span style="background:#ddd;">{{item.tags[1]}}</span>
<span style="background:#ddd;">{{item.tags[n]}}</span>
<!-- can I use ng-repeat or custom filter. if yes how??-->
<hr>
</body>
Can I use ng-repeat or custom filter. if yes how??
Thanks.
There is no need to create a custom filter to do so (although you can if you want to).
For this particular purpose, you can split the tags in your controller and then simply iterate through the strings in your view. In this case we'll use a double ng-repeat. The first one to iterate through all group of strings in each set of tags and the second one to iterate through the split string items. I've modified your code below and cleaned it up a bit.
var app = angular.module('myApp',[]);
app.controller('myCtrl', function($scope) {
var temp= {
"values": [
{
"id": "1",
"tags": "Design research, UI Frameworks, Wireframes"
},
{
"id": "2",
"tags": "Hockey, basketball, Cricket, Football, Baseball"
},
{
"id": "3",
"tags": "Sensors, maps, Location Service, Studio"
},
],
"count": "3"
};
$scope.items = temp.values.map(function (item) {
return item.tags.split(",");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" >
<div ng-controller ="myCtrl">
<div ng-repeat="group in items">
<p ng-repeat="tag in group">{{tag}}</p>
<hr />
</div>
</div>
</body>
Related
I checked other question but they don't seem to solve my issue.
Here is my code :
var app = angular.module('myApp', []);
app.controller('listdata', function($scope, $http) {
$scope.users = [{
"name": "pravin",
"queue": [{
"number": "456",
"status": "Unavailable"
},
{
"number": "111",
"status": "Unavailable"
}],
"phone": "7411173737"
},
{
"name": "pratik",
"queue": [{
"number": "111",
"status": "Unavailable"
}],
"phone": "8558855858"
},
{
"name": "priyanka",
"queue": [{
"number": "456",
"status": "Unavailable"
}],
"phone": "5454573737"
},
{
"name": "prerana",
"queue": [{
"number": "111",
"status": "Unavailable"
}],
"phone": "7454543737"
}];
$scope.filter111 = function (user) {
return (user.queue.find(({number}) => number === '111'));
}
$scope.filter456 = function (user) {
return (user.queue.find(({number}) => number === '456'));
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"></script>
<div ng-app="myApp">
<label class="switch">
<input type="checkbox" ng-model="queue111">111
</label>
<label class="switch">
<input type="checkbox" ng-model="queue456">456
</label>
<div class="row" ng-controller="listdata">
<div ng-repeat="user in users|filter: queue111? filter111: ''|filter: queue456? filter456: ''">
<p> {{user.name}} {{user.phone}}</p>
</div>
</div>
</div>
I have created custom functions $scope.filter111 and $scope.filter456 respectively to filter data
Currently when I click the checkbox 111, the filter return only the record whose queue has a number 111 and when I click the checkbox 456, the filter returns only the records whose queue has a number 456. This much is working perfectly. When I click both the filters it displays only that object whose queue has both the number 111 and 456 i.e an AND operation is occurring here.
Expected result : I want it such that when I click both the checkbox
it should display all the records from 111 as well as 456 together i.e an OR operation.
How do I do this?
You can try creating a custom angularJS filter by referring w3schools.com example and this link (for better understanding of custom filters).
In your case, the custom angularjs filter would take 3 inputs, i.e the list you want to filter and the value of the checkboxes- queue111 and queue456. Perform filtering and returning the data by providing necessary conditions based on the value of checkboxes inside the filter.
This also reduces the code that you use in your HTML for filtering inside ng-repeat from
<div ng-repeat="user in users|filter: queue111? filter111: ''|filter: queue456? filter456: ''">
<p> {{user.name}} {{user.phone}}</p>
</div>
to
<div ng-repeat="user in users|customFilter: queue111:queue456">
<p> {{user.name}} {{user.phone}}</p>
</div>
where
customFilter is the name (can be any name, provided that name as
an example) of the angularJS filter you create.
users will be the default first input of your custom filter and the value of your checkboxes will be the 2nd and 3rd input respectively.
Also, it would be helpful if you provide codepen/plunker demos so that people can debug your problem and provide solutions easily.
I am having a problem with displaying a JSON array objects that I have gotten from a async http request.
I have used ng-repeat to try and display the objects in the view but I am having no luck after many hours. Here is the code I have so far.
index.html
<div class="main" ng-controller = "MyController">
<ul>
<li ng-repeat="item in parks">
<div class="info">
<h2>{{item.parks.name}}<h2>
<h2>{{item.parks.park_size}}<h2>
<h2>{{item.parks.open_times}}<h2>
<h2>{{item.parks.days_closed}}<h2>
<img ng-src="images/{{item.parks.short}}.jpg">
</div>
</li>
controllers.js
var myApp = angular.module('myApp', []);
myApp.controller('MyController', ['$scope', '$http', function($scope, $http) {
$http.get('js/data.json').success(function(data) {
$scope.parks = data;
console.log(data);
});
}]);
data.json
{
"parks": [
{
"park_name": "Central Park",
"park_size": {
"miles": "1.2",
"meters": "1900"
},
"open_times": {
"Monday-Friday": "8am-10pm",
"Saturday-Sunday": "10am-6.30pm"
},
"days_closed": [
"December 25th",
"December 26th"
],
"images": [
{
"short": "centralimage1.jpeg"
},
{
"short": "centralimage2.jpeg"
},
{
"short": "centralimage3.jpeg"
},
{
"short": "centralimage4.jpeg"
}
]
},
{
"park_name": "Riverside Park",
"park_size": {
"miles": "0.2",
"meters": "320"
},
"open_times": {
"Monday-Friday": "7am-9pm",
"Saturday-Sunday": "9am-8.30pm"
},
"days_closed": [
"December 25th",
"December 26th",
"Jamuary 1st"
],
"images": [
{
"short": "riversideimage1.jpeg"
},
{
"short": "riversideimage2.jpeg"
},
{
"short": "riversideimage3.jpeg"
},
{
"short": "riversideimage4.jpeg"
}
]
}
]
}
JS fiddle
https://jsfiddle.net/owxwh0kz/
You are iterating over parks already, so your code can look like this
<li ng-repeat="item in parks">
<div class="info">
<h2>{{item.park_name}}<h2>
(I changed item.park.name to be item.park_name to match your data)
Otherwise check using the Angular inspector to see what the data looks like.
It looks like the data coming back from the json object is not consitent with your binding selectors. Inside an ng-repeat you are alreading interating over the scope of parks.
<li ng-repeat="item in parks">
<div class="info">
<h2>{{item.park_name}}<h2>
<h2>{{item.park_size}}<h2>
<h2>{{item.open_times}}<h2>
<h2>{{item.days_closed}}<h2>
For the images because they are in another array you would have to performn another repeat to grab all images.Note that nested ng-repeats can lead to negative performance impacts.
Based on your code, you should iterate over parks.parks to reach the array of the $scope.parks object.
Also, within the ng-repeat you should use item.* instead of item.parks.*
Here is JSFiddle with the fixed code: https://jsfiddle.net/x0ja420L/
Some code changes has been made in your code :
Proper closing of the HTML tags to work it properly.
Use <h2>{{item.park_name}}</h2> instead of <h2>{{item.park_name}}<h2>
ng-repeat directive iterate the array object so if you want to access park_name you have to use ng-repeat like this ng-repeat="item in parks.parks"
demo !
ng-repeat directive iterate the array object, so if you want to access park_name you have to use ng-repeat like this ng-repeat="item in parks.parks",code should like this
<li ng-repeat="item in parks.parks">
<div class="info">
<h2>{{item.park_name}}<h2>
<h2>{{item.park_size}}<h2>
<h2>{{item.open_times}}<h2>
<h2>{{item.days_closed}}<h2>
<img ng-src="images/{{item.images[0].short}}.jpg">
</div>
</li>
you can see the demo
var foo = [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
},
{
"id": 4,
"name": "Test"
},
{
"id": 5,
"name": "Sample value"
},
{
"id": 6,
"name": "Testvalue"
}
];
I am trying to get a simple search input, which shows a couple of listings on ng-repeat. The search is basically a filter which shows searched items in that listing. What I have achieved is when I search something, with $http, it gets back the whole list of foo, and within that it filters. How can I just get the data with my keyword, and the whole JSON? For example if I search sample, how can I get the objects of id 3 and 5 so that I can display a new set of listings, or if I search with ID number 12, I get the object which has id as 12. The search term will be dynamic. I will be giving a $http call on every search as well.
Thanks.
If I understood well, it should work:
(function() {
angular
.module('app', [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', '$http'];
function MainCtrl($scope, $http) {
$scope.foo = [
{
"id":12,
"name":"Test"
},
{
"id":2,
"name":"Beispiel"
},
{
"id":3,
"name":"Sample"
},
{
"id":4,
"name":"Test"
},
{
"id":5,
"name":"Sample value"
},
{
"id":6,
"name":"Testvalue"
}
];
}
})();
<!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">
<input type="text" ng-model="search" placeholder="Search">
<ul>
<li ng-repeat="item in foo | filter: search">
<span ng-bind-template="{{item.id}} - {{item.name}}"></span>
</li>
</ul>
</body>
</html>
Note: If you want to perform a $http request based on search input, look at this DEMO.
You can use $filter to achieve this.
function YourController($filter) {
var result = $filter('filter')(foo, {"id":3,"id":5});
};
You can iterate result later.
so I'm working with a basic product category model to get my head around filtering and I can't figure out how to extract a property value from one object within an array while repeating through another.
A simplified version of my category array, which is in scope, looks like this. I can output their names with the preceding directive and the results are as expected:
[{
"_id": "TY76",
"name": "Planes"
}, {
"_id": "887T",
"name": "Trains"
}, {
"_id": "A0K4",
"name": "Autos"
}]
<p ng-repeat="category in product.categories "> {{ category.name }}</p>
And here is a simplified product, also in scope, which may contain the ID of one or more categories. In this case, Bobble Head belongs to both Planes and Autos:
{
"_id": "9876",
"name": "Bobble Head",
"cats": "['TY76','A0K4']"
}
Now, here is where I'm having a hard time. I need to output the category names with the product. I can output the IDs no problem via:
<p ng-repeat="cat in product.cats ">{{ cat }}</p>
But that's of no use to the end user but I have no idea how to end up with something like:
Product: Bobble Head | Categories: Planes, Autos
I don't have the autonomy to add the category name to each product and I've tried a bunch of different filtering approaches but I don't think I'm wording my question right or something because I'm not finding much on the interwebs about this.
Any ideas?
Sounds like you want to build up a lookup for category id to category name:
var categories = [{
"_id": "TY76",
"name": "Planes"
}, {
"_id": "887T",
"name": "Trains"
}, {
"_id": "A0K4",
"name": "Autos"
}];
// build a category lookup id -> name
var categoryLookup = {};
categories.forEach(function(category) {
categoryLookup[category._id] = category.name;
});
Here's a full working fiddle: http://jsfiddle.net/02qadem7/1/
You can create a key-pair object where the key is the id and the value is the name of the category:
var categoriesArray = [{
"_id": "TY76",
"name": "Planes"
}, {
"_id": "887T",
"name": "Trains"
}, {
"_id": "A0K4",
"name": "Autos"
}];
$scope.categoriesMap = {};
categoriesArray.forEach(function(category) {
$scope.categoriesMap[category._id] = category.name;
});
Then in your view you can access the category name like this:
<div ng-repeat="product in products">
<strong>Product: </strong> {{product.name}} |
<strong>Categories: </strong> <span ng-repeat="category in product.cats">
{{categoriesMap[category]}}
</span>
</div>
Here's a plunkr: http://plnkr.co/edit/BpBcCizzU2Vh8VPniiHA?p=preview
I sugest using a custom filter on categories array.
myApp.filter('byCategoryIds', function() {
return function(categories, catIds) {
return categories.filter(function(item) {
return (catIds.indexOf(item._id) != -1);
});
};
});
Then you can iterate on categori array sending ids array like so:
<b>Product:</b>
{{product.name}};
<b>Categories:</b>
<span ng-repeat="cat in categories | byCategoryIds: product.cats">{{ cat.name }}, </span>
Often times I want to deal with both arrays and single objects in the same fashion. For example I have the property of an object that can either be an array or just a string (look at the scale property):
[
{
"name": "Experiment type14",
"id": "00000000014",
"scale": ["Whole Brain", "Cell"],
},
{
"name": "Experiment type15",
"id": "00000000015",
"scale": "Cell",
}
]
What I want is to show my scale like here:
<span ng-repeat="scale in experimentType.scale">
<!--some decoration here--> {{scale}}
</span>
Of course this won't work for a single string values. Is there any elegant way not to worry whether I'm dealing with a string or with an array?
You can create your custom filter, please see below
var app = angular.module("app", []);
function MainCtrl() {
this.message = "Welcome";
this.data = [{
"id": "00000000014",
"name": "Experiment type14",
"scale": ["Whole Brain", "Cell"],
},{
"id": "00000000015",
"name": "Experiment type15",
"scale": "Cell",
}];
}
function toArray() {
return function(input) {
console.log(input);
if (angular.isArray(input)) {
return input;
} else {
return [input];
}
};
}
angular.module("app").controller("MainCtrl", MainCtrl);
angular.module("app").filter('toArray', toArray);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="MainCtrl as vm">
<div class="container">
<h3>{{ vm.message }}</h3>
<div ng-repeat="item in vm.data">
<p>{{ item.name }}</p>
<ul>
<li ng-repeat="scale in item.scale | toArray">{{ scale }}</li>
</ul>
</div>
</div>
</div>
</body>
That's my best try. I just implement the following function in the scope:
$scope.toArrayIfNot = function (input) {
if (Object.prototype.toString.call(input) === '[object Array]') {
return input;
}
return [input];
};
I then use it like that:
<span ng-repeat="scale in toArrayIfNot(experimentType.scale)">
<!--some decoration here--> {{scale}}
</span>