ng-switch inside ng-repeat not working - javascript

I have data that basically boils down to this:
function ExampleCtrl($scope) {
$scope.myData= [
{text: "blah", other: 3, V: 'caseOne'},
{text: "blah", other: 3, V: 'caseTwo'},
{text: "blah", other: 3, V: 'caseThree'}
];
}
This is being used like this:
<div ng-controller="ExmapleCtrl">
<table>
<tr>
<td>Text</td>
<td>Other</td>
<td>V</td>
</tr>
<tr ng-repeat="data in myData">
<td>{{data.text}}</td>
<td>{{data.other}}</td>
<td ng-switch on="data.V">
<td ng-switch-when="caseOne"><img src="assets/img/pass.png"/></td>
<td ng-switch-when="caseTwo"><img src="assets/img/pass.png"/></td>
<td ng-switch-when="caseThree"><img src="assets/img/fail.png"/></td>
</td>
</table>
</div>
The problem is is that I am getting this error:
Error: No controller: ngSwitch..
I clearly have set the controller to ExampleCtrl, I don't see any typing errors, so I am at a loss unfortunately.

I believe the issue has to do with the ng-switch producing invalid markup. I'm not sure you can nest a td inside another td. Anyways, if you change it to this it will work:
<td ng-switch on="data.V">
<img src="assets/img/pass.png" ng-switch-when="caseOne"/>
<img src="assets/img/pass.png" ng-switch-when="caseTwo"/>
<img ng-switch-when="caseThree" src="assets/img/fail.png"/>
</td>
Here is a working demo: http://plnkr.co/edit/zUdkJYfnlJul6HsyCGfZ
I'll go ahead and suggest a couple more solutions that don't use a switch that might be a little nicer. Check out the last two td's
<tr ng-repeat="data in myData">
<td>{{data.text}}</td>
<td>{{data.other}}</td>
<td>
<img src='assets/img/{{data.V}}.png' /> <!-- assuming you have an image with name caseOne.png/caseTwo.png/etc -->
</td>
<td>
<img src='{{passFail[data.V]}}' /> <!-- transform the case stuff to pass/fail based on some business rules, this is an object but could be a function-->
</td>
</tr>
$scope.passFail = {
'caseOne' : 'assets/img/pass.png',
'caseTwo' : 'assets/img/pass.png',
'caseThree' : 'assets/img/fail.png'
};

An add-on to the above answer
Incase if there is just plain text inside td like switch casing user roles or something, you can add a span tag inside the td to contain the text
<td ng-switch="role">
<span ng-switch-when="1">Administrator</span>
<span ng-switch-when="2">Moderator</span>
</td>

Related

HTML javascript: expanding function changes the level relationship incorrectly

The problem is explained in the picture below. Once clicking the expanding function of "Parameter 1", the level of "Parameter 2" will change as seen in the middle picture. But actually it should remain in the same level.
Any suggestion is highly appreciated. Thanks in advance.
JAVASript
$('.P1').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).closest('tr').nextUntil('tr:has(.P2)').slideToggle(100, function() {});
});
$('.Sub-parameter-1').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).closest('tr').nextUntil('tr:has(.Sub-parameter-2)').slideToggle(100, function() {});
});
HTML
<table width="200" border="1">
<tr>
<td rowspan="6">Summary </td>
<td colspan="3">
<div align="center">1 st level</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="P1"><span>-</span>Parameter 1</div>
</td>
</tr>
<tr>
<td rowspan="3">L1</td>
<td colspan="2"><div class="Sub-parameter-1"><span>-</span>Sub parameter (1)</div></td>
</tr>
<tr>
<td>L2</td>
<td>description</td>
</tr>
<tr>
<td colspan="2"><div class="Sub-parameter-2"><span>-</span>Sub parameter (2)</td>
</tr>
<tr>
<td colspan="3">
<div class="P2">Parameter 2</div>
</td>
</tr>
</table>
JSFiddle: https://jsfiddle.net/gft08cmb/4/
EDIT based on answer
When applying the answer to more than 1 row of sub parameter, then the "Parameter 2" still changes its level seen in following link.
https://jsfiddle.net/gka7312L/ or https://jsfiddle.net/p2a2wxfv/1/
Your rowspan attribute in L1 is making problems since it should change from 3 to 2 and back in your case.
This works as you would want I think: https://jsfiddle.net/gft08cmb/6/
You should of course make it dynamic if your data is going to be dynamic also.
So probably a count of rows etc. and then manipulate based on this.
Let me know if you need further help.

ng-repeat inside ng-repeat creates empty td element - Angular

I've a little odd problem when using two ng-repeat for objects which contain arrays. Here is the Angular HTML-Code:
<tr data-ng-repeat="reqs in requirements | orderBy:['categoryOrder','order']">
<td>
<strong>{{reqs.category}}</strong>
</td>
<td data-ng-repeat="values in reqs.values | orderBy:'showOrder'">
<div data-ng-repeat="(key,value) in values">{{value}}</div>
<td>
</tr>
The table will be displayed fine and the data also looks fine. My only problem is, that after each tr an empy td element will be insert without any class and I can't get rid of it. Here is the outputted HTML:
<tr class="ng-scope" data-ng-repeat="reqs in requirements | orderBy:['categoryOrder','order']">
<td>
<strong class="ng-binding">Foobar</strong>
</td>
<td class="ng-scope" data-ng-repeat="values in reqs.values | orderBy:'showOrder'">
<td class="ng-scope" data-ng-repeat="values in reqs.values | orderBy:'showOrder'">
<td class="ng-scope" data-ng-repeat="values in reqs.values | orderBy:'showOrder'">
<td> </td>
</tr>
Does anyone else has experienced this kind of odd behaviour? The td element is completely empty and doesn't even has a class attribute assigned to it. Here is the object I'm using:
category: "Foobar"
categoryOrder: 10
description: "Some desc"
id: 2
order: 10
shortName: "SM-01"
values: [
0: {Foo: "Bar", showOrder: 1},
1: {Bar: "Foo", showOrder: 2},
2: {Meh: "Mah", showOrder: 3}
]
I'm using AngularJS 1.3.0. Any help is appreciated, as this is driving me nuts :).
Ares
missing closing tag <td> instead of </td>
don't worry.. we've all been there
You arent closing your td in your second td

How to make a custom HTML id by evaluating an expression

I try to make a version of "tic tac toe" with AngularJS and be as minimalistic as possible. The only solution for my problem is to assign every button a unique ID (f+i).
HTML
<table>
<tr ng-repeat="f in [5,10,15]">
<!-- numbers chosen for unique combos-->
<td ng-repeat="i in [0,1,2]">
<button ng-click="toTrue()" >
<div >
{{getXO()}}
</div>
</button>
</td>
</tr>
</table>
JavaScript
$scope.XObool=false;
$scope.toTrue = function() {
if(!$scope.XObool){
$scope.XObool=true;
}
else if($scope.XObool) {
$scope.XObool=false;
}
};
$scope.getXO = function(){
if($scope.XObool){
return 'X';
}
else {
return 'O';
}
};
ng-repeat gives you several variables to work with, namely $index. In your case you'll want something like:
<button id="{{$index}}" ...>
More info on the ng-repeat docs.
Second Option
Use the f and i variables to create unique IDs.
<table ng-app>
<tr ng-repeat="f in [5,10,15]" data-id="{{$index}}">
<td ng-repeat="i in [0,1,2]">
<button id={{'id' + (i+f)}} ng-click="toTrue()">
{{'id'+(i+f)}}
</button>
</td>
</tr>
</table>
Here's a demo.
You don't need to assign each button a unique ID.
Instead, you can pass your f and i variables into your functions to track the board state:
<table>
<tr ng-repeat="f in [0,1,2]">
<!-- numbers chosen for unique combos-->
<td ng-repeat="i in [0,1,2]">
<button ng-click="setState(f, i)">
<div >
{{ getXO(f,i) }}
</div>
</button>
</td>
</tr>
</table>
Working fiddle here: http://jsfiddle.net/m76w3kf5/
try markup binding with {{}} or $index
<div id="{{someObject.id}}" class="some-class" ng-repeat="f in [ array ]">
..
</div>
or a slightly extended example with $index, listing thumbnails in array with clicks to reference position by index
<tr ng-repeat="array in thumbnails track by $index">
<td ng-repeat="object in array track by object.id"
ng-click="tableClickHandler($index, object)">
<img class="user-thumbnail" src="{{object.src}}">
</td>
</tr>

jQuery sort in div - complicated

I have a div called #usersInRoom which is the placeholder for the inner divs.
Currently i have 2 rows /2 entries in the div.
But my question is, how can i via. jQuery update the entries to sort by "exp"?
Now it shows "Stefanie" first with "6" exp. And Bare Kald Mig Jesper with 14 exp. last.
How can i sort it, so it outputs the entries with highest exp first?
<div id="usersInRoom">
<div class="entry in_room" id="userInRoom-2" style="background-color: rgb(255, 255, 255);">
<table style="width:100%">
<tbody>
<tr>
<td style="width:32px">
<img src="https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn1/c33.33.414.414/s200x200/996882_221295918024677_1913237122_n.jpg" style="height:32px;width:32px">
</td>
<td style="vertical-align:middle"><strong>Stefanie Pedersen</strong>
</td>
<td align="right" style="vertical-align:middle;color:#999"><span id="exp-2">6</span> exp.</td>
</tr>
</tbody>
</table>
</div>
<div class="entry in_room" id="userInRoom-1" style="background-color: rgb(155, 229, 162);">
<table style="width:100%">
<tbody>
<tr>
<td style="width:32px">
<img src="https://fbcdn-profile-a.akamaihd.net/hprofile-ak-frc1/c176.49.608.608/s200x200/429356_10151257167066983_1091687280_n.jpg" style="height:32px;width:32px">
</td>
<td style="vertical-align:middle"><strong>Bare Kald Mig Jesper</strong>
</td>
<td align="right" style="vertical-align:middle;color:#999"><span id="exp-1">14</span> exp.</td>
</tr>
</tbody>
</table>
</div>
</div>
If you are showing the values from database ,you can sort using sql ORDER BY 'exp' ASC or DESC in the query in backend to populate reults.then you can get sorted results in the first place.
OR
if you want to sort it on the client side,then try using jueery data tables .
for example
https://datatables.net/release-datatables/examples/basic_init/zero_config.html
You can do this with current code using jquery in this way:
First add a class to the experience span.
<span id="exp-2" class="exp">6</span>
And then the jquery:
arr=$("#usersInRoom").find(".exp");
And now to select the parent div:
$(arr[i]).parents(".entry_in_room")
Sorting could be done by accessing text of the elements.
$(arr[i]).text()
But Ideally, why do you require such nesting? The data could be easily handled within a Table element. There's no no need of separate tables. And if you use a single table, there are many jquery plugins available for that.

Change the css class associated with a <TD> column based on value of column with javascript

I have a grid and for one of the columns i want to dynamically change the css used based on the value of another field in the resultset.
So instead of something like
<td class='class1'>
${firstname}
</td>
pseudo-wise I would like
{{if anotherColumnIsTrue }}
<td class='class1'>
${firstname}
</td>
{{/if}}
{{if !anotherColumnIsTrue }}
<td class='class2'>
${firstname}
</td>
{{/if}}
Is this thing possible..?
I think that jQuery makes this a lot easier.
It is very possible. I assume that you would want this for each row. Lets assume you have the following table:
<table id="coolTable">
<tr>
<td class="anotherColumn">True</td>
<td class="firstName">Chris</td>
</tr>
<tr>
<td class="anotherColumn">False</td>
<td class="firstName">Roger</td>
</tr>
</table>
You could go through rows and selectively add classes using the following code:
$(function(){
$("#coolTable tr").each(function(i,row){
if($(row).children("td.anotherColumn").html()=="True") // Any condition here
{
$(row).children("td.firstName").addClass("class1");
}else{
$(row).children("td.firstName").addClass("class2");
}
});
});
Have a look at this fiddle: http://jsfiddle.net/mrfunnel/LXq3w/2/

Categories