repeating a template with ng-repeat - angularjs

I have a template here that I want to repeat based on my $scope.dataset.
How do I get ng-repeat to repeat this template for each name?
HTML I have my template as follows
<table>
<tr ng-repeat = "data in dataset">
<td>{{data.name}}</td>
<td>
<div class="progressbar {{data.color}}" ng-style="{width:{{data.width}} + '%'}"
value = "{{data.value}}">
<span id="barValue">{{data.value}}</span>
</div>
</td>
</tr>
</table>
and as you can see, I'm trying to repeat this template inside the table.
dataset is as follows
$scope.dataset=[
{'name':'name1', 'value':34, 'width':34, 'color':'colorRed'},
{'name':'name2', 'value':50, 'width':50, 'color':'colorBlue'},
{'name':'name3', 'value':47, 'width':47, 'color':'colorRed'},
{'name':'name4', 'value':82, 'width':82, 'color':'colorBlue'},
{'name':'name5', 'value':72, 'width':72, 'color':'colorOrange'},
{'name':'name6', 'value':17, 'width':17, 'color':'colorGreen'},
{'name':'name7', 'value':20, 'width':20, 'color':'colorRed'},
]
When I try to use this, nothing pops up.
All I want is for the data to appear for each .name that comes up.
So first question is what am I doing wrong?
Second, is it possible to do all this in a custom directive?

You must be getting $parse error in your console as you are using
{{}} in ng-style
You shouldn't use {{}} interpolation directive inside ng-style directive.
color should be applied as style instead of adding class, you could be applied from ng-style directive.
HTML
<div class="progressbar" ng-style="{width:data.width + '%', color: data.color}"
value = "{{data.value}}">
<span id="barValue">{{data.value}}</span>
</div>

Related

Display models of text-angulars

I'm displaying two text-angular WYSIWYG fields in ng-repeat like so
<div data-ng-repeat="n in langInput.values" class="sell__description-container">
<h2 class="sell__heading-secondary">
Opis w języku: {{ n.selected }}
</h2>
<div text-angular="text-angular"
name="htmlcontent_{{n.id}}_{{ n.selected }}"
data-ng-model="descriptionHtml[$index]"
class="sell__text-editor"
required>
</div>
{{ descriptionHtml[$index] }}
And just below field I'm showing its model and it's working correctly. It shows text with all this tags which I chose in editor.
But 200 lines below I have something like summary and I want to display this model one more time in other ng-repeat loop:
<tr data-ng-repeat="n in langInput.values">
<td>Opis ({{ n.selected }})</td>
<td>
{{ descriptionHtml[$index] }}
<br>
{{ $index }}
</td>
</tr>
And here it is not showing description value. Althought $index is indeed 0 and 1 like above.. Why is that? How to fix?
At the moment I just want to make it work. Later on I'll not display it as a string in td but I'll pass this model as a string to function which will open bootstrap modal window in which I'll bind this string as html with ng-bind-html so it will be something like preview.
I found problem. I copied code from textangular docs and it has its own controller so my controller structure was like
<div ng-controller="external">
<div ng-controller="textEditor">
here i have ng-repeat and here i'm also displaying content of editor
</div>
here i tried to ng-repeat over it again
</div>
So in textEditor ctrl it was in right scope and it display correctly. I need to pass this value from child scope(textEditor) to parent scope(external).
Declaring $scope.descriptionHtml in parent controller solve the issue since child controller inherit scope and when I modify it in child then also parent is refreshed.

Angular if condition from value of ng-repeat

I'm rendering data in a table using Angular and ng-repeat. What I would like to do is add an if condition to say if the value contained in ng-repeat is a certain word, set the background colour of that row to red. I think it might look something like this, but I'm not sure how to do this in Angular.
if( {{field.value}} == THING){
var backgroundColour = red;
}
I was thinking of using ng-filter, although I dont wan't to actually filter the data, just set a variable based on a value.
Any ideas?
You could add an ng-class in the html to achieve this.
<div ng-repeat"field in fields" ng-class="{'with-background': field.value == THING}">
{{field.value}}
</div>
And then add with-background to css
.with-background {
background-color: red;
}
If THING is a variable pointing to some other value, you don't have to use quotes and if it's meant to be a string, use it as 'THING'
Here's the official documentation of ngClass: https://docs.angularjs.org/api/ng/directive/ngClass
You cann also use ng-style for this
<div ng-style="field.value == THING?{'background-color':'red'}:{}">
Hello Plunker!
</div>
plunker
You could do something like this below:
<div ng-repeat="field in collections"
ng-if="field.value && field.value =='THING'">
{{backgroundcolor}}
</div>
Or you could you use ng-class directive
<div id="wrap" ng-class="{true: 'yourClassName'}[field.value]">
You can use ng-class directive
<tr ng-class="{'color-red': item.value > 0}" ng-repeat="item in vm.items">
<td>{{ item.value }}>/td>
</tr>

Ng-click does not work outside of my tr tag AngularJS

I am working on an app and I cant seem to figure out why my ng-click only works inside of my (single) tr tag but as soon as I put it into another tr tag it stop working. Keep in mind it was working before I used the ng-repeat within the first tr tag. Here is what my code looks like, any advice would greatly help!
<table>
<tbody>
<tr>
<td ng-click="commentOpen = !commentOpen">
<div class="iconsize">Comment Closed</div>
</td>
<td ng-click="switchOpen = !switchOpen">
<div class="iconsize">Switch Closed</div>
</td>
</tr>
<tr>
<td>
<div ng-show="commentOpen == true">
<textarea>Comment Open</textarea>
</div>
<div ng-show="switchOpen == true">
<p>Switch On</p>
</div>
</td>
</tr>
</tbody>
</table>
I had the ng-repeat on the tag which was causing my ng-click to not fire. I ended up moving my ng-repeat to the tbody and the ng-click and ng-show started working again.
ngRepeat creates new scopes for its children, it just usually seems like it's accessing the same scope because this new scope inherits from its parent.
Meaning, commentOpen is actually referring to a property on the wrong scope.
Below are three potential ways for you to fix this:
1) controller as, and always refer to the controller you're after by name
2) $parent.commentOpen (Don't do this! It becomes very confusing as you nest)
3) Instead of commentOpen and switchOpen, you can use an Object (e.g. $scope.openControls = { comment: false, switch: false }, and then in the td tags you would write something like ng-click='openControls.comment = !openControls.comment'). This way it's passed inherited by reference (where as a boolean would be by value), and keeps synced.

ng-hide or ng-show does not work if its controlled from within a ng-repeat

I am trying to hide the div if any of the buttons in the ng-repeat is clicked. However it doesn't seem to work, it leads me to think if ng-hide or ng-show won't work if it is controlled from within a ng-repeat?
<div data-ng-hide="showChooseHardware">
<table class="table">
<tbody>
<tr data-ng-repeat="hardware in hardwares">
<td>{{hardware.name}}</td>
<td>
<button type="button" class="btn" data-ng-click="showChooseHardware=!showChooseHardware"/>
</td>
</tr>
</tbody>
</table>
</div>
This is due to the fact that ng-repeat creates a new scope for each template and due to how prototypal inheritance works in JavaScript (and AngularJS).
Use an object:
$scope.viewModel = { showChooseHardware: false };
HTML:
data-ng-hide="viewModel.showChooseHardware"
And:
data-ng-click="viewModel.showChooseHardware=!viewModel.showChooseHardware"
A great explanation on the issue can be found here.
I recommend using ng-showinstead in this case since the variable is called showChooseHardware.
ngRepeat directive creates new scope in every iteration,for every item in array.It can make a problem,which you have.

ngIf inside ngRepeat not working inside <table> when controller defined with string

I have an ng-if inside an ng-repeat in a template, and the ng-if is not working, even if I change it to just
ng-if="false"
I can make it work by adding
ng-controller="TemplateController"
to a parent div, however when I do this, my controller cannot receive resolved arguments:
resolve: {
myVar: function() {
return "hello world";
}
}
Unknown provider: myVarProvider <- myVar
if I remove the ng-controller, and add
controller: "TemplateController"
after my resolve:, then myVar is passed successfully, however ng-if no longer works
my HTML:
<table>
<div ng-repeat=“row in rows"><tr>
<span ng-if=“row.active==1">
<td>{{row.data}}</td>
<td></td>
<td>{{ row.date | date:"MM/dd/yyyy"}}</td>
<td>
<a href=“stuff”>click me</a>
</td>
</span>
<span ng-if=“row.active > 1">
<td>{{row.otherData}}</td>
<td>{{row.str}}</td>
<td>{{ row.date | date:"MM/dd/yyyy"}}</td>
<td>
<a href=“stuff”>click me instead</a>
</td>
</span></tr>
</div>
</table>
right now, I get a whole bunch of blank cells, and both 'click me' links.
if I remove the tags, it works, but it's not in a table
moreover, not only is the ng-if not working, but any variables I reference inside {{}} are being replaced with blanks (but they also work if is removed)
jsFiddle: http://jsfiddle.net/Mh2UH/1/
The golden rule to avoid this problem is
Always have a dot in your angular bindings
ng-if="false"
Does not have a dot. Therefore the value false is being passed to the scope of the ng-if but can't be updated, since false is an immutable boolean value.
The correct way,
ng-if=status.enabled
Where status is an object.

Resources