Notorious
Notorious

Reputation: 3217

FullCalendar - Change View for Mobile Devices

Using the FullCalendar plugin - I am trying to change the view, for mobile devices to "basicDay", but on desktops I still want the view to remain as "basicWeek".

I am a JS newbie, and have tried various different if/elseif statements with JS and PHP, but I cannot get the calendar to display correctly for mobile devices.

You will see my code below that I am using the argument "windowResize" - which works perfectly! Only when the window is resized, however when the calendar is loaded fresh from a mobile device the view is still "basicWeek".

I have tried various statements to solve this issue with no luck, example:

if( $(window).width() < 765 ) {
       <?php $view = 'basicDay'; ?>
} else {
       <?php $view = 'basicWeek' ?>
}

and then echoing the value with PHP (obviously doesn't work), and have tried other if/elseif statements with JS. Here is my fullCalendar code below:

$('#calendar').fullCalendar({
           header: {
                      left: 'prev,next today',
                      center: 'title',
                   },
           titleFormat:'MMMM D YYYY',
           hiddenDays: [0],
           columnFormat: 'dddd',
           defaultView: <?php echo "'" . $view . "'" ?>,

           // responsive
           windowResize: function(view) {
               if ($(window).width() < 765){
                    $('#calendar').fullCalendar( 'changeView', 'basicDay' );
                } else {
                    $('#calendar').fullCalendar( 'changeView', 'basicWeek' );
                }
           },
           timeFormat: 'hh:mm A',
});

So just to confirm, how can I have my calendar remain in basicWeek for desktops, but show as basicDay for mobile sized devices?

Thank-you in advance.

Upvotes: 10

Views: 40043

Answers (6)

Trees4theForest
Trees4theForest

Reputation: 1396

As of v5, defaultView was renamed to intialView so this works:

initialView: window.innerWidth >= 765 ? 'basicDay' : 'basicWeek',

Upvotes: 3

Craig Myles
Craig Myles

Reputation: 5464

I use Typescript and the React version of Fullcalendar (with hooks) and I wanted a solution that would change the calendar view on resize - as well as loading a default view based on the current browser width - so this solution might help those with similar requirements.

The List View is loaded by default for a browser width less than 765px and the Day Grid view otherwise. The view then changes if the browser width crosses the threshold of 765px.

import * as React from 'react';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import listPlugin from '@fullcalendar/list';
import interactionPlugin from '@fullcalendar/interaction'; // needed for dayClick

import './Calendar.css';

export default () => {
    const calendarComponentRef:any = React.createRef<FullCalendar>();

    const getHeaderProps = (): any => {
        return {
            left: '',
            center: 'prev,title,next',
            right: window.innerWidth < 765 ? '' : 'dayGridMonth,listWeek'
        }
    };

    const handleWindowResize = (view: any): void => {
        const calendar = calendarComponentRef.current.getApi();
        calendar.changeView(window.innerWidth < 765 ? 'listWeek' : 'dayGridMonth');
        calendar.setOption('header', getHeaderProps());  
    };

    return (
        <FullCalendar
            defaultView={window.innerWidth < 765 ? 'listWeek' : 'dayGridMonth'}
            header={getHeaderProps()}
            views={{
                listWeek: { buttonText: 'week' }
            }}
            plugins={[dayGridPlugin, listPlugin, interactionPlugin]}
            ref={calendarComponentRef}
            events={events} // not provided for brevity sake
            windowResize={handleWindowResize}
        />
    );
}

For the sake of an example, I've been a little slack with type definitions and method signatures, so I'd recommend modifying this accordingly if you were to use it.

Upvotes: 1

Simon Botero
Simon Botero

Reputation: 603

In the last version of full calendar (4.3.1) you need to make the next:

document.addEventListener('DOMContentLoaded', function() {
    var calendarTest = document.getElementById('calendar')
    /* Create function to initialize the correct view */
    function mobileCheck() {
        if (window.innerWidth >= 768 ) {
            return false;
        } else {
            return true;
        }
    };
    /* Start Full Calendar */
    var calendar = new FullCalendar.Calendar(calendarTest, {
            plugins: [ 'dayGrid' ],
            /* Create new view */
            views: {
                fiveDays: {
                    type: 'dayGridWeek',
                    duration: { days: 5 },
                }
            },
            /* Choose view when initialize */
            defaultView: mobileCheck() ? "fiveDays" : "dayGridWeek",
            /* Check if window resize and add the new view */
            windowResize: function(view) {
                if (window.innerWidth >= 768 ) {
                    calendar.changeView('dayGridWeek');
                } else {
                    calendar.changeView('fiveDays');
                }
            },
            editable: true,
        });
        calendar.render();
    });
});

Upvotes: 8

Oksana Romaniv
Oksana Romaniv

Reputation: 1650

If anyone if looking for the solution that will work when the media query changes (not only on calendar initialization), I managed to get this working using enquire.js library.

Init your calendar with the default view that corresponds your mobile desired view (using mobile-first approach here). In my case, I wanted to fold calendar to monthList on mobile/tablet and use month view on larger screens.

After that attach the enquire.register method to watch for media change. Enquire is also running media check on page load so the calendar displays in the desired view.

function initCalendar() {
    // Caching calendar for later use
    const calendar = $('#calendar');

    // Build calendar with default view of mobile query
    calendar.fullCalendar({defaultView: 'listMonth'});

    // Register media query watch handlers
    enquire.register("screen and (max-width: 1023px)", {
                match: () => {
                    calendar.fullCalendar('changeView', 'listMonth');
                },
            })
            .register("screen and (min-width: 1024px)", {
                match: () => {
                    calendar.fullCalendar('changeView', 'month');
                },
            });
}

Upvotes: 2

DesignMonkeyJim
DesignMonkeyJim

Reputation: 1935

This will work if you want to use window width and not the detect mobile function.

defaultView: $(window).width() < 765 ? 'basicDay':'agendaWeek',

Upvotes: 14

Nedim Hozić
Nedim Hozić

Reputation: 1901

Use function to detect mobile:

window.mobilecheck = function() {
  var check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

After that, on initalizing calendar, call this function and set defaultView like this:

defaultView: window.mobilecheck() ? "basicDay" : "agendaWeek"

Upvotes: 14

Related Questions