Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FullCalendar eventRender event freeze the browser tab

I am using FullCalendar plugin in AngularJs.

All works fine. In eventRender event I am adding background color, image, tooltip and label for every event, for that it freeze the browser tab for few seconds.

Is there any way to speedup or show loader or any thing?

I am using following code

$scope.uiConfig = {
  calendar: {
    height: 550,
    editable: false,
    header: {
      left: 'onlyErrorButton',
      center: 'title',
      right: 'today basicDay,basicWeek,month prev,next'
    },
    timeFormat: 'H:mm',
    defaultView: 'month',
    titleFormat: 'DD MMMM YYYY',
    views: {
      day: {
        columnFormat: 'dddd D.M'
      },
      week: {
        columnFormat: 'dd D.M'
      },
      month: {
        columnFormat: 'dd',
        titleFormat: 'MMMM'
      }
    },
    loading: function( isLoading, view ) {
      if(isLoading) {// isLoading gives boolean value
        $('#wait').show();
      } else {
        $('#wait').hide();
      }
    },
    theme: false,
    themeButtonIcons: false,
    customButtons: {
      onlyErrorButton: {
        text: $rootScope.getLabel('with_errors'),
        click: function() {
          $('.fc-onlyErrorButton-button').toggleClass('fc-state-active');
          vmCurves.onlyErrorButton = false;
          update_eventSources();
        }
      },
      withoutErrorButton: {
        text: $rootScope.getLabel('without_errors'),
        click: function(event) {
          $('.fc-withoutErrorButton-button').toggleClass('fc-state-active');
          vmCurves.withoutErrorButton = false;
          update_eventSources();
        }
      }
    },
    dayClick: function(date, jsEvent, view) {
      var x = new Date(date._d);
      var y = x;
      var start = y.setHours(0,0,0,0);
      var end = x.setHours(23,59,59,59);

      vmCurves.dateFrom =  new Date(start);
      vmCurves.dateTo = new Date(end);
      vmCurves.filter.pasteur = true;
      vmCurves.filter.heat = true;
      vmCurves.filter.cool = true;
      vmCurves.filter.feed = true;
      vmCurves.filter.reinigen = true;

      CurvesServices.feedings($stateParams.taxi_id, start/1000, end/1000, 0, true,true,true,true,true, false, false).then(function (result) {
        vmCurves.feedings = (result[0].data);
        vmCurves.showTable = true;
      });
    },
    eventClick: function(date, jsEvent, view) {
      setVisibles();
      var startTime = parseInt(date.startTimestamp) * 1000;
      var x = new Date(startTime);
      var y = x;

      var start = y.setHours(0,0,0,0);  
      var end = x.setHours(23,59,59,59);  

      vmCurves.dateFrom =  new Date(start);
      vmCurves.dateTo = new Date(end);

      var pasteur = true;
      var heat = true;
      var cool = true;
      var feed = true;
      var reinigen = true;

      vmCurves.filter.pasteur = true;
      vmCurves.filter.heat = true;
      vmCurves.filter.cool = true;
      vmCurves.filter.feed = true;
      vmCurves.filter.reinigen = true;

      CurvesServices.feedings(date.taxi_id, start/1000, end/1000, 0, heat, feed, cool , pasteur, reinigen).then(function (result) {
        vmCurves.feedings = (result[0].data);
      });
      getCurves({ 'taxi_id':date.taxi_id , 'feeding_id':date.feeding_id, 'process_id' : date.process_id});
      vmCurves.showTable = true;
    },
    eventRender: function(event, element, view ) {
      i++;
      if(i == 1) {
        //alert('loading');
        $('#wait').show(); //Trying to show loader here
      }
      $('.fc-day-grid-container').css('cursor', 'pointer'); // adding css style to event container
      $('.fc-toolbar .fc-left .fc-onlyErrorButton-button').addClass('fc-state-active'); // adding class to button
      //adding Tooltip to Buttons
      $('.fc-toolbar .fc-left .fc-onlyErrorButton-button').tooltip({
        'title' : $rootScope.getLabel('only_errors')
      });
      //getting details getLabel() function getting data from database
      var action = event.action ? $rootScope.getLabel(event.action.toLowerCase() ) : $rootScope.getLabel('fuettern');
      var startTime = event.startTime ? event.startTime : '-';
      var endTime = event.endTime ? event.endTime : '-';
      var amount = event.amount ? event.amount : '-';
      var dosings = event.dosings ? event.dosings : '-';
      var action_img = event.action ? event.action : 'fuettern';
      //Image for event
      img_src = "assets/media/img/" + action_img.toLowerCase() + ".png";
      //editing event container adding class's and images
      if(view.name === 'basicDay') {
        element.find(".fc-time")
          .before($("<span class=\"fc-event-icons\"></span>")
          .html("<img src='" + img_src +   "' style=\"width:7%; float:left\" />"));
        element.find(".fc-title").html(action);
        element.find(".fc-time").css({'padding-left' : '20px'});
      } else {
        element.find(".fc-time")
          .before($("<span class=\"fc-event-icons\"></span>")
          .html("<img src='" + img_src +   "' style=\"width:30%; float:left\" />"));
        element.find(".fc-time").css({'padding-left' : '20px'});
        element.find(".fc-title").html(action);
        element.find(".fc-title").hide();

        var moment = $('#calendar').fullCalendar('getDate');
        element.find(".fc-event").addClass("TEST!_" + moment.format("MMMM") + "_" + event.start.format("MMMM"));
      }
      //adding background-color to event
      var bgcolor = event.action == 'Pasteurisieren' ? '#42ca00' : event.action == 'Heizen' ? '#fa8072' : event.action == 'Kuehlen' ? '#00bfff' : event.action == 'reinigen' ? '#00baaa' : '#ffd700';
      $(element).css('background-color', bgcolor);
      //creating Tooltip title
      if(view.name !== 'basicDay') {
        var tooltipText =  $rootScope.getLabel('action') + ': ' + action  + ' | '  + $rootScope.getLabel('start') + ': '+ startTime + ' | ' + $rootScope.getLabel('end') + ': ' + endTime;
        if(event.amount || event.dosings) { //Feeder.Dort gibt es noch Amount und Dosings
          tooltipText +=  ' | ' + 'Liter: ' + amount + ' | ' + 'Dosierung: ' + dosings;
        }
      }
      //Tooltip to event
      $(element).attr('tooltip-placement', 'bottom');  //Tooltip nach unten
      $(element).tooltip({
        'title': tooltipText,
        'container': 'body',
        'placement' : 'bottom'
      });
      $compile(element)($scope);
      if(view.name !== 'basicDay' && (moment.format("MMMM") != event.start.format("MMMM"))) {
        element.find(".fc-content").addClass("othermonth");
      }
    },
    eventAfterAllRender:function(view){
      i = 0;
      $('#wait').hide();
    },
  },
};
like image 364
Jigarb1992 Avatar asked Aug 30 '16 09:08

Jigarb1992


People also ask

How do I use eventRender in FullCalendar?

eventRender is a great way to attach effects to event elements, such as a Tooltip. js tooltip effect: var calendar = new Calendar(calendarEl, { events: [ { title: 'My Event', start: '2010-01-01', description: 'This is a cool event' } // more events here ], eventRender: function(info) { var tooltip = new Tooltip(info.

What is eventDidMount?

eventDidMount - called right after the element has been added to the DOM. If the event data changes, this is NOT called again. eventWillUnmount - called right before the element will be removed from the DOM.

What is the use of FullCalendar?

FullCalendar generates real React virtual DOM nodes so you can leverage Fiber, React's highly optimized rendering engine.


1 Answers

Firstly, I would suggest avoiding modifying the DOM during the eventRender handler as much as possible. You don't need to add the img tag into the element. Instead just add a class which specifies a background image. So in your css have a class like:

.fuettern {
   background-image: 'assets/media/img/fuettern.png';
   width: '30px';
   height: '30px';
   etc
}

Then do element.addClass('fuettern'). DOM manipulations where you add nodes are costly. You could also optimise the way you set the background colour in a similar fashion. The same class (fuettern, reinigen etc) could set the background colour. In fact AFAICT, you should be able to do everything except set the tooltip purely by setting a class.

Secondly, take a look at how many objects (events) are in scope. Too many objects are the main cause of bug rendering delays in Angular. Ensure you are only rendering events you need to show.

Thirdly, your attempt to show a loader will never work this way. Basically the DOM only gets re-rendered once javascript has done its thing. So you can show a spinner while an asynchronous method is waiting to resolve, but you can't show one at the beginning of a synchronous method, then hide it at the end again. And even if you found some hack using $timeout or something, the spinner won't spin while javascript code is running - so the view will still look frozen.

like image 191
see sharper Avatar answered Nov 04 '22 01:11

see sharper