Skip to content

Instantly share code, notes, and snippets.

@umidjons
Last active October 5, 2019 08:42
Show Gist options
  • Save umidjons/b3b48c1b331de61daeb7 to your computer and use it in GitHub Desktop.
Save umidjons/b3b48c1b331de61daeb7 to your computer and use it in GitHub Desktop.
Show clicked row details. Using ng-switch, ng-click, ng-class, ng-repeat, $index.

Show clicked row details. Using ng-if, ng-repeat-start and ng-repeat-end directives

<!doctype html>
<html lang="en-US" ng-app="App">
<head>
	<meta charset="UTF-8">
	<script src="angular.js"></script>
	<title>Users</title>
	<style>
		table{ border-collapse:collapse; }
		td, th{ border:1px solid #999; }
	</style>
</head>
<body>

<table ng-controller="UsersCtrl">
	<thead>
		<tr>
			<th>Name</th>
			<th>Age</th>
		</tr>
	</thead>
	<tbody>
		<tr ng-repeat-start="user in users" ng-click="selUser(user)">
			<td>{{user.name}}</td>
			<td>{{user.age}}</td>
		</tr>
		<tr ng-repeat-end ng-if="isSelected(user)">
			<td colspan="2">{{user.desc}}</td>
		</tr>
	</tbody>
</table>

<script>
	angular.module('App',[])
			.factory('Users',function(){
				return {
					query:function(){
						return [
							{name:'John',age:25,desc:'Software Developer at MacroSoft LLC'},
							{name:'Jonatan',age:26,desc:'Professor at University of Tashkent'},
							{name:'Nataly',age:27,desc:'Nurse at central hospital'},
							{name:'Lucy',age:28,desc:'Teacher at district school'}
						];
					}
				}
			})
			.controller('UsersCtrl',function($scope,Users){
				$scope.users=Users.query();
				$scope.selUser=function(user){
					$scope.selected_user=user;
				}
				$scope.isSelected=function(user){
					return $scope.selected_user===user;
				}
			});
</script>
</body>
</html>

Show clicked row details. Using ng-switch, ng-click, ng-class, ng-repeat, $index.

I want to show additional row (user details) below clicked row (selected user) with details. First I need some data, therefore I create Users factory with query method. I'll show user name and age in row by default, but show desc only for selected user. I create 2 methods, selUser(user,idx) - called when clicked onto the row to select user and its index in table, isSelUser(user) - called to determine, is current row contains selected user. I also define selIdx to use in ng-class to switch class according selected user index.

Here is our AngularJS code:

angular.module('App',[])
.factory('Users',function(){
	return {
		query:function(){
			return [
				{name:'John',age:25,desc:'Software Developer at MacroSoft LLC'},
				{name:'Jonatan',age:26,desc:'Professor at University of Tashkent'},
				{name:'Nataly',age:27,desc:'Nurse at central hospital'},
				{name:'Lucy',age:28,desc:'Teacher at district school'}
			];
		}
	}
})
.controller('UsersCtrl',function($scope,Users){
	$scope.users=Users.query();
	$scope.selIdx= -1;

	$scope.selUser=function(user,idx){
		$scope.selectedUser=user;
		$scope.selIdx=idx;
	}

	$scope.isSelUser=function(user){
		return $scope.selectedUser===user;
	}
});

Here is our markup:

<table ng-controller="UsersCtrl">
	<thead>
		<tr>
			<th class="col-1">Name</th>
			<th class="col-2">Age</th>
		</tr>
	</thead>
	<tbody ng-repeat="user in users" ng-switch on="isSelUser(user)" ng-click="selUser(user,$index)">
		<tr ng-class="{sel:selIdx==$index}">
			<td>{{user.name}}</td>
			<td>{{user.age}}</td>
		</tr>
		<tr ng-switch-when="true">
			<td colspan="2" class="desc">{{user.desc}}</td>
		</tr>
	</tbody>
</table>

ng-switch-when used to show tr only when current row is selected row.

Here is some styling:

table { border-collapse: collapse; }
td, th { border: 1px solid #999; }
.col-1 { width: 200px; }
.col-2 { width: 300px; }
.sel { background-color: #bce65e; }
.desc { background-color: #d1e6ac; }

Full code is below:

<!doctype html>
<html lang="en-US" ng-app="App">
<head>
	<meta charset="UTF-8">
	<script src="angular.js"></script>
	<title>Users</title>
	<style>
		table { border-collapse: collapse; }
		td, th { border: 1px solid #999; }
		.col-1 { width: 200px; }
		.col-2 { width: 300px; }
		.sel { background-color: #bce65e; }
		.desc { background-color: #d1e6ac; }
	</style>
</head>
<body>

<table ng-controller="UsersCtrl">
	<thead>
		<tr>
			<th class="col-1">Name</th>
			<th class="col-2">Age</th>
		</tr>
	</thead>
	<tbody ng-repeat="user in users" ng-switch on="isSelUser(user)" ng-click="selUser(user,$index)">
		<tr ng-class="{sel:selIdx==$index}">
			<td>{{user.name}}</td>
			<td>{{user.age}}</td>
		</tr>
		<tr ng-switch-when="true">
			<td colspan="2" class="desc">{{user.desc}}</td>
		</tr>
	</tbody>
</table>
<script>
	angular.module('App',[])
			.factory('Users',function(){
				return {
					query:function(){
						return [
							{name:'John',age:25,desc:'Software Developer at MacroSoft LLC'},
							{name:'Jonatan',age:26,desc:'Professor at University of Tashkent'},
							{name:'Nataly',age:27,desc:'Nurse at central hospital'},
							{name:'Lucy',age:28,desc:'Teacher at district school'}
						];
					}
				}
			})
			.controller('UsersCtrl',function($scope,Users){
				$scope.users=Users.query();
				$scope.selIdx= -1;

				$scope.selUser=function(user,idx){
					$scope.selectedUser=user;
					$scope.selIdx=idx;
				}

				$scope.isSelUser=function(user){
					return $scope.selectedUser===user;
				}
			});
</script>
</body>
</html>
@imilic1
Copy link

imilic1 commented Aug 30, 2015

Thank you! Both Solutions are doing exactly what I need - loading details only when they are needed and not all the time time for all rows like with ng-show, which many people use.
Would you be able to provide pros and cons for each of the two if any or you consider these equally good solutions in addressing this requirement.

@StamTso
Copy link

StamTso commented Apr 11, 2018

Very useful example which doesn't use the confusing ng-repeat-start/end like most of the tutorials out there. It keeps everything simple and nice. I was looking for days for something like this. Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment