ng-click doesn't work with fotorama plugin - angularjs

I'm using Fotorama plugin with AngularJS. If I put ng-click directive inside Fotorama markup, it doesn't trigger the handler.
Here is my sample markup:
<div class="fotorama" data-click="false">
<div onclick="myJsHandler()">
<img src="/images/2.png"/>
</div>
<div ng-click="myNgHandler()">
<img src="/images/1.png"/>
</div>
</div>
The first handler (non-angular) works fine but the second doesn't. It seems that the reason is that Fotorama rebuilds the DOM, and AngularJS doesn't know about these changes. The only workaround I found requires to use $compile service directly from non-Angular code:
$(function(){
$(".fotorama").each(function() {
var content = $(this);
angular.element(document).injector().invoke(function($compile) {
var scope = angular.element(content).scope();
$compile(content)(scope);
});
});
});
Is there any better way to integrate Fotorama with AngularJS?

There is an fotorama module for angular https://github.com/tamtakoe/ap.fotorama

Related

ng-click is not working in kendo editor

I'm trying to insert an html tag with ng-click event in the kendo editor. When I get the inserted data and show in a div, ng-click is not working. The normal onclick in javascript is working fine, but ng-click is not.
The below given is the <a> tag inserted on the editor text area.
<a ng-click="testMsg()"><span>' + nodeId + '</span></a>
Any idea on how to resolve this ?
onclick is DOM native event handler but ng-click isn't. Only those functions that are registered in the scope will be available. Any built-in functions will NOT be available to ng-click without an explicit assignment to the scope as my example shows.
var app = angular.module('app1', []);
app.controller('ctrl1', ['$scope', function($scope) {
function testMsg() {
alert('Hello world');
}
$scope.goodTestMsg = testMsg;
}]);
<div ng-app="app1" ng-controller="ctrl1">
<p ng-click="goodTestMsg()">Click me will show a message</p>
<p ng-click="testMsg()">Click me should happen nothing</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
TL;DR: The method testMsg is not exposed to the controller scope. Try adding something like $scope.testMsg = testMsg; will solve your problem.
Instead of textarea, try using div. I am facing similar problem which was partially solved with div. However it will be inline editing as the toolbar will get hidden and it will be displayed only when you focus cursor on the div.

Detecting an image is fully loaded from a directive, where the directive is not applied to the image element

there are many examples in SO on how we can use an angular directive to know when an image is loaded. The examples describe a directive that is directly applied to the img element like so:
<img ng-src="myimage.jpg" my-great-directive />
And then in the directive "my-great-directive"
we can do an:
element.bind("load" , function(e){ }
And i works great.
However, what if the construct is like this:
<div my-great-directive>
<img ng-src="myimage.jpg" />
</div>
Within my-great-directive, how do I bind to the inside image loaded event?
This is not really a theoretical problem for me. I am using a 3rd party slider called angular-carousel-slider that wraps around like so:
<ul rn-carousel rn-carousel-buffered
rn-carousel-index="mycarousel.index"
rn-carousel-auto-slide="0.3" rn-carousel-pause-on-hover >
<li ng-repeat="slide in slides">
<img ng-src="{{eventBasePath}}{{slide.img}}?rand={{rand}}"/>
</li>
</ul>
I'm trying to modify its code so that it does not slide to the next image unless the current image is fully loaded (to avoid the situation of a fast slider half loading images and moving to the next). I'm stuck on how I can trap this image loaded event inside the directive. Doing element.bind("load") does not work as the directive is not applied to the image element.
Thank you!
Check this working demo: JSFiddle
Use anguler.element to find the img element and bind the event.
In your directive, it should be element.find('img').
angular.module('Joy', [])
.directive('hello', [function () {
return {
restrict: 'A',
link: function (scope, ele) {
var img = ele.find('img');
console.log(img);
img.bind('load', function () {
console.log('img is loaded');
});
}
};
}]);
HTML:
<div ng-app="Joy">
<div hello>
<img ng-src="https://www.google.com.hk/images/srpr/logo11w.png">
</div>
</div>
Update 1
If use ng-repeat, add a $timeout to wait for ng-repeat finishes first. Check working demo: JSFiddle.
Note: this demo is loading a very large image. After the image is loaded, the text img is loaded will be shown.
Update 2
If the event binding is not working, try native image.onload binding (or oncomplete to find images cached). Working demo: JSFiddle.

Angular JS ng-click inside a modal window / Refresh angular scope in modal callback

I'm loading a modal window into my html using magnific popup, which is essentially doing this:
<html ng-app='basket'>
<body ng-controller='BasketController as basket'>
<a id='open' href='/product/1'>Open modal</a>
<a ng-click='addToCart(1)'>Add to cart</a>
</body>
</html>
... After Ajax load
<html ng-app='basket'>
<body ng-controller='BasketController as basket'>
<div class='modal>
<h1>Product title</h1>
<a ng-click='addToCart(1)'>Add to cart</a>
</div>
<a id='open' href='/product/1'>Open modal</a>
<a ng-click='addToCart(1)'>Add to cart</a>
</body>
</html>
But the ng-click inside the modal doesn't fire. Is there a way I can refresh the scope with the modal content included?
To begin with, I thought I'd give it a go by adding an ng-click to the open modal button that can pass the scope to another function that opens the modal. I have a function that can console log the $scope after it has loaded, but I just need to refresh or something to make angular recognise the new html in the modal window.
The reason this doesn't work is because angularJS is not aware of the ng-click inside the modal. It was added by jQuery by the looks of it. AngularJS has not processed that HTMl and the ng-click does nothing.
You can, however, potentially use the $compile function in AngularJS to $compile the modal HTML with a particular scope. Then, the ng-click will work.
Have a read about $compile here:
https://docs.angularjs.org/api/ng/service/$compile
So an example in your case might be:
$compile(modalElement)($scope);
Where this happens inside BasketController, so that would be BasketController passed in to manage modalElement - the raw DOM element, not the jQuery element.
So at some point if you have access to the modal html (just after load) you could do that. Not recommended at all though! Use an Angular library.

How can I trigger angular 1.3 animation with ng-include binding to a partial

I have an ng-include which is bound to a scope variable.
I can change the included content dynamically through my own 'routing' system using this approach.
However angular animations are fired on enter and leave events and are not triggered simply when the binding changes for the ng-include.
what is the best approach to implementing this, some kind of custom directive that wraps the ng-include behaviour, or is there a simpler way to do this that I'm missing?
Here's the index html
<body ng-controller="MainCtrl">
<div ng-include="templateUrl" class="animation" ></div>
<br/><form>
<button ng-click="swapTemplate()">Swap</button>
</form>
</body>
and the controller code
$scope.templateUrl = 'page2.html';
$scope.swapTemplate = function() {
if($scope.templateUrl === 'page1.html'){
$scope.templateUrl = 'page2.html';
}
else {
$scope.templateUrl = 'page1.html';
}
}
And the plnk http://plnkr.co/edit/Oh1vKi0DCxj95qO1J23x
you need to add angular-animate.js file
<script data-require="angular-animate#*" data-semver="1.2.13" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular-animate.js"></script>
add ngAnimate module in to main module
var app = angular.module('plunker', ['ngAnimate']);
here is the demo Plunker

AngularJS - looking to add and remove an iframe based on dom events

I would like to add an iframe to a page when certain links are clicked and remove it when other mouse events happen on the page. From what I can see, it seems that using an AngularJS directive would be the best way to do this. What I'm not sure about is what is the best way to format the directive. I'm thinking of making the directive at the attribute level...something like this:
<div myIframeDirective></div>
What I'm not sure of is the best way of removing/adding the directive contents (an iframe and a header above it) when various click events happen on the main page. Not looking for anyone to write the code for me...just looking for examples of how this can be best accomplished.
You should be using ng-if.
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
Here's a working example:
var app = angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
</div>
In Angular, ng-if will remove the iframe from the DOM if it is false.
This means the URL will NOT be requested until ng-if is true.
<iframe ng-if="frameDisplayed" ng-src="{{src}}"></iframe>
And use the link
Toggle
Then in your controller, you can control what your iframe display:
$scope.src = 'https://angularjs.org';

Resources