Access the component ID in AngularJS - javascript

How can I get the id of a component in AngularJS ?
HTML
<li class="list-group-item" id="person_2" ng-click="invitePerson(this)">
<span class="label label-primary">A</span> Alexandre Dolabella Resende
</li>
JS
$scope.invitePerson = function(id) {
alert(id);
};
The alert returns [Object object], how can I access my component ID ? (in my case, should be person_2)
Console.log

Use $event to get the eventhandler param. From that param we can get the target element and its attributes
<li class="list-group-item" id="person_2" ng-click="invitePerson($event)">
<span class="label label-primary">A</span> Alexandre Dolabella Resende
$scope.invitePerson = function(e){
alert(e.target.id);
}

You can use ng-init or your controller to initialize the value. Then define a model, and you can then pass that model into a controller function, such as invitePerson
Working Plunker
HTML:
<ul>
<li class="list-group-item" id="person_2"
ng-init="person_2=5"
ng-model="person_2"
ng-click="invitePerson(person_2)">
<span class="label label-primary">A</span> Alexandre Dolabella Resende
</li>
</ul>
JS:
app.controller('MainCtrl', function($scope) {
$scope.invitePerson = function(id){
alert(id);
}

When I see "person_2" I immediately think of ng-repeat and maybe you should too if you want to iterate over object in your partial, http://plnkr.co/edit/b6ZePD826FauaY9x8b9p?p=preview
<label for="list">List</label>
<ul id="list">
<li class="list-group-item" id="person{{$index}}" ng-click="invitePerson(person)" ng-repeat="person in persons">
<span class="label label-primary">{{person.label}}</span> {{person.name}}
</li>
</ul>
<label for="invited">Invited</label>
<ul id="invited">
<li ng-repeat="invite in invited track by $index">{{invite.name}}</li>
</ul>

Related

How to detect which property is selected/clicked

I'm trying to detect which property is selected/clicked out of ngFor , which comes from a REST API.
I want to get which property(broker.username) is selected out of others
<div class="list-group">
<ul *ngFor="let broker of brokers">
<li class="broker_list"> {{broker.username}}</li>
</ul>
</div>
this is the REST call
[
{ id: 1, username: "PersonA"},
{ id: 2, username: "PersonB"}
]
You have to use event handler on anchor tag like this:
<div class="list-group">
<ul *ngFor="let broker of brokers">
<li class="broker_list">
<a (click)="onSelect(broker)" href="#" class="list-group-item list-group-item-action" style="text-align: center;"> {{ broker.username }}</a>
</li>
</ul>
</div>
Within your component add method:
#Component({ })
class XYZ {
// ... some code
public onSelect(broker) {
// Do what you need with broker?
}
}
Pass the broker directly in the method, like this
<div class="list-group">
<ul *ngFor="let broker of brokers">
<li class="broker_list"> {{broker.username}}</li>
</ul>
</div>
There are several ways, one of those would be to do something like this.
1) Add click handler on a tag:
<div class="list-group">
<ul *ngFor="let broker of brokers">
<li class="broker_list"> {{broker.username}}</li>
</ul>
</div>
2) Add method to component:
selected(brokerName: string) {
console.log(brokerName);
}
You could add a (click) property that calls a function, which takes a broker as a parameter. You can then access the username of that broker.
{{broker.username}}
The a tag should be able to know what the current broker is, since it is inside the *ngFor.

How to iterate an object with a specific key in angularjs?

I want to list an item inside a specific key using a filter. Now listing like this.
Sanal
Jin
John
Tim
Jeff
Sam
John
Tim
I want like this using a filterJeffSam
Here is the Fiddle
function testCtrl($scope) {
$scope.items = {"id":"B716","day":8,"di":{"type":"normal","one":[{"name":"Sanal","age":"18"},{"name":"Jin","age":"25"}],"two":[{"name":"Jeff","age":"55"},{"name":"Sam","age":"32"}],"three":[{"name":"John","age":"34"},{"name":"Tim","age":"39"}]}};
}
<div ng-app="" ng-controller="testCtrl">
<ul>
<li ng-repeat="val in items.di">
<ul>
<li ng-repeat="value in val">{{value.name}}</li>
</ul>
</li>
</ul>
</div>
in your ng repeat change it as
<li ng-repeat="value in val | filter: val.name='jeff'">{{value.name}}</li>
I have used name you can use the value that you want ot test

Nested elements and directives

I got an workaround here and need some help. It is a tree of categories. Some categores can be chosen by a checkbox.
I thougt the cleanest way to do that is via direction. On a <li kw-category-node> element put a on('click', function()) handler, which then does the choosing work (add object to data etc.).
So I came up with this HTML
<script type="text/ng-template" id="category_renderer.html">
<div ng-if="true == true" ng-mouseenter="over = true" ng-mouseleave="over = false">
<input type="checkbox"
ng-model="assignedCategories[category.category_id]"
ng-if="category.childs.length == 0"
ng-click="toggleCategory(category)">
</input> {{ category.name }}
<a href ng-if="over" ng-click="categories.remove(category)">
<small> <i class="fa fa-times"></i> Entf </small>
</a>
</div>
<ul class="list-unstyled">
<li ng-repeat="category in category.childs"
ng-include="'category_renderer.html'"
kw-category-node>
</li>
</ul>
</script>
<ul class="list-unstyled" kw-category-tree>
<li ng-repeat="category in categories.tree"
ng-include="'category_renderer.html'"
kw-category-node>
</li>
</ul>
And a directive like that
admin.directive('kwCategoryNode', ['$interval', 'dateFilter', function($interval, dateFilter) {
function link(scope, element, attrs) {
element.find('input').on('click', function() {
alert("wow, what a click!");
});
}
But element.find("input") wont give me that input element. Maybe the DOM is not loaded completly or I'm just in tilt.
Thanks

Filter matched elements by class name in Angular js.

Problem:
I have an unordered list of items which are returned from a json call and are output using ng-repeat. Each one of these items has a class name (there are about 9 categories).
I have a second unordered list which is simply a list of available categories.
Aim:
I want to be able to select one of the categories in the right hand list, which will apply a filter to the actual list of returned elements. This should be activated via a toggle (so click once: filtered, click again: filter removed). So it is simply looking to match the classname in the clicked element, to the elements that share the same classname in the list of json data.
I cannot use ng-model (as this is reserved for certain form elements).
For my jsfiddle I am simply using static html.
Here is my angular code:
/* angular custom filter on returned ajax api data */
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.chFilters = {};
$scope.links = [
{name: 'atm'},
{name: 'internet'},
{name: 'mobile'},
{name: 'sms'},
{name: 'postal'}
];
$scope.channels = ["ATM", "INTERNET", "SMS", "POSTAL","MOBILE"];
});
(this is based on another question I found on SO). Unfortunately the fiddle is a bit messy and has some extraneous code in it.
HTML:
<div ng-app="app">
<div ng-controller="main">
<ul>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="sms">Some stuff ATM</li>
<li class="atm">Some stuff ATM</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="postal">Some stuff POSTAL</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="sms">Some stuff SMS</li>
<li class="mobile">Some stuff MOBILE</li>
<li class="internet">Some stuff INTERNET</li>
<li class="mobile">Some stuff MOBILE</li>
</ul>
<ul class="channel-filters">
<li ng-repeat="link in links | filter:chFilters" class="{{link.name | lowercase}}"><a ng-click="chFilters.name = link.name">{{link.name | uppercase}}</a></li>
<li class="last" ng-click="chFilters.name = ''">CLEAR FILTER</li>
</ul>
<ul>
<li ng-repeat="channel in channels | filter:chFilters">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
</div>
</div>
This is the actual HTML from the application (with the call to the api).
<ul class="accordion">
<li class="search-text-channel">
<input type="textarea" ng-model="searchTextChannel.$" placeholder="Search"/>
</li>
<li ng-repeat="day in interactions.model.byDay | filter:searchTextChannel" ng-click="hidden = !hidden" ng-init="hidden = false" class="{{day.channel | removeSpace | lowercase}}" ng-class="{'closed': !hidden, 'open': hidden}">
<span class="date">{{day.date}}</span>
<span class="subheading">{{day.channel}}</span>
<ul ng-show="hidden">
<li ng-repeat="interaction in day.interactions">
{{interaction.time}} {{interaction.description | removeUnderscore}}
</li>
</ul>
</li>
<li class="load-more">
<i class="fa fa-plus"></i>LOAD MORE
</li>
</ul>
I have managed to recreate this functionality in jquery, but I think it would be better to implement an angular solution in an angular application.
I've tried researching and also attempted to implement show/hide as well as a custom filter, but so far no joy.
Here is my (messy) jsfiddle
<ul>
<li ng-repeat="channel in channels | filter:chFilters.name">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters.name">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
Update Plunker
Let me know if you have any question on this.
Here is part of the solution:
Suppose your items look like this:
$scope.items = [
{ class: "atm", label: "Some stuff ATM" },
{ class: "internet", label: "Some stuff INTERNET" },
{ class: "sms", label: "Some stuff SMS" },
{ class: "postal", label: "Some stuff POSTAL" },
...
];
To show a filtered list (only filtering by a single channel for now): create a separate list in the scope, with the filters applied:
$scope.click = function(name) {
$scope.chFilters.name = name;
$scope.filteredItems = $scope.items.filter(function(item) {
return item.class === $scope.chFilters.name;
});
};
Call this click handler from the bottom list:
...<a ng-click="click(link.name)">{{link.name | uppercase}}</a>....
And show filteredItems in the top list:
<ul>
<li ng-repeat="item in filteredItems" ng-class="item.class">{{item.label}}</li>
</ul>
So this is really just a starting point, it should be extended to handle multiple filters, etc...

function call from nested ng-repeat

<ul class="day">
<li ng-repeat="sessions in day">
<ul class="table-view">
<li class="table-view-cell" ng-repeat="(heading, session) in sessions">
<span class="group">{{heading}}</span>
<ul class="cell">
<li class="cell-content" ng-repeat="val in session" ng-click="session($event, val.id)">
<div class="time" style="background-color:#{{val.color}}">
<span>{{val.start | date:"h:mma"}}</span>
<span>to</span>
<span>{{val.end | date:"h:mma"}}</span>
</div>
<div class="session" ng-class-odd="'odd'" ng-class-even="'even'">
<span class="name">{{val.name}}</span>
<span class="room">Room: {{val.room}}</span>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
I've a nested ng-repeats and within the last inner loop have a function call, the function is defined on $scope but I'm getting the following error.
TypeError: object is not a function
$scope.session = function($event, id) {
console.log(id);
};
not sure if it has to do with nesting of ng-repeats and their scopes.
It has nothing to do with nesting several ng-repeats, but I think it is mixing it up with sessionobject which returns from ng-repeat="(heading, session) in sessions" . Try to change the function name to something else and give it a try.

Categories