AngularJS dynamic ng-repeat directive, the html not redering - javascript

here is demo: http://codepen.io/mafeifan/pen/PzrGRE?editors=1010
table1 is working,
in table2 I wrote a directive to render the td , but not work. I don't know why.
Html:
<table>
<tbody>
<tr ng-repeat="tr in vm.getTrs() track by $index">
<form-cell ng-repeat="cell in vm.getCellsByRow($index+1)">data</form-cell>
</tr>
</tbody>
</table>
JS:
App.directive('formCell', function(){
return {
replace: true,
template: '<td>td</td>'
}
});
if I change to
<table>
<tbody>
<tr ng-repeat="tr in vm.getTrs() track by $index">
<td ng-repeat="cell in vm.getCellsByRow($index+1)"><form-cell></form-cell></td>
</tr>
</tbody>
</table>
JS:
change the template to '<span>td</td>' in directive
it's working, I don't know why

You do need <th> or <td> in <tr> tags:
<html>
<body>
<table border="1">
<tr>
<td>renders</td>
<td>renders</td>
</tr>
<tr>
<div>renders outside the table</div>
<td>renders</td>
</tr>
</table>
</body>
</html>

It seems form-cell tag is not allowed inside tr tag and browser may do something wrong. Use the directive inside an attribute:
App.directive('formCell', function(){
return {
restrict: 'A', // <-- add the restriction
replace: true,
template: '<td>td</td>'
}
});
Like:
<td form-cell ng-repeat="cell in vm.getCellsByRow($index+1)">data</td>

Related

I'm having issues getting AngularJS to display my table correctly

I have an object that looks like this:
[{'name':'Mike', 'age':21},
{'name':'Joe', 'age':24}]
My angular/html code looks like this:
<table class="Names">
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tbody>
<tr ng-repeat-start="value in msg.object">
<td rowspan="2">{{value.name}}</td>
</tr>
<tr ng-repeat-end ng-repeat="value in msg.object">
<td>{{value.age}}</td>
</tr>
</tbody>
</table>
The names show up fine and vertically how i'd want them to be in the table (first column),
but for each value of name i get both of the ages displaying instead of just the age for that person.
Can anyone guide me in the right direction here? I feel like I'm close but just picked up angular today so I'm new to it and ng-repeat.
You only need a simple row repeat with 2 cells in each row
<tr ng-repeat="value in msg.object">
<td>{{value.name}}</td>
<td>{{value.age}}</td>
</tr>
Your table format is wrong. Place the headers inside and do a ng-repeat to generate tr
DEMO
var app =angular.module('testApp', []);
app.controller('testCtrl', function($scope) {
$scope.users = [{'name':'Mike', 'age':21},
{'name':'Joe', 'age':24}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="testApp" ng-controller="testCtrl">
<table border="2">
<tr>
<td>name</td>
<td>age</td>
</tr>
<tr ng-repeat="user in users">
<td >{{user.name}}</td>
<td >{{user.age}}</td>
</tr>
</table>
</body>

How to pass array to html in angularjs1.5.5

How can I pass array Json data from angularjs Controller to html.
Here is my html
<body ng-app="bookApp">
<div ng-controller="bookListCtr">
<table>
<thead>
<tr>
<th>something</th>
<th>something</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items">
<td><( item.id )></td>
</tr>
</tbody>
</table>
</div>
</body>
Here is my Angularjs
var bookApp = angular.module('bookApp', []);
bookApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('<(');
$interpolateProvider.endSymbol(')>');
});
bookApp.controller('bookListCtr', function ($scope, $http) {
$http.get('http://localhost/client_side/public/book').success(function(data) {
if(data.s_respond === 200){
$scope.items = data.data;
console.log(data.data)
}
});
});
This is Json data After console
s_respond = 200
data = "[{"id":"7","title":"Seven is my lucky number","link":"/api/v1/items/7"},{"id":"8","title":"A Dance with Dragons","link":"/api/v1/items/8"},{"id":"10","title":"Ten ways to a better mind","link":"/api/v1/items/10"},{"id":"42","title":"The Hitch-hikers Guide to the Galaxy","link":"/api/v1/items/42"},{"id":"200","title":"Book title #200","link":"/api/v1/items/200"},{"id":"201","title":"Book title #201","link":"/api/v1/items/201"},{"id":"202","title":"Book title #202","link":"/api/v1/items/202"},{"id":"203","title":"Book title #203","link":"/api/v1/items/203"},{"id":"204","title":"Book title #204","link":"/api/v1/items/204"},{"id":"205","title":"Book title #205","link":"/api/v1/items/205"}]"
I think that you need parse the json
$scope.items = JSON.parse(data.data);
a link that explain that:
https://www.quora.com/How-can-I-convert-JSON-format-string-into-a-real-object-in-JS
There r two tags... meaning 2 column try adding another in Ua body
<body ng-app="bookApp"> <div ng-controller="bookListCtr">
<table>
<thead>
<tr> <th>something</th> <th>something</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items"> <td>{{item.id }}</td>
<td>something else</td>
</tr>
</tbody>
</table>
</div>
</body>

Class="ng-hide" get appended automatically though I am using ng-show with correct syntax

I need to show/hide tr tag of a table as per the scope value in the controller. I have written the code as shown below but class="ng-hide" gets appended everytime with tr tag automatically though I have declared my ng-show with correct syntax.
<div ng-show="IsParentExist">
<table>
<thead>...</thead>
<tbody>
<tr ng-show="noValueExist">
<span>There are no records to show here..</span>
</tr>
<tr ng-repeat....>
<td> </td>
</tr>
</tbody>
</table>
</div>
Here is a problem when it gets rendered in DOM as below
<div ng-show="IsParentExist">
<span>There are no records to show here..</span>
<table>
<thead>...</thead>
<tbody>
<tr class="ng-hide" ng-show="noValueExist">
</tr>
<tr ng-repeat....>
<td> </td>
</tr>
</tbody>
</table>
</div>
I have assigned the scope variable in controller as below
$scope.noValueExist = true;
Until you set the value of noValueExist as true in controller, angular sets the class as ng-hide by default.Add this line in controller.
$scope.noValueExist = true;
Try replacing ng-show="noValueExist" by ng-hide="!noValueExist"
<tbody>
<tr ng-hide="!noValueExist">
<td>There are no records to show here.</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
In your controller, initialize your value.
$scope.noValueExist = false;
And when you need to show your <tr> element set this value to true.
$scope.noValueExist = true;
I hope this will help you.
As user #cst1992 mentioned the issue was with span was not wrapped in .
The span is getting misplaced because it is not supported inside 'tr' tag.
You need to use 'td' tag to show content inside table.
After replacing 'span' with 'td' tag,it gets rendered in DOM as below.
<div ng-show="IsParentExist" class="ng-hide">
<table>
<thead>
<tr><th>a</th>
<th>b</th>
</tr></thead>
<tbody>
<tr ng-show="noValueExist" class="ng-hide">
<td>There are no records to show here.</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
</div>

Angular ng-repeat on-filter

Does angular have a onfilter method or onquery as you type to query through results:
for example:
<input type='text' ng-model='query'>
<table>
<tr>
<td>Name</td>
<td># of Enrollments</td>
</tr>
<tr ng-repeat='c in courses | filter:query' onfilter='someStuff()'>
<td>{{c.name}}</td>
<td>{{c.enrollmentLength}}</td>
</tr>
</table>
when I type in the input text the letter "a", I want it to call the someStuff() function.
The way you do this is with a watch inside your controller:
$scope.$watch('query', function(newval) {
// this will fire when query is changed
});
Filter can call a function instead of using an expression. Here's an example:
$scope.processQuery = function(course) {
// do some processing
};
<input type='text' ng-model='query'>
<table>
<tr>
<td>Name</td>
<td># of Enrollments</td>
</tr>
<tr ng-repeat='c in courses | filter:processQuery'>
<td>{{c.name}}</td>
<td>{{c.enrollmentLength}}</td>
</tr>
</table>

Adding table row underneath each table row generated by ngRepeat

I'm using ng-repeat to populate a table with data. This is how I have it setup:
<tbody>
<tr ng-repeat="client in clients | filter:x | filter:y |orderBy:predicate:!reverse | itemsPerPage: pageSize">
<td><input id="option-{{client.id}}" type="checkbox" value=""></td>
<td>{{client.lastname}}</td>
<td>{{client.firstname}}</td>
<td>{{client.status}}</td>
<td>{{client.phone}}</td>
<td>{{client.email}}</td>
</tr>
</tbody>
But I'm needing it to add a table row underneath the row it creates in the ng-repeat. Is that possible?
You can create a directive:
app.directive('addRow', function ($parse, $compile) {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
var template = attrs.addRow ? $parse(attrs.addRow)(scope) : '<tr><td>-</td></tr>';
elem.after(template);
$compile(elem.contents());
}
}
});
It adds passed row template after each element. If template is not passed it uses default template. It also compiles your template, so you can use all angular's stuff inside (eg. <td>{{variable}}</td>).
Example use:
<table>
<tbody>
<tr ng-repeat="item in [1,2,3,4]" add-row="'<tr><td>my template</td></tr>'">
<td>{{item}}</td>
</tr>
</tbody>
</table>
Here is jsfiddle: http://jsfiddle.net/aartek/52b6e/
You can allways add a row manually to the table like:
<tbody>
<tr ng-repeat="client in clients | filter:x | filter:y |orderBy:predicate:!reverse | itemsPerPage: pageSize">
<td><input id="option-{{client.id}}" type="checkbox" value=""></td>
<td>{{client.lastname}}</td>
<td>{{client.firstname}}</td>
<td>{{client.status}}</td>
<td>{{client.phone}}</td>
<td>{{client.email}}</td>
</tr>
<tr>
<td>Footer 1</>
<td>Footer 2</>
<td>Footer 3</>
<td>Footer 4</>
<td>Footer 5</>
<td>Footer 6</>
</tr>
</tbody>
Even better include it in a tfoot tag.
Or if you need two rows, you can do this:
<tbody ng-repeat="item in items">
<tr>
<td>{{item.row_one_stuff}}</td>
<td>{{item.more_row_one_stuff}}</td>
</tr>
<tr>
<td>{{item.row_two_stuff}}</td>
<td>{{item.more_row_two_stuff}}</td>
</tr>
</tbody>

Categories