// JavaScript Document $(document).ready(function () { // Clear the signature on focus and put enter name back on blur if empty $("#email").focus(function() { if($('#email').val() == 'Please enter your email'){ $("#email").val(""); } }); $("#email").blur(function() { if($('#email').val() == ''){ $("#email").val("Please enter your email"); } }); // Initialize validation dialog $("#validationDialog").dialog({ autoOpen: false, bgiframe: true, modal: true, buttons: { Ok: function() { $(this).dialog('close'); } } }); // Pop up validation dialog when email fails $("#newsletterForm").submit(function (){ var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; var address = $("#email").val(); if ($("#email").val() == 'Please enter your email'){ $("#validationDialog").dialog('open'); return false; }else if(reg.test(address) == false) { $("#validationDialog").dialog('open'); return false; }else{ return true; } }); // Initialize changing city dialog $("#changeCityDialog").dialog({ autoOpen: false, bgiframe: true, modal: true, buttons: { Change: function() { $("#changeCityForm").submit(); } } }); // Open changing city dialog when link is clicked $("#changeCity").click(function(){ $("#changeCityDialog").dialog('open'); }); // Default date picker $(".date").datepicker({ showOn: 'both', buttonImageOnly: true, buttonImage: 'css/images/calendar-sm.gif', buttonText: 'Select date' }); // Flight date range var flight_dates = $('#flight_date_dep, #flight_date_ret').datepicker({ showOn: 'both', buttonImageOnly: true, buttonImage: 'css/images/calendar-sm.gif', buttonText: 'Select date', changeMonth: true, changeYear:true, numberOfMonths: 1, onSelect: function(selectedDate) { var option = this.id == "flight_date_dep" ? "minDate" : "maxDate"; var instance = $(this).data("datepicker"); var date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings); flight_dates.not(this).datepicker("option", option, date); } }); // Hotel date range var hotel_dates = $('#hotel_date_dep, #hotel_date_ret').datepicker({ showOn: 'both', buttonImageOnly: true, buttonImage: 'css/images/calendar-sm.gif', buttonText: 'Select date', changeMonth: true, changeYear:true, numberOfMonths: 1, onSelect: function(selectedDate) { var option = this.id == "hotel_date_dep" ? "minDate" : "maxDate"; var instance = $(this).data("datepicker"); var date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings); hotel_dates.not(this).datepicker("option", option, date); } }); // Car date range var car_dates = $('#car_date_dep, #car_date_ret').datepicker({ showOn: 'both', buttonImageOnly: true, buttonImage: 'css/images/calendar-sm.gif', buttonText: 'Select date', changeMonth: true, changeYear:true, numberOfMonths: 1, onSelect: function(selectedDate) { var option = this.id == "car_date_dep" ? "minDate" : "maxDate"; var instance = $(this).data("datepicker"); var date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings); car_dates.not(this).datepicker("option", option, date); } }); $("#gateway_dep").keyup(function(){ processSuggest($(this),$("#fromSuggest")); }); $("#gateway_dep").blur(function(){ $(this).css({"border" : "1px solid #7f9db9"}); setTimeout(function(){$('#fromSuggest').html('')},500); }); $("#dest_dep").keyup(function(){ processSuggest($(this),$("#toSuggest")); }); $("#dest_dep").blur(function(){ $(this).css({"border" : "1px solid #7f9db9"}); setTimeout(function(){$('#toSuggest').html('')},500); }); function processSuggest(element,suggestDiv) { if(element.val().length >= 3){ element.css({ "background" : "white url(images/indicator.gif) no-repeat right", "padding" : "1px" }); $.getJSON("ajax/qry_getAirport.cfm",{keyword: element.val()}, function(j){ element.css({ "background" : "white", "padding" : "1px", "border" : "1px solid #7f9db9" }); var result = ''; for (var i = 0; i < j.length; i++) { if(i % 2 == 0){ result += '
');
// Get destinations for picked departure
$.getJSON("ajax/softvoyage/" + $(this).val() + ".js",
function(destinations){
destinations_json = destinations;
$(".destination").html('');
$("#no_hotel").html('');
// Populate dropdown of destinations separated by regions
for (var i = 0; i < destinations.length; i++) {
if(destinations[i].TYPE == "section"){
$(".destination").append('');
} else {
$(".destination").append('');
}
}
$("#destination_load").html('');
}
);
});
// When clicked on the destination get the hotels for it
$(".destination").change(function(){
$("#hotel_load").html('
');
var codesArray = new Array();
// Only sub sections can have hotels, so create array of hotel codes for picked destination
for (var i = 0; i < destinations_json.length; i++) {
if(destinations_json[i].TYPE == "sub_section" && destinations_json[i].CODE == $(this).val()){
var codes = destinations_json[i].HOTELS + "";
codesArray = codes.split(",");
}
}
$("#no_hotel").html('');
// Now go to hotels.js file to match hotel codes with names
$.getJSON("ajax/softvoyage/hotels.js",
function(hotels){
// Loop through hotels in hotels.js file
for (var i = 0; i < hotels.length; i++) {
// Match with the ones that are currently in the array
for (var j = 0; j < codesArray.length; j++) {
if (codesArray[j] == hotels[i].CODE) {
$("#no_hotel").append(' 1;//make sure the settings are given right
if( settings.queue )
duration /= 2;//let's keep the overall speed, the same.
settings.offset = both( settings.offset );
settings.over = both( settings.over );
return this.each(function(){
var elem = this, $elem = $(elem),
t = target, toff, attr = {},
win = $elem.is('html,body');
switch( typeof t ){
case 'number'://will pass the regex
case 'string':
if( /^([+-]=)?\d+(px)?$/.test(t) ){
t = both( t );
break;//we are done
}
t = $(t,this);// relative selector, no break!
case 'object':
if( t.is || t.style )//DOM/jQuery
toff = (t = $(t)).offset();//get the real position of the target
}
$.each( settings.axis.split(''), function( i, axis ){
var Pos = axis == 'x' ? 'Left' : 'Top',
pos = Pos.toLowerCase(),
key = 'scroll' + Pos,
act = elem[key],
Dim = axis == 'x' ? 'Width' : 'Height',
dim = Dim.toLowerCase();
if( toff ){//jQuery/DOM
attr[key] = toff[pos] + ( win ? 0 : act - $elem.offset()[pos] );
if( settings.margin ){//if it's a dom element, reduce the margin
attr[key] -= parseInt(t.css('margin'+Pos)) || 0;
attr[key] -= parseInt(t.css('border'+Pos+'Width')) || 0;
}
attr[key] += settings.offset[pos] || 0;//add/deduct the offset
if( settings.over[pos] )//scroll to a fraction of its width/height
attr[key] += t[dim]() * settings.over[pos];
}else
attr[key] = t[pos];//remove the unnecesary 'px'
if( /^\d+$/.test(attr[key]) )//number or 'number'
attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) );//check the limits
if( !i && settings.queue ){//queueing each axis is required
if( act != attr[key] )//don't waste time animating, if there's no need.
animate( settings.onAfterFirst );//intermediate animation
delete attr[key];//don't animate this axis again in the next iteration.
}
});
animate( settings.onAfter );
function animate( callback ){
$elem.animate( attr, duration, settings.easing, callback && function(){
callback.call(this, target);
});
};
function max( Dim ){
var el = win ? $.browser.opera ? document.body : document.documentElement : elem;
return el['scroll'+Dim] - el['client'+Dim];
};
});
};
function both( val ){
return typeof val == 'object' ? val : { top:val, left:val };
};
})( jQuery );
/**
* jQuery.LocalScroll
* Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 3/10/2008
*
* @projectDescription Animated scrolling navigation, using anchors.
* http://flesler.blogspot.com/2007/10/jquerylocalscroll-10.html
* @author Ariel Flesler
* @version 1.2.5
*
* @id jQuery.fn.localScroll
* @param {Object} settings Hash of settings, it is passed in to jQuery.ScrollTo, none is required.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* @example $('ul.links').localScroll();
*
* @example $('ul.links').localScroll({ filter:'.animated', duration:400, axis:'x' });
*
* @example $.localScroll({ target:'#pane', axis:'xy', queue:true, event:'mouseover' });
*
* Notes:
* - The plugin requires jQuery.ScrollTo.
* - The hash of settings, is passed to jQuery.ScrollTo, so the settings are valid for that plugin as well.
* - jQuery.localScroll can be used if the desired links, are all over the document, it accepts the same settings.
* - If the setting 'lazy' is set to true, then the binding will still work for later added anchors.
* - The setting 'speed' is deprecated, use 'duration' instead.
* - If onBefore returns false, the event is ignored.
**/
;(function( $ ){
var URI = location.href.replace(/#.*/,'');//local url without hash
var $localScroll = $.localScroll = function( settings ){
$('body').localScroll( settings );
};
//Many of these defaults, belong to jQuery.ScrollTo, check it's demo for an example of each option.
//@see http://www.freewebs.com/flesler/jQuery.ScrollTo/
$localScroll.defaults = {//the defaults are public and can be overriden.
duration:1000, //how long to animate.
axis:'y',//which of top and left should be modified.
event:'click',//on which event to react.
stop:true//avoid queuing animations
/*
lock:false,//ignore events if already animating
lazy:false,//if true, links can be added later, and will still work.
target:null, //what to scroll (selector or element). Keep it null if want to scroll the whole window.
filter:null, //filter some anchors out of the matched elements.
hash: false//if true, the hash of the selected link, will appear on the address bar.
*/
};
//if the URL contains a hash, it will scroll to the pointed element
$localScroll.hash = function( settings ){
settings = $.extend( {}, $localScroll.defaults, settings );
settings.hash = false;//can't be true
if( location.hash )
setTimeout(function(){ scroll( 0, location, settings ); }, 0 );//better wrapped with a setTimeout
};
$.fn.localScroll = function( settings ){
settings = $.extend( {}, $localScroll.defaults, settings );
return ( settings.persistent || settings.lazy )
? this.bind( settings.event, function( e ){//use event delegation, more links can be added later.
var a = $([e.target, e.target.parentNode]).filter(filter)[0];//if a valid link was clicked.
a && scroll( e, a, settings );//do scroll.
})
: this.find('a')//bind concretely, to each matching link
.filter( filter ).bind( settings.event, function(e){
scroll( e, this, settings );
}).end()
.end();
function filter(){//is this a link that points to an anchor and passes a possible filter ? href is checked to avoid a bug in FF.
return !!this.href && !!this.hash && this.href.replace(this.hash,'') == URI && (!settings.filter || $(this).is( settings.filter ));
};
};
function scroll( e, link, settings ){
var id = link.hash.slice(1),
elem = document.getElementById(id) || document.getElementsByName(id)[0];
if ( elem ){
e && e.preventDefault();
var $target = $( settings.target || $.scrollTo.window() );//if none specified, then the window.
if( settings.lock && $target.is(':animated') ||
settings.onBefore && settings.onBefore.call(link, e, elem, $target) === false ) return;
if( settings.stop )
$target.queue('fx',[]).stop();//remove all its animations
$target
.scrollTo( elem, settings )//do scroll
.trigger('notify.serialScroll',[elem]);//notify serialScroll about this change
if( settings.hash )
$target.queue(function(){
location = link.hash;
});
}
};
})( jQuery );
/**
* jQuery.serialScroll
* Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 3/20/2008
*
* @projectDescription Animated scrolling of series.
* @author Ariel Flesler
* @version 1.2.1
*
* @id jQuery.serialScroll
* @id jQuery.fn.serialScroll
* @param {Object} settings Hash of settings, it is passed in to jQuery.ScrollTo, none is required.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* http://flesler.blogspot.com/2008/02/jqueryserialscroll.html
*
* Notes:
* - The plugin requires jQuery.ScrollTo.
* - The hash of settings, is passed to jQuery.ScrollTo, so its settings can be used as well.
*/
;(function( $ ){
var $serialScroll = $.serialScroll = function( settings ){
$.scrollTo.window().serialScroll( settings );
};
//Many of these defaults, belong to jQuery.ScrollTo, check it's demo for an example of each option.
//@see http://flesler.webs/jQuery.ScrollTo/
$serialScroll.defaults = {//the defaults are public and can be overriden.
duration:1000, //how long to animate.
axis:'x', //which of top and left should be scrolled
event:'click', //on which event to react.
start:0, //first element (zero-based index)
step:1, //how many elements to scroll on each action
lock:true,//ignore events if already animating
cycle:true, //cycle endlessly ( constant velocity )
constant:true //use contant speed ?
/*
navigation:null,//if specified, it's a selector a collection of items to navigate the container
target:null, //if specified, it's a selector to the element to be scrolled.
interval:0, //it's the number of milliseconds to automatically go to the next
lazy:false,//go find the elements each time (allows AJAX or JS content, or reordering)
stop:false, //stop any previous animations to avoid queueing
force:false,//force the scroll to the first element on start ?
jump: false,//if true, when the event is triggered on an element, the pane scrolls to it
items:null, //selector to the items (relative to the matched elements)
prev:null, //selector to the 'prev' button
next:null, //selector to the 'next' button
onBefore: function(){}, //function called before scrolling, if it returns false, the event is ignored
exclude:0 //exclude the last x elements, so we cannot scroll past the end
*/
};
$.fn.serialScroll = function( settings ){
settings = $.extend( {}, $serialScroll.defaults, settings );
var event = settings.event, //this one is just to get shorter code when compressed
step = settings.step, // idem
lazy = settings.lazy;//idem
return this.each(function(){
var
context = settings.target ? this : document, //if a target is specified, then everything's relative to 'this'.
$pane = $(settings.target || this, context),//the element to be scrolled (will carry all the events)
pane = $pane[0], //will be reused, save it into a variable
items = settings.items, //will hold a lazy list of elements
active = settings.start, //active index
auto = settings.interval, //boolean, do auto or not
nav = settings.navigation, //save it now to make the code shorter
timer; //holds the interval id
if( !lazy )//if not lazy, go get the items now
items = getItems();
if( settings.force )
jump( {}, active );//generate an initial call
// Button binding, optionall
$(settings.prev||[], context).bind( event, -step, move );
$(settings.next||[], context).bind( event, step, move );
// Custom events bound to the container
if( !pane.ssbound )//don't bind more than once
$pane
.bind('prev.serialScroll', -step, move ) //you can trigger with just 'prev'
.bind('next.serialScroll', step, move ) //for example: $(container).trigger('next');
.bind('goto.serialScroll', jump ); //for example: $(container).trigger('goto', [4] );
if( auto )
$pane
.bind('start.serialScroll', function(e){
if( !auto ){
clear();
auto = true;
next();
}
})
.bind('stop.serialScroll', function(){//stop a current animation
clear();
auto = false;
});
$pane.bind('notify.serialScroll', function(e, elem){//let serialScroll know that the index changed externally
var i = index(elem);
if( i > -1 )
active = i;
});
pane.ssbound = true;//avoid many bindings
if( settings.jump )//can't use jump if using lazy items and a non-bubbling event
(lazy ? $pane : getItems()).bind( event, function( e ){
jump( e, index(e.target) );
});
if( nav )
nav = $(nav, context).bind(event, function( e ){
e.data = Math.round(getItems().length / nav.length) * nav.index(this);
jump( e, this );
});
function move( e ){
e.data += active;
jump( e, this );
};
function jump( e, button ){
if( !isNaN(button) ){//initial or special call from the outside $(container).trigger('goto',[index]);
e.data = button;
button = pane;
}
var
pos = e.data, n,
real = e.type, //is a real event triggering ?
$items = settings.exclude ? getItems().slice(0,-settings.exclude) : getItems(),//handle a possible exclude
limit = $items.length,
elem = $items[pos],
duration = settings.duration;
if( real )//real event object
e.preventDefault();
if( auto ){
clear();//clear any possible automatic scrolling.
timer = setTimeout( next, settings.interval );
}
if( !elem ){ //exceeded the limits
n = pos < 0 ? 0 : limit - 1;
if( active != n )//we exceeded for the first time
pos = n;
else if( !settings.cycle )//this is a bad case
return;
else
pos = limit - n - 1;//invert, go to the other side
elem = $items[pos];
}
if( !elem || real && active == pos || //could happen, save some CPU cycles in vain
settings.lock && $pane.is(':animated') || //no animations while busy
real && settings.onBefore && //callback returns false ?
settings.onBefore.call(button, e, elem, $pane, getItems(), pos) === false ) return;
if( settings.stop )
$pane.queue('fx',[]).stop();//remove all its animations
if( settings.constant )
duration = Math.abs(duration/step * (active - pos ));//keep constant velocity
$pane
.scrollTo( elem, duration, settings )//do scroll
.trigger('notify.serialScroll',[pos]);//in case serialScroll was called on this elem more than once.
};
function next(){//I'll use the namespace to avoid conflicts
$pane.trigger('next.serialScroll');
};
function clear(){
clearTimeout(timer);
};
function getItems(){
return $( items, pane );
};
function index( elem ){
if( !isNaN(elem) ) return elem;//number
var $items = getItems(), i;
while(( i = $items.index(elem)) == -1 && elem != pane )//see if it matches or one of its ancestors
elem = elem.parentNode;
return i;
};
});
};
})( jQuery );
// when the DOM is ready...
$(document).ready(function () {
var $panels = $('#slider .scrollContainer > div');
var $container = $('#slider .scrollContainer');
// if false, we'll float all the panels left and fix the width
// of the container
var horizontal = true;
// float the panels left if we're going horizontal
if (horizontal) {
$panels.css({
'float' : 'left',
'position' : 'relative' // IE fix to ensure overflow is hidden
});
// calculate a new width for the container (so it holds all panels)
$container.css('width', $panels[0].offsetWidth * $panels.length);
}
// collect the scroll object, at the same time apply the hidden overflow
// to remove the default scrollbars that will appear
var $scroll = $('#slider .scroll').css('overflow', 'hidden');
// handle nav selection
function selectNav() {
$(this)
.parents('ul:first')
.find('a')
.removeClass('selected')
.end()
.end()
.addClass('selected');
$(this)
.parents('ul:first')
.find('li')
.removeClass('selected')
.end()
.end()
$(this).parent().addClass('selected');
}
$('#slider .navigation').find('a').click(selectNav);
// go find the navigation link that has this target and select the nav
function trigger(data) {
var el = $('#slider .navigation').find('a[href$="' + data.id + '"]').get(0);
selectNav.call(el);
}
if (window.location.hash) {
trigger({ id : window.location.hash.substr(1) });
} else {
$('ul.navigation a:first').click();
}
// offset is used to move to *exactly* the right place, since I'm using
// padding on my example, I need to subtract the amount of padding to
// the offset. Try removing this to get a good idea of the effect
var offset = parseInt((horizontal ?
$container.css('paddingTop') :
$container.css('paddingLeft'))
|| 0) * -1;
var scrollOptions = {
target: $scroll, // the element that has the overflow
// can be a selector which will be relative to the target
items: $panels,
navigation: '.navigation a',
// selectors are NOT relative to document, i.e. make sure they're unique
prev: 'img.left',
next: 'img.right',
// allow the scroll effect to run both directions
axis: 'xy',
onAfter: trigger, // our final callback
offset: offset,
// duration of the sliding effect
duration: 500,
// easing - can be used with the easing plugin:
// http://gsgd.co.uk/sandbox/jquery/easing/
easing: 'swing'
};
// apply serialScroll to the slider - we chose this plugin because it
// supports// the indexed next and previous scroll along with hooking
// in to our navigation.
$('#slider').serialScroll(scrollOptions);
// now apply localScroll to hook any other arbitrary links to trigger
// the effect
$.localScroll(scrollOptions);
// finally, if the URL has a hash, move the slider in to position,
// setting the duration to 1 because I don't want it to scroll in the
// very first page load. We don't always need this, but it ensures
// the positioning is absolutely spot on when the pages loads.
scrollOptions.duration = 1;
$.localScroll.hash(scrollOptions);
});