7

I'm using jquery full calendar with angularJS and angularstrap. The problem it seems is that the calendar will only display when I either click on one of the buttons in the calendar or resize the browser window. This calendar is being loaded in a modal box initialised using angularstrap.

I appreciate the help.

Plunkr here: LINK

Modal HTML is in search_modal.html Calendar controller is:calendarCtrl.js Parent controller is search.js

Edit: After experiencing the same problem with google maps and a gallery I've attempted to implement I dont think this is a problem directly related to the calendar rather its more related to the modal box itself. Anything thats interactive and involves javascript does not scale properly according to the size of the modal box. Anyone have any ideas on how to fix this?

Malcr001
  • 8,179
  • 9
  • 44
  • 57
  • Refer this Link: http://stackoverflow.com/questions/16533412/using-fullcalendar-methods-with-angularui-wrapper – Venkat.R Jun 17 '13 at 11:57

7 Answers7

7

Just to add another answer to this. I was using fullcalendar in a bootstrap tab. In order to render the calendar, I added:

$('a#id-of-tab').on('shown.bs.tab', function (e) {
    $("#the-calendar-container").fullCalendar('render');
});
user2320257
  • 71
  • 1
  • 1
4

The problem is that the calendar is initialized while the modal is not visible. If the modal was in a controller, you could potentially use $scope.$on('modal-shown', function() {}); to somehow trigger calendar('render');.

I couldn't figure out a way to detect visibility. I tried using a $watch in the directive on elm.is(':visible'), but could only get it to check 2 times, when it loaded.

skeemer
  • 323
  • 1
  • 3
  • 11
  • Thanks for your efforts. I'll be scratching my head simply trying to get something working. – Malcr001 Jun 08 '13 at 17:41
  • i found the same kind of problem in your code as @skeemer mentioned. You have to click the link twice before the modal opens (first click load and don't show) – Bass Jobsen Jun 14 '13 at 21:43
4

Your problem seems to be similar to How can I list two Linkedin Follow Buttons in a Twitter Bootstrap Dropdown

Your modal is set by:

 <a data-bs-modal="'search_modal.html'" href="#" class="ng-scope" data-target="#search_modal-003" data-toggle="modal">Search</a>
 <div id="search_modal-003" class="modal hide fade ng-scope in" tabindex="-1" aria-hidden="false">

Removing the display:none (give space) before the calendar insert will fix your problem. With the code above b.e. add #search_modal-003 {display:block; } to your custom css.

Community
  • 1
  • 1
Bass Jobsen
  • 48,736
  • 16
  • 143
  • 224
  • I dont quite understand your solution. Please duplicate my plunkr to show the solution working. – Malcr001 Jun 14 '13 at 23:22
  • Although this works on the modal box I have a jquery slideUp slideDown action on other pages where the calender exists and is intially hidden. It seems like the calendar must initially be visible for some reason in order for it to be rendered properly on the page? – Malcr001 Jun 15 '13 at 21:40
  • Yes, cause display: none element don't have space and the initial width of the calendat will be calculated wrong. Try to use display: block; visibility: hidden; (and set visibilty to visible when your calendar shows up), see: http://stackoverflow.com/questions/16905807/how-can-i-list-two-linkedin-follow-buttons-in-a-twitter-bootstrap-dropdown/ – Bass Jobsen Jun 15 '13 at 21:49
  • Thank you, I had NO idea why fullcalendar wasn't displaying! – Riveascore Jul 29 '15 at 18:55
2

I faced the same problem with foundation tab. Where my calendar was in second tab. What I did was, when user is clicking on the tab I simulated "Today" button click within a setTimeout with very minimal delay. This solves my problem

  • I'm using Angular and Bootstrap and this was the only thing that finally worked for me. I also had to use the `$timeout` provider in order to make sure `$('.fc-today-button').click()` was called after the digest cycle, otherwise there seemed to be a race condition with the Angular digest making things visible: https://docs.angularjs.org/api/ng/service/$timeout – Andy Raddatz Apr 07 '16 at 18:46
1

I have made a custom directive and a factory to control when to show and hide the calendar. When calendarFactory.isVisible is set to true, you call fullCalendar's render function.

restrict: 'A',
    scope: true,
    link: function (scope, element, attrs) {
        scope.$watch(function (scope) {
            return calendarFactory.isVisible;
        }, function (newValue, oldValue) {
            if(newValue === true)
                $(element).fullCalendar('render');

Code snippet is remade from production and might not be entirely correct, but the idea is. You should use $scope.$emit and $scope.$on instead of $watch btw.

Solution #2 would be ui-calandar I'm using it now for our own project and it can be nice for quick intergration, but I would suggest your own custom directive for flexibility. We do things like double calendar views, clientside localization, custom selection background-color, custom header for navigating multiple views. If you need things like that, I suggest alternative #1. And I really don't know how to write directives. So don't get discouraged! The hardest part will be getting FullCalendar to render dynamically.

OGHaza
  • 4,795
  • 7
  • 23
  • 29
Marcus Rådell
  • 622
  • 7
  • 12
1

You need to specify the height of the full calendar e.g.

document.addEventListener('DOMContentLoaded', function() {
  var calendarEl = document.getElementById('calendar');
  var calendar = new FullCalendar.Calendar(calendarEl, {
    plugins: [ 'dayGrid' ],
    height: "parent"
  });
  calendar.render();
});
Dale K
  • 25,246
  • 15
  • 42
  • 71
Kondjenim
  • 11
  • 1
  • This solution worked for me. It was probably the simplest since I'm using the calendar in a tab which is in a modal and the calendar would initialize but the grid would not be visible until I pressed any of the calendar buttons. This took care of the issue. – BlueSun3k1 Mar 11 '21 at 15:12
-2

Use settimeout function to delay load of the calendar then it will work.