Show one content at a time in ng repeat - angularjs

I have the code here where I want to expand only one item at a time. I am not able to figure out the condition for this. Appreciate it if someone can point out what I might be missing.
function sample ($scope) {
$scope.procedures = [
{
definition: 'Procedure 1',
discharged: 23
},
{
definition: 'Procedure 2',
discharged: 2
},
{
definition: 'Procedure 3',
discharged: 356
}
];
}
<ul class="procedures" ng-app ng-controller="sample">
<li ng-repeat="procedure in procedures">
<h4>{{procedure.definition}}</h4>
<div class="procedure-details" ng-class="{ 'hidden': ! showDetails }">
<p>Number of patient discharges: {{procedure.discharged}}</p>
</div>
</li>
</ul>

you need to store the previous selected Index to get things working .
html:
<ul class="procedures" ng-app ng-controller="sample">
<li ng-repeat="procedure in procedures">
<h4>{{procedure.definition}}</h4>
<div class="procedure-details" ng-class="{'hidden': !(curr == $index && showDetails)}">
<p>Number of patient discharges: {{procedure.discharged}}</p>
</div>
</li>
</ul>
code:
function sample($scope) {
$scope.showDetails = true;
$scope.fireIt = function(index) {
$scope.curr = index;
if($scope.prevIndex == index){ -- (1)
$scope.showDetails = !$scope.showDetails; return;
}
$scope.prevIndex = index ;
if(!$scope.showDetails) $scope.showDetails=!$scope.showDetails; -- (2)
}
$scope.procedures = [{
definition: 'Procedure 1',
discharged: 23
}, {
definition: 'Procedure 2',
discharged: 2
}, {
definition: 'Procedure 3',
discharged: 356
}];
}
working sample up here for grabs .
Note : Quoted points (1) & (2) are key .

You need to store the state for each procedure. Or you could put the procedure definition in your variable, something like :
<ul class="procedures" ng-app ng-controller="sample">
<li ng-repeat="procedure in procedures">
<h4>{{procedure.definition}}</h4>
<div class="procedure-details" ng-class="{ 'hidden': ! (showDetails && showDetails == procedure.definition) }">
<p>Number of patient discharges: {{procedure.discharged}}</p>
</div>
</li>
</ul>

<ul class="procedures" ng-app ng-controller="sample">
<li ng-repeat="procedure in procedures">
<h4>{{procedure.definition}}</h4>
<div class="procedure-details" ng-class="{ 'hidden': ! procedure.showDetail }">
<p>Number of patient discharges: {{procedure.discharged}}</p>
</div>
</li>
</ul>
function sample ($scope) {
$scope.clickLink = function(idx){
for(var i=0;i<$scope.procedures.length;i++){
if(i != idx)
$scope.procedures[i].showDetail = false;
else
$scope.procedures[i].showDetail = true;
}
}
$scope.procedures = [
{
definition: 'Procedure 1',
discharged: 23,
showDetail:false
},
{
definition: 'Procedure 2',
discharged: 2,
showDetail:false
},
{
definition: 'Procedure 3',
discharged: 356,
showDetail:false
}
];
}

You can define an activeItem variable in the controller to hold the item to be shown. Then, you should assign the index of the element you click to that variable:
ng-click="showDetails = ! showDetails; $parent.activeItem = $index"
Then, you should check both values to show an item:
ng-class="{ 'hidden': ! ( showDetails && $parent.activeItem == $index )}"
Check out the jsfiddle below:
http://jsfiddle.net/asmKj/1190/

Related

ng-model into ng-repeat Angularjs

I'm asking if is possible to do something as that in angular
<div ng-app="app">
<div ng-controller="mainController">
<ul ng-repeat="movie in movies |searchFilter:Filter.genre | searchFilter:Filter.name |searchFilter:Filter.pic ">
<li>{{movie.name}}</li>
</ul>
<h2>genre</h2>
<div>
<label>Comedy </label><input type="checkbox" ng-model="Filter.genre.Comedy" ng-true-value="Comedy" data-ng-false-value=''/><br/>
</div>
<h2>PIC</h2>
<label>aa</label><input type="checkbox" ng-model="Filter.pic.aa" ng-true-value="ciao" data-ng-false-value=''/><br/>
<h2>Name</h2>
<label>Shrek</label><input type="checkbox" ng-model="Filter.name.Shrek" ng-true-value="The God" data-ng-false-value=''/><br/>
</div>
</div>
i'm creating a checkbox for filter on different fields (size,name,genre)
ill have a list of avaible sizes,names and genres .
The issue is on ng-model and i tried to write it as "Filter.genre.genre.name" or
"Filter["genre"+genre.name]" and also "Filter.genre[genre.name]" but still not work .
the js.file is
var app =angular.module('app', []);
app.controller('mainController', function($scope) {
$scope.movies = [{name:'Shrek', genre:'Comedy',pic:"cc"},
{name:'Die Hard', genre:'Comedy',pic:"aa"},
{name:'The Godfather', genre:'Drama',pic:"ciao"},
{name:'The Godher', genre:'Comedy',pic:"lel"}];
$scope.genres = [{name:"Comedy"},{name:"Action"},{name:"Drama"}];
});
app.filter('searchFilter',function($filter) {
return function(items,searchfilter) {
var isSearchFilterEmpty = true;
//searchfilter darf nicht leer sein
angular.forEach(searchfilter, function(searchstring) {
if(searchstring !=null && searchstring !=""){
isSearchFilterEmpty= false;
}
});
if(!isSearchFilterEmpty){
var result = [];
angular.forEach(items, function(item) {
var isFound = false;
angular.forEach(item, function(term,key) {
if(term != null && !isFound){
term = term.toLowerCase();
angular.forEach(searchfilter, function(searchstring) {
searchstring = searchstring.toLowerCase();
if(searchstring !="" && term.indexOf(searchstring) !=-1 && !isFound){
result.push(item);
isFound = true;
// console.log(key,term);
}
});
}
});
});
return result;
}else{
return items;
}
}
});
if i make 3 different labels for the field Comedy, Action and Drama with ng-models called as
ng-model="Filter.genre.Comedy" ; ng-model="Filter.genre.Action" and ng-model="Filter.genre.Drama"
it work but it doesnt work if i try to write it into ng-repeat . I hope to have been clearer
In this sample i try to handle your question by change the Model of your page.
we have:
list of movies array => $scope.movies = []
dynamic filters array => $scope.genres = [], $scope.years = [] or more
our target:
Create a dynamic filters to search in movies
what we do
$scope.filterHandler = function (key, value) {}
Run when user start searching on input or select, this function help us to create a filter as object by sending key and value which result is {key:value}
$scope.searchTypeHandler = function (type, dependTo) {}
Run when our filters has some array for example genre has genres as dropdown select, this function help us to return the array which depend to the filter.
var app = angular.module("app", []);
app.controller("ctrl", [
"$scope",
function($scope) {
//your options
$scope.movies = [{
name: 'Shrek',
genre: 'Comedy',
year: 2000
},
{
name: 'Die Hard',
genre: 'Action',
year: 2000
},
{
name: 'The Godfather',
genre: 'Drama',
year: 2015
},
{
name: 'The Godher',
genre: 'Comedy',
year: 2017
}
];
$scope.genres = [{
name: "Comedy"
},
{
name: "Action"
},
{
name: "Drama"
}
];
$scope.years = [{
name: 2000
},
{
name: 2015
},
{
name: 2017
}
];
//
$scope.filter = {}
$scope.filterHandler = function(key, value) {
var object = {};
object[key] = value;
$scope.filter["find"] = object;
};
$scope.searchTypeHandler = function(type, dependTo) {
$scope.filter = {};
$scope.filter.searchType = type;
$scope.filter.options = undefined;
if (dependTo != null) {
$scope.filter.options = $scope[dependTo];
}
};
//default
$scope.searchTypeHandler("name");
}
]);
<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>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="container" ng-app="app" ng-controller="ctrl">
<div class="page-header">
<div class="row">
<div class="col-lg-12">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<h4>Movies</h4>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6 pull-right">
<div class="input-group">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
By {{filter.searchType}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-left">
<li><a ng-click="searchTypeHandler('genre', 'genres')">Filter By Genre</a></li>
<li><a ng-click="searchTypeHandler('name', null)">Filter By Name</a></li>
<li><a ng-click="searchTypeHandler('year', 'years')">Filter By Year</a></li>
</ul>
</div>
<input ng-hide="filter.options" type="text" class="form-control" ng-model="filter.query" ng-change="filterHandler(filter.searchType, filter.query)">
<select ng-show="filter.options" class="form-control" ng-model="filter.option" ng-change="filterHandler(filter.searchType, filter.option)" ng-options="option.name as option.name for option in filter.options"></select>
</div>
<!-- /input-group -->
</div>
</div>
</div>
</div>
<ul class="list-group">
<li class="list-group-item" ng-repeat="movie in movies | filter: filter.find">
{{movie.name}} - <label class="label label-info">Ggenre: {{movie.genre}}</label> - <label class="label label-default">Year: {{movie.year}}</label>
</li>
</ul>
</div>

AngularJs/Bootstrap - Bind checkbox in list not works properly

I have a roles list that filter a permissions list. The permissions list has a checkbox indicating that it is selected.
Each role has a list of associated permissions. When a role is selected, all available permissions are displayed and those already associated with them will be checked. By clicking on the checkbox of each permission you can associate or desesociate it.
But the select and unselect permission action does not work properly. I can not figure out what the problem. Can someone help me ? Thanks!!!
Code in Plunker
Page code
<div class="panel-body">
<div class="form-group">
<div class="col-md-6">
<div class="list-group">
<a ng-click="selectRole(role)" ng-repeat="role in model.roles" class="list-group-item" ng-class="{active: role.id == model.selectedRole.id}">{{role.name}}</a>
</div>
</div>
<div class="col-md-6">
<div class="list-group">
<a ng-repeat="permission in model.permissions" class="list-group-item">{{permission.name}} <input type="checkbox" class="pull-right" ng-checked="isSelected(permission.id) > -1" ng-click="clickPermission(permission)" ng-class="{active: permission.id == model.selectedPermission.id}" />
</a>
</div>
</div>
</div>
</div>
Controller code
app.controller('PermissionsToRoleController', function($scope) {
$scope.model = {
roles: [],
permissions: [],
selectedRole: null,
selectedPermission: null
};
$scope.selectRole = function(role) {
$scope.model.selectedRole = role;
}
var findRoles = function() {
$scope.model.roles = [{id: 1, name: 'ADMIN', permissions: [{id: 1, name:'MASTER'}] },
{id: 2, name: 'USER', permissions: [] }
];
$scope.model.permissions = [{id: 1, name: 'MASTER'}];
$scope.model.selectedRole = $scope.model.roles[0];
};
$scope.clickPermission = function(permission) {
$scope.model.selectedPermission = permission;
var idx = $scope.isSelected(permission.id);
if (idx > -1) {
$scope.model.selectedRole.permissions.splice(idx, 1);
} else {
$scope.model.selectedRole.permissions.push(permission);
}
};
$scope.isSelected = function(permissionId) {
for (var i = 0; i < $scope.model.selectedRole.permissions.length ; i++) {
if ($scope.model.selectedRole.permissions[i].id === permissionId) {
return i;
}
}
return -1;
}
findRoles();
});
The problem I found being the checkbox, while functions properly, the display won't "uncheck" when you click on it.
This can be fixed by changing the surrounding element to span instead of a
<span ng-repeat="permission in model.permissions" class="list-group-item">{{permission.name}}
<input type="checkbox" class="pull-right" ng-checked="isSelected(permission.id) > -1" ng-click="clickPermission(permission)" ng-class="{active: permission.id == model.selectedPermission.id}" />
</span>
I'm not sure about the reason behind this, though.

Angularjs filters OR conditions

I am trying to create a filter where I can conditionally select multiple attributes of the same variable. For example
var list = [ {id: 1, state: 'U'}, {id: 2, state: 'P'} ]
<div ng-repeat="item in list| filter:{state:'U'}>
This would result in id 1 only being displayed.
<div ng-repeat="item in list| filter:{state:'P'}>
This would result in id 2 only being displayed.
How can I create a filter to display all id's that have state:'P' OR state:'A'
Neither of the below work:
<div ng-repeat="item in list| filter:{state:'P' || 'A'}>
<div ng-repeat="item in list| filter:({state:'P'} || {state:'A'})>
Hope this below code snippet might help you ! Run it :)
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
$scope.list = [{
id: 1,
state: 'U'
}, {
id: 2,
state: 'P'
}, {
id: 3,
state: 'A'
}];
$scope.state = function(item) {
return (item.state == 'P' || item.state == 'A');
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl">
<div ng-repeat="item in list | filter:state">
{{item.id}}
</div>
</div>
Why do have so much confusion. Use ng-if just like your normal if statement like this
var list = [ {id: 1, state: 'U'}, {id: 2, state: 'P'},{id: 1, state: 'A'} ]
<div ng-repeat="item in list">
<div ng-if="item.state == 'A' || item.state== 'P'">
{{item.id}}
</div>
</div>
Implementation is also as below
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.list = [{id: 1,state: 'U'}, {id: 2,state: 'P'}, {id: 3, state: 'A'}];
});
<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="item in list">
<div ng-if="item.state == 'A' || item.state== 'P'">
{{item.id}}
</div>
</div>
</div>

Ng-Repeat Filter Empty string

I have tried to filter blank string item from ng-repeat. But didn't succeeded. Can someone please help me at this.
JSFiddel Link
HTML Code:
<div ng-app ng-controller="myCtrl">
<ul>
<li ng-repeat="detail in details | filter: filter2 ">
<p>{{detail.name}}</p>
</li>
</ul>
</div>
JS Code:
function myCtrl($scope) {
$scope.details = [{
name: 'Bill',
shortDescription: null
}, {
name: 'Sally',
shortDescription: 'A girl'
},{
name: 'Tally',
shortDescription: ''
}];
}
function filter2(detail){
if (item.shortDescription.length == 0){
return true;
}
else{
return false;
}
}
Expected Result:
/*
Expected Result
Bill
Sally
*/
<div ng-app ng-controller="myCtrl">
<ul>
<li ng-repeat="detail in details" ng-if="detail.shortDescription">
<p>{{detail.name}}</p>
</li>
</ul>
</div>
fiddle

Hide item selected in ng-repeat

I have a list such as
var items = [1, 2, 3];
var list = [
{
id: 1,
name: 'name 1'
},
{
id: 2,
name: 'name 3'
},
{
id: 3,
name: 'name 2'
}
]
and I use li tag (not option) to show this list.
<div ng-repeat="item in items">
<ul>
<li ng-repeat="name in listName">
<a ng-click="">{{name.name}}</a>
</li>
</ul>
</div>
It will show 3 item and 3 list is same in a item.
Help me when I click name 1 of item 1, will hide name 1 of item 2, 3,... Click name 2 in item 2 will hide name 2 of item 1, 3...
Thanks
Here is how you can do it
angular.module("myApp", []).controller("myCtrl", function($scope) {
$scope.items = [1, 2, 3];
$scope.list = [{
id: 1,
name: 'name 1'
}, {
id: 2,
name: 'name 3'
}, {
id: 3,
name: 'name 2'
}];
$scope.hideOthers = function(item, name){
$scope.selectedItem = item;
$scope.selectedName = name;
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp">
<body>
<div ng-controller="myCtrl">
<div ng-repeat="item in items">
<ul>
<li ng-repeat="name in list">
<a ng-click="hideOthers(item, name.name)" ng-show="!selectedItem || name.name !== selectedName || item === selectedItem">{{name.name}}</a>
</li>
</ul>
</div>
</div>
</body>
</html>
1) You dnt need use variable items only for set loop count. It can make in ng-repeat;
2) You have error in variable name - list, not listName;
<div ng-repeat="i in [1, 2, 3]">
<ul>
<li ng-repeat="name in list">
<a ng-click="name.select = i" ng-if="!name.select || name.select === i">{{name.name}}</a>
<strike ng-if="name.select && name.select !== i">{{name.name}}</strike>
</li>
</ul>
</div>
UPDATE:
3) Also use $scope.list = //data for broadcast data to template;

Resources