angular filter without using angular function - angularjs

What I want to do is to create 2 angular tables where I display tasks. In the first table I want to show all tasks which are not assigned to user and in the second tab I want to show all tasks which are assigned to user
UsersDTO is array, I may have more users assigned to the same task.
My html code looks like this. This is tab where I got all tasks with assigned user to it. I am not pretty sure why this is working, but I assume it somehow looks into property and check if there is anything.
<tbody>
<tr ng-repeat="task in project.ProjectTasksDTO | filter: {UsersDTO: {}}">
<td>{{task.Id}}</td>
<td>{{task.Title}}</td>
<td>{{task.Text}}</td>
<td>{{task.Description}}</td>
<td><p ng-repeat="user in task.UsersDTO">{{user.UserName}}</p></td>
<td>{{task.Status}}</td>
<td>{{task.CreatedBy}}</td>
<td><button class="btn-info" ng-click="editUser(user);">Profile</button></td>
</tr>
</tbody>
Is there a way how to tell to filter in ng-repeat that UsersDTO is null or empty, something like in code below.
<tbody>
<tr ng-repeat="task in project.ProjectTasksDTO | filter: {UsersDTO: {null}}">
<td>{{task.Id}}</td>
<td>{{task.Title}}</td>
<td>{{task.Text}}</td>
<td>{{task.Description}}</td>
<td><p ng-repeat="user in task.UsersDTO">{{user.UserName}}</p></td>
<td>{{task.Status}}</td>
<td>{{task.CreatedBy}}</td>
<td><button class="btn-info" ng-click="editUser(user);">Profile</button></td>
</tr>
</tbody>

Hi you can do it this way without a the need for a function.
<div ng-repeat="task in project.ProjectTasksDTO | filter:{UsersDTO.length: 0}:true">
<div ng-repeat="task in project.ProjectTasksDTO | filter:{UsersDTO.length: 0}:false">
Altough keep in mind that the :true and :false notation is actually an angular specific shorthand notation and will be replaced with function(actual,expected) in a literal comparison to see if these match yes:true or no:false
Fidle

Related

angularjs NgTable ng-repeat groupby with show/hide

I can't get the 'groupBy' working.
I have a data set returned from a $http factory. The data is passed to the $scope 'territoryReq' variable.
the data set looks like:
[{"Country":"Netherlands","Name":"firstName lastName","Phone":"+12345678","Mobile":"+987654321"},{"Country":"Netherlands","Name":"firstName2 lastName2","Phone":"+12345678","Mobile":"+987654321"}]
I have a simple 'dump' of the data by using:
<div>
<table ng-table="" class="table table-condensed table-bordered table-hover">
<tr class="ng-table-group" ng-repeat="entries in territoryReq">
<td>
{{entries.Country}}
</td>
<td>
{{entries.Name}}
</td>
<td>
{{entries.Phone}}
</td>
<td>
{{entries.Mobile}}
</td>
</tr>
</table>
</div>
This is all working. No problem.
Now I want to have the results grouped by Country. Preferably by being able to click on the country which then unhides the rows with the correct country.
I was looking at the example of example of ng-table with grouping
But I can't get it working for my data..
In the example they use e.g. group in $groups but I can't figure out where $groups come from?
Anyway, I hope someone can help me in the right direction...
thanks!
For straight up grouping, groupBy takes an object property as the parameter. It should be as simple as
<tr class="ng-table-group" ng-repeat="entries in territoryReq | groupBy: 'Country'">
But it sounds more like you want to filter the list based on criteria, like country.
I mocked this up to demonstrate what I think you're looking for. Please take a look and see if it helps... It has ordering via the table headers and filtering from a dynamic list of countries.
https://stackblitz.com/edit/angularjs-yvxdrd

ng-options disabled in array

I have a view that manages school's tests in a period (trimester or semester). Each semester can have many tests of type normal but only one of type examen.
I have made a script in jsFiddle that shows the behavior I am looking for https://jsfiddle.net/dfLf9zkm/.
The difference is that in the ng-repeat I have a ng-controller over each test so every time I called the ng-method it only affects the row I am on and not the rest. Something like
<div ng-app="app" ng-controller="Controller">
<table>
<tr>
<th>Type</th>
<th>Ponderation</th>
</tr>
<tr ng-repeat="test in tests track by test.id" ng-controller="TestRow">
<td><select ng-model="test.type" ng-options="type.id as type.type disable when type.id == 2 && hasExam && idExam!=test.id for type in types" ng-change="checkTests()"></select>
</td>
<td>{{test.ponderation}}%</td>
</tr>
</table>
</div>
If I change the value of $scope.hasExam with a method inside TestRow controller it only affect that row and not the rest. How can I do it?
I finally decided to leave everything in one controller and that fixed everything up

AngularJS incredibly slow performance when showing a table (1.6.5)

We are building an application to show a table with timetable data.
On the interface the user can set different filters.
I could use a data-grid which would speed up about everything.
I could use a table without grouping and use some sort of lazy fetching which would speed things up.
However we like the layout as is.
The consequence is that the watches are way over 2000 and we are experiencing bottlenecks. It is not that we show hundredths of rows.
How can we make this a bit more performant.
I tried track by, which didn't improve a thing. I tried bind-once but that didn't work either. (Honestly I have no clue how to make it work with key,value objects).
One performance trick might be changing the filters, move and chain them in the controller?
As you also can see, we re-use the same filters a lot, however this is necessary for the group by.
I also haven't seen any lazy-fetching mechanism which works with this kind of custom table / group by.
Hopefully you can help me to point me in the right direction, since I really kinda like the current layout.
The dataset is being displayed in a table and is grouped by date.
Example output:
hrefDateA | hrefDateB | hrefDateC | hrefDateD
DateA
RowA with columns
RowB with columns
RowC with columns
DateB
RowD with columns
RowE with columns
DateC
RowA with columns
RowB with columns
RowC with columns
....
<div ng-if="includeDesktopTemplate" ng-show="whateverdata.length > 0">
<div>
Jump to:
<a ng-href="#tableheader{{$index}}" ng-repeat="(key, value) in whateverdata | filter:filterA() | filter:filterB() | filter:filterC() | groupBy: 'someproperty'" class="someclass">
{{key}}
</a>
</div>
<hr />
<table>
<thead>
<tr>
<th class="timetablerow">HeaderA</th>
<th class="timetablerow">HeaderB</th>
<th class="timetablerow">HeaderC</th>
<th class="timetablerow">HeaderD</th>
<th class="timetablerow">HeaderE</th>
<th class="timetablerow">HeaderF</th>
</tr>
</thead>
<tbody ng-repeat="(key, value) in whateverdata | filter:filterA() | filter:filterB() | filter:filterC() | groupBy: 'someproperty'">
<tr>
<td colspan="6" class="desktoptablegroupby" id="tableheader{{$index}}">
{{key}}
</td>
</tr>
<tr>
<td colspan="6">
<hr class="redbackground" />
</td>
</tr>
<tr ng-repeat="row in value | filter:filterA() | filter:filterB() | filter:filterC()" ng-class-odd="'odd'" ng-class-even="'even'">
<td class="timetablerow">
{{row.propertyA}}
</td>
<td class="timetablerow">
{{row.propertyB}}
</td>
<td class="timetablerow">
{{row.propertyC}} - {{row.propertyD}}
</td>
<td class="timetablerow">
{{row.propertyD}}
</td>
<td class="timetablerow">
{{row.propertyE}}
</td>
<td class="timetablerow">
<div ng-show="{{row.propertyF}}">
<md-tooltip md-direction="{{tooltip.tipDirection}}">
{{row.propertyF}}
</md-tooltip>
<md-icon md-svg-src="~/Content/comment.svg">
</md-icon>
</div>
</td>
</tr>
</tbody>
</table>
<br /><br />
</div>
If I include the code below, watches can go from 3k to 6k
<div ng-show="{{row.propertyF}}">
<md-tooltip md-direction="{{tooltip.tipDirection}}">
{{row.propertyF}}
</md-tooltip>
<md-icon md-svg-src="~/Content/comment.svg">
</md-icon>
</div>
Regarding the code above. One column would show an icon with a tooltip which contains the value of an extra field of the dataset, only when the field contains data. But this also gives issues when the filters are being used (so redraw of screen), since other rows are showing the tooltip then, even when the value of the field of the specific row does not contain a value.(DOM/update/filter issue?)
This is a limitation by the way AngularJS handles change detection and rendering. There's really no easy solution - with emphasis on easy. What I've done on several occasions is use a technique often refered to as virtual-scroll/virtual-repeat. What it basically does is that it only renders the elements that can be seen in the viewport, but adds offsets to the top and bottom of the list/table to keep the scrollbar a constant size, regardless of how many elements are actually rendered. Then whenever you scroll, the elements that pop into view is seamlessly rendered before they become visible. This gives the illusion that it's a single long list/table, when it really only renders what is visible.
There are many libraries that implement this technique. I've personally got experience with the one called angular-vs-repeat but you should take a look at a few and evaluation which fits best your use case. I've also on one occasion implemented my own virtual scroll and it was certainly doable (my usecase in that scenario was that I needed virtual scroll to work both vertically and horizontally).

How to generate table tr from multiple overlapping ng-repeat

While replacing legacy javascript with angularjs code, I'm stuck with the following use case (simplified code as follows):
<tr ng-repeat="section in page.sections>
<td>{{section.name}}:</td>
</tr>
<tr ng-repeat="task in section.tasks>
<td>{{task.name}}:</td>
</tr>
The expected result should be a single table, with task rows should follow parent section row.
I understand that the inner loop won't work because of the scope of the section element is not the parent of the inner loop.
Is there a work around (or a best suitable way) to perform this?
The following should work:
<tr ng-repeat-start="section in page.sections">
<td>{{section.name}}:</td>
</tr>
<tr ng-repeat="task in section.tasks">
<td>{{task.name}}:</td>
</tr>
<tr ng-if="false" ng-repeat-end><td>end</td></tr>
See a demo plunkr

Order a row or column in a table with angularJS

I have been manually ordering columns in my table using AngularJS. Now I have the problem that I need to order the rows in a very specific way (much like the columns). Instead of making this table huge in the Html, I would rather ask around to see if there is a way that I could perhaps define an array in the .js script and have the columns/rows order themselves based on those arrays.
I have seen plenty of examples of how to sort alphabetically or by index but none so far that show how to sort by a predefined array.
Here is the table I am working with:
<table>
<thead>
<tr>
<th>
<select ng-init="selectedRace='Human'" ng-model="selectedRace">
<option ng-repeat="(raceName, item) in races">{{raceName}}</option>
</select>
</th>
<!--<th ng-repeat="(statGroup, item) in race.Attributes" class="{{statGroup}}">{{statGroup}}</th>-->
<!--Going to manually type the column headers until I figure out how to sort via array or something-->
<th>Starting Attribuites</th>
<th>Hero Limit</th>
<th>Epic Limit</th>
<th>Veteran Limit</th>
</tr>
</thead>
<tbody ng-model="race.Attributes">
<tr ng-repeat="(statName, item) in race.Attributes['Starting Attributes']">
<td class="statsDes">{{statName}}</td><!--These are not in proper order! I need to sort this via array or something-->
<td class="Starting Attributes">{{race.Attributes['Starting Attributes'] | FilterSet:statName}}</td>
<td>{{race.Attributes['Hero Limit'] | FilterSet:statName}}</td>
<td>{{race.Attributes['Epic Limit'] | FilterSet:statName}}</td>
<td>{{race.Attributes['Veteran Limit'] | FilterSet:statName}}</td>
</tr>
</tbody>
</table>
</br>
Any ideas? Other than doing it manually?
No need to do anything manually when you have AngularJS at your disposal.
AngularJS offers the orderBy filter to order an array by expression (http://docs.angularjs.org/api/ng.filter:orderBy).
If you need some feature that is not supported by the default orderBy filter, you can write your own custom filter to manipulate (sort) the array to your liking.
You can read more about custom filters on http://docs.angularjs.org/tutorial/step_09.
Hope that helps!

Resources