Ng-repeat over multi-dimensional array - javascript

localStorage is an object where the multi-dimensional array I want to iterate on (localStorage.add) is stored along with other arrays.
<tr ng-repeat = "(key, value) in localStorage track by $index" ng-if = "localStorage.add.length > $index || localStorage.subject.length > $index || localStorage.emailContent > $index" >
<td>
<input type="checkbox" ng-checked="checkAllEmail" ng-model="selectedEmail"/>
<a href="#">
<span class="glyphicon glyphicon-star-empty"></span>
</a>
</td>
<td >
{{localStorage.add[$index]}}
<td>
<td >
{{localStorage.subject[$index]}}
<td>
<td >
{{localStorage.emailContent[$index]}}
<td>
</tr>
This is the localStorage.add array - [["Elizabeth","Caroline"],["Patricia"],["Madhu"]].
{{localStorage.add[$index]}} displays
["Elizabeth","Caroline"]
["Patricia"]
["Madhu"]
I want only the values within the array to be displayed. So, for example, {{localStorage.add[1][0]}} displays "Patricia" and not ["Patricia"]. Does anyone have ideas on how to implement this? I tried {{localStorage.add[$index][$index]}}, it displays only Elizabeth ({{localStorage.add[0][0]}}) and not ["Elizabeth"]. So, I am looking for something similar to {{localStorage.add[$index][$index]}} that works for all the elements in the array.
Just to avoid confusion, my app is working as desired. I just don't want the user to see that I am storing these values in an array. This is what the final output should look like:
Elizabeth,Caroline
Patricia
Madhu

You need to convert the array to string, so in your controller, make a function that your view can call and get a returned string, such as:
<tr ng-repeat = "(key, value) in localStorage track by $index" ng-if = "localStorage.add.length > $index || localStorage.subject.length > $index || localStorage.emailContent > $index" >
<td>
<input type="checkbox" ng-checked="checkAllEmail" ng-model="selectedEmail"/>
<a href="#">
<span class="glyphicon glyphicon-star-empty"></span>
</a>
</td>
<td>
{{getNames(localStorage.add[$index])}}
<td>
<td >
{{localStorage.subject[$index]}}
<td>
<td >
{{localStorage.emailContent[$index]}}
<td>
</tr>
This will be in your controller, and you can alter delimiter as needed
$scope.getNames = function(names){
return names.join(',')
}
You could probably do this directly in the view like this:
localStorage.add[$index].join(',')
but I don't recommend it, if it works (not sure)

Related

Apply additional filter only to one element of ng-repeat

I am working on an existing AngularJS project. I have an object with key, values which displayed on the page.
All keys should be with a capitalized first letter, so I apply a filter. But if the key == 'sku' then I need to make all letters to be capital.
Could you advise how can I do that?
Thank you
HTML
<tr
class="product-characteristics"
ng-repeat="(prop, val) in $ctrl.product.additional_properties"
>
<td class="name">
{{prop | capitalize}}
</td>
<td>
<a ng-click="$ctrl.propertyClicked(prop, val)">{{val| titleCase}}</a>
</td>
</tr>
The easiest way would be to create separate condition for this case.
<td class="name" ng-if="prop === 'sku'">
{{ prop | uppercase }}
</td>
<td class="name" ng-if="prop !== 'sku'">
{{ prop | capitalize }}
</td>
But in the future you may want to extend this solution, therefore better soultion (and much more readable) would be to use switch-case option.
<td class="name" ng-switch="prop">
<span ng-switch-when="sku">{{ prop | uppercase }}</span>
<span ng-switch-default>{{ prop | capitalize }}</span>
</td>

Loop for object n HTML

My code is quite simple. I only want to add John and Marie to my table.
Works great but my issue is if there is no John and Marie I want to create a row and show a - in my td.
How do I know if there was not added any row when the ng-repeat ends?
<tr class="text-center" ng-if="name == 'John' || name == 'Marie'" ng-repeat="name in vm.names track by $index">
<td>{{name}}</td>
</tr>
Use the ng-switch directive:
<tr class="text-center" ng-switch"name" ng-repeat="name in vm.names track by $index">
<td ng-switch-when="John">{{name}}</td>
<td ng-switch-when="Marie">{{name}}</td>
<td ng-switch-when="Paul">{{name}}</td>
<td ng-switch-default>-</td>
</tr>
You could map your original object in the controller with something like this:
this.names = this.names.map(name => {
name ? name : '-';
})

How to compare for two different objects inside ng-repeat

What is the best way to compare two different objects for equality inside of ng-repeat, why doesn't angular.equals work for me here:
<tr ng-repeat="row in ctrl.filteredItems" ng-class="{'active':angular.equals(row,ctrl.ngModel), 'focus': angular.equals(row,ctrl.focusedRow)}">
<td ng-repeat="value in ctrl.sort(row) track by $index" class="text-center">
{{value}}
</td>
</tr>
I want to add the active class if the current row and the pre-selected row coming from the controller match.
Write a function in JS which will do angular.equals(obj1, obj2) and use this function to check is it active or not?
HTML
<tr ng-repeat="row in ctrl.filteredItems" ng-class="{'active': checkEqualiy(row, ctrl.ngModel), 'focus': checkEquality(row,ctrl.focusedRow)}">
<td ng-repeat="value in ctrl.sort(row) track by $index" class="text-center">
{{value}}
</td>
</tr>
JS
$scope.checkEquality= function(param1, param2){
return angular.equals(param1, param2)
}

Using ng-repeat in table format

I have the following array in my module in Angular.js:
$scope.hsbody = []; //Data array
$scope.hsresult = []; //Data array
$scope.hsProcess = []; //Boolean array
$scope.hssuccess = []; //Boolean array
$scope.hsfailure = []; //Boolean array
$scope.hsExpand = []; //Boolean array
$scope.hsExpandUser = []; //Boolean array
I want to show the array items in my Html page:
hsresult
hsbody
hsresult
hsbody
and so on..
So I do the following:
<div>
<pre>
<table class="table table-condensed">
<tr ng-repeat="hs in hsbody track by $i" ng-show="hsProcess[i] && !hssuccess[i] && !hsfailure[i]" class="warning"><td><div class="glyphicon"></div>{{hsbody}}</td></tr>
<tr ng-show="hssuccess" ng-repeat="highstate in hsbody track by $i" class="success"><td><div class="glyphicon" ng-show="!hsExpand[i]"></div><div class="glyphicon" ng-show="hsExpand[i]"></div>{{ hsresult[i] }} </td></tr>
<tr ng-show="hsfailure" ng-repeat="hs in hsbody track by $i" class="danger"><td><div class="glyphicon" ng-show="!hsExpand"></div><div class="glyphicon" ng-show="hsExpand[i]"></div>{{ hsresult[i] }}</td></tr>
<tr ng-repeat="hs in hsbody track by $i" ng-show="(hsProcess[i] && hsExpand[i]) || (hsExpand[i] && hsfailure[i])" class="active"><td><pre>{{ hsbody[i] }}</pre></td></tr>
</table>
</pre>
</div>
The problem is that nothing is shown in my HTML. but when I get rid of the ng-repeat and use i=0, then I can see the values.
It seems that I don't use the ng-repeat correctly, but I don't know where I wrong.
Inside anything with 'ng-repeat' you'll have to reference everything through whatever you specified in the ng-repeat.
e.g. say you had an array, 'main', in the controller 'data'.
You have usernames in objects within data.main
$scope.main = [
{username: 'jeff'},
{username: 'brad'},
]
or
this.main = [
{username: 'jeff'},
{username: 'brad'},
]
If you wrote
<div ng-repeat="theData in data.main track by $i">
{{ data.main.username }}
</div>
an error would come up, because it's undefined.
If you wrote
<div ng-repeat="theData in data.main track by $i">
{{ theData.username }}
</div>
you would get what you wanted.
The reason is that you are specifying theData as the source of everything inside the ng-repeat.
theData is equivalent to data.main, for inside the ng-repeat
You can't access anything outside the object data.main inside the div.
If you need anything from outside, think again. Do you really want that data printed however many times?
if you want to use the "track by" with index, you should write there: "track by $index".
good luck!
this works for you?
<div>
<pre>
<table class="table table-condensed">
<tr ng-repeat="hs in hsbody track by $index" ng-show="hsProcess[$index] && !hssuccess[$index] && !hsfailure[$index]" class="warning">
<td>
<div class="glyphicon"></div>{{hs}}
</td>
</tr>
<tr ng-show="hssuccess" ng-repeat="highstate in hsbody track by $index" class="success">
<td>
<div class="glyphicon" ng-show="!hsExpand[i]"></div>
<div class="glyphicon" ng-show="hsExpand[$index]"></div>{{ hsresult[$index] }}
</td>
</tr>
<tr ng-show="hsfailure" ng-repeat="hs in hsbody track by $index" class="danger">
<td>
<div class="glyphicon" ng-show="!hsExpand"></div>
<div class="glyphicon" ng-show="hsExpand[i]"></div>{{ hsresult[$index] }}
</td>
</tr>
<tr ng-repeat="hs in hsbody track by $index" ng-show="(hsProcess[$index] && hsExpand[$index]) || (hsExpand[$index] && hsfailure[$index])" class="active">
<td>
<pre>{{ hsbody[$index] }}</pre>
</td>
</tr>
</table>
</pre>
</div>

meteorjs handlebar customise condition

How can I create simple conditional handlebar?
What I want to do is get from collections that if mood =='+', render the roll in white, else render some other color.
This is HTML:
{{#if moodIsPlus}}
<tr>
<td>
<strong>{{mood}} <i class="icon-hand-up" value="+"></i></strong> {{message}}<br>
</td>
</tr>
{{else}}
<tr class="info">
<td>
<strong>{{mood}} </strong> {{message}}<br>
</td>
</tr>
{{/if }}
which moodIsPlus is define in JS:
Template.messages.moodIsPlus = function() {
return Messages.find({mood:'+'});
}
and it returns everything.
By the way, are handlebars and handlebar.js the same thing? Where can I get more reference on handlebar in meteorjs?
Checkout the Meteor Smart Package Handlebar-helpers as it comes with lots of similar helpers.
Here is how you would achieve what you are looking for with it:
<tr>
<td>
<strong>{{#if $eq mood '+'}}<i class="icon-hand-up" value="+"></i>{{/if}}</strong> {{message}}<br>
</td>
</tr>
You can used spacebar or handlebar(old) function to accomplish this.
First is get all messages. You can put it inside Template helpers like this:
Messages.helpers({
messages: function(){
return Messages.find({});
},
moodIsPlus: function(mood){
return (mood === "+") ? true : false; // return true if mood === "+"
}
});
Then, in your template.
{{#if moodIsPlus mood}} mood is from your Messages collection. that contains "+" or whatever.
<tr>
<td>
<strong>{{mood}} <i class="icon-hand-up" value="+"></i></strong> {{message}}<br>
</td>
</tr>
{{else}}
<tr class="info">
<td>
<strong>{{mood}} </strong> {{message}}<br>
</td>
</tr>
{{/if }}
Hope this help.

Categories

Resources