I have developed a ngtable with a filter. The pagination on the table does not work anymore though? When I select the show 10 rows on the bottom of the table it still shows 14 rows? How can i fix the pagination/indexing?
This is my table definition:
<table ng-table="tableParams" class="table">
<tr ng-repeat="account in $parent.filtered =(data | filter:search.accountName | filter:search.id)">
<td data-title="'id'">
{{account.account.accountId.id}}
</td>
<td data-title="'name'">
{{account.account.accountName}}
</td>
</tr>
</table>
plunkr:http://plnkr.co/edit/Rqt6px?p=preview
You need to figure pagination function by yourself. You may see ng-table's example in here.
var Api = $resource("/data");
this.tableParams = new NgTableParams({}, {
getData: function(params) {
// ajax request to api
return Api.get(params.url()).$promise.then(function(data) {
params.total(data.inlineCount); // recal. page nav controls
return data.results;
});
}
});
It first load all the data into Api. The params.url() contains current page and page count. It then use these two variable to return part of dataset. So you may need to figure out how to return this part of data.
Related
I'm trying to make a slight improvement to an existing widget that our team created, but can't seem to get it to work correctly. We have a widget that does a RowCount of tasks and groups them by state. I want the RowCount to auto update once a task is complete without having the user press the refresh button. I've read some documentation on $rootscope, $broadcast, and $on, but can't seem to get it to work.
Below is snippet of our HTML:
<table class="table table-sm table-responsive">
<tbody>
<tr class="h3">
<td colspan=2>Complete</td>
</tr>
<tr class="h2 bg-success" ng-repeat="x in data.values track by $index">
<td><span class="glyphicon glyphicon-check"></span></td>
<td>{{x.completedCount}}</td>
</tr>
</tbody>
</table>
A snippet of our Server Script:
var values = [];
var _completedCount;
var gsCompleted = new GlideRecordSecure('sn_hr_core_task');
//CLOSED COMPLETE, CLOSED INCOMPLETE,
gsCompleted.addQuery('state', 'IN', '3,4,7');
gsCompleted.addQuery('assigned_to', gs.getUserID());
gsCompleted.addQuery("parent.state", 'NOT IN', '1,800,900');
gsCompleted.query();
if(gsCompleted){
_completedCount = gsCompleted.getRowCount();
}
else{
_completedCount = 0;
}
values.push(
{
completedCount: _completedCount
});
data.values = values;
How do I get this widget to auto update the Completed row count without refreshing the page? I've been playing around with spUtil recordWatch, but cannot get it to work correctly:
function($scope, $sce, spUtil) {
var c = this;
c.data.loading = true;
//After page initially loads re-call server script to load data
c.server.get({
action: 'retrieve_data'
}).then(function(response) {
c.data.loading = false;
console.log('Response');
console.log(response);
c.data.values = response.data.values;
spUtil.recordWatch($scope, 'sn_hr_core_task', "", function(name,data) {
spUtil.update($scope);
})
});
}
Take a look at the widget Simple List, it has an example of one that may help a bit.
You should be able to change your recordWatch to this
var filter = "stateIN3,4,7^parent.stateNOT IN1,800,900^assigned_to=" + window.NOW.user_id;
spUtil.recordWatch($scope, 'sn_hr_core_task', filter);
You generally won't need a callback function unless there is some specific action you're triggering.
I have two components, the parent is called Layout and the child Report. In Report I have a table that loops through and renders a list of car accidents. I have a handler - handleIncidentReport in Report that calls a function in Layout to update this.state.obds (car messages) which then obviously updates the child Report.
My question is what is the proper ReactJS way to have it so only the row clicked has its {this.props.incident_report} updated, and not the other dynamically created rows with the same yield statement (not sure of the correct terminology).
I'm less than a week into ReactJS and I know I could hack it together but I want to know the proper way.
Here is a chunk of the two files -
Report
handleIncidentReport: function(e) {
var accident_id = $(e.target).closest('tr').data('accident-id')
this.props.changeIncidentReport(e, accident_id)
},
render: function() {
var self = this;
var accidents = [];
for (var i = 0; i < this.props.accidents.length; i++) {
var incident = this.props.accidents[i];
accidents.push([
<tr key={i} onClick={self.handleIncidentReport} data-accident-id={incident.id} >
<td>{incident.owner.first_name} {incident.owner.last_name}</td>
<td>{incident.car.title}</td>
<td>{moment(incident.created_at).format("MMM D, YYYY - hh:mm A")}</td>
</tr>,
<tr className="incident-report">
<td colSpan="3">
<Obds obds={this.props.incident_report} />
</td>
</tr>
]);
};
return (
<div className="report">
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Car</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{accidents}
</tbody>
</table>
</div>
);
}
Layout
changeIncidentReport: function(e, accident_id) {
var $tr = $(e.target).closest('tr');
$.ajax({
method: "GET",
data: {accident_id},
url: "/superadmin/emergency_analysis/get_incident",
datatype: 'jsonp'
}).success(function(incident){
this.setState({
incident_report: incident
});
}.bind(this));
},
You should make it so that handleIncidentReport returns a function that is configured (through closures) with the index of each of the rows, something like:
handleIncidentReport: function(accident_id) {
return function(e) {
this.props.changeIncidentReport(e, accident_id)
}
},
(If you aren't sure how closures work you should check out this excellent post: How do JavaScript closures work?)
Then update your render to use
<tr key={i} onClick={self.handleIncidentReport(i)} data-accident-id={incident.id} >
and each of the rows will have a unique handler all of their own that will be called when they're clicked on.
This should also get rid of some of that jQuery which figures out which accident_id was clicked on too.
I already used ngTable with static data before, it worked well (listing, sorting and filtering). I'm using ngTable v 0.8.3
My Goal
This time I want to create a ngTable with data loaded from a Web Service.
I made a custom factory to be able to create my ngTable with future others entities.
Issue
It doesn't work and I have no JS console errors. When I debug, I can clearly see that my method query from my service Employee return me my complete and correct objet containing employees details. I enter in the getData() function, the ngTable is being created, but with empty data.
Relevant and lightweighten code
Here is my HTML markup :
<table ng-table="tableParams" class="table table-striped" show-filter="true">
<tbody>
<tr ng-repeat="employee in $data">
<td data-title="'employee.firstname' | translate" filter="{'firstname' : 'text'}" sortable="'firstname'"><a ui-sref="employee.detail({id:employee.id})">{{employee.firstname}}</a></td>
<td data-title="'employee.lastname' | translate" filter="{lastname : 'text'}" sortable="'lastname'">{{employee.lastname}}</td>
<td data-title="'employee.mail' | translate" filter="{mail : 'text'}" sortable="'mail'">{{employee.mail}}</td>
<td data-title="'employee.phone-number' | translate" filter="{phone_number : 'text'}" sortable="'phone_number'">{{employee.phone_number}}</td>
<td data-title="'employee.birthdate' | translate" filter="{birthdate : 'text'}" sortable="'birthdate'">{{employee.birthdate}}</td>
</tr>
</tbody></table>
my Angular controller :
myapp.controller('EmployeeController', function ($rootScope, $scope, Employee, ngTableParams, ngTableFactory) {
$scope.tableParams = ngTableFactory.create(20, {lastname: 'asc'}); // count, sorting
});
And my Angular factory :
myapp.factory('ngTableFactory', function(ngTableParams, Employee) {
return {
create: function(count, sorting) {
return new ngTableParams({
page: 1, // initial page
count: count, // count per page
sorting: sorting // initial sorting
}, {
total: 0,
getData: function($defer, params) {
Employee.query({page: params.page(), size: params.count()}, function(result) {
$defer.resolve(result);
});
}
});
}
}
});
Edit 1, progresses :
My items are being listed if I remove params from my query method, so it was a bad handling of my Employee service. But, the sort and filter does not work on my table by default. to make sorting works, I have to add this line on my ngTable factory, in the getData() function :
result = $filter('orderBy')(result, params.orderBy());
Normally, the sorting of basic elements works as I added the 'sortable' keyword in my HTML ngtable template columns, and as I'm fetching my data over $data item. Still investigating.
Thanks for your help mates !
As far as I can see, your code works.
Please see https://github.com/masa67/NgTable for a working example (based on Node). I did not change anything (except filled-in the missing parts, maybe the problem is there).
The table formatting is not correct, but at least the data is coming in.
I have a JSON retrieve from database
[{"id":1,"firstname":"Alan Cayetano","numbers":2},{"id":2,"firstname":"Bong Marcos","numbers":0},{"id":3,"firstname":"I Dont Care","numbers":3},{"id":4,"firstname":"toto tata","numbers":0},{"id":5,"firstname":"titi terter","numbers":0},{"id":6,"firstname":"Ian Go","numbers":0}]
this is the result when displayed in table result
firstname lastname numbers
Alan Cayetano 10
Bong Marcos 4
Ian Go 3
What Ever 0
I only want the data with the highest number value
In this case
firstname lastname numbers
Alan Cayetano 10
This data is dynamically fetch from database
My angular.js
<script src="//code.angularjs.org/1.4.8/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//');
$interpolateProvider.endSymbol('//');
});
app.controller('customersCtrl',['$scope','$http',function($scope, $http) {
//$http.get("http://localhost:8093/voters/voters_angular")
$http.get("{{ path('vp_president') }}")
.success(function (response) {
$scope.names= JSON.parse(response);
});
}]);
//console.log(names);
</script>
Table
<div ng-app="myApp" ng-controller="customersCtrl">
<table class="table">
//names//
<thead>
<tr>
<th>Firsname</th>
<th>Lastname</th>
<th>NUm</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in names">
<td>//x.firstname//</td>
<td>//x.lastname//</td>
<td>//x.numbers//</td>
</tr>
</tbody>
</table>
</div>
How to achieve this? I am still learning Angular Js
I wonder if Angular's $last filter will work on this
This should work as describe
Link
<tr ng-repeat="x in names| orderBy:'-numbers' | limitTo:1">
<td>//x.id//</td>
<td>//x.firstname//</td>
<td>//x.numbers//</td>
</tr>
It's better to find your max in the controller, not in the view.
function findMax(names) {
var result = null;
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (result == null || name.numbers > result.numbers) {
result = name;
}
}
return result;
}
$scope.name = findMax($scope.names);
And in html
<tr>
<td>{{name.firstname}}</td>
<td>{{name.lastname}}</td>
<td>{{name.numbers}}</td>
</tr>
In AngularJS it's better to pre-sort your data before showing in the view, the ng-repeat creates a watcher for each object it repeat's, in AngularJS the number of watchers is associated with performance if you have many watchers your performance it's worst.
If you don't need the other values to appear, there is no need to create watchers for that values, so it's better to pre-sort the array.
you can do this :
<tr ng-repeat="x in names | orderBy:numbers:reverse | limitTo:1">
You can use:
angular.forEach($scope.names, function (value, key) { //code });
With angular foreach you can read row by row in your $scope.names, and use your logic for get the msx value.
When:
key -> is the position (use an alert(key) to see the info)
value -> is a the row of the json. For get data use value.id, value.firstname, etc.
First off please don't bash me for using old technology (polling) and an old version of Mootools (1.3.2) as I don't have control over these factors.
Ok here's my problem.
I have a page which refreshes every few seconds to fetch new data from the database via AJAX. Ideally the structure of the returned value should be as such:
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
After receiving this table row structure result, I need to append that to the current table in the page which essentially just adds a new record on the table if there are new records. If there's none, then no changes to the table are made.
Currently I am using
var req = new Request.HTML({url: url_to_get_new_rows,
onSuccess: function(html, responseHTML) {
// append table row 'html' here
}
}).send();
However, the returned value in the 'html' variable that I'm supposed to append at the end of the table only returns
1 2 3 4
This obviously is an undesired behavior as I need the tr and td elements to make it work.
I hope someone could help me with this problem.
THANKS!
Javascript:
new Request.HTML({
url:'tr.php',
onSuccess: function(responseTree, responseElements, responseHTML, responseJavaScript) {
var tbody = document.id('tbody');
tbody.set('html', tbody.get('html') + responseHTML);
// or
var tr = new Element('table', {'html': responseHTML}).getElement('tr');
tr.inject(tbody);
}
}).get();
HTML:
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
</tr>
</tbody>
</table>