Add focus/blur event in directive not working with templateUrl - angularjs

I'm on a mysterious bug since last friday and perhaps you have an explanation.
I have a directive define like that :
//------------------------------------------------------------------------------
// fl-main-menu
// Type: Element
// Description: Creates a...
//------------------------------------------------------------------------------
uiModule.directive('flNavMenu', ['$rootScope', function ($rootScope) {
//-------------------------
// CONTROLLER
//-------------------------
var componentController = function ($scope, $element, $state, localize, $stateParams, StateManager)
{
$scope.isMenuOpened = false;
$scope.buttonsData = [
{
name: "Games",
data: {
type: "navMenuIconButton",
label: "menu_Games",
imgUrl: "./images/ic-controller-w.svg",
imgUrlOver: "./images/ic-controller-w.svg",
cb: function () { StateManager.display("gameCategories"); }
}
},
{
name: "News",
data: {
type: "navMenuIconButton",
label: "News",
imgUrl: "./images/ic-news-w.svg",
imgUrlOver: "./images/ic-news-w.svg",
cb: function () { StateManager.display("newsList", { spaceId: '', newsIndex: 0}); }
}
}
];
var updateNavButtons = function (){
$scope.navButtons = [{
imgUrl: "./images/ic-menu-w.svg",
label: "Menu_Close"
}
];
if(app.fromGame){
$scope.navButtons.push({
imgUrl: "./images/navBar-ico-Y-w.svg",
label: "Btn_BackToGame"
}
);
}
};
updateNavButtons();
$scope.unregisterStageChange = $rootScope.$on('$stateChangeSuccess', function (event) {
var buttons: any = document.getElementsByClassName('fl-component navmenu-item-button');
var element : any;
if ($state.includes("newsList")) {
if (!$stateParams.spaceId)
element = buttons[2];
else
element = buttons[1];
}
else if ($state.includes("main")) {
element = buttons[0];
}
else {
element = buttons[1];
}
if (element) {
$element[0].children[0]._lastFocusElement = element;
$element[0].children[0]._focusables = buttons;
}
});
var fromGame = false;
$scope.app = app;
$scope.unwatchFromGame = $scope.$watch("app.fromGame", function (newValue, oldValue) {
if (newValue === fromGame) {
return;
}
updateNavButtons();
});
function openCloseMenu()
{
if ($element[0].style.display != 'none')
{
if ($rootScope.isVideoPlayerOpen)
{
$rootScope.$emit("closeVideo");
}
if (!$scope.isMenuOpened)
{
$scope.onViewOver();
}
else
{
$scope.onViewOut();
}
}
};
function isMenuButtonPressed(keyPressed)
{
var keyMapping = platform.getKeyMapping();
if ((platform.isPC() && keyPressed == keyMapping.Space)
|| (platform.isMobile()
&& keyPressed == keyMapping.Enter))
{
return true;
}
return false;
};
function onKeyUp(event)
{
if (isMenuButtonPressed(event.keyCode))
{
openCloseMenu();
}
};
EventManager.addEventListener(window.document.body, BaseEventType.KEYUP, BaseEventPhase.CAPTURE_PHASE, onKeyUp, this);
$scope.$on('$destroy', () => {
$scope.unwatchFromGame();
$scope.unregisterStageChange();
$element[0].children[0].onKeyDownEvent = undefined;
EventManager.removeEventListener(window.document.body, BaseEventType.KEYUP, BaseEventPhase.CAPTURE_PHASE, onKeyUp, this);
TweenMax.killTweensOf($element[0].children[0]);
TweenMax.killTweensOf($element[0].children[1]);
})
};
//-------------------------
// LINK
//-------------------------
var componentLink = function (scope, element)
{
var offset = 185;
var menu = element[0].children[0];
var tongue = element[0].children[1];
var wrapper = document.getElementById('wrapper');
/**
* Close the tongue and open the menu
*/
scope.onViewOver = function () {
var width = menu.scrollWidth;
TweenMax.killTweensOf(menu);
TweenMax.killTweensOf(tongue);
//Make the tongue disapear, and the menu appear
TweenMax.to(tongue, 0.2, { alpha: 0, ease: Quad.easeOut });
TweenMax.to(menu, 0.2, { alpha: 1, ease: Quad.easeIn });
//Open menu animation (css transition)
offset = $rootScope.app.isSnapMode ? 250 : 95;
if (wrapper) wrapper.style.left = ((width / 2) + offset) + 'px';
menu.style.left = '0px';
scope.isMenuOpened = true;
};
/**
* Close the menu and open the tongue
*/
scope.onViewOut = function () {
TweenMax.killTweensOf(menu);
TweenMax.killTweensOf(tongue);
//Make the menu disapear, and the tongue appear
TweenMax.to(tongue, 0.2, { alpha: 1.0, ease: Quad.easeIn });
TweenMax.to(menu, 0.1, { alpha: 0, ease: Expo.easeIn, delay:0.2});
//Close menu animation (css transition)
if (wrapper) wrapper.style.left = '0px';
menu.style.left = '-480px';
scope.isMenuOpened = false;
};
element[0].firstChild.onBlurEvent = scope.onViewOut;
element[0].firstChild.onFocusEvent = scope.onViewOver;
};
//-------------------------
// TEMPLATE
//-------------------------
var componentTemplate = '<div class="navmenu-wrapper">' +
'<div id="navmenu" class="fl-container navmenu navmenu-fixed-left fl-fixed-container">'+
'<div>'+
'<ul>' +
'<fl-nav-menu-item ng-repeat="buttonData in buttonsData" nav-item-data="buttonData" class="text - center" id="ID{{$index}}"></fl-nav-menu-item>' +
'</ul>'+
'<ul class="navmenu-nav-icons">' +
'<div ng-repeat="navButton in navButtons" class="navmenu-nav-icon">' +
'<img ng-src="{{navButton.imgUrl}}">' +
'<span>{{navButton.label | i18n }}</span>' +
'</div>' +
'</ul>'+
'</div>'+
'<div>'+
'</div>'+
'</div>'+
'<img src="./images/btn_drawer_menu.png" class="navmenu-tongue" id="navmenu-tongue">' +
'</div>';
//-------------------------
// RETURN
//-------------------------
return {
restrict: "E",
controller: ["$scope", "$element", '$state', 'localize', '$stateParams', 'UplayTracking', 'StateManager', componentController],
link: componentLink,
template: componentTemplate,
replace:true
}
}]);
You can see in the componentLink method that we had manually methods for onFocus/onBlur event:
element[0].firstChild.onBlurEvent = scope.onViewOut;
element[0].firstChild.onFocusEvent = scope.onViewOver;
The problem is : if I change the template of this directive for a templateUrl (so put all html in a separate file), when the onBlur/onFocus event are raised, our methods are not called. Do you have an idea why ? Thanks for your help !
-We use templateCache to loading our html template.
-I already verify if my element[0] is the same with ou without templateUrl and yes it's the same element.

Related

Directive Parameter Not Initializing on First Load In AngularJs

I'va made a Dropdown directive, i'm trying to assign methods on passing parameter to directive and i'll call these method from controller.
but on first load i'm not getting the assign method in controller but when i'm assigning it on second load (i.e on dropdown change event)and it's working fine.
how can i get the methods on first load of directive in the calling controller after first load.
here is the Directive:
"use strict";
myApp.directive("selectDirective", [function () {
return {
restrict: "E",
template: '<select class="form-control input-sm dropdown" data-ng-model="model.args.selectedItem" data-ng-options="item[model.args.displayField] for item in model.args.source" data-ng-change="model.itemChange(model.args.selectedItem)"><option value="">Select Any Item</option></select>',
scope: {
},
bindToController: { args: "=" },
controller: function () {
var self = this;
var initializeControl = function () {
if (self.args == undefined) {
self.args = {};
}
if (self.args.method == undefined) {
self.args.method = {};
}
if (self.args.isDisabled == undefined) {
self.args.isDisabled = false;
}
if (self.args.displayField == undefined) {
self.args.displayField = '';
//alert('Display Field is blank for dropdown control.')
}
if (self.args.valueField == undefined) {
self.args.valueField = '';
//alert('Value Field is blank for dropdown control.')
}
if (self.args.source == undefined) {
self.args.source = {};
}
if (self.args.hide == undefined) {
self.args.hide = false;
}
}
//here i'm assigning the methods in passing parameter
var assignMethod = function () {
self.args.method =
{
setEnable: function (args) {
self.args.isDisabled = !args;
},
setVisible: function (args) {
self.args.hide = !args;
},
getText: function () {
return self.args.selectedText;
},
getValue: function () {
return self.args.selectedValue;
},
setItem: function (item) {
debugger;
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
}
}
}
self.itemChange = function (item) {
debugger;
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
}
initializeControl();
assignMethod();
},
controllerAs: 'model'
}
}]);
Here is the Calling Controller Code:
"use strict";
myApp.controller("homeController", [function () {
var self = this;
var initializeControl = function () {
var myList = [{ id: 1, name: 'List1', value: 'List1' },
{ id: 2, name: 'List2', value: 'List2' }];
self.argsParam = {
displayField: 'name',
valueField: "value",
source: myList,
selectecText: '',
selectecValue: ''
};
self.clickMe = function () {
debugger;
var item = { id: 2, name: 'List2', value: 'List2' };
self.argsParam.method.setItem(item);
}
};
initializeControl();
}]);
View where i used the directive:
<div class="cold-md-12" ng-controller="homeController as model">
<h1>Home Page</h1>
<select-directive args="model.argsParam"></select-directive>
<input type="button" value="Click" ng-click="model.clickMe()" />
</div>
Scenario:
If assigned method called second time inside directive on dropdown-change event then i can get these method on passing param.
i.e
self.itemChange = function (item) {
debugger;
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
// here i'm assigning these method on change event then it's working fine after changing the value otherwise no success
assignMethod();
}
}
So, How i can i get the methods assign in the passing parameter on
First load of the directive?
I've moved the Controller Content to Link function in Directive and
it's working fine, but I still didn't get any idea how my previous code
not worked as expected.
Directive Code:
'use strict';
var testApp = angular.module('TestApp', []);
testApp.directive('sampleDirective', ['$http', function () {
return {
restrict: "E",
scope: {},
bindToController: { args: '=' },
template: '<div class="row">' +
'<select class="form-control"' +
'data-ng-model="model.args.selectedItem"' +
'data-ng-options="item[model.args.displayField] for item in model.args.source"' +
'data-ng-change="model.itemChange(model.args.selectedItem)">' +
'<option value="">Select Any Item</option>' +
'</select>' +
'</div>',
link: function (scope, element, attrs) {
var self = scope.model;
debugger;
var initializeControl = function () {
if (self.args == undefined) {
self.args = {};
}
if (self.args.method == undefined) {
self.args.method = {};
}
if (self.args.isDisabled == undefined) {
self.args.isDisabled = false;
}
if (self.args.displayField == undefined) {
self.args.displayField = '';
alert('Display Field is blank for dropdown control.')
}
if (self.args.valueField == undefined) {
self.args.valueField = '';
alert('Value Field is blank for dropdown control.')
}
if (self.args.source == undefined) {
self.args.source = {};
}
if (self.args.hide == undefined) {
self.args.hide = false;
}
}
var assignMethod = function () {
self.args.method =
{
setEnable: function (args) {
self.args.isDisabled = !args;
},
setVisible: function (args) {
self.args.hide = !args;
},
getText: function () {
return self.args.selectedText;
},
getValue: function () {
return self.args.selectedValue;
},
setItem: function (item) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
};
}
self.itemChange = function (item) {
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
}
initializeControl();
assignMethod();
},
controller: function () {
},
controllerAs: 'model'
}
}]);

angularjs directive is not rendered in browser

I am using this timepicker-popup directive from github:
https://github.com/mytechtip/timepickerpop
I am using it in my html:
<timepicker-pop input-time="activeStep.timeTest"
class="input-group" show-meridian='showMeridian'>
</timepicker-pop>
I do not understand, why the timepicker is not even initialized nor rendered.
I am new to the directive stuff but when the directive is named: 'timepickerPop' how can it be that the demo here: https://github.com/mytechtip/timepickerpop/blob/master/demo/timepickerpop-demo.html
uses in the html this format ????
What do I wrong? I get no errors in my browser console!
/**
* Anularjs Module for pop up timepicker
*/
angular.module('timepickerPop', [ 'ui.bootstrap' ])
.factory('timepickerState', function() {
var pickers = [];
return {
addPicker: function(picker) {
pickers.push(picker);
},
closeAll: function() {
for (var i=0; i<pickers.length; i++) {
pickers[i].close();
}
}
};
})
.directive("timeFormat", function($filter) {
return {
restrict : 'A',
require : 'ngModel',
scope : {
showMeridian : '=',
},
link : function(scope, element, attrs, ngModel) {
var parseTime = function(viewValue) {
if (!viewValue) {
ngModel.$setValidity('time', true);
return null;
} else if (angular.isDate(viewValue) && !isNaN(viewValue)) {
ngModel.$setValidity('time', true);
return viewValue;
} else if (angular.isString(viewValue)) {
var timeRegex = /^(0?[0-9]|1[0-2]):[0-5][0-9] ?[a|p]m$/i;
if (!scope.showMeridian) {
timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
}
if (!timeRegex.test(viewValue)) {
ngModel.$setValidity('time', false);
return undefined;
} else {
ngModel.$setValidity('time', true);
var date = new Date();
var sp = viewValue.split(":");
var apm = sp[1].match(/[a|p]m/i);
if (apm) {
sp[1] = sp[1].replace(/[a|p]m/i, '');
if (apm[0].toLowerCase() == 'pm') {
sp[0] = sp[0] + 12;
}
}
date.setHours(sp[0], sp[1]);
return date;
};
} else {
ngModel.$setValidity('time', false);
return undefined;
};
};
ngModel.$parsers.push(parseTime);
var showTime = function(data) {
parseTime(data);
var timeFormat = (!scope.showMeridian) ? "HH:mm" : "hh:mm a";
return $filter('date')(data, timeFormat);
};
ngModel.$formatters.push(showTime);
scope.$watch('showMeridian', function(value) {
var myTime = ngModel.$modelValue;
if (myTime) {
element.val(showTime(myTime));
}
});
}
};
})
.directive('timepickerPop', function($document, timepickerState) {
return {
restrict : 'E',
transclude : false,
scope : {
inputTime : "=",
showMeridian : "=",
disabled : "="
},
controller : function($scope, $element) {
$scope.isOpen = false;
$scope.disabledInt = angular.isUndefined($scope.disabled)? false : $scope.disabled;
$scope.toggle = function() {
if ($scope.isOpen) {
$scope.close();
} else {
$scope.open();
}
};
},
link : function(scope, element, attrs) {
var picker = {
open : function () {
timepickerState.closeAll();
scope.isOpen = true;
},
close: function () {
scope.isOpen = false;
}
}
timepickerState.addPicker(picker);
scope.open = picker.open;
scope.close = picker.close;
scope.$watch("disabled", function(value) {
scope.disabledInt = angular.isUndefined(scope.disabled)? false : scope.disabled;
});
scope.$watch("inputTime", function(value) {
if (!scope.inputTime) {
element.addClass('has-error');
} else {
element.removeClass('has-error');
}
});
element.bind('click', function(event) {
event.preventDefault();
event.stopPropagation();
});
$document.bind('click', function(event) {
scope.$apply(function() {
scope.isOpen = false;
});
});
},
template : "<input type='text' class='form-control' ng-model='inputTime' ng-disabled='disabledInt' time-format show-meridian='showMeridian' ng-focus='open()' />"
+ " <div class='input-group-btn' ng-class='{open:isOpen}'> "
+ " <button type='button' ng-disabled='disabledInt' class='btn btn-default ' ng-class=\"{'btn-primary':isOpen}\" data-toggle='dropdown' ng-click='toggle()'> "
+ " <i class='glyphicon glyphicon-time'></i></button> "
+ " <div class='dropdown-menu pull-right'> "
+ " <timepicker ng-model='inputTime' show-meridian='showMeridian'></timepicker> "
+ " </div> " + " </div>"
};
});

AngularJS: window service and directive

I'm learning AngularJS and I want to create a custom service and directive to show window view which I can close, minimize, maximize, drag and resize. I wrote something but I am not sure if this is correct, especially, when I use ng-view while changing route I had to add
scope.$on('$routeChangeStart', function (next, current) {
});
to my code and ngRoute to the dependecies list to see the view, but I didn't add anything to respond to it and I am not sure how this works.
I wanted also add possibility to close window on esc but when I added this functionality closing window with animation stop working.
Could someone take a look at the code and tell me what is wrong or missed or explain something?
(function (window, angular) {
'use strict';
var module = angular.module('bbWindow', []);
module.provider('bbWindow', function () {
var defaults = this.defaults = {
id: null,
controller: null,
scope: null,
windowTitle: null,
windowContent: null,
className: 'bbwindow-theme-default',
position: 'top', // position of the window: 'top', 'center', 'bottom'
size: 'medium', // size of the window: 'small', 'medium', 'large'
showButtons: true,
showCloseButton: true,
showMinimizeButton: true,
showMaximizeButton: true,
showBackdrop: false,
closeByBackdropClick: false,
closeByEscape: true,
onClose: null,
praventClosing: false,
animation: 'am-fade-and-scale', // use animations from angular-motion, eg. am-slide-top, am-fade-and-scale, am-flip-x
backdropAnimation: 'am-fade',
template: 'common/bbwindow/bbwindow.tpl.html',
plainTemplate: false,
contentTemplate: null,
plainContentTemplate: false,
draggable: true,
dragOpacity: 0.35,
resizable: true,
resizeMinHeight: 150,
resizeMinWidth: 330
};
var openedWindows = [],
globalId = 0,
zIndex = 1000,
minimizedWindowPositions = [],
topId = 0,
defers = []; // used to resolve when window is closed
this.$get = ['$rootScope',
'$document',
'$compile',
'$q',
'$templateCache',
'$http',
'$timeout',
'$sce',
'$animate',
'$route',
'$log',
function ($rootScope, $document, $compile, $q, $templateCache, $http, $timeout, $sce, $animate, $route, $log) {
var body = $document.find('body');
// private methods
function onKeyUp(event) {
event.stopPropagation();
if (event.keyCode === 27) {
if (topId) {
bbwindow.close(topId);
}
}
}
function fetchTemplate(template, plain) {
if (plain) {
return $q.when(template);
}
return $q.when($templateCache.get(template) || $http.get(template))
.then(function (res) {
if (angular.isObject(res)) {
$templateCache.put(template, res.data);
return res.data;
}
return res;
});
}
// find elements in element or document for specified selectors
function findElement(selectors, element) {
return angular.element((element || document).querySelectorAll(selectors));
}
// get height of the screen
function getDocHeight() {
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
}
function getElementPositionObject(element) {
return {
width: element.css('width'),
height: element.css('height'),
top: element.css('top'),
left: element.css('left'),
margin: element.css('margin')
};
}
// find the minimized window position in the array and remove it
function removeMinimizedWindowPosition(windowElement) {
var left = parseInt(windowElement.css('left')),
top = parseInt(windowElement.css('top')),
i,
position = -1;
for (i = 0; i < minimizedWindowPositions.length; i++) {
if (minimizedWindowPositions[i][0] == left && minimizedWindowPositions[i][1] == top) {
position = i;
break;
}
}
if (position > -1) {
minimizedWindowPositions.splice(position, 1);
}
}
// public object returned from service
var bbwindow = {
open: function (config) {
var self = this,
options = angular.copy(defaults);
config = config || {};
angular.extend(options, config);
globalId += 1;
var id = options.id || 'bbwindow' + globalId;
topId = id;
var defer = $q.defer();
defers[id] = defer;
var scope = options.scope && angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();
// Support scope as string options
angular.forEach(['windowTitle', 'windowContent'], function (key) {
if (options[key]) {
scope[key] = $sce.trustAsHtml(options[key]);
}
});
scope.showButtons = options.showButtons;
scope.showCloseButton = options.showCloseButton;
scope.showMinimizeButton = options.showMinimizeButton;
scope.showMaximizeButton = options.showMaximizeButton;
scope.close = function () {
scope.$$postDigest(function () {
if (!options.preventClosing) {
bbwindow.close(id);
}
if (options.onClose && $.isFunction(options.onClose)) {
options.onClose();
}
});
};
scope.maximize = function () {
scope.$$postDigest(function () {
bbwindow.maximize(id);
});
};
scope.minimize = function () {
scope.$$postDigest(function () {
bbwindow.minimize(id);
});
};
scope.$on('$routeChangeStart', function (next, current) {
});
// featch main window template
var templatePromise = fetchTemplate(options.template, options.plainTemplate);
// check if the user provided template for content and fetch it
if (options.contentTemplate) {
templatePromise = templatePromise.then(function (template) {
var templateElement = angular.element(template);
if (templateElement) {
// fetch content template
return fetchTemplate(options.contentTemplate, options.plainContentTemplate).then(function (contentTemplate) {
var contentElement = findElement('[data-ng-bind="windowContent"]', templateElement[0]);
if (contentElement) {
contentElement.removeAttr('data-ng-bind').html(contentTemplate);
return templateElement[0].outerHTML;
}
});
}
});
}
templatePromise.then(function (template) {
if (template) {
var windowElement = $compile(template)(scope);
scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();
windowElement.attr('id', id);
if (options.controller && angular.isString(options.controller)) {
windowElement.attr('data-ng-controller', options.controller);
}
// set default theme class
windowElement.addClass(options.className);
// set initial positioning
windowElement.addClass(options.position);
// set initial size of the window
windowElement.addClass(options.size);
// add drag option if enabled
if (options.draggable) {
$(windowElement).draggable({
addClasses: false,
cancel: "input,textarea,button,select,option,.bbwindow-content,.bbwindow-header-buttons",
opacity: options.dragOpacity
});
// jquery draggable plugin sets position to relative and then there is
// problem while resizing element, so change position to absolute
$(windowElement).css('position', 'absolute');
} else {
// if the window won't be draggable, then find h4 element in the header
// and change cursor from move to normal
$(windowElement).find('.bbwindow-header h4').css('cursor', 'default');
}
// add resize option if enabled
if (options.resizable) {
$(windowElement).resizable({
handles: "all",
minHeight: options.resizeMinHeight,
minWidth: options.resizeMinWidth
});
if (options.position == 'center') {
$(windowElement).css('transform', 'inherit');
}
}
if (options.closeByEscape) {
//body.off('keyup');
//windowElement.on('keyup', onKeyUp);
}
if (options.animation) {
windowElement.addClass(options.animation);
}
windowElement.on('mousedown', function () {
topId = id;
windowElement.css('z-index', zIndex++);
});
$animate.enter(windowElement, body, null, function () {
});
}
});
return {
id: id,
closePromise: defer.promise,
close: function() {
bbwindow.close(id);
}
};
},
confirm: function(config) {
var defer = $q.defer();
var options = {
closeByBackdropClick: false,
closeByEscape: false
};
angular.extend(options, config);
options.scope = angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();
options.scope.confirm = function(value) {
defer.resolve(value);
window.close();
};
var window = bbwindow.open(options);
window.closePromise.then(function () {
defer.reject();
});
return defer.promise;
},
close: function (id) {
var windowElement = angular.element(document.getElementById(id));
if (windowElement) {
var isMinimized = windowElement.scope().isMinimized || false;
if (isMinimized) {
removeMinimizedWindowPosition(windowElement);
}
if (defers[id]) {
defers[id].resolve({
id: id,
window: windowElement
});
delete defers[id];
}
windowElement.scope().$destroy();
$animate.leave(windowElement, function () {
});
}
},
maximize: function (id) {
var windowElement = angular.element(document.getElementById(id));
if (windowElement) {
var isMinimized = windowElement.scope().isMinimized || false;
if (isMinimized) {
return;
}
var bodyWidth = $('body').width(),
bodyHeight = getDocHeight(),
elementWidth = parseInt(windowElement.css('width')),
elementHeight = parseInt(windowElement.css('height'));
if (windowElement.scope().lastPosition && elementWidth == bodyWidth && elementHeight == bodyHeight) {
var lastPosition = windowElement.scope().lastPosition;
$(windowElement).animate({
position: 'absolute',
width: lastPosition.width,
height: lastPosition.height,
top: lastPosition.top,
left: lastPosition.left,
margin: lastPosition.margin
}, 200);
windowElement.scope().lastPosition = null;
} else {
windowElement.scope().lastPosition = getElementPositionObject(windowElement);
$(windowElement).animate({
position: 'fixed',
width: '100%',
height: '100%',
top: '0',
left: '0',
margin: '0'
}, 200);
}
}
},
minimize: function (id) {
var windowElement = angular.element(document.getElementById(id));
if (windowElement) {
var bodyWidth = $('body').width(),
bodyHeight = getDocHeight(),
isMinimized = windowElement.scope().isMinimized || false;
if (isMinimized) {
var lastPosition = windowElement.scope().lastPositionForMinimizedElement;
removeMinimizedWindowPosition(windowElement);
$(windowElement).animate({
width: lastPosition.width,
height: lastPosition.height,
top: lastPosition.top,
left: lastPosition.left,
margin: lastPosition.margin
}, 200);
windowElement.scope().isMinimized = false;
windowElement.scope().lastPositionForMinimizedElement = null;
$(windowElement).draggable('enable');
$(windowElement).resizable('enable');
} else {
windowElement.scope().lastPositionForMinimizedElement = getElementPositionObject(windowElement);
var headerHeight = $(windowElement).find('.bbwindow-header').css('height');
var top = bodyHeight - parseInt(headerHeight);
var width = 200;
var left = 0;
var i = 0;
var found = false;
// find position for minimized window
do {
i++;
if (minimizedWindowPositions.length == 0) {
found = true;
break;
}
var positions = minimizedWindowPositions.filter(function (pos) {
return pos[0] == left && pos[1] == top;
});
if (positions.length > 0) {
left = i * width;
if (left + width >= bodyWidth) {
i = 0;
left = 0;
top -= parseInt(headerHeight);
}
} else {
found = true;
}
} while (!found);
minimizedWindowPositions.push([left, top]);
$(windowElement).animate({
height: headerHeight,
left: left + 'px',
top: top + 'px',
margin: '0',
width: width + 'px'
}, 200);
windowElement.scope().isMinimized = true;
$(windowElement).draggable('disable');
$(windowElement).resizable('disable');
}
}
}
};
return bbwindow;
}];
});
module.directive('bbWindowMain', ['$sce', 'bbWindow', function ($sce, bbWindow) {
return {
restrict: 'E',
scope: true,
link: function (scope, element, attr, transclusion) {
var options = {scope: scope};
angular.forEach(['id', 'className', 'position', 'size', 'animation', 'template', 'contentTemplate'], function (key) {
if (angular.isDefined(attr[key])) {
options[key] = attr[key];
}
});
angular.forEach(['windowTitle', 'windowContent'], function (key) {
attr[key] && attr.$observe(key, function (newValue, oldValue) {
scope[key] = $sce.trustAsHtml(newValue);
});
});
bbWindow.open(options);
}
};
}]);
})(window, window.angular);

$watch in a directive not working

Any reason my $scope.$watch isn't working? When I type, I don't see the updates in the console.
(function () {
'use strict';
wikiApp.directive('wikiMarkdownEdit', ['pathSvc', function (pathSvc) {
var getFullPath = pathSvc.getFullPath;
return {
restrict: 'E',
templateUrl: getFullPath('html/directives/markdownEdit.html'),
replace: true,
scope: {
model: '=',
formId: '#',
rows: '#',
placeholder: '#'
},
controller: function($scope, $sce, $attrs, $log) {
var converter = new Showdown.converter();
$scope.showPreview = false;
/**
* Keep the preview up to date
*/
$scope.$watch('model', updateHTML);
var updateHTML = function() {
var html = converter.makeHtml($scope.model || '');
console.log(html);
// jQuery('#' + $scope.formId + 'Preview').html('1111');
};
updateHTML();
/**
* Sync the height of the preview div with the textarea
**/
var lastHeight = 0;
var getHeight = function() {
var newHeight = jQuery('#' + $scope.formId).outerHeight();
if (lastHeight === newHeight || newHeight < 20) {
setTimeout(getHeight, 100);
return;
}
lastHeight = newHeight;
jQuery('#' + $scope.formId + 'Preview').height(newHeight);
setTimeout(getHeight, 100);
};
getHeight();
/**
* Toggle preview button callback
*/
$scope.togglePreview = function() {
$scope.showPreview = !$scope.showPreview;
};
}
};
}]);
})();
try to change var updateHTML to function updateHTML, you can't use a function defined with var before the definition.
another way recommended:
function updateHTML() {
var html = converter.makeHtml($scope.model || '');
console.log(html);
};
$scope.$watch(function() {
return $scope.model;
}, updateHTML);
One more thing, in your directive scope, did you mean model to be bounded to ngModel? If so, try this approach:
...
scope: {
ngModel: '='
},
...
Or
...
scope: {
model: '=ngModel'
},
...

set the data from controller into directive

I had created the directive file like this:
angular.module('myApp')
.directive('rGraph', function() {
return {
link: function ( scope, element, attrs ) {
var width = Math.max($("#graph-container").innerWidth(), 400);
var height = Math.max(width, 550);
var rgraph = new $jit.RGraph({
injectInto: 'graphcontainer',
width: width,
height: height,
background: {
CanvasStyles: {
strokeStyle: '#555'
}
},
Navigation: {
enable: true,
panning: true,
zooming: 10
},
Node: {
color: '#ddeeff',
overridable: true
},
Edge: {
color: '#C17878',
lineWidth: 1.0
},
onCreateLabel: function(domElement, node){
domElement.innerHTML = node.name;
domElement.onclick = function(){
rgraph.onClick(node.id, {
onComplete: function() {
Log.write("done");
}
});
};
},
onPlaceLabel: function(domElement, node){
style = domElement.style;
style.display = '';
style.cursor = 'pointer';
if (node._depth <= 1) {
style.fontSize = "0.8em";
style.color = "#ccc";
} else if(node._depth == 2){
style.fontSize = "0.7em";
style.color = "#494949";
} else {
style.display = 'none';
}
var left = parseInt(style.left);
var w = domElement.offsetWidth;
style.left = (left - w / 2) + 'px';
},
onBeforePlotNode: function(node){
if (node.data.type == 'group') {
node.setData('type', 'square');
} else if (node.data.type == 'judge') {
node.setData('type', 'star');
node.setData('dim', '8');
}
}
});
//Here I need to set the data
rgraph.loadJSON();
rgraph.refresh();
// Completing animations on every change was too much
// TODO come up with better way to watch for changes
rgraph.graph.eachNode(function(n) {
var pos = n.getPos();
pos.setc(-200, -200);
});
rgraph.compute('end');
rgraph.fx.animate({
modes:['polar'],
duration: 2000
});
}
};
});
And my controller is like this:
angular.module('myApp').controller('AnalysisCtrl', ['$scope', '$http', '$q', 'SearchService', function($scope, $http, $q, SearchService) {
$scope.graph_data = {
'id': 'judge_id',
'name': judge.name,
'type': 'judge',
'children': filters
}
My view is where I ma calling directive is like this:
<div id="graphcontainer" r-graph="graph_data"></div>
Now i need to add the data get from controller i.e data of $scope.graph_data into to the rgraph.loadJSON(); of directives.So how to do that.
Thanks
Sabbu

Resources