Render from angularjs directive via eventRender Fullcalendar - angularjs

Is there a way to dynamically Render a template from angularjs directive via eventRender Fullcalendar ?
What I want to achieve is something like below:
eventRender: function(event, element, view) {
var template = '<my-directive></my-directive>';
element.find('.fc-event').append(template);
scope.$apply();
}
Following Documentation
The eventRender callback function can modify element.
For example, it can change its appearance via jQuery’s .css().
On eventRender insert the css classes with
eventRender: function (event, element) {
element.addClass(event.class)
}
Documentation on this topic is not broad in the subject.
It doesn't give any example of changing the template via Angularjs directives
and doesn't tell if there is any limitaion for template
to keep it treated by FullCalendar as event.
MyCodePen
EDITED_Code_Pen

1- add $compile to your controller
2- in eventRender make as bellow :
eventRender: function(event, element, view) {
var compiled = $compile('<div your-directive></div>')($scope);
element.find('.fc-content').replaceWith(compiled);
},
workingCodePen

Related

Custom search directive

I am building a small search app using AngularJS and Elasticsearch. I'm using AngularJS UI Bootstrap Typeahead for autocomplete functionality. Now I'm trying to create a custom search directive for the search functionality. Still learning AngularJS directives...
I should just be able to add the UI Bootstrap Typeahead directive to this custom search directive, right? (as an attr).
So I would just need to pass the suggestion function, search function and search terms (ng-model) to my custom search directive?
Using examples and citing from Angular Developer Guide: Directives.
Q1: "I should just be able to add the UI Bootstrap Typeahead directive to this custom search directive, right? (as an attr)."
A1: As your custom directives are dependency injected, you should be able to use any Angular component that you would normally dependency inject:
"Just like the module.controller API, the function argument in module.directive is dependency injected. Because of this, we can use $interval and dateFilter inside our directive's link function."
angular.module('docsTimeDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.format = 'M/d/yy h:mm:ss a';
}])
.directive('myCurrentTime', ['$interval', 'dateFilter', function($interval, dateFilter) {
Q2: "So I would just need to pass the suggestion function, search function and search terms (ng-model) to my custom search directive?"
A2: That is one way to do it, however your directive would be dependent on the controller host to have the functionality. If you go with this route you would do so with the & operator.
I would however go with the link property. Here your directive can have the code needed for calculations, and you can inject the search parameters into it with the = operator.
Link example of mine. I think you should be able to convert it to your problem easily :)
Directive:
function statisticsTableDirective(common) {
return {
restrict: 'E',
scope: {
tabledata: '='
},
templateUrl: 'app/statistics/statisticsTable.html',
link: function (scope, element, attrs) {
var vm = scope;
vm.isLastMonth = isLastMonth;
function isLastMonth(index) {
return index+1 === new Date().getMonth();
}
}
};
}
In the statisticsTable.html I can now use isLastMonth as it were directly on the scope. Like in a simple ng-class:
ng-class="::{highlight : isLastMonth($index)}"></td>

angularjs-- declenching events

Please, how can I change this code into angularJs
$('a.product_add').on('click', function(event){
event.preventDefault();
var collectionHolder = $('#task_tags');
var prototype = collectionHolder.attr('data-prototype');
form = prototype.replace(/__name__/g, collectionHolder.children().length);
collectionHolder.append(form);
});
First of all you need to show us what you've tried, but I'll write something here to help you
You should make a directive because you're using jquery code. Read more about directives here
AngularJS directives are extended HTML attributes with the prefix ng-.
The ng-app directive initializes an AngularJS application.
The ng-init directive initializes application data.
The ng-model directive binds the value of HTML controls (input,
select, textarea) to application data.
Example of a directive
app.directive('myDirective', function(){
function link($scope,$elem,$attrs){
$elem.on('click', function(event){
// click event code here
});
}
return {
link:link,
scope:{},
restrict:'A'
}
})
Example of usage for myDirective:
<a class='product_add' my-directive>link</a>
We can use angular custom directives.
Now you can access the element in the directive and do the same operations in the directive.
<directive-element ng-click=appendFunction()></directive-element>

JQuery UI event callbacks in Directives

I'm building an AngularJS app and would like some pointers on the way I'm structuring my Angular code.
For this module, I'd like to be able to click a button that will add a Div to a specific "parent div" that has JQuery UI draggable and resizable interactions attached to it.
They could add more than one Div that is draggable and resizable.
Right now, I have one directive that generates the whole Div. The event callback for when resizing is stopped is placed in the Button that has the directive attached to it.
Directive code gist:
var app = angular.module('myApp', []);
app.controller('IpadCtrl', function($scope) {
$scope.someFunc = function () {
console.log('resized');
alert('resized');
};
$scope.test = 'sup';
});
app.directive('addImageCont', function () {
return {
restrict: 'A',
link: function (scope, element, attributes) {
console.log(attributes);
element.on("click", function() {
var div = $("<div />").css({
'width': '100px',
'height': '100px',
'background-color': 'purple'
});
div.draggable();
div.resizable();
div.on('resizestop', function(event, ui) {
console.log(ui);
var cBack = scope[attributes.callback];
cBack();
});
element.parent().find('.ipad').append(div);
})
}
};
});
JSFiddle that has an example:
http://jsfiddle.net/GA2M8/3/
Is this the right way to handle callback events? I'd like to be able to have a callback for when resizing begins too.
I know there's a better way to handle this.
It has been suggested to me that I break up my directives.
One directive that just creates the Div and appends it to the Dom.
Another directive that attaches the JQuery UI draggable interaction to it.
Another directive that attaches the JQuery UI resizable interaction to it.
I'm not sure how to chain directives if that's how I should proceed.

How to trigger ngAnimate class sequence when using element.addClass inside directive

Inside of a directive I'm adding various classes on an element based on user interaction.
How can I get the ngAnimate class sequence (e.g. my-class-add -> my-class-add-active) when using element.addClass in place of ngClass directive?
I want to use CSS transitions, not JS animations.
Thanks.
You need to add the class via the animate service (angularjs 1.2) like
module.directive('directive', function ($animate) {
return {
restrict:"A",
link: function($scope,$element) {
$element.on("click", function() {
$animate.addClass($element,"my-animation");
});
};
}
});
Doc
Ideally you'd delegate that to another directive which is tied in with ngAnimate (i.e. ng-show, ng-if, ng-repeat .etc.)
You can set a scope property and let another directive handle the animation classes.

Angular-ui + D3: how to implement contextual menu (popover vs modal)?

Given the following use-case:
I use D3js to render objects which are managed by AngularJS. I would like to add interactivity to the D3 chart. When clicking on a svg element I would like to have a kind of popup menu allowing to modify the object properties. These properties are required by AngularJS but are not rendered by D3.
The D3-Angular integration is derived from http://bl.ocks.org/biovisualize/5372077 which uses a closure.
Current implementation:
As of today I am using the $modal service from angular-ui bootstrap to create the popup menu. From a functionnality point of view it works pretty well:
When clicking on a svg element, D3 dispatches an event
That event is catched by Angular which calls the $modal service
Within the modal window I modify the object properties
However I am not satisfied with the rendering. I would like the popup menu to look like a popover. It should be placed close to the svg element which was clicked.
As far as I understand, I have two options:
Continue to use the $modal service and modify its look. What approach should be taken? Using the windowClass option?
Stop using the $modal service and start hacking on the popover directive. The problem is that I do not think it is possible
to add such a directive to an svg element. The solution would be to
create a popover service close to the $modal service.
Which option should be chosen? and how to implement it?
EDIT:
Working plunker using a custom my-popover directive:
http://plnkr.co/edit/5KYvxi?p=preview
It is possible to add a directives to code generated by d3, only thing you need to ensure is that you call the $compile service on the content after it has been rendered.
For the given example, it would look something like this:
.directive('barChart', function($compile){ // inject $compile
var chart = d3.custom.barChart();
return {
restrict: 'E',
replace: true,
template: '<div class="chart"></div>',
scope:{
height: '=height',
data: '=data',
hovered: '&hovered'
},
link: function(scope, element, attrs) {
var chartEl = d3.select(element[0]);
chart.on('customHover', function(d, i){
scope.hovered({args:d});
});
scope.$watch('data', function (newVal, oldVal) {
chartEl.datum(newVal).call(chart);
$compile(element.contents())(scope); // <-- call to $compile
});
scope.$watch('height', function(d, i){
chartEl.call(chart.height(scope.height));
$compile(element.contents())(scope); // <-- call to $compile
})
}
}
And in the d3's drawing function:
bars.enter().append('rect')
.classed('bar', true)
.attr('myPopover', 'Text to show') // <-- Adding an attribute here.
.attr({x: chartW,
width: barW,
y: function(d, i) { return y1(d); },
height: function(d, i) { return chartH - y1(d); }
})
.on('mouseover', dispatch.customHover);
Demo

Resources