After the 3rd part of the series about how to build a hotel booking website using Meta Box, we had a basic system to create and book reservations for a small and medium hotel. However, I think that you still need a tool to collect all the booking details for easy management and scheduling.

That’s why in this 4th part, I will show you how to display all booking orders on one page so that you can view the booking schedule intuitively as well as easily check each information.

I will use a tool that is pretty similar to Google Calendar regarding the way it displays events. Each booking order will be put to this calendar and display as an event. I hope that this method is suitable for you. Let’s see!

Preparation

To handle all the manipulations in this part, you need to prepare these stuff:

  1. Make sure that you already followed the instructions in part 1-2-3 in the series. Particularly, in the previous parts, I named my post_type as room and booking and had a field group created with Meta Box plugin called group_booking in each booking post. If you changed these names in part 1-2-3, in this tutorial, you need to change mine to yours in the code to make it run properly.
  2. Use a jQuery library called FullCalendar. You can read its documentation here.

Now, just start!

Step 1: Create a New Plugin for Booking Management

Create a Folder for the New Plugin

What you need to do first is going to wp-content/plugin and create a new folder. This folder is used to create a booking management plugin so I name it as mb-hotel-management. The reason why I use the mb- prefix is to let you know it’s for Meta Box and to differentiate it with other plugins, avoiding having the same names.

Create the Necessary Folders for the Plugin

Each plugin must at least has two basic files: one main file (.php) and one readme.txt file.

  • The main file (.php) will be used to write code. I name it as mb-hotel-management.php.
  • The readme.txt file is to contain information about name, version as well as others of the plugin. If you create this plugin to use for yourself only, you can skip this file.

Here are the files and folders inside the created plugin folder.

create a booking management plugin
The main folders inside the plugin folder

As for the main file of the plugin (mb-hotel-management.php), you need to add the code below and fill in the information to declare the primary information of the plugin.

/**
* Plugin Name:
* Plugin URL:
* Description:
* Version:
* Author:
* Author URL:
* License: GPLv2 or later // Plugin license, if you don’t care about it, just keep GPLv2
*/

Activate the Plugin

After completing these steps, if you do it correctly you will see your new plugin display in the list of plugins on your website.

new plugin display in the list of plugins on your hotel booking website.

Just activate the plugin, then we can start the next steps to build its features.

Step 2: Create a Blank Page on the Backend for the Plugin

This page will be used to display the synthesis of booking orders. The work of adding and displaying the booking orders on this page will be done in the later steps. In this step, we just create a page.

In the inc folder of the plugin, we make a new file named front.php. Then, open the mb-hotel-management.php file and add this code:

<?php
class BookingManagement
{
    public function __construct()
    { add_action( 'admin_menu', array( $this, 'create_menu_admin_panel' ) );
    }
    public function create_menu_admin_panel()
    {
    add_menu_page( ‘Booking Management’, ‘Booking Management’, 'edit_posts', 'manager-booking', array($this, 'manager_booking' ) );
    }
    public function booking_management()
    {
    if (!current_user_can( 'edit_posts' )) {
    wp_die( __('You do not have sufficient permission to access this page.') );
    }
    include 'inc/front.php';
    }
}
$Init = new BookingManagement();
?>

Come back to the Admin Dashboard, you will see the Booking Management menu. Click this menu and you will see a blank page because we haven’t had any content for the front.php file.

a blank page will appear in the booking management menu on your hotel booking website
Booking management page on the backend

Step 3: Import Library and Files to the Plugin

Now, we will import the library and the files to the plugin to customize the template.

Go to the lib folder of the plugin and copy the FullCalendar library to it. You can read more about the necessary files and detailed installation here.

Besides, I will create two more files plugin.css and plugin.js in the folder css and js respectively. We will use these 2 files to make modifications or add key functions to the plugin.

Next, add this code to the booking_management() function that we put to the mb-hotel-management.php file in order to import the library as well as declare the above custom file.

wp_enqueue_style( 'fullcalendar-core', plugins_url( 'lib/fullcalendar/packages/core/main.css', __FILE__ ) );
wp_enqueue_style( 'fullcalendar-daygrid', plugins_url( 'lib/fullcalendar/packages/daygrid/main.css', __FILE__ ) );
wp_enqueue_style( 'css-custom', plugins_url( 'css/plugin.css', __FILE__ ) );

wp_enqueue_script( 'fullcalendar-core', plugins_url( 'lib/fullcalendar/packages/core/main.js', __FILE__ ) );
wp_enqueue_script( 'fullcalendar-daygrid', plugins_url( 'lib/fullcalendar/packages/daygrid/main.js', __FILE__ ) );
wp_enqueue_script( 'js-custom', plugins_url( 'js/plugin.js', __FILE__ ) );

add this code to the booking_management() function

Then, open the plugin.js file and add this code:

document.addEventListener('DOMContentLoaded', function() {
    var calendarEl = document.getElementById('calendar');
    var calendar = new FullCalendar.Calendar(calendarEl, {
        plugins: ['dayGrid'],
        defaultView: 'dayGridMonth',
        defaultDate: '2020-02-07',
        header: {
        left: 'prev,next today',
        center: 'title',
        },
        events: [
        {
        title : 'event1',
        start : '2020-02-27'
        },
        {
        title : 'event2',
        start : '2020-02-15',
        end : '2020-02-17'
        },
        {
        title : 'event3',
        start : '2020-02-09T12:30:00',
        allDay : false // will make the time show
        }
        ]
    });
    calendar.render();
});

Finally, open the front.php file and add this:

<div class="wrap">
    <h1 class="wp-heading-inline">Booking Management</h1>
    <div id='calendar'></div>
</div>

Both of the above code is to check if the files and library that we imported into the plugin are working. If you do it correctly, the result will look like this:

Displaying Hotel Booking orders on the Booking management

Step 4: Build the Features for the Plugin

My idea for the booking management page is that I will create each calendar for each room type. Each event on the calendar will represent a booking order and display as event1, event2, and event3, … as I created above.

After that, I will create another general calendar. I will put the schedule of all room types into the general calendar so that the hotel manager can view the booking schedule of all room types on one page.

To do it, we need to code a lot in this 4th step and there are quite many ways to customize. You can refer to my method below and feel free to leave a comment if you want any further explanation as well as discussion with us.

Display the Booking Information to the Calendar

I will use AJAX to create a variable containing all the booking orders of the hotel. Then, I will recall the function of FullCalendar to display all these booking orders on the calendar.

In the _contruct function of the plugin, I’ll create two more actions:

add_action( 'wp_ajax_feed_events', array( $this, 'feed_events_func') );
add_action( 'wp_ajax_nopriv_feed_events', array( $this, 'feed_events_func' ) );

After that, I’ll create the feed_events_func() function to return the booking calendar under the JSON format below:

public function feed_events_func(){
        $args = array(
        'post_type' => 'booking',
        'posts_per_page' => -1,
    );
    $query = new WP_Query( $args );
    if ( $query->have_posts() ) {
        $events = array();
        while( $query->have_posts() ) { $query->the_post();
            $bookings = get_post_meta( get_the_ID(), 'group_booking', true );
            if ($bookings) {
        foreach ($bookings as $key => $booking) {
            $room = $booking['room'];
            $begin = $booking['check_in'];
            $end = $booking['check_out'];

                            $e['title'] = "#".get_the_ID().' '.get_the_title($room);
                            $e['start'] = $begin;
                            $e['end'] = $end;
                            $e['url'] = get_edit_post_link(get_the_ID(),'');
                            $e['classNames'] = 'room-'.$room;
                            $e['allDay'] = true;

                            array_push($events, $e);
                        }
                    }
             }
             echo json_encode($events);
    }
wp_die();
}

Explanation:

  • $events: the array holding all the booking orders information.
  • 'title', 'start', 'end', 'url', … : the parameters of the event. You can refer to some others here. In this case, I will explain some special parameters, like:
    • + 'title': is the name of the event and will be displayed on the calendar. Here, I name it as #{booking_id}.
    • + 'url': is the page when users click the booking name on the calendar.
    • + 'classNames': I use it to set the class for each booking order. This will be used and explained more clearly in the next steps.

The next thing to do is opening the plugin.js file and add this code to download the returned JSON data.

$.ajax({
    type: 'post',
    url: ajaxurl,
    data: {action: 'feed_events'},
    error: function(err){
        console.log(err);
    },
    success: function (data)
    {
        init_calendar(data);
    }
})
function init_calendar(events){
    var calendarEl = document.getElementById('calendar');
    var calendar = new FullCalendar.Calendar(calendarEl, {
        plugins: [ 'dayGrid' ],
        defaultView: 'dayGridMonth',
        header: {
            left: 'prev,next today',
            center: 'title',
            right: ''
        },
        events: events,
        eventPositioned (view, element) {
            displayBookings();
        },
    });
    calendar.render();
}

Explanation:

  • The AJAX is to take the variable of all the booking orders from the feed_events_func function.
  • The init_fullcalendar(events) is the initial function but I passed the event variable, which is the data returned by AJAX, to it.

After this step, you will have the calendar of all the booking orders, and these orders will be displayed on the calendar. Clicking each booking order, users will be directed to the booking order page, which is the url parameter I passed above.

All the hotel booking orders displaying on dashboard
The bookings displaying on the calendar

Create a Functional Navbar

To make it easier to view the booking calendar of each room type, I’ll create a Navbar where each button represents a type of room. When clicking on these buttons, we’re able to view the booking calendar of each room type, and at the same time, the booking calendar of other room types will be hidden.

In this step, we just need to use some CSS and JavaScript.

Because I named the class of each booking order as room-{$room_id}, I just need to set up to display the corresponding class when clicking a room type. To make it simple, you can understand that I will create a filter by room_id.

Now, open the front.php file in the inc folder and add the code below before the calendar declaration <div id='calendar'></div>. This is to create a navbar containing the list of rooms with each button representing a room.

<div class="navbar mb-4">
<?php
    $args = array(
        'post_type' => 'room',
        'posts_per_page' => -1,
        'post__not_in' => array(498)
    );
    $query = new WP_Query( $args );
        if ( $query->have_posts() ) {
    echo '<button class="button filter-bookings" data-room="all">ALL</button>';
        while( $query->have_posts() ) { $query->the_post(); ?>
        <button class="button filter-bookings" data-room="<?php the_ID(); ?>"><?php the_title(); ?></button>
        <?php }
    } ?>
</div>

Explanation: 'post__not_in': I passed the ID (498), which is the ID of the extra-bed. In the previous part, I set an extra-bed as a room type, so I don’t want to show it here.

Now I will handle when clicking on each button (one room type), it will only display the booking orders of that room type by adding the following code to the plugin.js file:

$('.filter-bookings').on('click', function(event){
    event.stopPropagation();
    var room_id = $(this).attr('data-room');
    $('.wrap').attr('class', 'wrap ' + room_id);
        displayBookings();
})
function displayBookings(){
    var classes = $('.wrap').attr('class');
    if (classes != 'wrap') {
            room = classes.replace("wrap ", "");
            if (room == 'all') {
                $('[class*="room-"]').show();
            } else {
                $('[class*="room-"]').hide();
        $('.room-'+room).show();
            }
    }
}

Explanation:

  • displayBookings() is the function to hide all the bookings.
  • $('.filter-bookings') is to listen to the event when the button on the navbar is clicked.

At this point, you can view each room type by clicking the corresponding button, and the unrelated room types will be hidden. However, when you switch to view the calendar in another month of the year, all the booking orders are still displayed, not hidden. This is because my JavaScript was not executed when the html element was re-rendered. Thus, I have to listen to an event when rendering the booking order and call the function again.

In the FullCalendar v4.0 library, I use a callback named eventPositioned. This callback will be executed when the last event is loaded.

You need to add this code when calling the FullCalendar name:

eventPositioned (view, element) {
    displayBookings();
}

And this is the final result after you complete all these executions:

Hotel booking orders display in each type of room on the booking management page

And these are all the source code of my created plugin. You can refer to it:

https://github.com/wpmetabox/tutorials/tree/master/hotel-bookings

Final Though

In this part, you also learned the basics of programming a plugin in WordPress and how to use and access the FullCalendar library and its APIs. Although we still haven’t explored each issue deeply, hopefully this article as well as all 4 articles in this series can open up some ideas and information for you to develop more new functions for the plugin, as well as help you with the booking management on your website.

If you want to share or discuss more with us, feel free to leave a comment!

Get all tools to build your hotel booking

Leave a Reply

Your email address will not be published. Required fields are marked *