fullCalendar + Bootstrap tabs glitch: not rendering events until resizing browser - javascript

I'm having a strange problem when using fullCalendar along with Bootstrap, having the calendar rendered within a non active tab pane. I'm using the AgendaView, and it's initially displayed with the column for hours with just 1 pixel of width assigned to it.
It's placed within the "Operarios" tab.
But the biggest problem is when rendering the events. They all are displayed compressed at the top of the timetable.
Then if I resize the browser, or the frame, if I'm using Chrome Dev Tools or similar, then it's automatically re-rendered and it's correctly displayed.
You may check it out here:
https://codepen.io/luisapuyen/pen/RYXZPr
The HTML:
+ function($) {
$(function() {
var opcionesCalendario = {
selectable: true,
unselectAuto: false,
locale: 'es',
defaultView: 'agendaWeek',
header: false,
footer: false,
height: 400,
columnHeaderFormat: 'ddd',
eventColor: '#ffdc11',
views: {
agenda: { // name of view
titleFormat: '',
allDaySlot: false,
slotEventOverlap: false,
minTime: '07:00:00',
maxTime: '23:00:00',
slotDuration: '01:00:00',
footer: false
}
},
select: function(startDate, endDate, event, view) {
var evento = [{
start: startDate,
end: endDate
}];
$calendario.fullCalendar('addEventSource', evento);
console.log('selected ' + startDate.format() + ' to ' + endDate.format(), view);
}
},
$body = $('body'),
$tabs = $body.find('#tabs-panel-autovisita'),
$forms = $body.find('form'),
$operariosSel = $forms.filter('[name="operarios"]').find('select[name="operarios"]')
$calendario = $body.find('.calendario').fullCalendar(opcionesCalendario);
// INICIO
init();
function init() {
mostrarRangos();
$operariosSel.on('change', function() {
mostrarRangos();
});
}
function obtenerDiaInicial() {
return moment().isoWeekday(1);
}
function mostrarRangosOperarioCalendario(rangos) {
var diaInicialMoment = obtenerDiaInicial(),
diaMoment,
diaSemana,
eventos = [];
$.each(rangos, function(i, rango) {
diaSemana = +rango.dia_semana - 1;
diaMoment = diaInicialMoment.clone().add(diaSemana, 'days');
eventos.push({
start: moment(diaMoment.format('YYYY-MM-DD') + 'T' + rango.hora_inicio),
end: moment(diaMoment.format('YYYY-MM-DD') + 'T' + rango.hora_fin)
});
});
$calendario.fullCalendar('removeEvents')
$calendario.fullCalendar('renderEvents', eventos);
}
function obtenerRangosOperario(idOp) {
// ajax request that returns:
var res = JSON.parse('{"rangos":[{"dia_semana":"2","hora_inicio":"11:00:00","hora_fin":"13:00:00"},{"dia_semana":"1","hora_inicio":"09:00:00","hora_fin":"14:00:00"},{"dia_semana":"4","hora_inicio":"10:00:00","hora_fin":"17:00:00"},{"dia_semana":"3","hora_inicio":"14:00:00","hora_fin":"18:00:00"}],"ok":"1"}');
mostrarRangosOperarioCalendario(res.rangos);
}
function mostrarRangos() {
var idOp = +$operariosSel.val();
obtenerRangosOperario(idOp);
}
});
}(jQuery);
<div class="container">
<div class="row">
<div class="col-sm">
<h3>Configuración Auto-visitas</h3>
<nav>
<div class="nav nav-tabs" id="tabs-autovisita" role="tablist">
<a class="nav-item nav-link active" data-toggle="tab" role="tab" href="#general">General</a>
<a class="nav-item nav-link" data-toggle="tab" role="tab" href="#operarios">Operarios</a>
<a class="nav-item nav-link" data-toggle="tab" role="tab" href="#companyias">Compañías</a>
</div>
</nav>
<div class="tab-content">
<div class="tab-pane show active" id="general" role="tabpanel">
</div>
<div class="tab-pane" id="operarios" role="tabpanel">
<form method="post" name="operarios">
<div class="form-group">
<label>Operarios</label>
<select name="operarios" class="form-control dato">
<option value="0">Todos</option>
</select>
</div>
<div class="calendario dato"></div>
<button type="submit" class="btn btn-primary guardar">Guardar</button>
</form>
</div>
<div class="tab-pane" id="companyias" role="tabpanel">
</div>
</div>
</div>
</div>
</div>
I'm not sure whether it's a bug produced when using fullCalendar and Bootstrap together.
The only way I've found it works is having the calendar in the active pane at first. But since semantically it corresponds to the first tab to be the one which must be active, I'd like to find a better solution.
Any ideas?

Fullcalendar is failing to retrieve sizes and dimensions of elements because they are set to display: none. You can see that from computed styles on page refresh. Your events are supposed to have a top and bottom set but instead they receive a value of 0 for both.
This is why your events are all "displayed compressed at the top of the timetable".
A simple fix is to listen for a tab change event and re-render fullcalendar.
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
$calendario.fullCalendar( 'rerenderEvents' );
});
Here's a functioning example.

In React fullcalendar (version 5), I could not call the render or rerender method.
FullCalendar automatically updates size if it listens to window resize events. I just the trigger resize event when the calendar tab is visible with some delay.
Refer following code
setTimeout(() => window.dispatchEvent(new Event('resize')), 500)

Related

Iframe invoked with Youtube API does not appear after Vue.js V-if command

I use Vue.Js in my project.
I tried Iframe invoked with Youtube Api but iframe that use this api in a hide element from " v-if " contribution .
Video in iframe worked but vide is not show.Just have a sound but video is not show.
I tried solution that at this links but I can not.
StackOverFlow Solutions 1
My Code html code:
<div id="egitim">
<div class="row">
<div class="col-md-12" v-if="type=='list'">
//...there another code block
</div>
<div class="col-md-12" v-if="type=='detail'" id="det">
<div class="col-md-3 bosluk">
<button class="btn btn-block btn-danger" type="button" v-on:click="goBack()">
<i class="fa fa-arrow-left"></i>
Geri Dön
</button>
</div>
<div class="clearfix"></div>
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
<li><a data-toggle="tab" href="#menu1" v-if="detail.Id>0">Personel</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">
<div class="col-md-12">
<div id="playerX">
</div>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
and my vue.js code
var faturaList = Vue.component("egitim", {
template: "#egitim",
created: function () {
this.getList();
// $("#playerX").hide();
},
updated: function () {
},
data: function () {
return {
type: "list",
list: [],
detail: {},
tutorialPersonel: [],
personel: [],
ilgiliSinavCaption: "",
sinavModal: [],
done: false
}
},
props: {
},
filters: {
},
methods: {
getList: function () {
},
getDetail(id) {
var self = this;
axios.post("./ws.asmx/GetTutorialDetail", { id: id }).then(function (r) {
var d = JSON.parse(r.data.d);
self.detail = d.Tutorial;
self.tutorialPersonel = d.Personel;
// $("#playerX").css("visibility","visible");
// changeVideo(self.detail.ItemLink.split("youtu.be/")[1]);
var player;
var x = self.detail.ItemLink.split("youtu.be/")[1]
player = new YT.Player('playerX', {
height: '390',
width: '640',
videoId: x,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
});
self.type = "detail";
pWaitHide();
}).catch(function (r) {
pWaitHide();
console.log(r);
$.ms.hataMesaji("Bir hata ile karşılaşıldı");
});
}
}
After doing some in-depth research, I realize that the event is caused entirely by a mistake of the v-if command.
If you use "v-show" instead of "v-if", you'll see that $ ("# anyElement"). css ("visibility", "visible") in jquery is the counterpart.
Thank you for all

Lightslider bugging out inside featherlight on second click

FIDDLE: http://jsfiddle.net/2patspw2/3429/
I am using featherlight as my modal box and am running lightslider inside of it. It runs fine the first time it is clicked, but them for some reason it seems to bug out and duplicate itself. I had thought it might be duplicate slides so I read light slider documentation and added this:
onSliderLoad: function(el) {
el.lightGallery({
selector: '.gal .lslide'
});
This didn't fix the problem, so then I tried doing an each() of function (index) like so:
$('.inline').each(function(index) {
$(document).on("click", '.modal', function() {
// relevant code
});
});
I bound it to a delegated event since I have to activate via an on:click. However the element still seems to duplicate itself?
HTML:
<a href=".inline" class="modal" data-featherlight>Inline</a>
<div class="inline">
<ul class="gal">
<li data-thumb="http://sachinchoolur.github.io/lightslider/img/cS-1.jpg">
<img src="http://sachinchoolur.github.io/lightslider/img/cS-1.jpg"> TEST!!!!
</li>
<li data-thumb="http://sachinchoolur.github.io/lightslider/img/cS-2.jpg">
<img src="http://sachinchoolur.github.io/lightslider/img/cS-2.jpg"> YEAH!!!
</ul>
</div>
<a href=".inline-two" class="modal" data-featherlight>Inline2</a>
<div class="inline-two">
<ul class="gal">
<li data-thumb="http://sachinchoolur.github.io/lightslider/img/cS-1.jpg">
<img src="http://sachinchoolur.github.io/lightslider/img/cS-1.jpg"> asfasdf
</li>
<li data-thumb="http://sachinchoolur.github.io/lightslider/img/cS-2.jpg">
<img src="http://sachinchoolur.github.io/lightslider/img/cS-2.jpg"> YEAH!!!
</ul>
</div>
jQuery:
$(document).each(function(index) {
$('.modal').on("click", function() {
$('.gal').lightSlider({
gallery: true,
item: 1,
loop: true,
thumbItem: 9,
slideMargin: 0,
enableDrag: false,
currentPagerPosition: 'left',
onSliderLoad: function(el) {
el.lightGallery({
selector: '.gal .lslide'
});
}
});
})
});
Why is the carousel essentially duplicate the navigation and bugging out?
Note I tried doing loop: false as well, and it didn't change anything.

fullcalnder not calls on button click and inside any function

I am using fullcalendar.
When my page loads fullcalendar loads properly.
Now, I want to retrieve new data from table and want to display it on calendar.
For that, I call an ajax on button click, The ajax will retrieve the new data from table and display on fullcalendar.
But i am getting an error in firebug console.
TypeError: $(...).fullCalendar is not a function
It works when page will load, but when i used it in a function or any click event it wont works.
Here is my code. Please check it and suggest me.
<script>
$(document).ready(function() {
var today = new Date();
// This works because it calls on page load
$('#calendars').fullCalendar({
header: {
right: 'month,agendaWeek,agendaDay,prev,next today'
},
defaultDate: today,
editable: true,
navLinks: true, // can click day/week names to navigate views
eventLimit: true, // allow "more" link when too many events
events: {
url: 'fullcalendar/demos/php/get-events.php',
error: function(eee) {
$('#script-warning').show();
}
},
loading: function(bool) {
$('#loading').toggle(bool);
}
});
// This doesn't works because it calls on button click. It gives me TypeError: $(...).fullCalendar is not a function
$("#clickme").click(function(){
var timezone = localStorage.getItem("timezone");
var start = "2016-10-16";
var end = "2016-10-21";
$('#calendars').fullCalendar({
events: function(start, end, timezone, callback) {
$.ajax({
url: "fullcalendar/demos/php/get-events.php?mode=customdate&start=" + start + "&end=" + end,
type: 'json',
success: function(doc) {
var events = [];
$(doc).find('event').each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start') // will be parsed
});
});
callback(events);
}
});
}
});
});
});
</script>
<div id='script-warning'>
<code>php/get-events.php</code> must be running.
</div>
<div id='loading'>loading...</div>
<div>
<div class="row" style="border-top:2px solid">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4" style="border-right:1px solid">
<div id='overviewDatePicker' style='margin-bottom:10px;margin-top:90px'></div>
<div><b>Filter By Eventname</b></div>
<div>
<input type="text" placeholder="Search"/>
</div>
<div><b>Filter By Stage</b></div>
<ul style="list-style:none">
<li><span class="glyphicon glyphicon-flag" style="margin:3px"></span>Tentative Booking</li>
<li><span class="glyphicon glyphicon-ok" style="margin:3px"></span>Complete Booking</li>
</ul>
<br><br><br>
</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8" id="eventcalendar">
<button id="clickme"> Click</button>
<div id="calendars"></div>
</div>
</div>
</div>
I have update my code according your code. Please check on click function where I have made changes modified you code accordingly and let me know outcome
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.css" />
<script>
$(document).ready(function() {
var today = new Date();
// This works because it calls on page load
$('#calendars').fullCalendar({
header: {
right: 'month,agendaWeek,agendaDay,prev,next today'
},
defaultDate: today,
editable: true,
navLinks: true, // can click day/week names to navigate views
eventLimit: true, // allow "more" link when too many events
events: {
url: 'fullcalendar/demos/php/get-events.php',
error: function(eee) {
$('#script-warning').show();
}
},
loading: function(bool) {
$('#loading').toggle(bool);
}
});
// Please check this part only
$("#clickme").click(function(){
var timezone = localStorage.getItem("timezone");
var start = "2016-10-16";
var end = "2016-10-21";
$.ajax({
url: "fullcalendar/demos/php/get-events.php?mode=customdate&start=" + start + "&end=" + end,
type: 'json',
success: function(doc) {
var events = [];
$(doc).find('event').each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start') // will be parsed
});
});
//$("#calendars").fullCalendar('removeEvents'); //If you want to remove existing events from calender
$("#calendars").fullCalendar('addEventSource', events);
}
});
});
});
</script>
</head>
<body>
<div id='script-warning'>
<code>php/get-events.php</code> must be running.
</div>
<div id='loading'>loading...</div>
<div>
<div class="row" style="border-top:2px solid">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4" style="border-right:1px solid">
<div id='overviewDatePicker' style='margin-bottom:10px;margin-top:90px'></div>
<div><b>Filter By Eventname</b></div>
<div>
<input type="text" placeholder="Search"/>
</div>
<div><b>Filter By Stage</b></div>
<ul style="list-style:none">
<li><span class="glyphicon glyphicon-flag" style="margin:3px"></span>Tentative Booking</li>
<li><span class="glyphicon glyphicon-ok" style="margin:3px"></span>Complete Booking</li>
</ul>
<br><br><br>
</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8" id="eventcalendar">
<button id="clickme"> Click</button>
<div id="calendars"></div>
</div>
</div>
</div>
</body>
</html>

Response menu not collapsing and reloads page

At http://www.dentalo.se/contact it is using a responsive menu for mobile devices.
When clicking on the menu button it collapses the menu but the same time reloads the page.
Can anyone tell my why and how I can fix it?
Thanks for the time you are taking to help me.
Edit
HTML
<div class="container">
<div class="navbar-header">
<!-- BEGIN RESPONSIVE MENU TOGGLER -->
<button type="button" class="navbar-toggle btn navbar-btn" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- END RESPONSIVE MENU TOGGLER -->
<!-- BEGIN LOGO (you can use logo image instead of text)-->
<a class="navbar-brand logo-v1" href="/">
<img src="/assets/img/logo_blue.png" id="logoimg" alt="">
</a>
<!-- END LOGO -->
</div>
<!-- BEGIN TOP NAVIGATION MENU -->
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li id="MainMenuHome">Start</li>
<li class="dropdown" id="MainMenuDentalo">
<a class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false" href="#">
Dentalo
<i class="icon-angle-down"></i>
</a>
<ul class="dropdown-menu">
<li id="SubMenuAbout">Om Dentalo</li>
<li id="SubMenuJob">Lediga tjänster</li>
<li id="SubMenuConnect">Anslut</li>
</ul>
</li>
<li id="MainMenuLogIn">Logga in</li>
<li id="MainMenuContact">Kontakt</li>
<li class="menu-search">
<span class="sep"></span>
<i class="icon-search search-btn"></i>
<div class="search-box">
<form action="#">
<div class="input-group input-large">
<asp:TextBox runat="server" placeholder="Sök..." CssClass="form-control" ID="textBoxSearch"></asp:TextBox>
<span class="input-group-btn">
<asp:Button runat="server" CssClass="btn theme-btn" ID="ButtonSearch" OnClick="ButtonSearch_Click" Text="Sök" />
</span>
</div>
</form>
</div>
</li>
</ul>
</div>
<!-- BEGIN TOP NAVIGATION MENU -->
</div>
JavaScript
/*
* Project: Twitter Bootstrap Hover Dropdown
* Author: Cameron Spear
* Contributors: Mattia Larentis
*
* Dependencies?: Twitter Bootstrap's Dropdown plugin
*
* A simple plugin to enable twitter bootstrap dropdowns to active on hover and provide a nice user experience.
*
* No license, do what you want. I'd love credit or a shoutout, though.
*
* http://cameronspear.com/blog/twitter-bootstrap-dropdown-on-hover-plugin/
*/
;(function($, window, undefined) {
// outside the scope of the jQuery plugin to
// keep track of all dropdowns
var $allDropdowns = $();
// if instantlyCloseOthers is true, then it will instantly
// shut other nav items when a new one is hovered over
$.fn.dropdownHover = function(options) {
// the element we really care about
// is the dropdown-toggle's parent
$allDropdowns = $allDropdowns.add(this.parent());
return this.each(function() {
var $this = $(this),
$parent = $this.parent(),
defaults = {
delay: 500,
instantlyCloseOthers: true
},
data = {
delay: $(this).data('delay'),
instantlyCloseOthers: $(this).data('close-others')
},
settings = $.extend(true, {}, defaults, options, data),
timeout;
$parent.hover(function(event) {
// so a neighbor can't open the dropdown
if(!$parent.hasClass('open') && !$this.is(event.target)) {
return true;
}
if(shouldHover) {
if(settings.instantlyCloseOthers === true)
$allDropdowns.removeClass('open');
window.clearTimeout(timeout);
$parent.addClass('open');
}
}, function() {
if(shouldHover) {
timeout = window.setTimeout(function() {
$parent.removeClass('open');
}, settings.delay);
}
});
// this helps with button groups!
$this.hover(function() {
if(shouldHover) {
if(settings.instantlyCloseOthers === true)
$allDropdowns.removeClass('open');
window.clearTimeout(timeout);
$parent.addClass('open');
}
});
// handle submenus
$parent.find('.dropdown-submenu').each(function(){
var $this = $(this);
var subTimeout;
$this.hover(function() {
if(shouldHover) {
window.clearTimeout(subTimeout);
$this.children('.dropdown-menu').show();
// always close submenu siblings instantly
$this.siblings().children('.dropdown-menu').hide();
}
}, function() {
var $submenu = $this.children('.dropdown-menu');
if(shouldHover) {
subTimeout = window.setTimeout(function() {
$submenu.hide();
}, settings.delay);
} else {
// emulate Twitter Bootstrap's default behavior
$submenu.hide();
}
});
});
});
};
// helper variables to guess if they are using a mouse
var shouldHover = false,
mouse_info = {
hits: 0,
x: null,
y: null
};
$(document).ready(function() {
// apply dropdownHover to all elements with the data-hover="dropdown" attribute
$('[data-hover="dropdown"]').dropdownHover();
// if the mouse movements are "smooth" or there are more than 20, they probably have a real mouse
$(document).mousemove(function(e){
mouse_info.hits++;
if (mouse_info.hits > 20 || (Math.abs(e.pageX - mouse_info.x) + Math.abs(e.pageY - mouse_info.y)) < 4) {
$(this).unbind(e);
shouldHover = true;
}
else {
mouse_info.x = e.pageX;
mouse_info.y = e.pageY;
}
});
});
// for the submenu to close on delay, we need to override Bootstrap's CSS in this case
var css = '.dropdown-submenu:hover>.dropdown-menu{display:none}';
var style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
$('head')[0].appendChild(style);
})(jQuery, this);
It appears that your button element (navbar-btn) is submitting your form. Try adding type="button" to the button element.
Also in the click event handler you can also try to add e.preventDefault() to your click event handler.
I cant seem to find the JavaScript from the click event of your button so I can help much more. If this does not work, please edit your question to show the relevant HTML and JavaScript sections.

Jquery Tab should remain unchanged after refresh

I am new to Jquery. I am facing a problem with tab implementation. When I refresh the page I am getting redirected to the intial set tab.
$(function() {
var indicator = $('#indicator'),
indicatorHalfWidth = indicator.width()/2,
lis = $('#tabs').children('li');
$("#tabs").tabs("#content section", {
effect: 'fade',
fadeOutSpeed: 0,
fadeInSpeed: 400,
onBeforeClick: function(event, index) {
var li = lis.eq(index),
newPos = li.position().left + (li.width()/2) - indicatorHalfWidth;
indicator.stop(true).animate({ left: newPos }, 600, 'easeInOutExpo');
}
});
});
This is HTML VIEW :
<nav>
<ul id="tabs">
<li><a class "current" t" href="#">Change Password</a></li>
<li>Update Your Profile</li>
</ul>
<span id="indicator"></span>
</nav>
<div id="content">
<section>
<!--content1 -->
</section>
<section>
<!--content2-->
</section>
</div>
You can do this in several ways. Here are two ways to do:
You can use hash tags that are well explained in below post
Can I keep on same jQuery tab on page refresh or when I have navigated away from the page?
Initialize a tabs with the cookie option specified.
$( "#tabs" ).tabs({ cookie: { expires: 30 } });

Categories

Resources