Angularjs. ng-switch not working inside a table - angularjs

Is there anyway I can get ng-switch working inside a table? The table example is not working but the ul example just work fine. The problem is that I really need the table example. I am using angular 1.07.
<table>
<tbody ng-repeat="item in items">
<tr><td>{{ item.heading }}</td></tr>
<tr ng-repeat="row in item.fields" ng-switch on="row.nb">
<div ng-switch-when="01">
<td>{{ row.nb }}</td>
</div>
</tr>
</tbody>
</table>
<ul ng-repeat="item in items">
<li ng-repeat="row in item.fields" ng-switch on="row.nb">
<div ng-switch-when="01">
{{ row.nb }}
</div>
</li>
</ul>

You need to move the ng-switch-when to the td otherwise it will ignore it as invalid because a div is not valid markup inside a tr. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr
Remove the div and change it to:
<td ng-switch-when="01">{{ row.nb }}</td>
Demo: http://plnkr.co/edit/yHkBGekjgGDts8pNtekJ?p=preview

Related

Div inside tbody with ng-if not filtering the result

First of all let me please accept angular and html is not my trade.
Following is my scenario
<tbody ng-repeat="item in items.ItemList">
<div ng-if="item.variableName == false">
<tr>
<tr/>
<tr ng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</div>
</tbody>
I am trying to control the table rows that I wan't to display with ng-if inside the div and it is not working. By moving ng-if to tbody will filter the rows fine but not at div level.
Unfortunately, I can't move ng-if to the tbody as I have to deal with the else part of the if condition and in that case there is an array inside each item of the repeater that should render rows separately.
Following is the output that I want to have once ng-if condition works appropriately.
P.S. I am not specific to the <div> tag here. I am open to replace div with any other tag as long as it can get me the desired result.
Here someone might say why not ng-if at <tr> level? I am using ng-show and ng-animate so the row with ng-if changes its scope in Doom object and hover over functionality stops working.
<tbody ng-repeat="item in items.ItemList">
<div ng-if="item.variableName == false">
<tr>
<tr/>
<tr ng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</div>
<div ng-if="item.variableName == true">
<tr>
<tr/>
<trng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</div>
</tbody>
I use this and it's work.
Look exemple in the jsfilddle
http://jsfiddle.net/ADukg/12003/
<tbody ng-repeat="item in items.ItemList" ng-show="item.variableName">
<tr>{{item | json}}</tr>
</tbody>
Div won't help you out here as it defies the rules of tbody according to html.
Use ng-container like this instead, it is of no meaning to HTML so it won't defy the rules and you will get your condition fulfilled
<tbody ng-repeat="item in items.ItemList">
<ng-container ng-if="item.variableName == false">
<tr>
<tr/>
<tr ng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</ng-container>
<ng-container ng-if="item.variableName == true">
<tr>
<tr/>
<trng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</ng-container>
</tbody>
Also in your case you can use ng-switch instead of ng-if like this
<tbody ng-repeat="item in items.ItemList" ng-switch="item.variableName">
<ng-container ng-switch-when="false">
<tr>
<tr/>
<tr ng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</ng-container>
<ng-container ng-switch-when == "true">
<tr>
<tr/>
<trng-show="isPermitted" ng-animate="isPermitted">
<tr/>
</ng-container>
</tbody>

ng-repeat with click modifying input

<input ng-model = "val">
<a href ng-click="val = 1"> val = 1 </a>
<div class="test" ng-controller="Ctrl">
<table>
<thead>
<tr>
<th>let</th>
<th>num</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in data">
<td>
<a href ng-click="val = 1">
{{thing.let}}
</a>
</td>
<td>{{thing.num}}</td>
</tr>
</tbody>
Is there a way to make an input change based on a click in an ng-repeat?
In this jsfiddle you can the input change with a click outside of an ng-repeat, but in the repeat it doesn't change the input.
http://jsfiddle.net/Hp4W7/2403/
The problem is that you are setting the val property in a child scope created by ng-repeat.
The solution is to create a function that assigns this value to the parent scope:
$scope.changeVal = function(val){
$scope.$parent.val = val;
}
And call it with ng-click="changeVal(1)"
Fiddle here: http://jsfiddle.net/nawd7jjc/
ng-repeat always make new scope for every iteration so if you change any primitive value inside ng-repeat ("val" in this case) then it will not refer to the actual "val". So to solve it, it should be a object type, for ex. obj.val something
Below is the working solution for this problem:
<div class="test" ng-controller="Ctrl" ng-init="obj.val=12345">
<input ng-model = "obj.val">
<a href ng-click="obj.val = 2"> val = 2 </a>
<table>
<thead>
<tr>
<th>let</th>
<th>num</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in data">
<td>
<a href ng-click="obj.val = thing.num">
{{thing.let}}
</a>
</td>
<td>{{thing.num}}</td>
</tr>
</tbody>
</table>
<div>

Angular Display NG-Repeat Display

I have the following code to display 3 different types on the page:
Production
Development
Maintenance
And I want the entire section (Production h4 and table/tbody) to disappear if there is no content in filteredResults. (Only appear if there is content)
<span ng-repeat="type in types">
<table class="max-width">
<tbody>
<div class="row" ng-repeat="result in filteredResults = (results | filter:search) | filter: status('status', type)">
<div class="left-header-padding" ng-if="$index==0">
<tr class="pull-left">
<h4 class="title">{{type.charAt(0).toUpperCase() + type.substring(1)}}</h4>
</tr>
</div>
</div>
</tbody>
</table>
</span>
I am currently trying ng-if for content inside the table, checking if ng-repeat occurs and only rendering the if there is content in ng-repeat, but I want the entire section (table included) to disappear when there is no content. Does anyone know how to accomplish this?
if you want hide table put ng-show into table tag ie:
<table class="max-width" ng-show="filteredResults.length >0">
<tbody>
<div class="row" ng-repeat="result in filteredResults = (results | filter:search) | filter: status('status', type)">
<div class="left-header-padding">
<tr class="pull-left">
<h4 class="title">{{type}}</h4>
</tr>
</div>
</div>
</tbody>
add ng-show="filteredResults.length" to your table element
<table ... ng-show="filteredResults.length">
example: http://plnkr.co/edit/WFQzRtXFe3UnvuzA8psa?p=preview
also, iv'e used tr inside tbody instead of div
Try using ng-init to create a local filtered collection and use the ng-if statement to hide the table if there is no items in the filtered collection.
<div ng-repeat="type in types">
<div ng-init="filteredResults = (results | filter:search) | filter: status('status', type)">
<table class="max-width" ng-if="filteredResults.lenght > 0">
<tbody>
<div class="row" ng-repeat="result in >
<div class="left-header-padding" ng-if="$index==0">
<tr class="pull-left">
<h4 class="title">{{type.charAt(0).toUpperCase() + type.substring(1)}}</h4>
</tr>
</div>
</div>
</tbody>
</table>
</div>
</div>
Let me know if you have any questions.

Conditionally add row in ng-repeat

I've got a simple repeating table-row in AngularJS
<tr ng-repeat="item in items">
<td>{{ item.prop1 }}</td>
<td>{{ item.prop2 }}</td>
</tr>
My item object has a comment property on it, and if that comment contains a value, I want to display that in a row all by itself on the line right after the rest of the elements and have it span the entire row. Is that type of thing possible? I looked at ng-repeat-end but that doesn't seem to be what I want, and I can't just add and extra <tr> element inside the ng-repeat as that'd be invalid HTML.
You can use ng-repeat's special repeat start and end points via ng-repeat-start and ng-repeat-end.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-repeat="comment in post.comments">
<td>{{comment.content}}</td>
</tr>
</table>
UPDATE: If the comment is a string, then simply remove the ng-repeat at the ng-repeat-end end point and add an ng-if expression that validates the existence of post.comment.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-if="post.comment">
<td>{{post.comment}}</td>
</tr>
</table>

angularjs: ng-repeat-start and ng-repeat-end with inner ng-repeat

Hi I have a simple use case for ng-repeat-start and end and is working just fine, the problem appears when I want to add an inner ng-repeat.
Here is the my code
<tr ng-repeat-start="obj in rows" >
<td ng-repeat="e in obj.row">{{e}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="4">{{obj.description}}</td>
<tr>
The inner ng-repeat into td element is not working, I'm seeing the ngRepeat comment when I inspect the html source code, but the td elements are not being created.
<!-- ngRepeat: e in obj.row -->
My ugly workaround (given that I know the size of that vector) is:
<tr ng-repeat-start="obj in rows" >
<td>{{obj.row[0]}}</td>
<td>{{obj.row[1]}}</td>
<td>{{obj.row[2]}}</td>
<td>{{obj.row[3]}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="4">{{obj.description}}</td>
<tr>
I am not sure whether you are using angular 1.1.6 or not since ng-repeat-start and ng-repeat-end are not available in 1.1.5 or 1.0.7 yet.
However, you don't actually have to use the new directives to achieve that. You can simply implement it like this for right now:
<table>
<tbody ng-repeat="obj in rows">
<tr ng-repeat="e in obj.row">
<td>{{e}}</td>
</tr>
<tr>
<td colspan="4">{{obj.description}}</td>
<tr>
</tbody>
</table>
You may use ng-repeat-start and ng-repeat-end to reimplement it when AngularJS 1.1.6 version is officially released.
Demo
I think it might be something wrong with your data structure. Using Angular 1.2.1 this works for me
<div ng-app="myApp" ng-controller="myCtrl">
<div class="h" ng-repeat-start="val in data">{{val.title}}</div>
<div ng-repeat="con in val.content">
{{con}}
</div>
<div class="b" ng-repeat-end>footer</div>
</div>
See jsFiddle
You should be able to use index-based iterations to bypass that:
<tr ng-repeat-start="obj in rows" >
<td ng-repeat="e in obj.row">{{obj.row[$index]}}</td>
</tr>
<tr ng-repeat-end>
<!-- ... -->

Resources