Unable to make NgTable work with AngularJs 1.5 - javascript

I'm trying to integrate NgTable with angularjs 1.5 in a component-based architecture (so, no old-style controllers).
The NgTable controls (filter, icons for sorting) appear, but they don't seem to work at all, so they don't filter and don't sort.
Here's my code
--- activity-list-module.js ---
angular.module('activityList', ['ngTable']);
--- activity-list-component.js ---
(function(){
'use strict';
angular.
module('activityList').
component('activityList', {
templateUrl: "app/activity-list/activity-list.html",
controller: ['NgTableParams', function (NgTableParams) {
var self=this;
self.activitiesForm=[{id:0,description:"att0"},{id:1,description:"att1"},{id:2,description:"att2"}];
self.tableParams = new NgTableParams({}, { dataset: self.activitiesForm});
}]
});
})();
--- activity.list.html ----
<div style="margin:20pt">
<h3>Manage Activities</h3>
<div style="margin:20pt">
<h3>Manage Activities</h3>
<div class="row" style="margin-left:20pt" >
<table id="myViewTable" ng-table="$ctrl.tableParams" class="table" show-filter="true" class="table actTable" style="width:95%;table-layout: fixed;" >
<tbody>
<tr ng-repeat="projectActivity in $ctrl.activitiesForm track by projectActivity.id">
<td data-title="'Id'">{{projectActivity.id}}</td>
<td data-title="'description'" filter="{ description: 'text'}" sortable="'description'">{{projectActivity.description}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Of course the component is called using the tag <activity-list></activity-list> in another page.
I'm working with AngularJs 1.5.8 and ng-table 3.0.1.
I'm doing something wrong or there is an incompatibility between AngularJs >= 1.5 and ng-table ?
Here is the plnkr
PS In the last case, how can I do ? Is smarttable compatible with AngularJs 1.5 ?

After raised an issue in ng-table GIT repo i got a working example from the creator of ng-table and i could have a look.
The point is in the use of controller variables, instead of a $data variable generated by ng-table.
So, in the case of the 'new style' component the issue is solved changing
<tr ng-repeat="projectActivity in $ctrl.activitiesForm track by projectActivity.id">
with
<tr ng-repeat="projectActivity in $data track by projectActivity.id">
In the case of the "old Style" controller it's solved changing
<tr ng-repeat="user in vm.data">
with
<tr ng-repeat="user in $data">
I don't like a lot this solution, because it add a kind of global, but it works.
EDIT
it works also using
$ctrl.tableParams.data (for Component Example) and vm.tableParams.data (for the Controller Example) which let me feel much better about.

Related

AngularJS: nest directive in ng-repeat for using smart-table with dynamic table fields

I'm trying to use angular-smart-table for grid in my new AngularJS app. According to the document, to sort a column, I should use the st-sort directive like bellow:
<th st-sort="firstName">first name</th>
<th st-sort="lastName">last name</th>
However, I'm trying to re-use the piece of code for not only one table, so I don't know the table field names in advance until the run-time. I'm doing something like bellow:
<script type="text/ng-template" id="content1">
<div ng-repeat="table in $ctrl.tables">
<h2>{{table._tableName}}</h2>
<table st-table="table._data" class="table table-striped">
<tr>
<th ng-repeat="fieldName in table._fieldNames" st-sort="{{fieldName}}">{{fieldName}}</th>
</tr>
<tr ng-repeat="data in table._data">
<td ng-repeat="fieldName in table._fieldNames">{{$ctrl.formatCell(table, data, fieldName)}}</td>
</tr>
</table>
</div>
</script>
And this cannot work (cannot sort, other functions OK). I tried bellow it does not work, seems the st-sort has to be in the <th> tag.
<th ng-repeat="fieldName in table._fieldNames"><span st-sort="{{fieldName}}">{{fieldName}}</span></th>
And bellow does not work as well:
<tr>
<span ng-repeat="fieldName in table._fieldNames">
<th st-sort="{{fieldName}}">{{fieldName}}</th>
</span>
</tr>
Today I tried to develop a directive and use it in the comment by setting restrict to "M" to solve the above. Then I got a new problem: I'm using UI-Router in this app and I cannot get the table contents in my directive, because UI-Router states have isolated scopes and it only supports controllers but does not support directives. The author may think supporting directives is not necessary (yes in most cases, but this kind of assumptions are always dangerous).
I'm Trying two possible ways: 1., put the field names to the session/local storage for sharing as a work-around; 2., abandon UI-Router. Appreciate anyone providing a better solution.

ng-repeat angularjs 1.5.11 not work

i have an angularJS v1.5.11 app,
but i've got big problem when i want to do a simple ng-repeat in table like
<tbody>
<tr ng-repeat="score in data.result">
<td ng-repeat="item in score"> {{ item }} </td>
</tr>
</tbody>
my code works fine on angularJS v1.1.1,
hope you can help me.
i made a JSFiddle here : https://jsfiddle.net/vpLj20w1/5/
u can change AngularJS framework version in JSFiddle to see work fine on 1.1.1, but on 1.4.8 and higher doesn't work..
best regards,
Axel.
You need to tell angularjs that your controller exists. Try declaring a module and adding the controller to the module:
<div ng-app="myApp">
<div ng-controller="scoreCtrl">
...
</div>
</div>
and then add to your javascript:
var app = angular.module("myApp", []);
app.controller("scoreCtrl", scoreCtrl);
Now it runs better than it did, but you have a problem with ng-repeat="item in score" as angularjs needs a unique key for anything used in ng-repeat and you have duplicated items.
Change the inner loop to:
<td ng-repeat="item in score track by $index"> {{ item }} </td>
and now you should get the expected output.
BTW, looking at the javascript console in your browser would have helped you here: initially it was complaining that it couldn't find the controller function and then when I injected it into the app it complained about the repeater.
This is because you haven't injected your controller into the app. I can't explain why your example works on 1.1.1, as I only have experience on 1.4.x+, but you need to use the module controller injection.
https://jsfiddle.net/vpLj20w1/7/
angular.module('app', [])
.controller('scoreCtrl', scoreCtrl);
And give your ng-app a name (I used app)

Angular OrderBy index not functioning

I am setting the default orderby on a directive. On certain click events I'm changing the order by the column that was clicked upon. However when I try to set a default order by the index I get some really strange results.
I've created a Plunker based off the Angular Documentation. My goal is to have the default orderBy (only code shown here) perform no sorting so that I can change the orderBy property later.
Plunker: Plunker Or HTML Below
<div ng-controller="ExampleController">
<table class="friend">
<tr>
<th>Name</th>
<th>Phone Number</th>
<th>index</th>
</tr>
<tr ng-repeat="friend in friends | orderBy:'index'">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
<td>{{friends.indexOf(friend)}}</td>
</tr>
</table>
</div>
New Plunker. It appears as if this is a change from Angular 1.2 to 1.3 I tested working code on different versions of angular and in 1.2 you can pass a empty order by and it will order by the index but in 1.3 and 1.4 it sorts differently
You don't need any sorting at all here, the array is already in the order you want it to be. Assuming that you have a variable $scope.orderByField defining which property you want to use for ordering you could do something like:
<tr ng-repeat="friend in (orderByField ? (friends | orderBy : orderByField) : friends)">
So you would use the orderBy filter only if you really need it.
Plunker: http://plnkr.co/edit/kXOSF4adOohDDxLEtnGT?p=preview
Appart from that you can also define a custom comparator method and use it:
$scope.sortByIndex = function(a, b) {
return $scope.friends.indexOf(a) - $scope.friends.indexOf(b)
}
<tr ng-repeat="friend in friends | orderBy : sortByIndex">
But i wouldn't really recommend to use that, cause you will do unnecessary calculations.
I solved this issue by presorting my list at all times.
Then my function did all the work I was previously relying on Angular to do for me.
As an FYI I also submitted this as a bug to the angularJS team. They reported that it will be fixed in the next release (https://github.com/angular/angular.js/issues/12100)

Angular append directive template to table

I have situation when i need to repeat multiple tbody in one table, what im trying to do is to make every tbody directive and i want its template to append to table, but when im put the directive inside the table tag its put his content outside the table.
the cart draw directive:
return {
restrict : 'AE',
templateUrl: 'client/cart/views/cart-draw.html',
scope : {},
replace: true,
controller : controller
}
the tpl:
<tbody ng-repeat="draw in CartService.items.draws track by $index">
<tr>
<td>
//some content
</td>
</tr>
</tbody>
the html:
<table class="table">
<cart-draw></cart-draw>
</table>
here is the plunker, if you inspect element you will see the tbody is out of the table:
http://plnkr.co/edit/9wEGFE5K0w0ayp6qo8Lx?p=preview
That is happening because the <table> tag doesn't recognize your custom <cart-draw> element as a valid child.
I would modify like so: http://plnkr.co/edit/u88N76h5dvLAvR3C1kRs?p=preview
index.html
<table><tbody cart-draw></tbody></table>
cart-draw.html
<tbody ng-repeat="body in bodies">
<tr>
<td>
{{body}}
</td>
</tr>
</tbody>
app.js
$scope.bodies = ["hello1", "hello2", "hello3"];
This is a long pending issue in Angular's Github repo.
https://github.com/angular/angular.js/issues/1459
I also stumbled upon to this problem once (with SVG). It happens because before rendering the directive, the template is cross verified with HTML DTD and alone doesn't make sense (without tag) and so it doesn't work. Same applies to <tr> and <li>
There are many solutions which uses ng-transclude and link functions to wrap it in respective parent tag and then use it.
This is actually a known & strange issue when it comes to directives & <table>'s.
I believe it actually comes in as invalid HTML at first, causing it somehow appear outside of your <table> tag.
Try making cart-draw an attribute of a <tbody>:
<table>
<tbody cart-draw></tbody>
</table>
plunker Example
This will make it work as intended.

Sort or Rearrange Rows of a table in angularjs (drag and drop)

I wanted to have the functionality of rearranging rows in a table (sorting rows using drag and drop).
And the index of the row arrangement should also change in the model.
How can I do something similar to this : http://jsfiddle.net/tzYbU/1162/
using Angular Directive?
I am generating table as :
<table id="sort" class="table table-striped table-bordered">
<thead>
<tr>
<th class="header-color-green"></th>
<th ng-repeat="titles in Rules.Titles">{{titles.title}}</th>
</tr>
</thead>
<tbody ng-repeat="rule in Rules.data">
<tr>
<td class="center"><span>{{rule.ruleSeq}}</span></td>
<td ng-repeat="data in rule.ruleData">{{statusArr[data.value]}}</td>
</tr>
</tbody>
</table>
I did it. See my code below.
HTML
<div ng:controller="controller">
<table style="width:auto;" class="table table-bordered">
<thead>
<tr>
<th>Index</th>
<th>Count</th>
</tr>
</thead>
<tbody ui:sortable ng:model="list">
<tr ng:repeat="item in list" class="item" style="cursor: move;">
<td>{{$index}}</td>
<td>{{item}}</td>
</tr>
</tbody>{{list}}
<hr>
</div>
Directive (JS)
var myapp = angular.module('myapp', ['ui']);
myapp.controller('controller', function ($scope) {
$scope.list = ["one", "two", "thre", "four", "five", "six"];
});
angular.bootstrap(document, ['myapp']);
There is another library: RubaXa/Sortable: https://github.com/RubaXa/Sortable
It is for modern browsers and without jQuery dependency. Included is a angular directive. I'm going to check it out now.
You get good touch support additionally.
AngularJS was not really built for the manipulation of DOM elements, rather to extend the HTML of a page.
See this question and this Wikipedia entry.
For DOM manipulation, jQuery/mootools/etc will suite you just fine (hint: the example in your jsFiddle link).
You could probably use AngularJS to keep track of the ordering of your elements to update your model. I'm not sure how to do this using directives, but the following code may be useful
var MyController = function($scope, $http) {
$scope.rules = [...];
...
}
var updateRules = function(rule, position) {
//We need the scope
var scope = angular.element($(/*controller_element*/)).scope(); //controller_element would be the element with ng-controller='MyController'
//Update scope.rules
}
Then when you reorder the list, simply call updateRules() with the changed rule and its new position in the model.
Anyone else who wants something like this but not understanding the accepted answer. Here is a directive UI.Sortable for AngularJS that allows you to sort an array/ table rows with drag & drop.
Requirements
JQuery v3.1+ (for jQuery v1.x & v2.x use v0.14.x versions)
JQueryUI v1.12+
AngularJS v1.2+
Usage
Load the script file: sortable.js in your application: (you can find this sortable.js from here
<script type="text/javascript" src="modules/directives/sortable/src/sortable.js"></script>
make sure you have included JQuery, AngularJs and JQueryUI js files in
order before this sortable file
Add the sortable module as a dependency to your application module:
var myAppModule = angular.module('MyApp', ['ui.sortable'])
Apply the directive to your form elements:
<ul ui-sortable ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
Developing Notes:
ng-model is required, so that the directive knows which model to update.
ui-sortable element should contain only one ng-repeat
Filters that manipulate the model (like filter, orderBy, limitTo,...) should be applied in the controller instead of the ng-repeat
3rd point is very Important as it took almost an hour to understand
why my sorting was not working?? It was because of orderBy in html
and that was resetting the sorting again.
For more understanding you can check the detail here.
If I understand you correctly, you want to be able to sort the rows? If so, use UI-Sortable: GitHub
Demo: codepen.io/thgreasi/pen/jlkhr
Along with RubaXa/Sortable there is one more angularjs library avilable that is angular-ui-tree. Along with drag and drop we can arrange elements in a tree structure and we can add and delete elements (nodes)
Please see the this link for examples
http://angular-ui-tree.github.io/angular-ui-tree/#/basic-example .
Please see this for github
https://github.com/angular-ui-tree/angular-ui-tree.

Categories

Resources