AngularJs - how to handle multiple events - angularjs

I have an angular application.on click of a tag, I am populating another div. Now I have a requirement to change the route as well on the click of the tag. how can I do this using Angularjs?

You can call a function on the scope as the click event handler.
For example: In your controller you have
$scope.myClickHandler = function() {
populateDiv();
changeRoute();
}
In your HTML template:
<div ng-click="myClickHandler()></div>

Related

How to handle click events from inside of the directive?

I have a modal component that takes an object with binding (ng-model). Something like:
<modal ng-model="modals.createContact"></modal>
I'm checking for $ctrl.ngModel.show to show/hide the modal:
<div class="modal" ng-show="$ctrl.ngModel.show" ng-transclude></div>
I show/hide modal by setting modals.createContact.show using ng-click directive:
<button ng-click="modals.createContact.show = true"></button>
But this solution is hard to maintain.
I need a directive something like this to toggle modal's show property:
<button modal="modals.createContact">Toggle modal</button>
Directive should listen the click event of the element (button) then toggle the $ctrl.modal.show property.
What I mean with toggling is:
$ctrl.modal.show = !$ctrl.modal.show;
How can achieve this scenario using directives?
To handle click events inside a directive be sure to use $apply:
app.directive("myDirective", function() {
return {
link: postLink
}
function postLink(scope, elem, attrs) {
elem.on("click", function(ev) {
scope.$apply(function() {
//code here
});
});
}
})
AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc... You can also use $apply() to enter the AngularJS execution context from JavaScript.
For more information, see
AngularJS Developer Guide - Integration with the browser event loop

(angularjs ui grid)how to add an ng-click on the headercellclass?

I want an event in this name whenever I click It
I mean i'm in typescript angularjs.
I'm using angular Ui-Grid.
i want to make my header cell, clickable
is there a ways to insert an onclick event on the headercell of ui grid
I don't want to redesign the template
I just want to add click event in the headercell
Do something like this
<div ng-class="{ 'text-success': clicked, 'text-large': !clicked }">
on controller
$scope.setClass(new function(){
$scope.clicked = true;
})

how to make custom directive in angular?

I am trying to make custom directive in angular .I try to add input field in my view when I click on button .In other words I am trying to make one custom directive in which when user press the button it add one input field in the browser .I think it is too easy if I am not use custom directive Mean If I use only controller then I take one array and push item in array when user click on button and button click is present on controller.
But when need to make custom directive where I will write my button click event in controller or directive
here is my code
http://play.ionic.io/app/23ec466dac1d
angular.module('app', ['ionic']).controller('appcontrl',function($scope){
$scope.data=[]
}).directive('inputbutton',function(){
return {
restrict :'E',
scope:{
data:'='
},
template:'<button>Add input</button> <div ng-repeat="d in data"><input type="text"></div>',
link:function(s,e,a){
e.bind('click',function(){
s.data.push({})
})
}
}
})
I just need to add input field when user click on button using custom directive ..could you please tell me where i am doing wrong ?
can we make button template and click event inside the directive
The reason it doesn't work is because your registering your click handler with jQuery. So when the click handler fires it is out of the scope of angular so angular does not know it needs to update its bindings.
So you have two options, the first is to tell angular in the click handler, 'yo buddy, update your bindings'. this is done using $scope.$apply
$apply docs: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply
e.bind('click',function(){
s.$apply(function() {
s.data.push({});
});
});
However angular already has built in directive for handling things like mouse clicks you can just use that and let angular do the work for you. This would be the better option.
so first in your view register a click handler on your button
<button ng-click="add()">Add input</button> <div ng-repeat="d in data"><input type="text"></div>
Then in your link simply add the add() method of your scope
s.add = function () {
s.data.push({});
}
Heres a working fiddle showing both examples. http://jsfiddle.net/3dgdrvkq/
EDIT: Also noticed a slight bug in your initial click handler. You registering a click but not specifying the button to apply it to. So if you clicked anywhere in the directive, not just the button, the handler would fire. You should be more specific when registering events manually, using ids, class names attributes etc.
The e or element property of the link function is a jqlite or full jQuery object of the entire directive. If you have jQuery included before angular it will be a full jQuery object. If not it will a jqlite object. A thinned out version of jQuery.
Here is a basic example for your logic .
var TestApp = angular.module('App', []);
// controller
TestApp.controller('mainCtrl', function mainCtrl($scope) {
$scope.data = [];
$scope.addDataItem = function () {
$scope.data.push({
someFilield: 'some value'
});
console.log('pushing value ... ');
}
});
// view
<div ng-app="App" class="container" ng-controller="mainCtrl">
<button type="button" ng-click="addDataItem()">Add an input</button>
<div ng-repeat="d in data track by $index">
<custom-directive model="d"></custom-directive>
</div>
</div>
// directive
TestApp.directive('customDirective', function customDirective() {
return {
restrict: 'E',
scope: {
model: '='
},
template: 'item -> <input type = "text" />',
link: function (scope, elem, attrs) {
console.log('scope.model', scope.model);
},
controller: function ($scope) {
// do staff here
}
}
});

Using template in angular directive works but templateUrl doesn't work

I have the following example.
In the example I'm using kendo menu with angular directive for kendo. Each item in the menu is my custom directive. When I use template inside the directive is works fine but when I use templateUrl it doesn't work, any ideas?
The reason I am using a custom directive for the menu is because I couldn't find out how to register click of a specific item in the menu. There is an event in kendo menu (select) that I can use to register all menu item selections but then in the callback function I don't know which item was selected because there is no id on the DOM element and I also don't get the model data so there is no indication of what was clicked. How can I know that the "Open" menu was clicked for example?
1) The directive kendo-menu bootstraps the kendo menu from it's content. If you are using a template all is fine because the sub html structure is created before kendo bootstraps the menu. If you are using a templateUrl the template gets loaded and if the data arrive angular updates the dom in your directive. But at this time the kendo-menu directive is ready with bootstrapping the menu, so it will not be aware of any changes angular made on the dom. How to solve this: as you did - only use inline templates or put the templates to the templateCache before you used the template. But this requires a lot of changes to your code.
2) I am not quite sure where your problem is. But you may register a ng-click function like this:
<ul kendo-menu>
<li ng-repeat="item in menuData.dataSource">
<label>{{item.text}}</label>
<ul>
<li ng-click="menuSelected(subitem)" ng-repeat="subitem in item.items/>
<label>{{subitem.text}}</label>
</li>
</ul>
</li>
</ul>
in your controller you have access to the selected item:
$scope.menuSelected = function(selected){
console.log(selected);
}
here is the working PLUNKR
If you populate the menu from a dataSource you can specifiy a select function in your menuData:
$scope.menuData = {
select: function(e) {
console.log(e);
console.log(e.item.textContent);
},
dataSource: [ ... ] };
e.item.textContent is the value that you have provided in your dataSource as text.

AngularJS Directive-Controller-Service Interaction

I'm trying to design a single page pagination app that displays the different pages of a document beneath each other in the same window. It has to meet the following requirements:
A pagination toolbar where the user can click next/previous/... and submit a page to go to.
The window scrolls to the right page of the document after a page has been submitted
If the user scrolls manually, the current page should update automatically
I tried some different stuff but was never really satisfied with the result. This is how I see the solution:
The app consists of 1 factory:
DocumentFactory: Stores the current page of the document and has the following methods:
setPage(page): sets the page in a factory so different controllers/directives can use this page
broadcast(pageChanged): broadcasts an event after the page has changed so the controllers/directives can listen to this even and react approprialty
2 controllers:
PaginationCtrl[DocumentFactory]: The pagination toolbar controller, updates the page by calling the setPage(method) of the DocumentFactory and listens to the pageChange event to update it's own scope when the page changes in an other controller/directive
DocumentCtrl: The controller of the document
1 Directive:
Page[DocumentFactory]: Resembles a page in the document and has the following methods/listeners
scrollToPage(): If the currentPage equals this pages number (added to the directive as an attribute, scroll to this page)
If this page is visible and the highest in the window of all visible pages, change the current page to this page's number by calling the DocumentFactory setPage(page) method.
Is this the right approach to store the page in a service and use events for the other controllers/directives to listen to it?
Should I create a controller in the directive to listen to the event or add a $watch in the link function to watch for changes in the current page (inherited from the parent Ctrl scope)?
Should I let each directive check if it's page number equals the current page on page change or should I let the DocumentCtrl scroll to the right element?
AS you already have the methods in the controller calling the factory, what you need is to use the '&' isolate scope in the directive to call the method you want.
Create the methods in the controller
var app = angular.module('app', []);
app.controller("Ctrl", function ($scope) {
$scope.goForward = function (){
alert("call to the paginator page up service");
};
$scope.goBack = function (){
alert("call to the paginator page down service");
};
});
Then set up the '&' scope isolates in the directive:
app.directive('paginator', function (){
return{
restrict: 'E',
scope:{
forward: '&',
back: '&'
},
template: '<button ng-click="forward()">Page up</button>' +
'<button ng-click="back()">Page down</button>'
}
});
Finally add the directive to the page with your attributes as defined in the directive:
<paginator forward="goForward()" back="goBack()"></paginator>
Here's the code in Plnkr.
HTH

Resources