I modified the code found here:
http://jsfiddle.net/jaredwilli/SfJ8c/
var App = angular.module('App', []);
App.directive('resize', function ($window) {
return {
//restrict: 'A',
scope: {},
link: function(scope, element) {
var w = angular.element($window);
alert('Rezise');
w.bind('resize', function() {
scope.$apply();
});
}
};
});
This does not work when the browser windows is resized only refreshed...what am I missing?
Related
In a directive i want to require a controller but i get the error that the controller can't be found. I am sure it is a small thing or maybe it is not possible the way i want to do it.
angular.module('myApp', []);
angular.module('myApp').controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
//some function here returning data
}]);
angular.module('myApp').directive('yoloswag', function() {
return {
require: ['^?ngModel', '^GreetingController'],
restrict: 'A',
scope: {
},
link: function(scope, element, attrs, controllers) {
var modelCtrl = controllers[0],
greetingsCtrl = controllers[1];
console.log(controllers)
}
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="GreetingController">
{{ greeting }}
<div yoloswag>test</div>
</div>
</div>
What am i doing wrong?
Thank you so much!
Your code does not having and dependency with your main module, that's why you are getting that error.
Your code should be the following
angular.module('myApp', [])
.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
//some function here returning data
}])
.directive('yoloswag', function() {
return {
require: ['^?ngModel', '^GreetingController'],
restrict: 'A',
scope: {
},
link: function(scope, element, attrs, controllers) {
var modelCtrl = controllers[0],
greetingsCtrl = controllers[1];
console.log(controllers)
}
};
});
or set a variable for main module then you can add controller and directive with the main module like,
var MainModule = angular.module('myApp', []);
MainModule.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
//some function here returning data
}]);
MainModule.directive('yoloswag', function() {
return {
require: ['^?ngModel', '^GreetingController'],
restrict: 'A',
scope: {
},
link: function(scope, element, attrs, controllers) {
var modelCtrl = controllers[0],
greetingsCtrl = controllers[1];
console.log(controllers)
}
};
});
You can use controller property of directive :
make sure don't update property in link function.
return {
restrict: 'A',
scope: {
},
controller : 'GreetingController',
link: function(scope, element, attrs) {
var modelCtrl = controllers[0],
greetingsCtrl = controllers[1];
console.log(controllers)
}
};
How do I use $broadcast to update custom validation in other directives which already have isolated scope?
I want to be able create separate validation rules used on a single input field.So in the future I can change the validation of a field by simply changing the directive reference.
Check the plunkr
edit: I am using angular 1.2.8
The element the directive is on has isolated scope.
Validation Directive 1
(function () {
'use strict';
angular
.module('app')
.directive('dateOneValidation', dateOneValidation);
function dateOneValidation() {
var directive = {
require: 'ngModel', // note: this has to stay
restrict: 'A',
link: link
};
return directive;
function link(scope, element, attrs, ctrl) {
scope.$on('updateDateOneValidation', function(e, date){
ctrl.$parsers.unshift(function (viewValue) {
var form = scope.form;
var dateOne = moment(form.dateOne.$viewValue, "DD/MM/YYYY", true);
var today = moment();
var dateOneBeforeOrOnToday = dateOne.isSame(today, 'day') || dateOne.isBefore(today, 'day');
dateOneBeforeOrOnToday ? form.dateOne.$setValidity('dateOneBeforeOrOnToday', true):
form.dateOne.$setValidity('dateOneBeforeOrOnToday', false);
return viewValue
});
});
}
}
})();
Validation Directive 2
(function () {
'use strict';
angular
.module('app')
.directive('dateTwoValidation', dateTwoValidation);
function dateTwoValidation() {
var directive = {
require: 'ngModel', // note: this has to stay
restrict: 'A',
link: link
};
return directive;
function link(scope, element, attrs, ctrl) {
scope.$on('updateDateTwoValidation', function(e, date){
ctrl.$parsers.unshift(function (viewValue) {
var form = scope.form;
var dateOne = moment(form.dateOne.$viewValue, "DD/MM/YYYY", true);
var dateTwo = moment(viewValue, "DD/MM/YYYY", true);
var dateTwoAfterDateOne = dateTwo.isSame(dateOne, 'day') || dateTwo.isAfter(dateOne, 'day');
dateTwoAfterDateOne ? form.dateTwo.$setValidity('dateTwoAfterDateOne', true):
form.dateTwo.$setValidity('dateTwoAfterDateOne', false);
return viewValue
});
});
}
}
})();
(function () {
'use strict';
angular
.module('app')
.directive('stepOne', stepOne);
function stepOne() {
parentController.$inject = ['$scope'];
function parentController($scope) {
var vm = this;
vm.dateOne = '01/01/2000'
vm.dateTwo = '01/01/1900'
vm.validateStepOne = validateStepOne;
function validateStepOne() {
$scope.$broadcast('updateDateOneValidation');
$scope.$broadcast('updateDateTwoValidation');
}
}
var directive = {
restrict: 'EA',
require: '^form',
templateUrl: 'src/app/form/step1.html',
scope: {
},
controller: parentController,
controllerAs: 'vm'
};
return directive;
}
})();
(function () {
'use strict';
angular
.module('app')
.directive('dateOneValidation', dateOneValidation);
function dateOneValidation() {
var directive = {
require: 'ngModel', // note: this has to stay
restrict: 'A',
link: link
};
return directive;
function link(scope, element, attrs, ctrl) {
var form = scope.form;
var today = moment();
scope.$watch(attrs.ngModel, function () {
validator()
});
scope.$on('updateDateOneValidation', function () {
validator();
});
function validator() {
var dateOne = moment(form.dateOne.$viewValue, "DD/MM/YYYY", true);
var dateOneBeforeOrOnToday = dateOne.isSame(today, 'day') || dateOne.isBefore(today, 'day');
dateOneBeforeOrOnToday ? form.dateOne.$setValidity('dateOneBeforeOrOnToday', true) :
form.dateOne.$setValidity('dateOneBeforeOrOnToday', false);
}
}
}
})();
(function () {
'use strict';
angular
.module('app')
.directive('dateTwoValidation', dateTwoValidation);
function dateTwoValidation() {
var directive = {
require: 'ngModel', // note: this has to stay
restrict: 'A',
link: link
};
return directive;
function link(scope, element, attrs, ctrl) {
var form = scope.form;
scope.$watch(attrs.ngModel, function () {
validator();
});
scope.$on('updateDateTwoValidation', function (e, date) {
validator();
});
function validator() {
var dateOne = moment(form.dateOne.$viewValue, "DD/MM/YYYY", true);
var dateTwo = moment(form.dateTwo.$viewValue, "DD/MM/YYYY", true);
var dateTwoAfterDateOne = dateTwo.isSame(dateOne, 'day') || dateTwo.isAfter(dateOne, 'day');
dateTwoAfterDateOne ? form.dateTwo.$setValidity('dateTwoAfterDateOne', true) :
form.dateTwo.$setValidity('dateTwoAfterDateOne', false);
};
};
}
})()
Alternatively You can use a higher shared scope with a form object and pass it to your directives. Something like the following:
topLevelScope - ngForm
directive1(topLevelScope.ngForm)
topLevelScope.ngForm.$setValidity('input1', true)
directive2(topLevelScope.ngForm)
topLevelScope.ngForm.$setValidity('input2', true)
directive3(topLevelScope.ngForm)
topLevelScope.ngForm.$setValidity('input3', true)
My 2 cents.
I am trying to generate thumbnails using angular-thumbnails (https://github.com/aztech-digital/angular-thumbnails) from local video files instead of video urls, this is what I have so far, it only works with some videos: https://plnkr.co/edit/j7LR7FU0itRmPmLJWgwT?p=preview
var app = angular.module('plunker', ['angular-thumbnails']);
app.controller('MainCtrl', function($scope) {
$scope.$watch('myFile', function(newVal, oldVal) {
var reader = new FileReader();
reader.addEventListener('load', function() {
$scope.myVideoData = reader.result;
console.log('myVideoData', $scope.myVideoData);
}, false);
if (newVal) {
reader.readAsDataURL(newVal);
}
});
});
app.directive('fileModel', function() {
return {
restrict: 'A',
scope: {
fileModel: '='
},
link: function(scope, element, attrs) {
element.bind('change', function(e) {
scope.$apply(function() {
scope.fileModel = e.target.files[0];
});
});
}
};
});
I use CKEditor in my AngularJS webapp. I defined the event pasteState to listen to text changes and copy it to my ng-model.
Today, I upgraded CKEditor from version 4.4.7 to 4.5.1 (the last one) and discovered that my pasteState event is never fired.
My directive with the change event:
appDrct.directive('ckEditor', function() {
return {
require: '?ngModel',
link: function($scope, $elm, attr, ngModel) {
var config = {
toolbar:[[ 'Bold', 'Italic', 'Underline', 'Strike', 'TextColor', 'FontSize', '-', 'JustifyLeft', 'JustifyRight' ]]
};
config.removeButtons = '';
config.fontSize_sizes = 'petit/12px;normal/14px;grand/16px;';
var ck = CKEDITOR.inline ($elm[0], config);
if (!ngModel) return;
//ck.on('pasteState', function() {
ck.on('change', function() {
console.log(ck.mode);
$scope.$apply(function() {
ngModel.$setViewValue(ck.getData() || '');
});
});
ngModel.$render = function (value) {
ck.setData(ngModel.$viewValue);
};
$scope.$on("$destroy",function() {
CKEDITOR.instances[ck.name].destroy();
});
}
};
});
You should listen to the following events:
dataReady, change, blur, saveSnapshot.
From source code of ng-ckeditor:
['dataReady', 'change', 'blur', 'saveSnapshot'].forEach(function(event) {
ckeditor.$on(event, function syncView() {
ngModel.$setViewValue(ckeditor.instance.getData() || '');
});
});
But, my suggestion is to reuse a project that already exists, if you find something wrong or that can be improved you may suggest a modification (pull request) and make reusable code.
In a brief search I found two good projects:
https://github.com/lemonde/angular-ckeditor
https://github.com/esvit/ng-ckeditor
EDIT:
If you really want a simple version, you can use this working demo:
var app = angular.module('app', []);
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = CKEDITOR.replace(elm[0]);
ck.on('change', function() {
$scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
$scope.$on("$destroy",function() {
ck.destroy();
});
}
};
}]);
There's no "pasteState" in the public API of CKEditor, so it seems weird trying to use something like that (what kind of relation can exists between content changes and state of Paste?)
It seems that you should use 'change' instead.
I'm trying to pass a value to a directive. The directive is used to integrate a jquery plugin Knob
JSFIDDLE: http://jsfiddle.net/Tropicalista/TH87t/93/
I have this code:
var App = angular.module('Knob', []);
App.controller('myCtrl', function($scope) {
$scope.number = 24;
})
App.directive('knob', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
$(element).knob().val(scope.number);
console.log(attrs)
}
};
});
The problem is that knob() doesn't return the element. Use this instead:
link: function(scope, element, attrs) {
$(element).val(scope.number).knob();
}
Here's your fiddle: http://jsfiddle.net/TH87t/94/
I used your question as reference for a fully bi-direction binding. For a working version with angular 1.2.1 see http://jsfiddle.net/sander_van_dam/m5YJu/
App.directive('knob', function() {
return {
require: 'ngModel',
scope: { model: '=ngModel' },
controller: function($scope, $element, $timeout) {
var el = $($element);
$scope.$watch('model', function(v) {
var el = $($element);
el.val(v).trigger('change');
});
},
link: function($scope, $element, $attrs,$ngModel) {
var el = $($element);
el.val($scope.value).knob(
{
'change' : function (v) {
$scope.$apply(function () {
$ngModel.$setViewValue(v);
});
}
}
);
}
}
});