How to pass data to angular-strap popover - angularjs

I'm trying to show angular-strap popover when hovering on fullcalendar items.
I am using eventMouseover/eventMouseout callbacks to show/hide the popover:
$scope.calendarConfig = {
defaultView: 'basicWeek',
eventMouseover: function(event, jsEvent, view) {
element = $(jsEvent.target).closest('.fc-event');
popover = $popover(element, {placement: 'bottom', contentTemplate: 'calendar-item-popover.html'});
popover.$promise.then(popover.show);
},
eventMouseout: function() {
popover.hide();
popover = null;
}
};
Then I have a popover body template:
<script type="text/ng-template" id="calendar-item-popover.html">
<p>Event</p>
<p>event: {{event | json}}</p>
</script>
My question is how can I pass the 'event' to popover scope?
Here is the plunker: http://plnkr.co/9c6BDWsYuuWAfI4HnJAH

I have a working solution; popover's scope can be accessed with popover.$scope:
popover.$scope.event = event
Working plunker:
http://plnkr.co/W8n6LxsLCyZFO6ufPHvW
Not sure if that's an optimal solution, so I will wait some time for feedback.

Related

Not able to display ui-grid in ui-bootstrap modal windown

[SOLVED] I figured this out. The issue is related to modal sizing, if you resize the window the grid will be displayed. Adding auto-resizing directive solved the problem. See more details at http://ui-grid.info/docs/#/tutorial/213_auto_resizing
I have the impression that there is some sort of conflict between the grid's style and bootstrap style (CSS and DIVs structure)...
[ORIGINAL POTS]
Help wanted!
I am not able to display an ui-grid in a modal window generated by ui-bootstrap. The modal window comes up but the grid is not rendered. I am able to render other grids outside a modal window.
Basically speaking, it is hosted in Plunker. This is what I have:
index.html
<div ng-controller="TradeListController">
<button type="button" ng-click="openBoardgamegeekSearchWindow()">Search Board Game in Modal Window</button>
</div>
components/MtApp.js
var mtApp = angular.module('mtApp', ['ui.bootstrap', 'ui.grid']);
var TradeListController = function($scope, $modal) {
//=== Modal Window : Boardgamegeek Search ===//
$scope.openBoardgamegeekSearchWindow = function() {
console.log("Opening boardgamegeek search in modal window.");
var modalWindow = $modal
.open({
templateUrl: 'components/boardgamegeek/boardgamegeek-search.html',
controller: 'BoardgamegeekSearchController',
});
modalWindow.result.then(function(modalReturn) {
console.log("Boardgamegeek search window returned: ", modalReturn);
}, function() {
console.log('Boardgamegeek search window returned dismissed.');
});
};
};
angular.module('mtApp').controller('TradeListController', TradeListController);
var BoardgamegeekSearchController = function($scope, $modalInstance) {
//=== Properties ===//
$scope.boardGames = [{
tradeListId: 666666666,
boardgamegeekId: 42533,
name: "QWERTY",
thumbnailURL: "http://cf.geekdo-images.com/images/pic485388_mt.jpg"
}];
//=== Grid to render board games ===//
$scope.gridOptions = {
data: $scope.boardGames,
columnDefs: [{
field: 'name',
name: 'Name'
}]
};
};
angular.module('mtApp').controller('BoardgamegeekSearchController', BoardgamegeekSearchController);
components/boardgamegeek/boardgamegeek-search.html
<div ui-grid="gridOptions"></div>
gridOptions = {{gridOptions}}
I figured this out. The issue is related to modal sizing, if you resize the window the grid will be displayed.
Adding auto-resizing directive solved the problem.
See more details at http://ui-grid.info/docs/#/tutorial/213_auto_resizing
I have the impression that there is some sort of conflict between the grid's style and bootstrap style (CSS and DIVs structure)...
This link can be useful , it covers a basic guide to migrate from ng-grid to ui-grid https://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/

$scope is not available to ng-template

I'm trying to use modal for editing a form, the modal is in ng-template script, but the form data is not displayed when clicking the edit button.
The $scope is not available to the template script.
I have created a Plunker here
$scope.setCurrentItem = function (item) {
$scope.currentItem = item;
};
$scope.edit = function (item) { //editing item
$scope.setCurrentItem(angular.copy(item));
//$scope.editItem = item;
openEditModal();
};
<!--html-->
<script type="text/ng-template" id="myModalContent.html">
<label for="name">Role: </label>
<input type="text" ng-model="currentItem.roleName" required />
</script>
How can I fix that?
By default ui bootstrap $modal uses $rootScope as its default scope. But you are assuming it will automatically take the scope of the controller that opened the dialog, which does not happen. But there is a scope property that you can set to pass the scope to the ui modal so that it will use that scope and create a child scope out of the provided scope and will be used as the underlying scope for the modal. So have your modal wrapper take the scope property as well in its settings and pass it through.
From Doc
scope - a scope instance to be used for the modal's content (actually the $modal service is going to create a child scope of a provided scope). Defaults to $rootScope.
Example changes:-
function openEditModal() {
var modalOptions = {
closeButtonText: 'Cancel',
actionButtonText: 'Save role',
headerText: 'Edit role',
bodyText: '',
scope:$scope //<-- Pass scope
};
Modal.showModal({ templateUrl: 'myModalContent.html', size: 'lg' }, modalOptions).then(function (result) {
console.log("save!", result);
});
}
and in your service:-
/*I just did this here based on my limited understanding of your code*/
return $modal.open(angular.extend(tempModalDefaults, customModalOptions)).result;
From your modal template pass the item back, i am not sure if your template is generic, if so then you may want to take a different approach to transfer the data back:-
<button class="btn btn-primary" ng-click="modalOptions.ok(currentItem)">{{modalOptions.actionButtonText}}</button>
Demo

Bootstrap popover inside angular repeats form content whenever opened

I am showing a form inside of a popover. The popover opens on the click of a button. The issue is that every time I click the button to open the popover, the same form gets appended to the existing popover. Here's my code:
$('.filter-node-btn').popover({
trigger:'click',
html : true,
placement: 'bottom',
content: function() {
return $compile($(".filterNodeDialog").html())($scope);
}
});
update
I found the issue while writing a jsfiddle for this problem. It worked in the fiddle but not my local environment. I am using bootstrap js 3.1.1 while for fiddle I tried bootstrap js 3.0. heres the line thats giving me issue in boostrap.js
bootstrap 3.1.1
Popover.prototype.setContent = function () {
....
$tip.find('.popover-content')[ // we use append for html objects to maintain js events
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' ](content)
...
}
bootstrap 3.0 the code says
Popover.prototype.setContent = function () {
....
$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
...
}
If I tried replacing the older code it works in my local environment too. http://jsfiddle.net/46Z59/6/
My question is how do I fix it with the bootstrap 3.1.1 ?
Updated Answer
Anything having to do with DOM should go into a directive and not a controller. In fact, by transitioning to a directive, your problem can be easily solved.
Placing your popover HTML into a template that is included in a directive will cause its content will be compiled by Angular automatically. In this case, a manual $compile using content extracted from the DOM by jQuery -- which seems to be at the root of the problem -- is unnecessary.
Such a directive might look like this:
.directive('myPopover', function($compile){
return {
restrict: 'EA',
controller: function($scope){
$scope.clearFilter = function(){
$scope.filterOption = "";
};
$scope.setFilterOption = function(){
console.log("filter option :",$scope.filterOption);
if($scope.filterOption == 'hdnodes'){ }
else if($scope.filterOption == 'gnodes'){ }
else if($scope.filterOption == 'clusters'){ }
else if($scope.filterOption == 'standalones'){ }
};
},
link: function(scope, elem, attrs) {
elem.popover({
trigger:'click',
html : true,
placement: 'bottom',
content: function() {
return elem.find('div');
}
});
},
templateUrl: 'fn-dialog.html'
}
})
... where fn-dialog.html looks like this:
<!-- Button which opens popover when clicked -->
<button title="Filter" type="button" name="filter-node-btn" class="filter-node-btn">open</button>
<!-- Popover content -->
<div class="filterNodeDialog">
<div class="filterCriteriaContent">
<form name="filterCriteriaForm">
<input type="radio" name="filterOption" value="hdnodes" ng-model="filterOption" ng-change="setFilterOption();">
<span>All HD nodes</span>
[ the rest of the content for the popover ... ]
Plunker Demo

Bootstrap 3 Popover in Angular-UI Calendar

I'm using Angular-UI Calendar directive and Bootstrap 3 popover to attempt to create a popover on click. I tried using the day click event:
$scope.dayClick = function(event, allDay, jsEvent, view){
jsEvent.stopPropagation();
jsEvent.preventDefault();
var eventID = event.getDate();
eventID = jsEvent.target;
$(eventID).popover({
html: true,
title: 'Hello',
placement: 'bottom',
content: '<button id="close-me">Close Me!</button>'
}).parent().delegate('button#close-me', 'click', function() {
jsEvent.stopPropagation();
$(eventID).popover('hide');
return false;
});
$(eventID).popover('show');
};
The problem with this way is that it causes the calendar cells to push to the right at times or duplicate. Is there a better way I could attach the popover to the existing calendar?
Are you trying to create pop-over when any day is clicked?
If yes, then dayClick is the correct way for a popover.
Can you create a Plunk to provide more details.
I think the problem may be due to CSS.

backbone and twitter-bootstrap popover

This is a very similar question to Backbone not binding events to jQuery Popover - however the answer does not seem to meet my needs.
I wish to bind a (twitter bootstrap) popover to one of my views, but not sure how I am supposed to do it?
events : {
"hover .info" : "showDetails",
},
render : function(){
var content = this.template.tmpl(this.model.toJSON());
$(this.el).html(content);
return this;
},
showDetails : function() {
this.$(".info").popover({title: 'Hello', content: 'World'});
this.$(".info").popover('show');
console.log(this.model.get('description'));
},
My template looks like
<script type="text/template" id="item-template">
<div class="well listitem" style="padding: 14px 19px;">
<div class="row show-grid" title="Irregular three column layout">
<div class="span6">${heading}</div>
<div class="span1">${price}</div>
<div class="span1"><button class="btn info">Details</button></div>
</div>
</div>
</script>
So I am trying to show some text in the popover when the mouse enters the button and vanish when mouse leaves - however on mouse over
The popover appears with undefined as the heading
On mouse out it stays in position.
I think I am not binding properly but would be great if someone could see my mistake.
The problem is that the Jquery hover event needs two callback functions, one for mouseenter and one mouseleave. In your case you pass only one function that will call on mouseenter and open your popover. From the jquery docs:
Calling $(selector).hover(handlerIn, handlerOut) is shorthand for:
$(selector).mouseenter(handlerIn).mouseleave(handlerOut);
So change your code like this will fix your second problem:
events : {
"mouseenter .info" : "showDetails",
"mouseleave .info" : "hideDetails"
},
render : function(){
var content = this.template.tmpl(this.model.toJSON());
$(this.el).html(content);
return this;
},
showDetails : function() {
this.$(".info").popover({title: 'Hello', content: 'World'});
this.$(".info").popover('show');
console.log(this.model.get('description'));
},
hideDetails : function() {
this.$(".info").popover('hide');
},

Resources