Preprocess ng-repeat variables? - angularjs

I am using ng-repeat to print the output in div. Elements in bCrumbs collection start with slash and space and I want to remove them from 1st loop iteration.
My Code:
<div ng-repeat="bCrumb in bCrumbs" id="{{bCrumb.name}}">{{ bCrumb.name }}</div>
the output from {{ bCrumb.name }}:
/ Test1
/ Test2
expected Output:
Test1
/Test2

You can use ng-repeat-start and ng-repeat-end
<div ng-repeat-start="bCrumb in bCrumbs" ng-if="$first>
{{ beautify(bCrumb.name) }}
</div>
<div ng-repeat-end ng-if="!$first">
{{ bCrumb.name }}
</div>
Besides, define a function called beautify in your controller:
$scope.beautify = function (name) {
return name.replace('/ ', '');
};
You can read the detailed documentation here
update
A better way to handle string beautify is creating a filter to handle it
app.filter('beautify', function () {
return function (data) {
return data.replace("/ ", "");
};
});
Then in your view template:
<div ng-repeat-start="bCrumb in bCrumbs" ng-if="$first>
{{ bCrumb.name | beautify }}
</div>
<div ng-repeat-end ng-if="!$first">
{{ bCrumb.name }}
</div>

I think you should change your controller (or whatever is producing bCrumbs) to strip the slashes before reaching view. This way it'll be more testable and (hopefully) clear. You could do something like this:
function strip(s) {
if(s.indexOf('/ ') === 0) {
return s.substring(2);
} else {
return s;
}
}
$scope.bCrumbs = originalBCrumbs.map(function(bc, idx) {
return idx === 0 ? strip(bc) : bc;
});

Related

Show {{ value }} except special one in AngularJS 1.6

After SPAN click my DIV get this category title , but in one case , when category.title is 'Favorite' (or category.id = '1',its the same) i need ignore it in DIV and don't change the value on it.
How can i realize that ?
Thanks in advance
My HTML :
<div> {{ selections.category.title }} </div>
<span ng-repeat="category in categories track by category.id" ng-click="selectCategory(category)">
...
</span>
My controller :
$scope.selectCategory = function selectCategory(category) {
$scope.selections.category = category;
...
}
EDIT.
I need only ignore it in DIV's text , not ignore click on this element .
<div> {{ selectedTitle }} </div>
$scope.selectCategory = function selectCategory(category) {
if(category.title !== 'Favorite' && category.id !== '1') {
$scope.selectedTitle = category.title;
}
$scope.selections.category = category;
...
}

Adding more than one filter is not working for list in Angularjs

I have added 2 filters like uppercase and lowercase for list, data is not displaying . If apply only lowercase or uppercase data is displaying.
Please check the code below and please let me know where is the issue.
<div ng-app="myApp1" ng-controller="ctrl1">
<ul >
<li ng-repeat="x in names | orderBy:'name'">
{{x.name | lowercase +' , '+x.country | uppercase }}
</li>
</ul>
</div>
<script>
var app1= angular.module("myApp1",[]);
app1.controller("ctrl1", function($scope){
$scope.names=[{name:"ravi", country:"india"},{name:"kavitha",country:"india"},
{name:"Jo", country:"UK"},{name:"Hasi", country:"USA"},
{name:"Raj", country:"London"},{name:"Kal", country:"USA"}];
});
</script>
Here list is not populating, if have both uppercase and lowercase filters.
You should write a custom filter instead, if you're gonna be doing something more complex than what's out of the box...
angular.module("MyApp", []).filter("myFilterName", function() {
return function(input) {
if(!input) return "";
else
return input.name.toLower() + input.country.toUpper();
}
});
HTML:
<div ng-repeat="thing in things">
{{ thing | myFilterName }}
</div>
Try this:
angular.module('YourModule').filter('personLocationDisplay', function() {
return function(person) {
return (person.name.toLowerCase() + ', ' + person.country).toUpperCase();
};
});
And you can use it like:
<ul>
<li ng-repeat="x in names | orderBy:'name'">
{{x | personLocationDisplay }}
</li>
</ul>

how get the list of selected items in angular.js

Here I am using angular.js to show a list of people
<div class="recipient" ng-repeat="person in people">
<img src="{{person.img}}" /> person.name
<div class="email">person.email</div>
</div>
$scope.people = [{id:1}, {id:2}, {id:3}, {id:4}];
The looks is like below
What I want to do is I can select multiple items and by click a OK button, I can get a list of selected items. so If I select id 1 and id 2, then I want to get return a list of [{id:1},{id:2}]
How could I implement it in angular.js
Well I guess that if you're looping through a collection of people using a ng-repeat, you could add the ng-click directive on each item to toggle a property of you're object, let's say selected.
Then on the click on your OK button, you can filter all the people that have the selected property set to true.
Here's the code snippet of the implementation :
<div class="recipient" ng-repeat="person in people" ng-click="selectPeople(person)">
<img src="{{person.img}}" /> person.name
<div class="email">person.email</div>
</div>
<button ng-click="result()">OK</button>
function demo($scope) {
$scope.ui = {};
$scope.people = [{
name: 'Janis',
selected: false
}, {
name: 'Danyl',
selected: false
}, {
name: 'tymeJV',
selected: false
}];
$scope.selectPeople = function(people) {
people.selected = !people.selected;
};
$scope.result = function() {
$scope.ui.result = [];
angular.forEach($scope.people, function(value) {
if (value.selected) {
$scope.ui.result.push(value);
}
});
};
}
.recipient {
cursor: pointer;
}
.select {
color:green;
}
.recipient:hover {
background-color:blue;
}
<script src="https://code.angularjs.org/1.2.25/angular.js"></script>
<div ng-app ng-controller="demo">
<div class="recipient" ng-repeat="person in people" ng-click="selectPeople(person)" ng-class="{ select: person.selected }">
<div class="name">{{ person.name }}</div>
</div>
<button ng-click="result()">OK</button>
Result :
<ul>
<li ng-repeat="item in ui.result">{{ item.name }}</li>
</ul>
</div>
If you only want to show checked or unchecked you could just apply a filter, but you would need to toggle the filter value from undefined to true if you didn't wan't to get stuck not being able to show all again.
HTML:
<button ng-click="filterChecked()">Filter checked: {{ checked }}</button>
<div class="recipient" ng-repeat="person in people | filter:checked">
<input type='checkbox' ng-model="person.isChecked" />
<img ng-src="{{person.img}}" />{{ person.name }}
<div class="email">{{ person.email }}</div>
</div>
Controller:
// Apply a filter that shows either checked or all
$scope.filterChecked = function () {
// if set to true or false it will show checked or not checked
// you would need a reset filter button or something to get all again
$scope.checked = ($scope.checked) ? undefined : true;
}
If you want to get all that have been checked and submit as form data you could simply loop through the array:
Controller:
// Get a list of who is checked or not
$scope.getChecked = function () {
var peopleChkd = [];
for (var i = 0, l = $scope.people.length; i < l; i++) {
if ($scope.people[i].isChecked) {
peopleChkd.push(angular.copy($scope.people[i]));
// Remove the 'isChecked' so we don't have any DB conflicts
delete peopleChkd[i].isChecked;
}
}
// Do whatever with those checked
// while leaving the initial array alone
console.log('peopleChkd', peopleChkd);
};
Check out my fiddle here
Notice that person.isChecked is only added in the HTML.

List value in array with angularjs markup?

I have this html :
<div class="{{ article.contributor }}" ng-repeat="article in articles">
Which gave me this :
<div class="["harry", "eddy", "john"]">
But I want this :
<div class="harry eddy john">
What is the best way to do this ?
Thank you very much
Try joining the array, like this:
<div class="{{ article.contributor.join(' ') }}" ng-repeat="article in articles">
Ohhh the choices... joyous choices.
Quick and dirty...
<div class="{{ typeof article.contributors === 'array' ? article.contributors.join(' ') : article.contributors }}" ng-repeat="article in articles"></div>
As a filter...
myAppname.module.filter('spaceSeperatedValues', function() {
return function(data){
//handles if just a string (e.g., 'John')
return data === 'array' ? data.join(' ') : data;
}
}
<div class="{{ article.contributors | spaceSeperatedValues }}" ng-repeat="article in articles"></div>
As a controller function..
app.module.controller('ArticleController', ['$scope'], function ($scope) {
$scope.articles = [{ text : 'my article text', contributors : ['harry', 'eddy', 'john'] }]
$scope.spaceSeperatedValues = function(data) {
//handles if just a string (e.g., 'John')
return data === 'array' ? data.join(' ') : data;
}
}
<div ng-controller="ArticleController">
<div class="{{ spaceSeperatedValues(article.contributors) }}" ng-repeat="article in articles"></div>
</div>
Have not checked this code in a debugger... <-- disclaimer. :D

How can I put a condition inside a data binding in AngularJS?

I would like to do the following:
<div>
<div ng-repeat="row in test.active">
<div>{{ row.id }}</div>
<div>
{{ if (row.testTypeId == 1) { test.exams.dataMap[row.examId].name; } }}
{{ if (row.testTypeId == 2) { test.topics.topicNameMap[row.topicId] } }}
</div>
</div>
</div>
However this is giving me an error with the { inside of the {{ }}. Is there another way I could make this work?
#jack.the.ripper is correct. Move the logic to a function in the $scope and call that instead.
$scope.name = function (row) {
if (row.testTypeId == 1) {
return test.exams.dataMap[row.examId].name;
} else {
return '';
}
}
In the HTML:
{{ name(row) }}
Ternary operators certainly work, plnkr.
{{ (row.testTypeId == 1) ? test.exams.dataMap[row.examId].name : '' }}
{{ (row.testTypeId == 2) ? test.topics.topicNameMap[row.topicId] : '' }}
You can use ng-show to do this:
<div>
<div ng-repeat="row in test.active">
<div>{{ row.id }}</div>
<div ng-show="row.testTypeId == 1">
{{test.exams.dataMap[row.examId].name }}
</div>
<div ng-show="row.testTypeId == 2">
{{ test.topics.topicNameMap[row.topicId] }}
</div>
</div>
</div>
Why does it need to be in the databinding itself? Couldn't you just use the ng-if directive?
<div ng-if="row.testTypeId == 1">stuff</div>
<div ng-if="row.testTypeId == 2">otherstuff</div>

Resources