Applying CSS style conditionally in ng-repeat in AngularJS - angularjs

This is my code.Am applying css for if condition and removing that css for else condition its working fine.But I dont want to use 2 <tr> within one tr I need to achieve this and I dont want to use inine css.
<tr ng-repeat="data in userList"
ng-if="data.appDate>=delivery.joinedDate"
ng-style="{'background-color': '#ffd6d6','border':'dashed 3px #9e0b0f'}">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate }}</td>
<td>{{data.joinedDate}}</td>
</tr>
<tr ng-repeat="data in userList" ng-if="!(data.appDate>=delivery.joinedDate)">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate }}</td>
<td>{{data.joinedDate}}</td>
</tr>
Any suggestion?

You would do this using the ng-class directive. You'll simply add your styling as a class in your stylesheet and change your angular code to this:
<tr ng-repeat="data in userList"
ng-class="{ 'my-css-class': data.appDate>=delivery.joinedDate }">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate }}</td>
<td>{{data.joinedDate}}</td>
</tr>
Stylesheet:
.my-css-class {
background-color: #ffd6d6;
border: dashed 3px #9e0b0f;
}

Try looking at ngClass.
You can dynamically set css based on a model.
Angularjs ngClass docs
As a note, inline styling is not good practice.

Related

Apply Background color for specific <tr> in angular

I have one angular table.
<tr ng-repeat="data in userList">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate }}</td>
<td>{{data.joinedDate}}</td>
</tr>
Here when joinedDate>appDate ,for that particular row I need to add background color with dottedlines.
I did this
<tr ng-repeat="data in userList" ng-if="data.appDate>=delivery.joinedDate" ng-style="{'background-color': '#ffd6d6','border':'dashed 3px #9e0b0f'}">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate }}</td>
<td>{{data.joinedDate}}</td>
</tr>
<tr ng-repeat="data in userList">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate }}</td>
<td>{{data.joinedDate}}</td>
</tr>
But rows are displaying two times.What is the mistake?Any suggestion?
Change your 2nd tr tag like this:
<tr ng-repeat="data in userList" ng-if="data.appDate>=delivery.joinedDate" ng-style="{'background-color': 'red'}">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate |}}</td>
<td>{{data.joinedDate}}</td>
</tr>
<tr ng-repeat="data in userList" ng-if="!(data.appDate>=delivery.joinedDate)">
<td>{{$index+1}}</td>
<td>{{data.name }}</td>
<td>{{data.age}}</td>
<td>{{data.dept}}</td>
<td>{{data.appDate |}}</td>
<td>{{data.joinedDate}}</td>
</tr>

AngularJs redirect

I've got a table where 1 row has to link to something else.
Right now I've got it like this:
<table class="table table-hover">
<thead>
<tr>
<th>Functie</th>
<th>Bedrijf</th>
<th>Naam</th>
<th>Achternaam</th>
</tr>
</thead>
<tbody ng-show="!homeCtrl.loading">
<tr ng-repeat="employee in homeCtrl.employees" ng-click="homeCtrl.redirectToShow(employee.EmployeeId)">
<td>{{ employee.Role }}</td>
<td>{{ employee.Company }}</td>
<td>{{ employee.FirstName }}</td>
<td>{{ employee.LastName }}</td>
<td ng-show="homeCtrl.canEdit" ng-click="homeCtrl.redirectToEdit(employee.EmployeeId)"><span class="glyphicon glyphicon-pencil"></span></td>
</tr>
</tbody>
</table>
The last td has to link to something else. But right now all links to the same how could I manage that?
(In the ng-click method I redirect)
There are two problems in your current implementation.
You could use $last to bind click event to fire on last element. I had put $last before homeCtrl.redirectToEdit function call because that will make sure until $last(last element of ng-repeat appears) row gets clicked then only it will call the next function.
ng-click="$last && homeCtrl.redirectToEdit(employee.EmployeeId);$event.stopPropagation()"
I think you are facing problem related to event bubbling, where you have click event binded to child and parent element. So when click event happen inside inner element it will propagate that event to its parent. To avoid such unwanted behaviour you should stop inner event bubbling just by calling $event.stopPropagation() on inner td.
You can use $last(boolean) and pass as parameter to your ng-click function, then redirect the user depending if is the last element or not.
<td ng-show="homeCtrl.canEdit" ng-click="homeCtrl.redirectToEdit(employee.EmployeeId, $last)"><span class="glyphicon glyphicon-pencil"></span></td>
try this
<td ng-show="$last && homeCtrl.canEdit" ng-click="homeCtrl.redirectToEdit(employee.EmployeeId)"><span class="glyphicon glyphicon-pencil"></span></td>
You can use $last and a condition:
<td ng-show="homeCtrl.canEdit && !$last" ng-click="homeCtrl.redirectToEdit(employee.EmployeeId)"><span class="glyphicon glyphicon-pencil"></span></td>
<td ng-show="homeCtrl.canEdit && $last" ng-click="homeCtrl.somethingDifferent(employee.EmployeeId)"><span class="glyphicon glyphicon-pencil"></span></td>
Ideally, You should set the ng-click to be per td because setting an ng-click to the full row will take precedence over any ng-clicks inside it. Try this:
<table class="table table-hover">
<thead>
<tr>
<th>Functie</th>
<th>Bedrijf</th>
<th>Naam</th>
<th>Achternaam</th>
</tr>
</thead>
<tbody ng-show="!homeCtrl.loading">
<tr ng-repeat="employee in homeCtrl.employees">
<td ng-click="homeCtrl.redirectToShow(employee.EmployeeId)">{{ employee.Role }}</td>
<td ng-click="homeCtrl.redirectToShow(employee.EmployeeId)">{{ employee.Company }}</td>
<td ng-click="homeCtrl.redirectToShow(employee.EmployeeId)">{{ employee.FirstName }}</td>
<td ng-click="homeCtrl.redirectToShow(employee.EmployeeId)">{{ employee.LastName }}</td>
<td ng-show="homeCtrl.canEdit" ng-click="homeCtrl.redirectToEdit(employee.EmployeeId)"><span class="glyphicon glyphicon-pencil"></span></td>
</tr>
</tbody>
That said, if you want to keep your markup the way it is, you can look at this StackOverflow answer about stopping bubbling: Howto: div with onclick inside another div with onclick javascript

AngularJS searching from navbar in view

I have a navbar on my page that has an input on it that I want to search a view, that should load in index.html after the user types in their search items. I can only figure out how to search with an input if it's in the same page that the table of ng-repeat items is in. Is there a way to search the table outside of the view? I've created a plnkr. It doesn't work. I'm not sure how to make it work. http://plnkr.co/edit/nqChzn5OATNMeSZL7ItJ?p=preview
Here is some of my code:
navbar
<input type="text" class="form-control" placeholder="Search" ng-model="vm.query">
Here is my table where the data displays.
<table ng-if="query" class="table table-hover table-responsive" >
<thead>
<tr>
<th>
({{filteredResults.length}}) Results Found
</th>
</tr>
<tr>
<td>Acc. ID</td>
<td>Acc. Name</td>
<td>Acc Address</td>
<td>City</td>
<td>Zip</td>
<td>Phone</td>
<td>Parent Name</td>
<td>Account Type</td>
<td>Account Status</td>
<td>Credit Term</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in vm.results | filter:query as filteredResults">
<td>{{ result.accountId }}</td>
<td>{{ result.accountName }}</td>
<td>{{ result.address }}</td>
<td>{{ result.city }}</td>
<td>{{ result.state }}</td>
<td>{{ reuslt.zip }}</td>
<td>{{ result.phone }}</td>
<td>{{ result.parentName }}</td>
<td>{{ result.accountType }}</td>
<td>{{ result.accountStatus }}</td>
<td>{{ result.accountStatus }}</td>
</tr>
</tbody>
</table>
Is it possible to do what I want to do?
I've looked at your plunker and I don't believe that your code hasn't initialized angular. I can't see an ng-app tag anywhere in your code.
That a side, you will be able to use any input to filter/search (via. various implementations) so long as the input and table are contained with your ng-app and controller parts of the DOM. Otherwise you won't be able to access it the controller.
Can I suggest that you distill your question down? give the smallest amount of code that demonstrates your problem.
here's a rough outline:
<body ng-app="app" ng-controller="cntrl">
<!-- nav bar -->
<div>
<input ng-model="filterVal"/>
</div>
<!-- table -->
<div>
<table>
<tr ng-repeat="r in data.rows | filter:filterVal">....</tr>
</table>
</div>
</body>
Here's a plunker where the default filter functionality is working: http://plnkr.co/edit/GDJs5xTCpqq48SDFTk67
If you need to have your nav bar outside of your app/controller or in an different controller (etc.) then there are solutions to this.
Assuming you are using ui-route, this is how to use a service to communicate between controllers:
functioning example:
http://plnkr.co/edit/fZZLUvlHO9zUFwQYd1an?p=preview
Eggheads video:
https://egghead.io/lessons/angularjs-sharing-data-between-controllers

Mixing a Table with Angular-UI Accordion

I'm trying to mix a table with angular-ui's accordion but I can't figure out a way to do it.
I'm not a pro, writing directives. I wonder if such a bridge exist. To achieve something like this :
<table class="table table-hover table-condensed" thead>
<thead>
<tr>
<th>{{ data.profile.firstname }}</th>
<th>{{ data.profile.lastname }}</th>
<th>{{ data.profile.email }}</th>
<th>{{ data.profile.company_name }}</th>
<th>{{ data.profile.city }}</th>
</tr>
</thead>
<tbody accordion close-others="true">
<!-- <tr ng-repeat="client in clients" ng-click="goTo('profile/' + client.username);"> -->
<tr ng-repeat="client in clients" accordion-group is-open="client.isOpen">
<accordion-heading>
<td>{{ client.firstname }}</td>
<td>{{ client.lastname }}</td>
<td>{{ client.email }}</td>
<td>{{ client.company_name }}</td>
<td>{{ client.city }}</td>
</accordion-heading>
Accordion Content
</tr>
</tbody>
</table>
Though it's not working :( Is there anyone who succeded to achieve something like this ?
The result I'm looking for is for when I click on a line in the table, it does the same behavior of an accordion.
In my case I made it a bit primitive but maybe that would be a good solution for you as well. Look:
<tbody ng-repeat="person in people | orderBy:predicate:reverse" >
<tr ng-click="isOpen=!isOpen">
<td>{{person.name}}</td>
<td>{{person.job}}</td>
<td>{{person.age}}</td>
<td>{{person.grade}}</td>
</tr>
<tr ng-if="isOpen">
<td>Just an empty line</td>
</tr>
</tbody>
1) You can try div instead of table for main accordion. It works for me.
2) And here is the accordion table example done in JSFiddle below, i hope it will help you. http://jsfiddle.net/Pixic/VGgbq/

Table with details in AngularJS

I've got tabular data loaded in AngularJS app. I want to display them in a table. But I also want to have detail view for some rows. Something like:
<table>
<tr ng-repeat="datum in data">
<!-- if datum.showDetail => detail view -->
<td colspan="N">
<h1>{{ datum.field1 }} <small>{{ datum.field2 }}</small></h1>
...
<p>{{ datum.fieldN }}</p>
</td>
<!-- else => row view -->
<td>{{ datum.field1 }}</td>
<td>{{ datum.field2 }}</td>
...
<td>{{ datum.fieldN }}</td>
</tr>
</table>
What's the Angular way of doing this?
Why not just adding ng-show and ng-hide directives to the td's?
<table>
<tr ng-repeat="datum in data" >
<!-- if datum.showDetail => detail view -->
<td colspan="N" ng-show="datum.showDetail">
<h1>{{ datum.field1 }} <small>{{ datum.field2 }}</small></h1>
...
<p>{{ datum.fieldN }}</p>
</td>
<!-- else => row view -->
<td ng-hide="datum.showDetail">{{ datum.field1 }}</td>
<td ng-hide="datum.showDetail">{{ datum.field2 }}</td>
...
<td ng-hide="datum.showDetail">{{ datum.fieldN }}</td>
</tr>
</table>
Also note that, in case you're using the Angular UI extensions, the ui-if directive would probably be a better fit, since it would actually remove the unused td's from the table, instead of just hiding them, like ng-hide.

Resources