0

I'm trying to create a Javascript calendar which will show the price and availability of hotel rooms by date. Similar to this example (see Availability tab), however mine needs to show prices and availability for three different room types on each date.

So far I've tried out the Availability Calendars and Rooms modules, but both would require significant work to adapt to my needs.

I've also been looking into using a straight-forward calendar module. First I tried Calendar, however this reloads the page when moving to the next/previous month which won't do. Then I tried Fullcalendar, but I can't figure out how to make multi-day items appear as separate daily items (they appear as one item spanning many days), and there's also a problem rendering the calendar on a quicktab (it only shows the next/previous buttons and not the calendar until you actually click next or previous).

So I'm looking for some ideas on how to proceed...

PS I'm using Drupal 7.15

1 Answer 1

0

I figured it out using the standard Calendar plugin. You need to create the view as normal, then I created a custom block which embeds the view 6 times, calling it with a different month argument each time. Then I added some javascript magic to hide and show the calendars as required.

Create the block - PHP

/**
 * Implements hook_block_info().
  */
function viajes_block_info() {
  $blocks['viajes_room_prices'] = array(
    'info' => t('Viajes: Room prices and availability calendar'),
    'cache' => DRUPAL_CACHE_PER_ROLE,
  );

  return $blocks;
}

/*
 * Implement hook_block_view()
 * Display the search form in a block
 */
function viajes_block_view($delta = '') {
   $block = array();

switch ($delta) {
    case 'viajes_room_prices':
        $block['subject'] = t('Disponibilidad de habitaciones');
                    $block['content'] = viajes_room_prices();
                    break;      
    }

    return $block;
}

function viajes_room_prices() {
$MONTHS_TO_SHOW = 6;
$hotel_nid = arg(1);

//js is already added by the reservation form code, no need to add it again
//drupal_add_js(drupal_get_path('module', 'viajes') . '/js/hotels.js');
drupal_add_js(array('viajes_room_price' => array('max_months' => $MONTHS_TO_SHOW)), 'setting');

//previous/next controls
$ret =
'<div id="viajes-rooms-controls">
    <div id="viajes-rooms-previous" class="disabled"><a>' . t('Previous') . '</a></div>
    <div id="viajes-rooms-next"><a>' . t('Next') . '</a></div>
</div>';

//calendars
for ($i=0; $i<=$MONTHS_TO_SHOW-1; $i++) {
    $date = strtotime(date('Y-m-d').' +'.$i.' month');

    $ret .= 
    '<div id="viajes-rooms-month-'.$i.'" ' . ($i!=0 ? ' class="hidden"' : '') .  '>
        <div class="viajes-rooms-month-title">' . 
            date('F',$date) . ' ' . date('Y',$date) .
        '</div>
        <div class="viajes-rooms-calendar">' .
            views_embed_view('room_prices', 'page_1', $hotel_nid, date('Y',$date).'-'.date('m',$date)) .
        '</div>
    </div>';
}

return $ret;
}

The Javascript

(function($) {
Drupal.behaviors.viajes = {
    attach: function(context, settings) {
           /*
        * Room price/availability calendar
        */

        //next button click
        $('#viajes-rooms-next', context).click(function() {
            var curr = getCurrent();

            //re-enable previous button if we've just left the first month
            if (curr == 0) {
                $('#viajes-rooms-previous', context).removeClass('disabled');
            }

            //disable next button if we've just arrived at the last month
            if (curr == (getMaxMonths() - 2) ) {
                $(this).addClass('disabled');
            }

            //roll the calendar if we're not on the last month
            if (curr < (getMaxMonths() - 1) ) {
                $('#viajes-rooms-month-'+curr, context).addClass('hidden');
                $('#viajes-rooms-month-'+(curr+1), context).removeClass('hidden');
            }
        });

        //previous button click
        $('#viajes-rooms-previous', context).click(function() {
            var curr = getCurrent();

            //disable previous button if we've just arrived at the first month
            if (curr == 1) {
                $(this).addClass('disabled');
            }

            //re-enable next button if we've just left the last month
            if (curr == (getMaxMonths() - 1) ) {
                $('#viajes-rooms-next', context).removeClass('disabled');
            }

            //roll the calendar back if we're not on the first month
            if (curr > 0) {
                $('#viajes-rooms-month-'+curr, context).addClass('hidden');
                $('#viajes-rooms-month-'+(curr-1), context).removeClass('hidden');
            }               
        });

        //get currently visible month
        function getCurrent() {
            for (i=0; i<=(getMaxMonths()-1); i++) {
                if (! $('#viajes-rooms-month-'+i, context).hasClass('hidden')) {
                    return i;
                }
            }
        }

        //wrapper for the max_months setting
        function getMaxMonths() {
            return Drupal.settings.viajes_room_price['max_months'];
        }

    }
}
})(jQuery);

Just make sure you have the following classes in your CSS:

.disabled a {
pointer-events: none;
    cursor: default;
color: #979797;
}

.hidden {
    display: none;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.