FullCalendar tooltip bug when dragging event in Resource timeline - javascript

I'm using JavaScript FullCalendar library to build my calendar. Now updating my codes to work with FullCalendar V4. When Dragging event in resource timeline view, the tooltip does not work as expected (duplicate tooltips show when dragging). This issue only happens in resource timeline view, not in dayGrid view. I've attached two codepen codes. Daygrid view works fine, but Resource timeline view does not.
https://codepen.io/nmwangxin/pen/WNeRQaX
https://codepen.io/nmwangxin/pen/qBWROKz
eventRender: function(info) {
var tooltip = new Tooltip(info.el, {
title: 'test',
placement: 'top',
trigger: 'hover',
container: 'body'
});
},

When dragging the event it gets re-rendered each time, so basically you are recreating a new tooltip each time thus creating multiple instances which in turn loose their reference to the element that gets destroyed hence it's odd placement.
I would suggest to hook into "eventMouseEnter" and "eventMouseLeave" callbacks and create and destroy a single tooltip object there.
Here is an example:
var tooltip = null;
eventMouseEnter: function(info) {
tooltip = new Tooltip(info.el, {
title: info.event.title,
placement: 'top',
trigger: 'hover',
container: 'body'
});
},
eventMouseLeave: function(info) {
if (tooltip) {
tooltip.dispose();
}
}
https://codepen.io/alex-hazanov/pen/rNBjPyL

Or use bootstrap's tooltip like this :
eventMouseEnter: function (info) {
$(info.el).tooltip({
title: info.event.title + '<br />' + info.event._instance.range.start,
html: true,
placement: 'top',
trigger: 'hover',
container: 'body',
});
}

Related

Find display type in FullCalendar callbacks

I am using FullCalendar to display events from two sources. I have one source to display them as background events and the other set to display as block events.
This works fine, but then I am using the eventClick callback. When I check the info.event.display property of the event clicked on, it returns as auto. In this callback I need to check this property to determine whether to do something or not.
This also is a problem with the eventDidMount callback. I was using that but have disabled it for now.
IE: In this case I only want a modal to appear if the display type is block.
Code:
let calendarEl = document.getElementById('calendar')
let loader = document.querySelector('.calendar-wrapper .loader')
let tooltip
let calendar = new Calendar(calendarEl, {
plugins: [dayGridPlugin],
firstDay: 1,
contentHeight: "auto",
aspectRatio: 1.5,
eventSources: [
{
url: '/api/trips.json',
display: 'background'
},
{
url: '/parks/visits.json',
display: 'block'
}
],
startParam: 'start',
endParam: 'end',
showNonCurrentDates: true,
loading: function (isLoading) {
if (isLoading) {
loader.style.display = 'flex'
} else {
loader.style.display = 'none'
}
},
headerToolbar: {
start: 'title',
center: 'prevYear,nextYear',
end: 'today prev,next'
},
// eventDidMount: function(info) {
// console.log(info.event);
// tooltip = new tippy(info.el, {
// theme: 'light-border',
// trigger: 'mouseenter',
// allowHTML: true,
// content: info.event.extendedProps.tooltipcontent,
// interactive: false,
// interactiveBorder: 0,
// animation: 'shift-away',
// moveTransition: 'transform 0.2s ease-out',
// zIndex: 99999,
// inertia: true,
// placement: 'top',
// touch: 'hold'
// })
// },
eventClick: function(info) {
console.log(info)
info.jsEvent.preventDefault()
let modal = document.querySelector('#modal-container')
modal.innerHTML = info.event.extendedProps.modalcontent
// tooltip.hide()
MicroModal.show('modal-visit')
}
})
Any suggestions?
It's because "background" is a property of the event source, not the event. Whilst that rule may then be applied when rendering, to control how the event appears, the event itself doesn't automatically have the value "background" set as the value for its own "display" property (because an individual event can potentially override the event source value for any given property).
Fortunately the event will contain a reference to the event source and, although the path to the information is convoluted (but fortunately discoverable by logging the event object to the Console), you can get the "display" property of the event source from it:
eventClick: function(info) {
alert(info.event.source.internalEventSource.ui.display);
}
Live demo: https://codepen.io/ADyson82/pen/BaQVyRO

How do I display Angular UI Bootstrap date picker on click?

I have an Angular app that uses Full Calendar. I have a Full Calendar custom button that when a user clicks, should open a Angular Bootstrap Datepicker. I'm currently toggling CSS visibility but for some reason, the date picker doesn't display (after clicking the button) unless I resize the window.
My template:
<div id="cal-go-to-date" ng-style="goToDate.style">
<div uib-datepicker ng-model="goToDate.dt" class="well well-sm" datepicker-options="goToDate.options"></div>
</div>
My Angular controller:
$scope.uiConfig = {
calendar: {
// Other configuration
header: {
center: 'title'
},
customButtons: {
goToDate: {
text: 'go to date',
click: function(event) {
$scope.goToDate.style.visibility = 'visible';
}
}
},
// Other configuration
}
};
$scope.goToDate = {
dt: new Date(),
options: {
datepickerMode: 'month',
minMode: 'month'
},
style: {
'position': 'absolute',
'top': '224px',
'left': '76px',
'min-height': '290px',
'z-index': '99999',
'visibility': 'hidden'
}
};
I am calling $scope.goToDate.style.visibility = 'visible'; but that doesn't work unless I resize the window. What can I do to toggle the visibility of the picker?
Try wrapping the call with $applyAsync like:
$scope.$applyAsync(function(){ $scope.goToDate.style.visibility = 'visible'; });
since it looks like this happens outside of angularjs scope.
If its the problem resizing try using this function
$scope.windowResize = function () {
setTimeout("$(window).trigger('resize')",400);
};
and then call this function on the click of that button .
Hope it might help

Destroy bootstrap-popover after mousedown event is completed

I want to destroy a specific popover when the mousedown event is completed. As long as the user presses on the mouse, the popover is visible. When the user isn't anymore, there should be a delay of let's say 3.5 seconds, then it should be destroyed.
My current implementation displays the popover correctly as long as the mousedown is true, but when I release the mouse, the popover is destroyed immediately, without a delay. What shoud I do?
jQuery:
function destroyPopover(selector)
{
setTimeout(function () {
$(selector).popover('destroy');
}, 3500);
}
...
$('#otp_table').on('mousedown', 'td', function() {
$(this).popover({
container: 'body',
content: 'Lorem ipsum',
placement: 'top',
}).popover('show');
}, hidePopover(this));
To correct my problem, I've added this line in the popover object:
delay: { "hide": 3500 },
which gives this...
$('#otp_table').on('mousedown', 'td', function() {
$(this).popover({
container: 'body',
delay: { "hide": 3500 },
content: 'Lorem ipsum',
placement: 'top',
}).popover('show');
}, destroyPopover(this);
also, I've removed the setInterval in my destroyPopover() function, which gives this...
function destroyPopover(selector)
{
$(selector).popover('destroy');
}
Hope it will be useful!

load jquery tabs on dynamically added content

So i'm trying to load tabs in a modal window, and it's not calling the JS .tabs() method im wondering what i'm doing wrong:
http://jsfiddle.net/uMTC7/24/
I don't know if there is a conflict between the bootstrap tab() method, but i suppose it could be a possibility.
$('.launcher').on('click',function() {
var domhtml ='<div id="tabs">'+
'<ul>'+
'<li>Nunc tincidunt</li>'+
'<li>Proin dolor</li>'+
'<li>Aenean lacinia</li>'+
'</ul>'+
'<div id="tabs-1"><p>Tab 1 Stuff</p></div>'+
'<div id="tabs-2">'+
'<p>Tab 2 Stuff</p></div>'+
'<div id="tabs-3"><p>Tab 3 Stuff</p></div></div>';
BootstrapDialog.show({
title: 'Draggable Dialog',
message: domhtml,
draggable: true,
buttons: [{
label: 'Cloze',
cssClass: 'btn-primary',
action: function(dialog){
dialog.close();
}
}]
});
//this does not load:
$( "#tabs" ).tabs();
});
Your script would start executing as soon as your document is ready, binding all the events to the corresponding elements. Since your div#tabs is created only on click of the button, and is not available prior to that, none of the events would get bound to it.
Hence, you have to pass your elements with all the handlers attached. You can do that either as shown below, or you can bind them within your click function and pass the final variable to the message option. Updated fiddle here
BootstrapDialog.show({
title: 'Draggable Dialog',
message: function(dialog){
var $content = $(domhtml);
$($content).tabs();
return $content;
},
draggable: true,
buttons: [{
label: 'Cloze',
cssClass: 'btn-primary',
action: function(dialog){
dialog.close();
}
}]
});

Load new panel.Panel when click on items in tree.Panel

I'm new in ExtJS
I need load new panel every time when I click on item in tree.Panel
Here is my code creating new panel (by default)
var contentPanel = Ext.create('Ext.panel.Panel', {
id: 'content-panel',
region: 'center',
layout: 'card',
activeItem: 0,
border: false,
items: [dict_modules['profiles-area']]
});
This code for creating tree.Panel
var treePanel = Ext.create('Ext.tree.Panel', {
id: 'tree-panel',
store: store,
height: '100%',
rootVisible: false
});
this is my click handler for tree.Panel
treePanel.getSelectionModel().on('select', function(selModel, record){
if (record.get('leaf')) {
contentPanel.removeAll(true);
contentPanel.add([dict_modules[record.data.id + '-area']]);
contentPanel.doLayout();
}
});
When my app is loaded, it looks like this
Once I click on the "specialty" it looks like this (all right(!!!))
BUT(!!!), once I click on "Profiles", it looks like this (WHY????)
On top of "content-panel" you can see some line
And if I again click on "Specialty", it looks like this (WHY???)
There are no lines at the top! Why??? What I'm do incorrect?
This code solved problem
treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {
Ext.getCmp('content-panel').layout.setActiveItem(record.getId() + '-area');
}
});

Categories

Resources