I have started an angularjs project and I would like to implement fancybox.
For this, I have included the jQuery and fancybox plugins to the solution. I am attempting to open the template in the code shown below in a fancybox window.
View
ADD
Controller
app.controller('MainController',
function MainController($scope) {
$scope.user = "Hey Welcome";
$scope.open = function(template_path){
$.fancybox({"href":template_path})
}
}
)
And popup/add.html
<div class="pop-contnr">
<h2>ADD</h2>
<table>
<thead>
<tr>
<th align=center>{{user}}</th>
</tr>
</thead>
</table>
</div>
Fancybox successfully opens a window containing the template, but the {{user}} expression has not been evaluated. Can anyone please help?
I have created a directive for fancybox
app.directive('fancybox',function($compile, $timeout){
return {
link: function($scope, element, attrs) {
element.fancybox({
hideOnOverlayClick:false,
hideOnContentClick:false,
enableEscapeButton:false,
showNavArrows:false,
onComplete: function(){
$timeout(function(){
$compile($("#fancybox-content"))($scope);
$scope.$apply();
$.fancybox.resize();
})
}
});
}
}
});
Here is a simplified version of a fancybox directive my team and I wrote to open fancyboxes based on a template with a single click.
It is invoked in the markup like this:
<div fancybox ng-click="openFancybox('templateUrl')"> </div>
The code for the directive is:
app.directive('fancybox', function ($compile, $http) {
return {
restrict: 'A',
controller: function($scope) {
$scope.openFancybox = function (url) {
$http.get(url).then(function(response) {
if (response.status == 200) {
var template = angular.element(response.data);
var compiledTemplate = $compile(template);
compiledTemplate($scope);
$.fancybox.open({ content: template, type: 'html' });
}
});
};
}
};
});
It can be seen working in this plunker
I extended the answer above to use Angular's template cache.
It is invoked in the markup like this:
<div fancybox fancybox-template="template.html">Open Fancybox</div>
The code for the directive is:
app.directive('fancybox', function ($templateRequest, $compile) {
return {
scope: true,
restrict: 'A',
controller: function($scope) {
$scope.openFancybox = function (url) {
$templateRequest(url).then(function(html){
var template = $compile(html)($scope);
$.fancybox.open({ content: template, type: 'html' });
});
};
},
link: function link(scope, elem, attrs) {
elem.bind('click', function() {
var url = attrs.fancyboxTemplate;
scope.openFancybox(url);
});
},
}
});
Here's the plunker.
Related
Been trying to figure this out for too long now. Maybe someone can shed some light:
Am experimenting with custom directives and as an exercise I'm trying to create a method within the custom directive's controller that can be called from a simple button within the view. But the method isn't being called, even though I can see the method (using console) as a property within isolated scope object. Any ideas please?
HTML:
<my-dir>
<p>My dir content</p>
<p><button ng-click="hideMe()">Hide element with isolated scope</button></p>
</my-dir>
JS:
var app = angular.module('myApp', []);
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
controller: ['$scope', function ($scope) {
$scope.hideMe = function(){
console.log('hideMe called');
};
}]
};
})
You have to declare your template inside the directive using template: property or inside an external .html file using templateUrl:"path/to/template.html"
Example using template :
var app = angular.module('myApp', []);
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
template : '<p>My dir content</p><p><button ng-click="hideMe()">Hide me</button></p>',
controller: ['$scope', function ($scope) {
$scope.hideMe = function(){
console.log('hideMe called');
};
}]
};
})
Example using templateUrl :
var app = angular.module('myApp', []);
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
templateUrl : 'my-dir.tpls.html',
controller: ['$scope', function ($scope) {
$scope.hideMe = function(){
console.log('hideMe called');
};
}]
};
})
Template : my-dir.tpls.html
<p>My dir content</p>
<p><button ng-click="hideMe()">Hide me</button></p>
HTML:
<my-dir></my-dir>
You can try this,
Directive:
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
link: function($scope, element, attrs) {
$scope.hideMe = function() {
alert('hideMe called');
}
}
}
});
HTML:
<div ng-controller="MyCtrl">
<my-dir>
<p>My dir content</p>
<p>
<button ng-click="hideMe()">Hide element with isolated scope</button>
</p>
</my-dir>
</div>
DEMO
Using the angular directive Max created on this post for easily importing SVGs, I've imported a handful of SVGs on my page. I now want to add a click event to an SVG, except the directive doesn't transfer the click method to the imported SVG. If I inspect the SVG in my browser I see that it is indeed missing the ng-click.
HTML
<svg-image class="svg foo" src="img/foo.svg" ng-click="bar()"></svg-image>
JS
$scope.bar = function() {
console.log("click");
};
If I move ng-click="bar()" to another element on my page it works just fine. I've also tried moving ng-click="bar()" to the svg file itself which didn't work, and I've tried doing what was suggested in this post which didn't work either.
plunker as requested: https://plnkr.co/edit/eqOZJO5Ar8oOmXCjg3Vs
One of possible solutions is to compile your new element and call resulting template function, passing in scope:
.directive('svgImage', ['$http', '$compile', function($http, $compile) {
return {
restrict: 'E',
link: function(scope, element, attrs) {
var imgURL = element.attr('src');
// if you want to use ng-include, then
// instead of the above line write the bellow:
// var imgURL = element.attr('ng-include');
var request = $http.get(
imgURL,
{'Content-Type': 'application/xml'}
);
scope.manipulateImgNode = function(data, elem){
var $svg = angular.element(data)[4];
var imgClass = elem.attr('class');
if(typeof(imgClass) !== 'undefined') {
var classes = imgClass.split(' ');
for(var i = 0; i < classes.length; ++i){
$svg.classList.add(classes[i]);
}
}
$svg.removeAttribute('xmlns:a');
angular.element($svg).attr("ng-click", attrs.ngClick);
return $compile($svg)(scope);
};
request.success(function(data){
element.replaceWith(scope.manipulateImgNode(data, element));
});
}
};
}]);
Plunker
Try this
var jimApp = angular.module("mainApp", []);
jimApp.controller('mainCtrl', function($scope){
$scope.bar = function() {
console.log("click");
};
});
jimApp.directive('svgImage', function() {
return {
restrict: 'E',
replace: true,
scope: {
onClick: '&'
},
template: '<div ng-click="bar();">Hai</div>',
link: function(scope, element, attrs, fn) {
scope.bar = function(){
scope.onClick()();
}
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="mainApp" ng-controller="mainCtrl">
asas
<svg-image on-click="bar"></svg-image>
</div>
I am facing a small problem during the compilation of html code in angularjs. Here is the brief description of my problem :
$scope.report= reportdata;
reportdata is the html code that contains angularcontents like : {{name}} , {{firstname}} etc.
so, I am searching for a function that can compile the above html in my controller just like this :
$scope.compiledReportdata = function() {
$scope.compildeHtml = somefunction(reportdata);
}
Is there any function that can do the trick for me , Please suggest.
This is what i have tried i works for HTML but not for Controller
angular.module('myapp')
.directive('dynamic', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
ele.bind('blur', function () {
scope.$apply(attrs.uiBlur);
debugger
});
scope.$watch(attrs.dynamic, function (html) {
ele.html(html);
var data1 = ele.html(html);
var data2 = $compile(ele.contents())(scope);
$compile(ele.contents())(scope);
});
}
};
});
You can use the $interpolate service in the controller to interpolate the string...
var app = angular.module('app', ['ngSanitize']);
app.controller('controller', function ($scope, $interpolate) {
$scope.name = 'Costanza';
$scope.firstname = 'George';
$scope.report = '<strong>{{name}}</strong> , {{firstname}}';
$scope.compiledReportdata = function () {
return $interpolate($scope.report)($scope);
};
});
And you can use ngBindHtml with ngSanitize to display it...
<div ng-app="app" ng-controller="controller">
<div ng-bind-html="compiledReportdata()"></div>
</div>
JSFiddle
I am trying to pass some objects to a new browser window. I followed the suggestion from AngularJS: open a new browser window, yet still retain scope and controller, and services
It works on Chrome, but doesn't on IE. My shared objects are always undefined on IE. Any suggestions?
Code for simplified version of what I am trying to do
My parent html
<html ng-app="SampleAngularApp">
<body>
<div ng-controller="popupCtrl">
<my-popup foo="foo" abc="abc">Open Popup from here</my-popup>
</div>
</body>
</html>
My parent JS
var SampleAngularApp = angular.module('SampleAngularApp', []);
var popupCtrl = function ($scope) {
$scope.foo = { baz: 'qux' };
$scope.abc = "12345";
};
SampleAngularApp.directive('myPopup', ['$window', function ($window) {
return {
restrict: 'EA',
scope: {
foo: '=',
abc: '='
},
link: function (scope, elem, attrs) {
elem.css({ 'cursor': 'pointer' });
elem.bind('click', function () {
var popWdw = $window.open("popupWindow.html", "popupWindow", "width=500,height=500,left=100,top=100,location=no");
popWdw.abc = scope.abc;
popWdw.foo = JSON.stringify(scope.foo);
});
}
};
}]);
My popup html
<html ng-app="PopupApp">
<body ng-controller="childCtrl">
</body>
</html>
My popup JS
var PopupApp = angular.module('PopupApp', []);
var childCtrl = function ($scope) {
alert(window.foo);
};
PopupApp.controller(childCtrl);
Per shaunhusain and Sunil D's suggestions, I have changed my code as below and it works
My parent JS
link: function (scope, elem, attrs) {
elem.css({ 'cursor': 'pointer' });
elem.bind('click', function () {
$window.abc = scope.abc;
$window.foo = JSON.stringify(scope.foo);
var popWdw = $window.open("popupWindow.html", "popupWindow", "width=500,height=500,left=100,top=100,location=no");
});
}
My popup JS
var childCtrl = function ($scope) {
alert(window.opener.foo);
};
I need to develop a workflow editor in Angularjs
This requires a directive(inner) that should add a div with some data and data for this directive should come from another directive(outer)
series of divs will be added right, top or bottom based on parameters.
Since you didn't post any code or exact requirements, please take a look on this demo where it shows calling directive from other directive:
HTML
<div ng-controller="MyCtrl">
<div directive-foo></div>
JS
var app = angular.module('myApp',[]);
app.directive('directiveFoo', function() {
return {
template: '<div directive-bar="123">bar</div>',
replace: true,
controller: function() {
console.log('in foo ctrl');
this.isFooAlive = function() {
return 'Foo is alive and well';
}
}
}
});
app.directive('directiveBar', function() {
return {
controller: function() {
console.log('in bar ctrl');
},
require: 'directiveFoo',
link: function(scope, element, attrs, fooCtrl) {
console.log(fooCtrl.isFooAlive());
}
}
});
function MyCtrl($scope) {
}
FIDDLE DEMO
Hope it will help you