I have a list of several objects and at the beginning I want to load just some of them. I took a look at the statement ng-repeat, but I need to have a structure like this:
<table class="table table-hover table-hidden">
<thead>
<tr>
...
</tr>
</thead>
<tbody>
<tr ng-repeat-start="object in objects | filter:query | orderBy:predicate:reverse" ng-init="isCollapsed=true">
...
</tr>
<tr ng-repeat-end class="more">
...
</tr>
</tbody>
</table>
I tried to apply the statement limitTo inside ng-repeat-start, in this way:
<tr ng-repeat-start="object in objects | filter:query | orderBy:predicate:reverse| limitTo: limit" ng-init="isCollapsed=true">
and on controller I wrote:
$scope.limit = 10;
$scope.incrementLimit = function () {
$scope.limit += 10;
};
The function incrementLimit is called by a click on hyperlink
<a href ng-click="incrementLimit()">more</a>
The list of objects is instantiated and filled (with all the elements) when the page loads.
With my approach at the beginnig are loaded and showed first 10 elements correctly, and when I click on "more" the variable $scope.limitis incremented, but on the page nothing happens. Anyone can explain me why?
limitTo is working fine inside ng-repeat-start
Take a look at this
var app = angular.module('myApp', []);
app.controller('Controller', function ($scope) {
$scope.limit = 1;
$scope.incrementLimit = function () {
$scope.limit += 1;
};
$scope.data = [{
title: 'Foo',
text: 'Lorem'
}, {
title: 'Bar',
text: 'Iste'
}, {
title: 'Jon',
text: 'Fat'
}, {
title: 'Los',
text: 'Ice'
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<div ng-app='myApp' ng-controller="Controller">
<table border="2" class="table table-hover table-hidden">
<thead>
<tr>...</tr>
</thead>
<tbody>
<tr ng-repeat-start="object in data | filter:query | orderBy:predicate:reverse| limitTo: limit" ng-init="isCollapsed=true" ng-bind="object.title">...</tr>
<tr ng-repeat-end class="more">...</tr>
</tbody>
</table>
more
</div>
Please check the below code and fiddle it is working fine
<body ng-controller="myController">
<button ng-click="incrementLimit()" >increment</button> <br/>
<table class="table table-hover table-hidden">
<thead>
<tr clospan="3">
Head
</tr>
</thead>
<tbody>
<tr ng-repeat-start="friend in objects|limitTo: limit" ng-init="isCollapsed=true">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friend.age}}</td>
</tr>
<tr ng-repeat-end class="more">
<td colspan="3">Footer</td>
</tr>
</tbody>
</table>
</table>
</body>
js code
app = angular.module("app", []);
app.controller("myController", function($scope) {
$scope.objects =
[{
name: 'John',
phone: '555-1212',
age: 10
}, {
name: 'Mary',
phone: '555-9876',
age: 19
}, {
name: 'Mike',
phone: '555-4321',
age: 21
}, {
name: 'Adam',
phone: '555-5678',
age: 35
}, {
name: 'Julie',
phone: '555-8765',
age: 29
}];
$scope.limit = 2;
$scope.incrementLimit = function () {
$scope.limit += 1;
};
});
Fiddle http://jsbin.com/hoguxexuli/1/edit
I solved my problem. Basically I put the hyperlink in a different div, so the controller and the $scope were also different. It was a stupid carelessness.
Related
I tried the code of AngularJS as follows:
var app = angular.module('MyApp', []);
app.controller('new_controller', function($scope) {
$scope.people= [{
name: "GeekAgashi",
Age: 12,
attended: 1
}, {
name: "GeekSatoshi",
Age: 16,
attended: 0
}, {
name: "GeekNakumato",
Age: 14,
attended: 1
}];
});
In HTML file the code:
<div class="sidebar-pane" ng-app="MyApp" id="flight_info" ng-controller="new_controller">
<table>
<tr>
<td>Name</td>
<td>Age</td>
</tr>
<tr ng-repeat="p in people">
<td>{{p.name}}</td>
<td>{{p.Age}}</td>
</tr>
</table>
</div>
On the webpage, I can only get the table frame which I think means that the data is successfully passed. But I cannot get the table items:
<table>
<tbody>
<tr>
<td>Name</td>
<td>Age</td>
</tr>
<!-- ngRepeat: p in people -->
<tr ng-repeat="p in people" class="ng-scope">
<td></td>
<td></td>
</tr>
<!-- end ngRepeat: p in people -->
<tr ng-repeat="p in people" class="ng-scope">
<td></td>
<td></td>
</tr>
<!-- end ngRepeat: p in people -->
<tr ng-repeat="p in people" class="ng-scope">
<td></td>
<td></td>
</tr>
<!-- end ngRepeat: p in people -->
</tbody>
</table>
I am just wondering if it is a bug or there is something wrong with my code, or the browser (chrome v79) does not support it.
Appendix:
I write the backend in Django and I found that if I directly run the plain HTML, the table is visible. The problem happens if I run it through a Django server. Since I am a green hand to the frontend, I am wondering if it is possible that the problem lies in the CSS file or the confliction with other local javascript?
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div class="sidebar-pane" ng-app="MyApp" id="flight_info" ng-controller="new_controller">
<table>
<tr>
<td>Name</td>
<td>Age</td>
</tr>
<tr ng-repeat="p in people">
<td>{{p.name}}</td>
<td>{{p.Age}}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('MyApp', []);
app.controller('new_controller', function($scope) {
$scope.people= [{
name: "GeekAgashi",
Age: 12,
attended: 1
}, {
name: "GeekSatoshi",
Age: 16,
attended: 0
}, {
name: "GeekNakumato",
Age: 14,
attended: 1
}];
});
</script>
</body>
</html>
Kindly check if the above code is running?
I copy & paste your code to the snipped (Angulerjs version 1.7.5) and it seems like it's working.
var app = angular.module('MyApp', []);
app.controller('new_controller', function($scope) {
$scope.people = [{
name: "GeekAgashi",
Age: 12,
attended: 1
}, {
name: "GeekSatoshi",
Age: 16,
attended: 0
}, {
name: "GeekNakumato",
Age: 14,
attended: 1
}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div class="sidebar-pane" ng-app="MyApp" id="flight_info" ng-controller="new_controller">
<table>
<tr>
<td>Name</td>
<td>Age</td>
</tr>
<tr ng-repeat="p in people">
<td>{{p.name}}</td>
<td>{{p.Age}}</td>
</tr>
</table>
</div>
In your question you specify that you are using django. I assume that you are using it to retrieve the people data (correct me if I'm wrong). Can you please show us how you retrieve the data? This might just be a case of async operation, so the data isn't there at the time the page is rendered.
The reason is a confliction of django and angularJS templates. The solution could be find in this question.
I just began learning AngularJS, and I am trying to create a pretty simple web application. Right now, I have some users. Each user is displayed in an individual table and each user has its own details which is displayed in a table under it.
$scope.userList = [{username: "Bob_t", detailsId: 1}, {username: "Mike_V", detailsId: 2}];
$scope.userDetails = [{Name: "Bob", Age: 20, id: "1"}, {Name: "Michael", Age: 18, id: "2"}];
You can see that each user has a reference to it's corresponding details (detailsId in userList corresponds to id in userDetails).
Basically, what I'm trying to do is initially have the details table hidden for each user. And when someone clicks the expand button for a specific user, open that user's corresponding details table and populate it with that user's details. What I'm having trouble with is getting the detailsId from the clicked expand button and then using that to query my DB to get the correct user's details to display in the table under it.
<div ng-repeat="user in userList | filter:searchBox">
<div class="uk-panel-box-secondary uk-overflow-container tableDiv uk-margin-large-bottom">
<table class="uk-table uk-table-hover uk-margin-top">
<thead>
<tr>
<th>Username</th>
</tr>
</thead>
</table>
<a class="uk-margin-bottom uk-margin-left" id="expandIcon" ng-click="isOpened=!isOpened; showOrHideDetails(isOpened, param)" ng-class="{'uk-icon-plus-square-o': !isOpened, 'uk-icon-minus-square-o': isOpened}"></a>
</div>
<div class="uk-panel-box-secondary uk-overflow-container uk-margin-top uk-margin-large-left uk-margin-bottom tableDiv">
<table class="uk-table uk-table-hover uk-margin-top">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th></th>
</tr>
</thead>
<tr ng-repeat="details in userDetails" id={{user.id}}>
<td>{{details.Name}}</td>
<td>{{details.Age}}</td>
<td>
</td>
</tr>
</table>
</div>
</div>
my controller:
$http({
method : "GET",
url : "http://database:8081/userAccounts/"
}).then(function mySucces(response) {
$scope.userList = response.data;
}, function myError(response) {
// $scope.userList = response.statusText;
});
$scope.showOrHideDetails = function(isOpened, param)
if(isOpened){
console.log($scope.id)
$scope[id] = true;
console.log($scope.id);
$http({
method : "GET",
url : "http://database:8081/details?id=" + index
}).then(function mySucces(response) {
$scope.userDetails = response.data;
}, function myError(response) {
$scope.userDetails = response.statusText;
});
}
else{
$scope.showDetails = false;
}
}
What is really confusing to me is once I get the correct userDetails object after querying the DB, how do I populate the corresponding table with that info?
I know I probably need a model, but this confuses me because the number of users is unknown.
First, your code is a bit confuse..
After each query you're attributing the response (which one is the details of a single user) to the whole array userDetails:
$scope.userDetails = response.data;
While it should be:
$scope.userDetails.push(response.data);
In addition, you have a single variable called isOpened, for sure it won't work, because you have multiple buttons for only 1 variable.
So my suggestion is to change it to:
<a class="uk-margin-bottom uk-margin-left" id="expandIcon" ng-click="showOrHideDetails(user)" ng-class="{'uk-icon-plus-square-o': !user.isOpened, 'uk-icon-minus-square-o': user.isOpened}"></a>
Also you have to check if the userDetail is already in your userDetails array.
Finally, since you want to show the details based on the user, you can use the native filter, because you already have the id property of users in both arrays, as below:
<tr ng-if="user.isOpened" ng-repeat="details in userDetails | filter: { id: user.detailsId }" id={{user.id}}>
A simple demo:
(function() {
angular
.module('app', [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', '$http'];
function MainCtrl($scope, $http) {
$scope.userList = [{
username: "Bob_t",
detailsId: 1
}, {
username: "Mike_V",
detailsId: 2
}];
$scope.userDetails = [{
Name: "Bob",
Age: 20,
id: "1"
}, {
Name: "Michael",
Age: 18,
id: "2"
}];
$scope.showOrHideDetails = function(user) {
user.isOpened = !user.isOpened;
function mySuccess(response) {
$scope.userDetails.push(response.data);
}
function myError(response) {
console.log(response.statusText);
}
if (user.isOpened) {
$http.get('http://database:8081/details?id=' + user.id)
.then(mySuccess)
.catch(myError);
} else {
$scope.showDetails = false;
}
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.26.4/js/uikit.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.26.4/css/uikit.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="user in userList | filter:searchBox">
<div class="uk-panel-box-secondary uk-overflow-container tableDiv uk-margin-large-bottom">
<table class="uk-table uk-table-hover uk-margin-top">
<thead>
<tr>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-bind="user.username"></td>
</tr>
</tbody>
</table>
<a class="uk-margin-bottom uk-margin-left" id="expandIcon" ng-click="showOrHideDetails(user)" ng-class="{'uk-icon-plus-square-o': !user.isOpened, 'uk-icon-minus-square-o': user.isOpened}"></a>
</div>
<div class="uk-panel-box-secondary uk-overflow-container uk-margin-top uk-margin-large-left uk-margin-bottom tableDiv">
<table class="uk-table uk-table-hover uk-margin-top">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th></th>
</tr>
</thead>
<tr ng-if="user.isOpened" ng-repeat="details in userDetails | filter: { id: user.detailsId }" id={{user.id}}>
<td ng-bind="details.Name"></td>
<td ng-bind="details.Age"></td>
<td>
</td>
</tr>
</table>
</div>
</div>
</body>
</html>
I hope it helps!!
have you tried passing user from
<div ng-repeat="user in userList | filter:searchBox">
to function showOrHideDetails(user)
In this plunk I have two tables, one regular ng-table and an ng-table-dynamic with columns. Both point to the same data.
The second table doesn't show column titles, how to fix that?
HTML
<br/> Table 1
<table ng-table="tableParams" class="table table-bordered table-hover">
<tbody>
<tr ng-repeat="u in data" ng-dblclick="alert('double click')">
<td title="'User ID'">{{ u.uid }}</td>
<td title="'Group'">{{ u.ugr }}</td>
</tr>
</tbody>
</table>
<br/> Table 2
<table ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
<tr ng-repeat="row in data">
<td title="col.nm" ng-repeat="col in cols">{{row[col.nm]}}</td>
</tr>
</table>
Javascript:
var app = angular.module('app', ['ngTable']);
app.controller('myCtl', function($scope,NgTableParams) {
$scope.cols = [ {nm:'uid'}, {nm:'ugr'} ];
$scope.data = [
{ uid: 'User 1',ugr: 'Group 1'},
{ uid: 'User 2', ugr: 'Group 2'}
];
$scope.tableParams = new NgTableParams({dataset: $scope.data});
});
You're missing the title property within your cols:
$scope.cols = [ {nm:'uid', title: 'User ID'}, {nm:'ugr', title: 'Group ID'} ];
See this plunkr.
I have similar kind of scenario as per the example below, and want to print serial number for each row independent of child, I.E. for each mark record.
Java script Object structure:
$scope.childsList = [
{
id:12346,
name : 'Sagar Kulthe',
marksList : [{subject:'Math', marks: 55}, {subject:'English', marks: 54},
{subject:'Biology', marks: 65},
{subject:'Physics', marks: 78}]
},
{
id:12346,
name: 'Amol Pawal',
marksList : [{subject:'Math', marks: 55}, {subject:'English', marks: 54},
{subject:'Biology', marks: 65},
{subject:'Physics', marks: 78}]
},
{
id:12346,
name: 'Tushar Shah',
marksList : [{subject:'Math', marks: 55}, {subject:'English', marks:
54}, {subject:'Biology', marks: 65},
{subject:'Physics', marks: 78}]
}
];
View:
<table>
<thead>
<th>Sr NO:</th>
<th>Name</th>
<th>Subject</th>
<th>Marks</th>
</thead>
<tbody ng-repeat="child in childsList track by $index">
<tr ng-repeat="mark in marksList track by $index" ng-init="marksIndex = $index">
<td>{{marksIndex }}</td>
<td>{{child.name}}</td>
<td>{{mark.subject}}</td>
<td>{{mark.marks}}</td>
</tr>
</tbody>
</table>
Below approach will help you,
https://plnkr.co/edit/CEbyJNevu94LBogYUek7?p=preview
<table ng-init="count[0] = 0">
<thead>
<th>Sr NO:</th>
<th>Name</th>
<th>Subject</th>
<th>Marks</th>
</thead>
<tbody ng-repeat="child in childsList track by $index" ng-init="count[+$index + 1] = +count[+$index] + child.marksList.length">
<tr ng-repeat="mark in child.marksList track by $index">
<td>{{count[+$parent.$index] + $index + 1}}</td>
<td>{{child.name}}</td>
<td>{{mark.subject}}</td>
<td>{{mark.marks}}</td>
</tr>
</tbody>
I suppose you have to change to this:
<td>{{mark.subject}}</td>
<td>{{mark.marks}}</td>
Also, i don't think you need to have ng-init directive, as $index is directly accessible. So, you can change to this:
Updated as per comment at other answer now deleted
Suppose this is the controller:
app.controller('appCtrl', ['$scope', function($scope){
$scope.counter = 0;
$scope.childsList = [
......
];
}]);
Now in the markup
<tbody ng-repeat="child in childsList track by $index">
<tr ng-repeat="mark in marksList track by $index" ng-init="marksIndex = $index">
<td>{{counter+1}}</td><!-- Will start as 1, 2, 3 -->
<td>{{child.name}}</td>
<td>{{mark.subject}}</td>
<td>{{mark.marks}}</td>
</tr>
</tbody>
I just do an example hope it can help you
Just need to change number 2 equal your markList length brother.
https://embed.plnkr.co/vkizqh213NN6aUeB9tgQ/
I have consulted these related articles, but the presented solutions do not work:
Clickable bootstrap row with angular
Adding parameter to ng-click function inside ng-repeat doesn't seem to work
Angular ng-click not working in div
Here is my plunkr:: http://plnkr.co/edit/kha6mAKDBtrY0XtTc6Wp?p=preview
<body ng-controller="MainCtrl">
<table>
<caption>Troubles with ng-repeat and ng-click</caption>
<thead>
<tr>
<th>Name</th>
<th>Occupation</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="employee in employees" ng-click="alert('hi')">
<td>{{employee.name}}</td>
<td>{{employee.occupation}}</td>
</tr>
</tbody>
</table>
var app = angular.module("plunker", []);
app.controller("MainCtrl", function($scope) {
$scope.employees = [
{
name: "John Doe",
occupation: "Miner"
},
{
name: "Theressa",
occupation: "Construction Worker"
}
]
});
It does work, but alert is not part of your $scope so it won't do anything.
You can add it in your controller:
$scope.alert = function(message) { alert(message); }