How can I use ng-bind-html as an element? - angularjs

For an Angular 1.2 project, I'd like to render a subset of <td>s inside of a table row using ng-bind-html in order to reduce the number of watchers. I cannot easily render all <td>s this way because some of them have ng-clicks, ng-if's and ng-classes attached to them.
Currently the ng-bind-html element is rendered as td children elements of the <td> that it's called in. However, ng-bind-html cannot be called as an element (must be an attribute).
Any ideas on how to approach this? (I've been looking at some jquery but I'm pretty new to that area).
<tr>
<td><span>{{entry.name}}</span></td>
<td ng-bind-html="generateStaticHtmlColumns(entry.data)"></td>
<td>{{entry.address | number}}</td>
<td ng-if='!entry.loading' tooltip position="bottom">{{entry.phone | number}}</td>
</tr>
Essentially, I'd like the <td> calling using ng-bind-html to be replaced with the "td"s it's returning rather than appending them as children.

Related

ReactJS: Is it possible to change my 'data-target' attribute dynamically? rather then individually setting them?

Basically I'm creating a bootstrap table in my react project and am using an accordion toggle to contain the excess info in a dropdown. As of now when i click the dropdown all of the dropdowns open, so i'm trying to set the data-target attribute (currently set to #demo1) and the id attribute to change dynamically in order to give me better control over which drop down is open and when.
I'm using React and bootstrap and am still fairly new :S
I tried setting data-target to a unique ID {item._id} which is the same as the key, but nothing happens i presume it's because i don't have the # in front of it, but it would error out if i add it to the front of the expression.
<tr
key={item._id}
className="accordion-toggle"
data-toggle="collapse"
data-target="#demo1"
>
{...}
</tr>
<tr>
<td colSpan="6" className="hiddenRow">
<div className="accordion-body collapse" id="demo1">
<table className="table table-dark">
</table>
</div>
</td>
</tr>
I would probably do this by tracking the state of all Dropdowns (open vs closed) in the parent component in an array, and passing it to the child component as a boolean prop such as 'isOpen'.
If there is more to it, perhaps you can attach a screenshot of what you are trying to do?

Change display text based upon value

I am displaying Errors on my Html page using Angular JS. The problem is I am receiving only error codes from the HTML . What are the various ways in which i can change the error code to the the Error text i like
<table>
<tr ng-repeat='item in errorsd'>
<td align="left" class="validationMsg"> {{item.message}}</td></tr>
</table>
If my item.message has one . I would like to display Beginner ,if its 2 Intermediate like that and so on . Should i use ng-if ? should i use ng-switch or should i input some logic on the controller side .
Should i use ng-if ?
ng-switch is more readable and hence a better option. Later when you look back at the code it will be intuitive to you and other developers about what this code does.
should i input some logic on the controller side .
Why put a logic in controller-side if the framework already provides a solution for such use-case?
I would do it like:
<table>
<tr ng-repeat='item in errorsd'>
<td ng-switch="item.message" align="left" class="validationMsg">
<span ng-switch-when="1">Beginner</span>
<span ng-switch-when="2">Intermediate</span>
<!-- and so on.. -->
</td>
</tr>
</table>
I say use a switch statement inside of your controller.
So depending on the value, the global message would change thus displaying the correct one when triggering the validation msg box to show.

AngularJs - Dynamic rows in table

I have two table, table 1 and table 2.. Table 1 has a field count. based on the count value(count value= no of rows populated), rows should be automatically populated in table 2. I am new to angularjs. Please let me know how can acheive this
To render values in your table you can use ng-repeat directive.
You can use things such the ngIf, ngShow and ngHide directive to hide or show DOM objects based on an expression, or use ngRepeat to dynamically add additional DOM object based on a growing or shrinking array in your controller.
My guess is you're looking for an visibility directive, so I think the following might help:
<table id="table1">
<tr data-ng-repeat="row in table1">
<td>{{row.someData}}</td>
</tr>
</table>
<table id="table2" data-ng-show="table1.length == 0">
<tr data-ng-repeat="row in table2">
<td>{{row.someData}}</td>
</tr>
</table>
Note that both tables are filled with an ngRepeat by using corresponding arrays from your controller as a source. On the second table, you can see an ngShow directive with an expression that says: "if table1 is empty, show me".
I hope this helps.

Angular JS Nested ng-repeat for bootstrap badges

Im trying to tag different video items in a bootstrap table. I'm already using an ng-repeat to loop over the array of objects which store video data. I'm now trying to create a nested ng-repeat to loop over another array of "tags" within the ng-repeat that creates each table row.
I'm getting some weird results though. I was hoping that I could just put an ng-repeat on the td and then put the angular expression in a span with the boostrap class "badge". Any thoughts as to whats going wrong?
http://jsfiddle.net/jheimpel/6nh100ca/
<tr ng-repeat="topic in topics">
<td><a ng-href="#/{{topic.url}}"><i class="fa fa-play"></i></a></td>
<td>{{topic.topic}}</td>
<td>{{topic.date}}</td>
<td>{{topic.presenter}}</td>
<td ng-repeat="tag in topic.tags">
<span class="badge">{{topic.tags}}</span>
</td>
</tr>
Change it to
<span class="badge" ng-bind="tag"></span>
You're telling it to print out the array you're ng-repeating instead of the object the ng-repeat is giving you. Also ng-bind is better, see this

Angular.js - Why one root restriction with replace and how to get around it?

Any Angular.js savvy person probably knows about this ...
Angular.js Root Error
My question is why and how do i get around this. When using tables it is not always possible to group the contents of your directive into a single parent element. So how do I get around this. I know ng-repeat does replace single elements with multiple, with out a parent wrapper, so it must be possible. What's the simplest way?
-- UPDATE --
Have ...
<td class="text-right">{{dsfgsdf.sdfgdsf.dsfg}}</td>
<td class="text-center">dsfgsdfg</td>
<td class="text-right">1500.00</td>
<td class="text-right">0.00</td>
<td class="text-right">2.51</td>
<td class="text-right">1502.51</td>
<td class="text-right">0.00</td>
<td class="text-center">-</td>
<td class="text-right">-1502.51</td>
<td class="text-right">-1502.51</td>
<td class="text-center">11/01/2013</td>
<td class="text-center">{{sdfg.sdfg}}</td>
<td class="text-center">{{sdfg.sdfg}} - {{dfg.sdfg}}</td>
<td class="text-left">sdfgdsfg</td>
Want to add a directive ...
<td class="text-right">{{dsfgsdf.sdfgdsf.dsfg}}</td>
<td detailsDirective></td>
<td class="text-center">{{sdfg.sdfg}}</td>
<td class="text-center">{{sdfg.sdfg}} - {{dfg.sdfg}}</td>
<td class="text-left">sdfgdsfg</td>
To answer the general question of why angular directive templates are restricted to one root array, I'll refer to this text in the link to the error:
When a directive is declared with template (or templateUrl) and
replace mode on, the template must have exactly one root element. That
is, the text of the template property or the content referenced by the
templateUrl must be contained within a single html element. For
example, <p>blah <em>blah</em> blah</p> instead of simply blah
<em>blah</em> blah. Otherwise, the replacement operation would result
in a single element (the directive) being replaced with multiple
elements or nodes, which is unsupported and not commonly needed in
practice.
Angular, in it's compile/link phases, needs to assign a hierarchical scope tree that corresponds to the DOM tree. So, angular needs a single DOM element to hang a new scope for the directive off of. That is essentially a limitation with how angular works. Therefore, the comment above that anything else is unsupported.
The single-root rule shouldn't make problems. If you don't want a wrapping element (span, for example) inside your TD, you can use "replace:true" with your detailsDirective
directive('detailsDirective', function() {
return {
replace: true,
template: '<td></td>', // wrapper
Also, See the transclude option, it can resolve your problem as well.
Otherwise, post here your directive's code.

Resources