UI Bootstrap with Flot causing misaligned ticks - javascript

I'm working on an Angular web-app with UI Bootstrap and have run into a problem with the y-tick label alignment in flot charts using UI tabs.
With standard bootstrap tabs, the plots match inside and outside the tabset:
http://jsfiddle.net/TDwGF/614/
However, with UI Bootstrap's tabset, we find that the y-tick labels overlap with the plot:
http://jsfiddle.net/TDwGF/615/
In playing with different approaches in building the flot directive, I can create a plot where only half of the y-tick labels are misaligned (I was not able to reproduce this well in a minimal example, however).
I cannot find any inherited css modifications that would cause these issues, and I haven't met with any luck in going through the tabs directive source code.
Any help would be appreciated.

I remember that something similar had already happened with me while working with Highcharts.
The root cause of the misalignment is probably the browser dynamic rendering timing restraining the canvas/svg container space.
To workaround this kind of issue, just wrap the plot creation with a timeout to render it on next digest cycle:
App.directive('chart', function() {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
var data = scope[attrs.ngModel];
setTimeout(function(){
$.plot(elem, data, {});
scope.$apply();
}, 0);
}
};
});
See working setTimeout fiddle here.
Anternatively you could inject angular $timeout, so it already calls scope.$apply() for you:
App.directive('chart', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
var data = scope[attrs.ngModel];
$timeout(function() {
$.plot(elem, data, {});
}, 0);
}
};
}]);
See working $timeout fiddle here.

Related

$document.ready() on directive template?

I have a directive that returns a template that does not appear to be sizing itself as it should. Elements in the template have their height set to 100%, however, it seems the parent's height (outside the directive) is not being set quick enough (also from 0 to 100%).
I do not have an issue if I refresh the page, this only comes up when resizing the window.
Example: http://codepen.io/sweatherly/pen/rLYPvE (decrease the window size, then refresh to see)
Please note the the example does not use a directive, just highlights the problem.
(function() {
"use strict";
angular
.module("ngApp")
.directive("currentCard", function() {
return {
templateUrl: 'components/orders/current/current-card.tpl.html',
scope: {
orders: "=",
cardTitle: "#cardTitle"
}
}
});
})();
Is it possible to somehow use $document.ready() on/with the template?
Edit: It turned out to be a stupid CSS issue (targeting wrong element), but I know understand a bit about directive's link function.
You can simply use the link function...
Link is a built in feature for directive, this function is executed when the directive is loaded or appears in the parent template.
Reference here ; example here
(function() {
"use strict";
angular
.module("ngApp")
.directive("currentCard", function() {
return {
templateUrl: 'components/orders/current/current-card.tpl.html',
scope: {
orders: "=",
cardTitle: "#cardTitle"
},
link: function(){
console.log("ready")
}
}
});
})();
You can use link function which will be executed after the template is loaded.
Usually any DOM manipulation, adding/removing event handlers should be done in link function.
Please refer difference between compile and link function .

Angular, How to implement the below code on resize as well as on load

angular.module(module.name).directive(current.name, ['$timeout', function (timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].style.margin = '0.1px';
timeout(function () {
element[0].style.margin = '0px';
}, 3000);
}
}
}]);
The above angular code is something that I wrote so when the browser loads it'll repaint the browser after to show the content on a single page app properly. However I have come to another issue where I need to do this on Resize.
I want to be able to use the same function below and add resize to it.. I'm a bit lost if I can add resize to this or will I need to write a different script.
I'm still coming to grips with angular so I'm looking for an answer that will explain this properly and what would be the best practise for what I want.
Do you want to apply it on any resize of the window or just below particular ratio/size?
If you want on any resize of the window, take a look at this JSFiddle
scope.$watch(scope.getWindowDimensions, function (newValue, oldValue) {...

NgAnimate - My Modal Show Hide Not Working due to NGAnimate

Hi I am using one small directive for hide and show bootstrap modal from controller which was working fine when i was not using ngAnimate. But after inclusing ngAnimate it shows
element.modal is not a function
below is my directive
app.directive('akModal', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.akModal, function(value) {
if (value) element.modal('show');
else element.modal('hide');
});
}
};
});
any fixes?
Managed to do it myself.
actually we should load bootsrap.js befor NGAnimate to avoid clashes.
Reason:
element.modal function is created in bootsrap.js so it should be loaded in order to use it afterwards.

Detect scrolled-to-document-end implementation in Angular JS

I know how to detect the document end while scrolling in plain JS, my problem is - how to implement that in AngularJS, I know I should attach the scroll event to both the $window and $document, my question is about where to implement the behavior?, directives?, services?, if anyone can show me what is the right way to implement that kind of detection in AngularJS I'll be very thankful.
After struggling with it for a long time- stumbled across the library: http://binarymuse.github.io/ngInfiniteScroll/documentation.html.
Based on your use-case, you could do something like:
<div infinite-scroll="addMoreItems()">
<div ng-repeat="item in items">Item number {{$index}}: {{$item}}</div>
</div>
As it allows you to attach this to any div- you could almost do anything in the function you want to.
Depending on what you're doing it can go in a combination of places. Typically when dealing with DOM manipulation (which is what I assume will be happening) you should use a directive - something like:
app.directive("scrollDetector", ["$document", "$window", function($document, $window) {
return {
restrict: "A",
link: function(scope, elem, attrs) {
angular.element($window).bind("scroll", function() {
//scroll logic here
});
}
}
}]);
And then implement the scroll-detector directive. (ex: <div scroll-detector></div>)

Initialize Zurb Foundation 5 in an AngularJS Directive

I've created three plunkrs to illustrate my problem. I'm trying to create an AngularJS Directive that will initialize foundation and apply the necessary javascript to the loaded template. At first I was trying to use ngInclude to add the Foundation 5 nav bar to all of the pages of my website. The top bar works as expected when the html is directly applied to a partial. When the html is added in a directive, such as ngInclude, the top bar looses all its functionality. I suspect that this was because foundation is not getting initialized after the template is added by the directive. As a solution I created a custom directive that would initialize foundation and compile the html template. Initializing foundation the way I do freezes the application. Anyone have a solution to this?
Trying to achieve this without resorting to Angular UI.
Example 1: HTML directly applied to the view. Works as expected, when you click on the menu dropdown the pages are displayed.
http://plnkr.co/edit/aQc6j2W9MpRuJo822gAF?p=preview
Example 2: ngInclude used to load template to dom. No functionality is achieved, when you click on the menu dropdown nothing happens.
http://plnkr.co/edit/fSS3FfYKFilMXsIkYUHg?p=preview
Example 3: Created separate directive to replace ngInclude that would initialize foundation, compile, and load the template to DOM. Can't provide a plunkr because it would just freeze up, but here is the code.
.directive('testdirective', function($compile) {
return {
restrict: 'AE',
templateUrl: 'partials/includes/nav.html',
link: function(scope, element, attrs) {
$compile($(document).foundation())(scope);
}
}
})
applied in partial by:
<div testdirective></div>
Do this:
link: function(scope, element, attrs) {
$compile(element.contents())(scope);
$(document).foundation();
}
If you compile the element itself, you create an infinite loop:
$compile(element)(scope); //fail
Always be sure that you only compile the element's contents:
$compile(element.contents())(scope); //win
It seems that you are compiling the whole document and creating the infinite loop.
You can probably just do this:
templateUrl: 'partials/includes/nav.html',
compile: function() {
$(document).foundation();
}
because the template will be automatically compiled so you don't have to do it manually.
Note: it's best practice to inject and use Angular's $document, which is a wrapper for document that helps in testing. $($document).foundation();

Categories