ng-click not working on a custom directive - javascript

I am trying to use ng-click directive on a custom directive but it doesn't seem to execute the associated function defined in the controller. Looks like I am missing something very obvious. Please help. Thanks.
HTML:
<tab-link class="checked" ng-click="onEdit('performance')" href="#" value="Performance"></tab-link>
<tab-link href="#/planning" ng-click="onEdit('forecast')" value="Forecast"></tab-link>
Directive:
.directive('tabLink', function () {
return {
restrict: 'E',
template: "<a class='tab-link'><span></span></a>",
replace: true,
scope: {
text: '=',
value: '#'
},
link: function (scope, element) {
$(function () {
var span = element[0].children[0];
span.innerHTML = scope.value;
$(element[0]).on("click", function (e) {
$.each($(".tab-link"), function (index, el) {
if (el != element[0]) {
if ($(el).hasClass("checked")) {
$(el).removeClass("checked");
}
} else {
if (!$(el).hasClass("checked")) {
$(el).addClass("checked");
}
}
});
})
});
}
}
})
Controller:
$scope.onEdit = function(page) {
console.log(msg);
};

You can check the alert.
$scope.onEdit = function(page) {
alert(page);
console.log(page);
};

Related

directive without scope setting value undefined

In my angular app, I've to use different directives on a single field.
here are my directives
angular.module('app')
.directive('focusMe', function ($timeout) {
return {
scope: { trigger: '#focusMe' },
link: function (scope, element, attr) {
scope.$watch('trigger', function (value) {
if (value === "true") {
$timeout(function () {
element[0].focus();
});
}
});
}
};
});
and another one for datepicker
.directive('ngDatepicker', function() {
return {
restrict: 'A',
replace: true,
scope: {
ngOptions: '=',
ngModel: '='
},
template: "<div class=\"input-append date\">\n <input type=\"text\"><span class=\"add-on\"><i class=\"icon-th\"></i></span>\n</div>",
link: function(scope, element) {
scope.inputHasFocus = false;
element.datepicker(scope.ngOptions).on('changeDate', function(e) {
var defaultFormat, defaultLanguage, format, language;
defaultFormat = $.fn.datepicker.defaults.format;
format = scope.ngOptions.format || defaultFormat;
defaultLanguage = $.fn.datepicker.defaults.language;
language = scope.ngOptions.language || defaultLanguage;
return scope.$apply(function() {
return scope.ngModel = $.fn.datepicker.DPGlobal.formatDate(e.date, format, language);
});
});
element.find('input').on('focus', function() {
return scope.inputHasFocus = true;
}).on('blur', function() {
return scope.inputHasFocus = false;
});
return scope.$watch('ngModel', function(newValue) {
if (!scope.inputHasFocus) {
return element.datepicker('update', newValue);
}
});
}
};
});
it throws me an error
Multiple directives asking for new/isolated scope
after hours of searching and working on different solutions, i finally understand this one same like my problem and changed my first directive like this
angular.module('app')
.directive('focusMe', function ($timeout) {
return {
link: function (scope, element, attr) {
scope.$watch(attr.focusMe, function (value) {
if (value === "true") {
$timeout(function () {
element[0].focus();
});
}
});
}
};
})
But now its not working because it always gives me value = undefined and I don't know why it is happening. May be I'm missing something here or not doing it properly??
here is my html where I'm binding its value
<input type="text" focus-me="{{ DateOfBirthFocus }}" ng-datepicker>
Any kind of help will be appreciated.

How to call another directive from directive angularjs

I want to call alertForm directive in loginForm directive. Where I want call 'alertForm' directive in 'loginForm' is highlighted as //i want to call here
alertForm directive
angular.module('myApp')
.directive('alertForm', function () {
return {
templateUrl: 'app/directives/alert/alertForm.html',
restrict: 'E',
scope: {
topic: '=topic',
description: '=description'
},
controller: function($scope) {
$scope.words = [];
this.showAlert = function() {
$scope.description.push("hello");
};
}
};
});
loginForm directive
angular.module('myApp')
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs) {
},
controller: function ($rootScope, $scope, authenticationService) {
$scope.loginFormData = {};
$scope.inProgress = false;
$scope.onLogin = function (form) {
if (form.$valid) {
$scope.inProgress = true;
authenticationService.loginUser('password', $scope.loginFormData).then(function () {
$scope.successCallback({formData: $scope.loginFormData});
}, function (err) {
$scope.inProgress = false;
if (err.message) {
**// i want to call here**
}
});
}
}
}
};
});
You can use require config of directive.
When a directive requires a controller, it receives that controller as
the fourth argument of its link function. Ref : Documentation
You can implement this in your code
angular.module(‘myApp')
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
require:'alertForm',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs, alertFormCtrl) {
scope.alertFormCtrl = alertFormCtrl;
},
controller: function ($rootScope, $scope, authenticationService) {
$scope.loginFormData = {};
$scope.inProgress = false;
$scope.onLogin = function (form) {
if (form.$valid) {
$scope.inProgress = true;
authenticationService.loginUser('password', $scope.loginFormData).then(function () {
$scope.successCallback({formData: $scope.loginFormData});
}, function (err) {
$scope.inProgress = false;
if (err.message) {
// Calling showAlert function of alertFormCtrl
$scope.alertFormCtrl.showAlert();
}
});
}
}
}
};
});
Add the following line in the app/directives/loginForm/loginForm.html :
<alertForm topic="something" description = "something" ng-if="showAlert"></alertForm>
Now inside the loginForm directive's controller : // i want to call here
use
$scope.showAlert = true;
Note: you can use some variable to setup the topic and description as well inside the alertForm.

How to call controller function from directive in angular js ?

I am opening a dialog-box on click of button.I want to add endless scroll in that.
Problem:
When user scrolls at the end of dialog-box i want to call addMoreData() written in controller.
HTML of Dialog-box:
<modal-dialog show='modalShown' width='60%' height='325px' >
<div id='diaogContainer'>
<p>Modal Content Goes here<p>
</div>
</modal-dialog>
Controller:
sampleApp.controller('view3Controller', function($scope) {
$scope.modalShown = false;
$scope.toggleModal = function() {
$scope.modalShown = !$scope.modalShown;
}
**$scope.showMore = function(){
console.log('showMore');
}**
});
Directive of Dialog-box:
sampleApp.directive('modalDialog', function() {
return {
restrict: 'E',
scope: {
show: '='
},
replace: true, // Replace with the template below
transclude: true,
link: function(scope, element, attrs) {
scope.dialogStyle = {};
if (attrs.width)
scope.dialogStyle.width = attrs.width;
if (attrs.height)
scope.dialogStyle.height = attrs.height;
scope.hideModal = function() {
scope.show = false;
};
},
template: "<div class='ng-modal' ng-show='show'><div class='ng-modal-overlay'ng-click='hideModal()'></div><div class='ng-modal-dialog' hello **scrolly='showMore()'** ng-style='dialogStyle'><div class='ng-modal-close' ng-click='hideModal()'>X</div><div class='ng-modal-dialog-content' ng-transclude></div></div></div>"
};
});
Directive to load more data:
sampleApp.directive('hello', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var raw = element[0];
element.bind('scroll', function () {
console.log(raw.scrollTop +'-------'+raw.offsetHeight+'----'+raw.scrollHeight);
if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
// here is problem
// I am not able to call function through this attr
//
**scope.$apply(attrs.scrolly);**
}
});
}
};
});
You can't pass in a function to a directive through an attribute, you can however pass it through an isolate scope. Pass a reference to the function you wish to call to the directive:
sampleApp.directive('hello', function () {
return {
restrict: 'A',
scope:{
onScrollEnd:'&'
},
link: function (scope, element, attrs) {
var raw = element[0];
element.bind('scroll', function () {
console.log(raw.scrollTop +'-------'+raw.offsetHeight+'----'+raw.scrollHeight);
if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
scope.onScrollEnd();
}
});
}
};
});
Now assuming you have the addMoreData() function defined on your controller, you can pass it to the directive this this:
<div hello on-scroll-end='addMoreData()'></div>
EDIT
I think the problem is that the hello directive can't access functions on the parent controller since the modalDialog directive is using an isolated scope, therefore making everything o the parent controller invisible. Pass the function to through the isolate scope of the modalDialog Directive as well:
scope: {
show: '=',
onScrollEnd:'&'
},
you can try like this.
Directive part
var module = angular.module('direc');
module.directive("direcApp", ['$timeout', function ($timeout) {
return {
restrict: 'E',
templateUrl: "template/template.html",
compile: function (iel, iattr) {
return function (scope, el, attr) {
}
},
scope: {
type: "#",
items: '=',
onClick: '&',
val: "="
},
controller: function ($scope) {
$scope.selectItem = function (selectedItem) {
$scope.val = selectedItem;
if (angular.isFunction($scope.onClick)) {
$timeout($scope.onClick, 0);
}
};
}
};
}]);
Controler part
var app = angular.module('app', ['direc']);
app.controller("appCtrl", ['$scope', '$http', function ($scope, $http) {
var t = {
count: function () {
return $scope.$$watchersCount; // in angular version 4 get total page listener
},
val1: "",
onClick: function () {
console.log($scope.data.val1);
},
items: [{ text: 'Seçenek 1', value: '1' },
{ text: 'Seçenek 2', value: '2' },
{ text: 'Seçenek 3', value: '3' },
{ text: 'Seçenek 4', value: '4' },
{ text: 'Seçenek 5', value: '5' }]
};
angular.extend(this, t);
}]);
Html part
<div ng-controller="appCtrl as data">
<div><b>Watcher Count : {{data.count()}}</b></div>
<direc-app items="data.items"
val="data.val1"
on-click="data.onClick1()"
>
</selection-group>
</div>
Add data as parameter to directive: scope: { data: '='}, and in directive just data.push({name:'i am new object'})
Add function parameter to directive as suggested in previous answer.

Nested directives with ng-include templates

I have a page which has nested directives, the nesting is potentially infinite. I want to be sure that all the templates are loaded before to do something else. I am trying to acces my function "registerLoad", but my scope.$parent.hasOwnProperty('registerload') keep being 'false', I think i have a scope issue. Thanks for your help.
<div inbook-include="template/1.html"></div>
<div inbook-include="template/2.html">
<div inbook-include="template/2-1.html">
<div inbook-include="template/2-1-1.html">
</div>
</div>
<div inbook-include="template/2-2.html">
</div>
</div>
app.directive('inbookInclude', function (inbookConstants, $log, templateLoader, $timeout, $interpolate) {
// ID of parent
var parentId;
function registerLoad(scope) {
if (scope.$parent.hasOwnProperty('registerload')) {
parentId = scope.$parent.registerLoad(scope);
console.log('I got a dad too');
} else {
console.log('all have been loaded');
}
}
return {
restrict: 'A',
replace: true,
template: '<div ng-include="url.address" onload="onLoad()">,
scope: true,
compile: function compile(iElement, iAttrs) {
var urlTemplate = iAttrs.inbookInclude;
return {
pre: function prelink(scope, iElement, iAttrs) {
scope.url = {};
},
post: function postlink(scope, iElement, iAttrs) {
scope.$on('loaded', function (event, childId) {
console.log('one of my kids loaded', event, childId);
}),
scope.onLoad = function () {
if (scope.$parent) {
if (scope.$parent.hasOwnProperty('registerload')) {
scope.$parent.registerLoad(scope.$id);
console.log('my dad can register me');
}
console.log('my dad cannot register me', scope.$parent);
console.log(getMethods(scope.$parent));
}
scope.$broadcast('reveal');
}
if (scope.$eval(iAttrs.forceLoad)) {
init();
}
templateLoader.onReveal(iElement.parent(), scope, function () {
init();
scope.$emit('loaded', scope.$id);
});
function init() {
//
//
}
}
}
}
}
});

Call controller of another directive in AngularJs

How can I refer to directive's controller function from $apply in another directive of the same element? Example:
<myelement hint="myelement.controller.getMe()">hoverMe</myelement>
app.directive("myelement", function () {
return {
restrict: "E",
controller: function ($scope) {
this.getMe = function () {
return "me";
};
}
}
});
app.directive("hint", function () {
return {
restrict: "A",
controller: function ($rootScope) {
this.showHint = function (getMsg) {
alert($rootScope.$apply(getMsg)); //what should be written here?
}
},
link: function (scope, element, attrs, controller) {
element.bind("mouseenter", function () {
controller.showHint(attrs.hint);
});
}
}
});
Sources: http://plnkr.co/edit/9qth9N?p=preview
Use require (read more about it here).
app.directive("hint", function () {
return {
restrict: "A",
require: ["myelement", "hint"],
controller: function ($scope) {
this.showHint = function (msg) {
alert($scope.$apply(msg)); //what should be written here?
}
},
link: function (scope, element, attrs, ctrls) {
var myElementController = ctrls[0],
hintController = ctrls[1];
element.bind("mouseenter", function () {
hintController.showHint(myElementController.getMsg());
});
}
}
});
UPDATE (about making Hint universal, see comments below)
To make Hint directive universal, than you could use the $scope as the medium between them.
app.directive("myelement", function () {
return {
restrict: "E",
controller: function ($scope) {
$scope.getMe = function () {
return "me";
};
}
}
});
<myelement hint="getMe()">hoverMe</myelement>
The only change is that the getMe message is not setted in the controller (this.getMe) but in the $scope ($scope.getMe).

Categories

Resources