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
Related
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
I'm trying to databind an object received via an HTTP request to a table in angularjs.
The normal way to do this would be to use ng-repeat as follows.
<table class="table table-striped">
<tr>
<th>name</th>
<th>artist</th>
</tr>
<tr>
<td ng-repeat="track in $scope.trackList.items">
{{ track.name }}
{{ track.artist }}
</td>
</tr>
</table>
The problem with this is that the page loads and ng-repeat is ran before the data is returned from the server causing no items to be in the collection so nothing is drawn into the table.
What would be the best way to do this?
You don't need $scope in your view. Also, you probably want to put ng-repeat on <tr>, not <td>.
<table class="table table-striped">
<tr>
<th>name</th>
<th>artist</th>
</tr>
<tr ng-repeat="track in trackList.items">
<td>{{ track.name }}</td>
<td>{{ track.artist }}</td>
</tr>
</table>
You don't need $scope here just simple trackList.items.
$scope is the glue b/w Views and controller and you don't need to explicitly call $scope in the view it is already implicit that things are already picking from the scope.
<td ng-repeat="track in trackList.items">
{{ track.name }}
{{ track.artist }}
</td>
And if you are talking about the http call then here come's the magic of two way binding into picture.If anything update in controller by $http call that will be reflect in view as well you don't need to do it manually.
Hope it helps. :)
Let me correct your code first
<table class="table table-striped">
<tr>
<th>name</th>
<th>artist</th>
</tr>
<tr>
<td ng-repeat="track in trackList.items">{{ track.name }}</td>
<td>{{ track.artist }}</td>
</tr>
</table>
You don't have to explicitly specify $scope while binding data.
With respect to your problem, even though the code will get executed when the page is getting loaded, any changes that you do to the scoped data will be honored by the angular and view will get updated.
In your case, at the time of page load, if there is data available in trackList.items it will be shown in the page. Otherwise table will be rendered with just headers. Later when the application receives data from AJAX (or any other source), you have to simply assign it to $scope.trackList in your JS code. This will result in instant view updates and you will see the table starts reflecting the new data.
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/
I'm not sure how to do this in angular, after coming from jquery.
I have a table:
<div class="col-xs-10">
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
</thead>
<tbody ng-repeat="val in data">
<tr>
<td>val.Time</td>
<td>val.Distance</td>
<td ng-click="callmethod()"><img src="delete"></td>
</tr>
</tbody>
</table>
</div>
Essentially I want the callmethod() to know which row is being clicked so that I can make a update in the model in my controller. What is the right way to do this?
You can use the $index property:
callmethod($index)
Then on your controller you would do something like:
function callmethod(index) {
var foo = $scope.data[index];
}
Change that ng-click to this:
<td ng-click="callmethod(val)"><img src="delete"></td>
You'll get the whole val object when that method gets called.
I've got a simple repeating table-row in AngularJS
<tr ng-repeat="item in items">
<td>{{ item.prop1 }}</td>
<td>{{ item.prop2 }}</td>
</tr>
My item object has a comment property on it, and if that comment contains a value, I want to display that in a row all by itself on the line right after the rest of the elements and have it span the entire row. Is that type of thing possible? I looked at ng-repeat-end but that doesn't seem to be what I want, and I can't just add and extra <tr> element inside the ng-repeat as that'd be invalid HTML.
You can use ng-repeat's special repeat start and end points via ng-repeat-start and ng-repeat-end.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-repeat="comment in post.comments">
<td>{{comment.content}}</td>
</tr>
</table>
UPDATE: If the comment is a string, then simply remove the ng-repeat at the ng-repeat-end end point and add an ng-if expression that validates the existence of post.comment.
DEMO
HTML
<table ng-controller="PostController">
<tr ng-repeat-start="post in posts">
<td>{{post.content}}</td>
</tr>
<tr ng-repeat-end ng-if="post.comment">
<td>{{post.comment}}</td>
</tr>
</table>