ng-if only deletes innerHTML in my table - javascript

I am making a custom directive which will paginate and make my table sortable. I am trying to make it so that multiple data types will work with the sorting with no effort from the user. Here is my problematic html in my templateUrl:
<tr ng-repeat="row in cndPaginatedObject track by $index">
<td ng-repeat="data in row track by $index" ng-if="!isValidDate(row[cndTableHeaders[$index]])">
{{row[cndTableHeaders[$index]]}}
</td>
<td ng-repeat="data in row track by $index" ng-if="isValidDate(row[cndTableHeaders[$index]])">
{{row[cndTableHeaders[$index]] | date: cndDateFormat}}
</td>
</tr>
I would prefer to use ng-if as opposed to ng-show/hide because it would unnecessarily duplicate DOM elements with ng-show/hide and just not show them. I have tried both ways, but I get the same result either way. The content of columns with dates in them don't show up, but the td itself is still there taking up space. So, I end up having three headers for columns and more than three columns. As far as I was aware, ng-if is supposed to remove the entire element from the DOM.
here is my other code of significance:
scope.isValidDate = (data) => {
var timestamp = Date.parse(data);
return !(isNaN(timestamp));
}
As for cndPaginatedObject, it is just an array of objects with multiple strings contained within. Thank you for any help in advance!
UPDATE:
Just thought I would also add that the cndTableHeaders is literally the table headers. cndPaginatedObject uses the table headers as the keys to each of the values. This way they show up in the proper order in the table.

Two ways to do what you're doing better without the need to produce extra doms and looping a ng-repeat twice
A better way to do what you want to do is
<tr ng-repeat="row in cndPaginatedObject track by $index">
<td ng-repeat="data in row track by $index">
{{(!isValidDate(row[cndTableHeaders[$index]])) ? row[cndTableHeaders[$index]] : row[cndTableHeaders[$index]] | date: cndDateFormat}}
</td>
</tr>
Or add a span inside the with the ng-if logic
<tr ng-repeat="row in cndPaginatedObject track by $index">
<td ng-repeat="data in row track by $index"">
<span ng-if="!isValidDate(row[cndTableHeaders[$index]])>
{{row[cndTableHeaders[$index]]}}
</span>
<span ng-if="isValidDate(row[cndTableHeaders[$index]])">
{{row[cndTableHeaders[$index]] | date: cndDateFormat}}
</span>
</td>
</tr>
Alternatively you could create your own filter which checks if date is valid and then using the date filter to filter it.

Related

How do I display an array / object using ng-repeat

I have an array that looks like the following:
I want to display that using angularJS ng-repeat, showing both count and value for each.
This is currently the HTML and angular I have but nothing displays.
I also don't need to display the 0 index in the array, I want to start from 1 if possible.
<tr ng-class="" ng-repeat="x in vm.data | filter: searchArray">
<td>{{x.value}}</td>
<td>{{x.count}}</td>
</tr>
I went back to the basics and understood that an ng-repeat is just a loop in javascript, and what do you need to do if you want to access data in JavaScript if your array is multi-dimensional? well you do a nested for loop, and thats exactly what I'm doing in this case.
This is the updated html/angularjs that displays the data I need:
<tbody>
<tr ng-repeat="x in vm.data">
<td ng-repeat="y in x">{{y.value}} {{y.count}}</td>
</tr>
</tbody>
Thank you guys again!

angular-translate multiple keys in one element

In my application I am pulling translations keys from a single cell in a database table and displaying them dynamically in a setting page. Most will only have one key in the display object but there will be a number of entries that would have multiple.
Is there a way in angular-translate to have one element host multiple keys and translate them?
en.json={"title1":"balance","title2":"other stuff"}
ctrl.list=[{display:"title1 title2"}]
<tbody class="validation-table-body">
<tr ng-repeat="entry in ctrl.list">
<td class="validation-name" >
{{entry.display | translate}}
</td>
</tr>
</tbody>
displayed:
<td>title1 title2</td>
expected:
<td>balance other stuff</td>
I am just trying to get this to work before trying to add a comma or something to display.
This is possible in the translate directive at least:
<ANY translate="{{toBeInterpolated}}"></ANY>
toBeInterpolated is the name of the key to be looked up.
Ref:https://angular-translate.github.io/docs/#/guide/05_using-translate-directive

AngularJS filter on multiple deep nested properties

I've couple of select fields on basis of which I want to filter data. Here is working plukr: http://plnkr.co/edit/VUnAoL2Sl0IqGcZqHbbi?p=preview
If I select any one value from select, it works fine, but when I select the other one it don't show any data.
These filters are going to be dynamic (depending on number of columns) So I want that in HTML I could use it with single filter declaration like: <tr ng-repeat="row in data | filter:{columns: filt}">
Not like: <tr ng-repeat="row in data | filter:{columns: filt.something} | filter: {some: thing}">
<tr ng-repeat="row in _data = (data | filter:{columns: {dealType:filt.dealType}}) | filter:{columns:{primaryUse:filt.primaryUse}}">
<td ng-repeat="column in row.columns">
{{column[column.header]}}
</td>
</tr>
I have got the same issue and it worked with a change in your code as above. Thanks

AngularJS nested ng-repeats with nested bindings

I am trying to make an entirely dynamic angularJS page in such a way that the data-model and header-column-model can be passed in as JSON format and the angular/view can decode everything no matter how many columns, etc.
I have everything (Column Headers, single-Column sorting, multi-Column textbox filtering) working except the data portion where it looks like I want to nest {{bindings}}.
The idea is something like this:
<tr ng-repeat="item in model | filter:filters | orderBy:predicate:reverse">
<td ng-repeat="header in headers">{{{{$parent.item}}.{{header.colName}}}}</td>
</tr>
So that it would resolve to item.column (which is how this is done normally/statically).
However, there doesn't seem to be any embedding/nesting allowed for the double-squiggle references; aka. the first '{{' matches with the first '}}' automatically.
Is there a [good] way to do this?
Try using $eval:
<tr ng-repeat="item in model | filter:filters | orderBy:predicate:reverse">
<td ng-repeat="header in headers">{{$eval('item.' + header.colName}}</td>
</tr>
Here is a plunker showing that concept:
http://plnkr.co/edit/msGuMCCj477jyUAqjChz?p=preview

Get key values and create a table header

I have an angularjs application that basically takes JSON and creates a HTML table, with the keys in the <thead> and the values as table rows.
I have a JSFiddle here where I take the JSON and create table rows based on the values. But I can't figure out how to take the keys and align them with the values as table headers.
My angular code:
<tr ng-repeat='row in rows'>
<td ng-repeat="data in row.data">
{{data}}
</td>
</tr>
and:
function TableController($scope){
$scope.rows = data;
}
Take a look here: How can I iterate over the keys, value in ng-repeat in angular
<tr ng-repeat="(key, value) in data">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
====EDIT==== Since you're doing it all in the same table, you'll need to do it a different way. You need to separate the header values while you're still in the controller so that you have a clean way to iterate over your list. Here the fiddle: http://jsfiddle.net/L93v5/1/
Your revised way looks bad because there are two different tables and the cell sizes are different. This will keep it all in the same table and make things a bit cleaner.

Categories