tails.png
tails.png
tails.png
tails.png
tails.png

Simple Integration


SCROLL DOWN

Simple Integration


How to Install Blue Sky Bookings Reservation System Redirection onto your Website

Purpose

The following documentation is intended to be step-by-step directions on how to install Blue Sky Bookings Reservation System redirection onto your website

Summary of elements that will be added to or modified on the website

  1. Reservation Button
  2. JQuery Script Library
  3. FancyBox.js PlugIn with Optional Feature Scripts
  4. Resolution Script for jQuery Conflicts
  5. User Agent detection/redirection Script and calling fancyBox()
  6. COMING...Remote Access to Reservation Widget via code snippet

Implementation Sequence

  1. Button Generation

    The first step is to generate a button or navigation element you wish to direct to Blue Sky Bookings Reservation System.

    A simple example would be:

    1
    <img id="btnBook" src="img/booknow.jpg" alt="Book Now" />
     
             <img id="btnBook" src="img/booknow.jpg" alt="Book Now" />
             

  2. jQuery Library Addition

    The next step is to load the most current jQuery Library into the head of your html. The fancybox plugin used for displaying the reservation utilizes jQuery syntax and is required for it to work properly.

    Copy and Paste the following code for the the JQuery 1.x library into the head of your webpage. Make sure the code is inserted below the <title></title> tag and after the <link/> tag for your css sheets.

                      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
                   
  3. FancyBox.JS PlugIn with Optional Feature Scripts

    Now that you have loaded the jQuery library, the next step will involve loading the fancyBox plugins into the head of your webpage. The plugin consists of 3 critical files and 3 optional files.

    Copy and Paste the following fancyBox scripts and css files to your head, directly below the jQuery Library you just loaded and above the jQuery noConflict() script. The files have to be connected to your jQuery library and thus have to follow directly after the library.

    FancyBox files:
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    <!-- Add mousewheel plugin (this is optional) -->
    <script type="text/javascript" src="fancybox/lib/jquery.mousewheel-3.0.6.pack.js"></script>
    <!-- Add fancyBox main JS and CSS files -->
    <script type="text/javascript" src="fancybox/source/jquery.fancybox.js?v=2.1.5"></script>
    <link rel="stylesheet" type="text/css" href="fancybox/source/jquery.fancybox.css?v=2.1.5" media="screen" />
    <!-- Add Button helper (this is optional) -->
    <link rel="stylesheet" type="text/css" href="fancybox/source/helpers/jquery.fancybox-buttons.css?v=1.0.5" />
    <script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-buttons.js?v=1.0.5"></script>
    <!-- Add Thumbnail helper (this is optional) -->
    <link rel="stylesheet" type="text/css" href="fancybox/source/helpers/jquery.fancybox-thumbs.css?v=1.0.7" />
    <script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-thumbs.js?v=1.0.7"></script>
    <!-- Add Media helper (this is optional) -->
    <script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-media.js?v=1.0.6"></script>
     
                      <!-- Add mousewheel plugin (this is optional) -->
                      <script type="text/javascript" src="fancybox/lib/jquery.mousewheel-3.0.6.pack.js"></script>
                      <!-- Add fancyBox main JS and CSS files -->
                      <script type="text/javascript" src="fancybox/source/jquery.fancybox.js?v=2.1.5"></script>
                      <link rel="stylesheet" type="text/css" href="fancybox/source/jquery.fancybox.css?v=2.1.5" media="screen" />
                      <!-- Add Button helper (this is optional) -->
                      <link rel="stylesheet" type="text/css" href="fancybox/source/helpers/jquery.fancybox-buttons.css?v=1.0.5" />
                      <script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-buttons.js?v=1.0.5"></script>
                      <!-- Add Thumbnail helper (this is optional) -->
                      <link rel="stylesheet" type="text/css" href="fancybox/source/helpers/jquery.fancybox-thumbs.css?v=1.0.7" />
                      <script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-thumbs.js?v=1.0.7"></script>
                      <!-- Add Media helper (this is optional) -->
                      <script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-media.js?v=1.0.6"></script>
                   
  4. Wrapping the button with fancyBox:

    In order to detect and redirect the user to the desired reservation site and initiate fancyBox() we must first begin by giving the anchor tag a class name.

    Copy and Paste the following code onto the page where your button will be found. Replace the example img tag with the button you generated in step one.

    1
    2
    3
    <a class="blueskybooking-book" data-fancybox-type="iframe">
         <img id="btnBook" src="img/booknow.jpg" alt="Book Now" />
    </a>
     
    
                      <a class="blueskybooking-book" data-fancybox-type="iframe">
                           <img id="btnBook" src="img/booknow.jpg" alt="Book Now" />
                      </a>
    
                   

    The addition of the class ".blueskybooking-book" allows for you to target the element using the jQuery library you installed. The addition of data-fancybox-type="iframe" sets the prompt box as an iframe element.

    Customized styling of the fancyBox element can be done by referring to the fancyBox documenation page

  5. Resolution Script for JQuery Conflicts

    If your site contains an older version of the jQuery library or another javascript library (ie. Prototype), you will have to apply a small script called jQuery.noConflict(). This method ultimately allows you to bounce between the libraries.

    Basically the following script allows you to store the jQuery library you want in a variable and then use it when fancyBox is called but revert back to the the previous setup after activation. The reversion will allow your previously added plugins or libraries to work properly.

    Copy and Paste the following code directly after the fancybox box scripts and stylesheets you just installed in the head tag.

    1
    2
    3
    <script type="text/javascript">
         var $jQueryBookings = jQuery.noConflict(true);
    </script>
     
                      <script type="text/javascript">
                           var $jQueryBookings = jQuery.noConflict( true );
                      </script>
                   

    If you're unfamiliar with this script you can read more about it straight from the jQuery API documentation; however, I found an article by Jacob Chappell, How to use jQuery.noConflict() the right way. which does a simple but meaningful job at explaining the process.

  6. User Agent detection/redirection Script and Calling fancybox();

    The last thing to with your code is to detect the user agent, redirect to the appropriate webpage and call fancyBox() into action.

    Copy and Paste the following code directly before the </body> tag. The script will open a desktop html version of the booking system in a fancyBox iframe if a desktop user agent is detected, a mobile html version if a mobile user agent is detected and a new window if an ipad is detected (due to a disagreement with Apple iPads and fancyBox.js).

    Line 5 requires you to provide your company's ID. The Company_ID field can be found in our Booking Agent application.
    File > Configuration > System

    Code for Mobile Detection Script and FancyBox Initiation
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    <script type="text/javascript">
         $jQueryBookings(document).ready(function ($) {
           // Assign the Company_ID
           var $intCompany_ID = 46;
          
           var isMobile = function (_, ua) {
             _.Android = ua.match(/Android/i);
             _.BlackBerry = ua.match(/BlackBerry/i);
             _.iOS = ua.match(/iPhone|iPad|iPod/i);
             _.iPad = ua.match(/iPad/i);
             _.Opera = ua.match(/Opera Mini/i);
             _.Windows = ua.match(/IEMobile/i);
             _.Palm = ua.match(/webOS/i);
             _.any = _.Android || _.BlackBerry || _.iOS || _.Opera || _.Windows || _.Palm;
             return _;
           }({}, navigator.userAgent);
          
           var $objBooking = $(".blueskybooking-book");
          
           var $chrDesktop = "https://bookings.blueskybooking.net/Booking.aspx?Company_ID=" + $intCompany_ID;
           var $chrMobile  = "https://mobile.blueskybooking.net/Booking.aspx?Company_ID=" + $intCompany_ID;
            
           if (isMobile.any == null) {
             // Desktop version (Same Window/Fancybox, Desktop)
          
             $objBooking.fancybox({
               href: $chrDesktop,
               iframe: { preload : false },   
               width: 960,
               maxWidth: 960,
               autoSize: true,
               modal: true,
               afterLoad: function () {
                 if (this.modal) {
                   this.closeBtn = true;
                 }
               },
               helpers: {
               }
             });
           } else if (isMobile.iPad != null) {
             // IPad version (New Window, Desktop)
             $objBooking.click(function (e) {
               var $objWindow = window.open($chrDesktop, '_blank');
               $objWindow.focus();
             });
           } else if (isMobile.any != null) {
             // Mobile version (Same Window, Mobile)
             $objBooking.click(function (e) {
               var $objWindow = window.open($chrMobile, '_self');
               $objWindow.focus();         
             });
           };
         });
       </script>
     
    
                <script type="text/javascript">
                     $jQueryBookings(document).ready(function ($) {
                       // Assign the Company_ID
                       var $intCompany_ID = 46;
                     
                       var isMobile = function (_, ua) {
                         _.Android = ua.match(/Android/i);
                         _.BlackBerry = ua.match(/BlackBerry/i);
                         _.iOS = ua.match(/iPhone|iPad|iPod/i);
                         _.iPad = ua.match(/iPad/i);
                         _.Opera = ua.match(/Opera Mini/i);
                         _.Windows = ua.match(/IEMobile/i);
                         _.Palm = ua.match(/webOS/i);
                         _.any = _.Android || _.BlackBerry || _.iOS || _.Opera || _.Windows || _.Palm;
                         return _;
                       }({}, navigator.userAgent);
                     
                       var $objBooking = $(".blueskybooking-book");
                     
                       var $chrDesktop = "https://bookings.blueskybooking.net/Booking.aspx?Company_ID=" + $intCompany_ID;
                       var $chrMobile  = "https://mobile.blueskybooking.net/Booking.aspx?Company_ID=" + $intCompany_ID;
                       
                       if (isMobile.any == null) {
                         // Desktop version (Same Window/Fancybox, Desktop)
                     
                         $objBooking.fancybox({
                           href: $chrDesktop,
                           iframe: { preload : false },    
                           width: 960,
                           maxWidth: 960,
                           autoSize: true,
                           modal: true,
                           afterLoad: function () {
                             if (this.modal) {
                               this.closeBtn = true;
                             }
                           },
                           helpers: {
                           }
                         });
                       } else if (isMobile.iPad != null) {
                         // IPad version (New Window, Desktop)
                         $objBooking.click(function (e) {
                           var $objWindow = window.open($chrDesktop, '_blank');
                           $objWindow.focus();
                         });
                       } else if (isMobile.any != null) {
                         // Mobile version (Same Window, Mobile)
                         $objBooking.click(function (e) {
                           var $objWindow = window.open($chrMobile, '_self');
                           $objWindow.focus();          
                         });
                       };
                     });
                   </script>
    
                
  7. Putting It All Together

    An example of the entire code required for the reservation system to be implemented on your site can be found below. If you have any questions regarding the code please contact support@blueskybooking.net.

    Example Page

The next page will go one step further and touch on how to directly integrate a more advanced, customizable form into your webpage.

tails.png

Direct Field Integration


Direct Field Integration


How to Integrate Blue Sky Booking Search Button into your Website

Purpose

The following documentation is intended to be a simple step-by-step manual on how to integerate Blue Sky Booking Reservation Systems "Search Button" into your website

Outline of elements that will be added to or modified on the website

  1. Accessing important background information
  2. Determining what fields you'd like to incorperate
  3. Building the simple form
  4. Insertion of script for autoloading select fields
  5. Insertion of script for passing parameters to server
  6. Launch of fancybox and return results

The installation of the "Book Now Button" allowed for a simple but effective way for enhancing your websites booking experience via the the Blue Sky Booking application.

Blue Sky Booking hasn't stopped there! The following documentation provides our customers with several other simple but effective methods for incorperating more online booking features directly in their webpage. The first tutorial will explain how to integrate a search button into your page which will return the selections based on the parameters provided by a form.

Note: The following examples follow a basic guideline. It's in place to allow the customer to get the the functionality of the features working; however, it's up to the customer to customize and style to match the themes of their pages.

Lets quickly summarize what was added in our previous tutorial for the "Book Now" button and how we will expand on it

  • first we embedded all the required external scripts directly into the head of the page which includes; jQuery, fancybox and a few others
  • we then included a script that takes care of any conflicts with any other jQuery Libraries or libraries already present on the page (not recommended to have to several different jQuery libraries loaded)
  • we also included a script that checks the browsers status and will provide you with a mobile version or a desktop version

All these files can remain if you wish to include a search button in your site. In fact, since you are going to be calling fancybox again you will want to make sure to have the same libraries and stylesheets loaded into the head of your page as the book now button


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<link href="http://cdn.officedoxs.com/themes/classy-blue/classy-blue.css" rel="stylesheet" type="text/css" />
<!-- Add fancyBox -->
<!-- Add mousewheel plugin (this is optional) -->
<script type="text/javascript" src="http://cdn.officedoxs.com/lib/jquery.mousewheel-3.0.6.pack.js"></script>
<!-- Add fancyBox -->
<link rel="stylesheet" href="http://cdn.officedoxs.com/fancybox/jquery.fancybox.css?v=2.0.6" type="text/css" media="screen" />
<script type="text/javascript" src="http://cdn.officedoxs.com/fancybox/jquery.fancybox.pack.js?v=2.0.6"></script>
<!-- Optionally add helpers - button, thumbnail and/or media -->
<link rel="stylesheet" href="http://cdn.officedoxs.com/fancybox/helpers/jquery.fancybox-buttons.css?v=1.0.2" type="text/css" media="screen" />
<script type="text/javascript" src="http://cdn.officedoxs.com/fancybox/helpers/jquery.fancybox-buttons.js?v=1.0.2"></script>
<script type="text/javascript" src="http://cdn.officedoxs.com/fancybox/helpers/jquery.fancybox-media.js?v=1.0.0"></script>
<link rel="stylesheet" href="http://cdn.officedoxs.com/fancybox/helpers/jquery.fancybox-thumbs.css?v=2.0.6" type="text/css" media="screen" />
<script type="text/javascript" src="http://cdn.officedoxs.com/fancybox/helpers/jquery.fancybox-thumbs.js?v=2.0.6"></script>
<!--- http://fancybox.net/api -->

A brief understanding of the search button

The idea for this feature is to bypass the "Book Now" pop up and integrate the search fields directly into your webpage. All of the parameters and input types found in the book now button can be used in the search button form.

As with most forms, the selected parameters for each input element will be passed to the url bar and a request will be made to the our server. Our server will then return all results wrapped in the fancybox plugin window.

It's that simple.

So lets begin:

Since the search results are customized to your company's fields we will have to access some background information through your desktop Blue Sky Booking application. This background information will be incorperated into the code so make sure you jot it down.

First, you will need to locate Finding Company_ID, License and API Key (this feature will be in the next upgrade).

To do this:

  1. In the Booking Agent, click File > Configuration > Services.
  2. Click Settings
  3. Make note of the Company_ID, License and API Key.

You'll need this information in order to access company specific API's for values required for parameters to be passed to the server

We now have to decide on what fields we would like to incorperate into our form. Blue Sky booking's application has been built for over 10 options.

Fields Optional for form based integration

  1. Departure/Arrival Locations
  2. Departure/Arrival Dates
  3. Departure/Return Range
  4. Time of Day filter
  5. Return : Include return flight listings or not
  6. Gender: defines weight and fare group
  7. Segment : Single or multiple segments to filter
  8. Tier : Select a tier
  9. Sorting Options
  10. CSS.file : override default CSS files set in company

Each field can be incorperated into the section using input/select elements and given values that correspond with a dedicated set of values for your company stored in our database.

Lets start to integrate our search button using a simple form featured on Salt Spring Air.

There are several elements that are required for your submission to work.

Required code:

If you're using a form then the action attribute requires the base url seen below. This will be followed by "hidden" input elements.

      
<form id="" class="" accept-charset="UTF-8" method="get" action="https://bookings.blueskybooking.net/Booking.aspx"/>

<input class="ui-search-company_id" type="hidden" value="42" name="Company_ID"/>

<input type="hidden" value="Booking" name="Action"/>>

<input type="hidden" value="https://mobile.blueskybooking.net/Booking.aspx" name="mobile_url">
      
   

Your base url for the form's action attribute used for accessing the server looks like this.

https://{bookings|mobile}.blueskybooking.net/Booking.aspx?Company_ID={Company_ID}&Action=Booking

Using the get for the method attribute you can pass/add parameters to the end of the string enables us to provide a specific request and in turn the server returns the results of your query.

Take the customer ID you jotted down from your background information and plug it into the value attribute for your input element containing class="ui-search-company_id". This class is also required for this element.

Optional Search Fields

Departure/Arrival Fields

Class markup = Departure_Location_ID and Arrival_Location_ID
Definition: Departure and arrival location identifier.
Example: Departure_Location_ID=3, Arrival_Location_ID=18

Departure_Date/Return_Date

Class markup = Departure_Date and Return_Date Definition: Departure and Return (optional) date
Example: Departure_Date=09/20/2012, Return_Date=09/22/2012

Date Range

Class markup = Date_Departure_Range and Date_Return_Range
Definition: Optional number of +/- days to display.
Options: 0, 1, 2, 3
Example: Date_Departure_Range=0

Preferred Flight Time

Class markup = Date_Departure_Time and Date_Return_Time
Definition: Time of day filter.
Options: 0,1440 Any Time 0,720 Morning 720,1080 Afternoon 1080,1440 Evening
Example: Date_Departure_Time=0,720

Return Flight Option

Class markup = Return Definition: Include return flight listings or not.
Options: 0, 1
Example: Return=1

Weight

Class markup = Weight_ID[ID]
Definition: The Weight group, defines gender, seats (Locks), weight and fare group.
Options: You will need to log into your API to find the specific values >>> https://api.blueskybooking.net/genders/?Web=True&Active=True
Username: {License}
Password: {APIKey}
Example: Weight_ID[9]=2 [ 2 Males ], Weight_ID[7]=1 [ 1 Child ]

Segment : Trip Option

Class markup = Segment_ID Definition: Select a single or multiple segments to filter.
Options: You will need to log into your API to find the specific values >>> https://api.blueskybooking.net/segments/
Username: {License}
Password: {APIKey}
Example: Segment_ID=4
Segment_ID=8,12,14,22

Tier

Class markup = Tier_ID Definition: Select a single tier to filter.
Example: Tier_ID=12
Some airlines use this option for Fare Type: Regular, Sale, Premium, etc.

Sorting

Class markup = Sorting Definition: Sorting options for time order (default) or by price.
Options: 0 (Time), 1 (Price)
Example: Sorting=1

CSS file for Return Form Styling

Class markup = CSS.File
Definition: Override default CSS files set in company settings. Normally not used.
Options:

  • blue-gray.css
  • green-blue.css
  • orange-blue.css
  • red-blue.css
  • red-gray.css

Example: CSS.File=red-gray.css

Using a simple javascript you can access the elements using the class attribute which will eventaully produce a string based off all the filled elements

Every customer will have a destination and most an arrival input field. A script provided by Blue Sky Booking requires these fields to be marked up with specific class attributes in order to complete a field autofill. See the examples below.

   
<select id="cboDeparture_Location_ID" style="width: 100%;" class="ui-search-departure-location"> </select>

<select id="cboArrival_Location_ID" style="width: 100%;" class="ui-search-arrival-location ui-search-arrival-location-disabled"> </select>

<input id="txtDate_Return" type="text" value="" maxlength="10" class="ui-field-search-date-return" autocomplete="off" style="width: 100px;" disabled="disabled" />
   

Just to reiterate a few tips that were stated above

Simple styling of the date field can be done by calling the datepicker() method from the jQueryUI library. This method call is also incorperated into the script.

Tier is usually used for different levels of ticket pricing. For example you may have the Tier set for Fair Type which could then include; All Fares, Regular Fares and Discounted Fares.

The segment parameter is used for differet types of trips.

It is on the you as the customer to provide validation for each field. The script includes valdiation but should be examined.

Other snippets from the background information that must be incorperated: Based on each customer's fleet a standardized weight class has been set for each Passenger Field. It is important to adjust the value extracted from the information. For example, the [9] below stands as a weight class for male


<select id="cboWeight_ID[9]" style="width: 55px;" class="ui-search-gender">
<option value="0" SELECTED>0</option>

Insertion of script for auto filling destination and arrival fields

The following script should be embedded in the head or the body of the page. We would recommend that you make it an extrernal script and minimize it. However, for this demonstration we will keep it long and strong so you can get a better understanding of what's going on.



  jQuery(document).ready(function ($) {
  var $intCompany_ID = -1;

  $(".ui-search-company_id").first().each(function (e) {
    $intCompany_ID = $(this).val();
  });

  // Setup data variable
  var $JSONLocations = {};

  if ($intCompany_ID > 0) {
    // Disable drop-down lists at startup
    $(".ui-search-departure-location, .ui-search-arrival-location").prop("disabled", true);

    var $strURL = "https://bookings.blueskybooking.net/Search/Locations.aspx";

    if ($("input.ui-search-host").val() == "1") {
      $strURL = "https://" + window.location.host + "/Search/Locations.aspx";
    };

    // Grab location Routes into JSON table
    $.ajax({
      type: "GET",
      url: $strURL,
      data: "Company_ID=" + $intCompany_ID + "&Web=1&Active=1",
      //data: "Session=" + $strSession + "&Web=1&Active=1",
      async: true,
      error: function (xhr, ajaxOptions, thrownError) {
        //alert("{Error / Network / " + xhr.status + " : " + ajaxOptions + " : " + thrownError + "}");
      },
      success: function (data) {
        // Assign the JSON data to the local variable
        $JSONLocations = data;

        var $intDeparture_Location_ID = -1;
        var $intArrival_Location_ID = -1;

        if ($(".ui-search-departure-location").val() > 0) { $intDeparture_Location_ID = $(".ui-search-departure-location").val(); };
        if ($(".ui-search-arrival-location").val() > 0) { $intArrival_Location_ID = $(".ui-search-arrival-location").val(); };

        // Departure Location
        if ($(".ui-search-arrival-location").not(".ui-search-arrival-location-disabled").length == 1) {
          $.fn.GetLocations(-1, $intArrival_Location_ID, $(".ui-search-departure-location"), -1);
        } else {
          $.fn.GetLocations(-1, -1, $(".ui-search-departure-location"), -1);
        };

        // Arrival Location
        $.fn.GetLocations($intDeparture_Location_ID, -1, $(".ui-search-arrival-location"), -1);

        $.fn.GetLocations($intArrival_Location_ID, -1, $(".ui-search-return-location"), -1);
      },
      complete: function () {
        // Enable the drop-down lists
        $(".ui-search-departure-location, .ui-search-arrival-location").prop("disabled", false);
      }
    });
  } else {
    $(".ui-search-departure-location, .ui-search-arrival-location").prop("disabled", false);
  }

  // Function to reset the location drop-down lists
  $.fn.GetLocations = function ($intDeparture_Location_ID, $intArrival_Location_ID, $objLocations, $intSelected) {
    // If nothing defined, exit (failsafe)
    if ($.isEmptyObject($JSONLocations.Routes)) {
      return false;
    }

    // Loop through each drop-down list passed through
    $objLocations.each(function (e) {
      // Grab the drop-down list
      var $objList = $(this);

      // Save current selected item, unless manually passed
      if ($intSelected < 0) {
        $intSelected = $objList.val();
      }

      // Clear list
      $objList.find("option").remove().end();

      // Add blank / default item
      $objList.append($("<option>",
            { value: -1,
              text: '',
              selected: false
            }));

      // Force reset of enter list, then exit
      // Occurs when user select blank (-1) option from the list
      if ($intDeparture_Location_ID == -1 &&
          $intArrival_Location_ID == -1) {

        // Loop through the list of Locations
        $($JSONLocations.Location).each(function (index, data) {

          // Add location as option
          $objList.append($("<option>",
                { value: data.Location_ID,
                  text: data.Location,
                  selected: ($intSelected) == (data.Location_ID)
                }));
        });
        return true;
      };

      // Loop through list of Routes
      $($JSONLocations.Routes).each(function (index, data) {

        // Check if location matches, either departure or arrival ID
        if ($intDeparture_Location_ID == data.Arrival.Location_ID) {
          // Add location as option
          $objList.append($("<option>",
                { value: data.Departure.Location_ID,
                  text: data.Departure.Location,
                  selected: ($intSelected) == (data.Departure.Location_ID)
                }));

        } else if ($intArrival_Location_ID == data.Departure.Location_ID) {
          // Add location as option
          $objList.append($("<option>",
                { value: data.Arrival.Location_ID,
                  text: data.Arrival.Location,
                  selected: ($intSelected) == (data.Arrival.Location_ID)
                }));
        };
      });
    });
  }

  // Departure changed, force refresh
  $(".ui-search-departure-location").change(function (e) {
    $.fn.GetLocations($(this).val(), -1, $(".ui-search-arrival-location"), -1);
    //$.fn.GetLocations($(".ui-search-arrival-location").val(), -1, $(".ui-search-return-location"));
  });

  // Arrival changed, force refresh
  //  $(".ui-search-arrival-location").not(".ui-search-arrival-location-disabled").change(function (e) {
  //    $.fn.GetLocations(-1, $(this).val(), $(".ui-search-departure-location"), -1);
  //  });

  $(".ui-search-arrival-location").change(function (e) {
    var $objLocation = $(this);
    if (!$objLocation.is(".ui-search-arrival-location-disabled")) {
      $.fn.GetLocations(-1, $(this).val(), $(".ui-search-departure-location"), -1);
    }

    // Automatically set the return location
    $.fn.GetLocations($(".ui-search-arrival-location").val(), -1, $(".ui-search-return-location"), -1);
  });

  // Swap departure and arrival location
  $(".ui-search-swap").click(function (e) {
    e.preventDefault();

    var $intDeparture_Location_ID = $(".ui-search-departure-location").val();
    var $intArrival_Location_ID = $(".ui-search-arrival-location").val();

    if ($intDeparture_Location_ID < 0 || $intArrival_Location_ID < 0) {
      return false;
    }

    // Departure | Show Full List
    if ($(".ui-search-arrival-location").not(".ui-search-arrival-location-disabled").length == 0) {
      $.fn.GetLocations(-1, -1, $(".ui-search-departure-location"), $intArrival_Location_ID);
    } else {
      $.fn.GetLocations(-1, $intDeparture_Location_ID, $(".ui-search-departure-location"), $intArrival_Location_ID);
    }

    $.fn.GetLocations($intArrival_Location_ID, -1, $(".ui-search-arrival-location"), $intDeparture_Location_ID);

    // Automatically set the return location
    $.fn.GetLocations($(".ui-search-arrival-location").val(), -1, $(".ui-search-return-location"), -1);
  });

  // Swap departure and arrival location
  $(".ui-search-reset").click(function (e) {
    e.preventDefault();

    var $intDeparture_Location_ID = $(".ui-search-departure-location").val();
    var $intArrival_Location_ID = $(".ui-search-arrival-location").val();

    $.fn.GetLocations(-1, -1, $(".ui-search-departure-location"), 0);
    $.fn.GetLocations(-1, -1, $(".ui-search-arrival-location"), 0);

    // Automatically set the return location
    $.fn.GetLocations($(".ui-search-arrival-location").val(), -1, $(".ui-search-return-location"), -1);
  });
});

Let's take a brief look and the previous script. It basically accesses the value from the Company_ID input element and pulls the fields values for the departure and arrival elements that have been marked up with ui-search-departure-location and ui-search-arrival-location classes

Each input element is validated and as soon as the search button is selected then another script is initiated

Insertion of Script for Button Selection and Server Request Generator

copy and paste the following script into the body of the page.

   

   jQuery.noConflict();
   
   jQuery(document).ready(function () {
    var $intCompany_ID = 4;

    //function isiPhone() { return ((navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1)); }
    function isiPhone() { return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) }

    var $strHostPrimary = 'bookings';
    var $strHost = 'bookings';

    if (isiPhone()) {
      $strHost = 'mobile';
      jQuery("#pnlMobile").show()
      jQuery("#pnlBookings").hide();
    }

    var CurrentDate = new Date();
    var CurrentDateString = (CurrentDate.getMonth() + 1) + '/' + CurrentDate.getDate() + '/' + CurrentDate.getFullYear();

    jQuery("#txtDate_Departure").val(CurrentDateString);
    jQuery("#txtDate_Return").val(CurrentDateString);

    if (isiPhone() == false) {
      jQuery(".fancybox").fancybox({
        onCancel: function () { alert('Cancel'); return false },
        //beforeClose: function () { alert('hi'); return false;  },
        afterClose: function () { getStatusJSONP(); },
        openSpeed: 400,
        //closeSpeed: 2000,
        //overlay : null
        //height: 675,
        //minHeight: 500,
        width: 945,
        minWidth: 945,
        maxWidth: 945,
        height: 950,
        //minHeight: '90%',
        autoSize: false,
        openEffect: 'fade',
        //minHeight: 675,
        modal: true,
        afterLoad: function () {
          if (this.modal) {
            this.closeBtn = true;
          }
        },
        helpers: {
          overlay: {
            opacity: 0.4,
            css: {
              'background-color': '#000'
            }
          }
        }
      });
    };

    jQuery("#Booking").find("input, select").on("focus keyup", function (e) {
      jQuery(this).removeClass("ui-error");
    });

    jQuery(".ui-search-gender").on("focus keyup", function (e) {
      jQuery(".ui-search-gender").removeClass("ui-error");
    });    

    jQuery(".ui-button-review").click(function () {
      var $this = jQuery(this);

      var $strLink = "https://" + $strHost + ".blueskybooking.net/Dashboard.aspx";

      $strLink = $strLink + "?Company_ID=" + $intCompany_ID;

      $this.attr("href", $strLink);
    });

    jQuery("#btnDashboard").click(function () {
      jQuery(".ui-button-review").trigger("click");
    });

    jQuery(".ui-button-book").click(function () {
      var $this = jQuery(this);

      var $intDeparture_Location_ID = jQuery("#cboDeparture_Location_ID option:selected").val();
      var $intArrival_Location_ID = jQuery("#cboArrival_Location_ID option:selected").val();
      var $strDate_Departure = jQuery("#txtDate_Departure").val();
      var $intDate_Departure_Range = jQuery("#cboDate_Departure_Range").val();
      var $strDate_Departure_Time = jQuery("#cboDate_Departure_Time").val();
      var $strDate_Return = jQuery("#txtDate_Return").val();
      var $intDate_Return_Range = jQuery("#cboDate_Return_Range").val();
      var $strDate_Return_Time = jQuery("#cboDate_Return_Time").val();
      var $bitReturn = 0;
      if (jQuery("#chkReturn").is(":checked") == true) {
        $bitReturn = 1;
      }
      var $bitSorting = 0;
      if (jQuery("#chkSorting").is(":checked") == true) {
        $bitSorting = 1;
      }

      var $intLocks = 0;
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[9\\] option:selected").val());
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[10\\] option:selected").val());
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[7\\] option:selected").val());
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[8\\] option:selected").val());

      var $intAdult = 0;
      $intAdult = $intAdult + parseInt(jQuery("#cboWeight_ID\\[9\\] option:selected").val());
      $intAdult = $intAdult + parseInt(jQuery("#cboWeight_ID\\[10\\] option:selected").val());

      var $intChild = 0;
      $intChild = $intChild + parseInt(jQuery("#cboWeight_ID\\[7\\] option:selected").val());

      var $intInfant = 0;
      $intInfant = $intInfant + parseInt(jQuery("#cboWeight_ID\\[8\\] option:selected").val());

      //        alert($intLocks);

      var $strWeight_ID = ""
      $strWeight_ID = $strWeight_ID + "&Weight_ID[9]=" + jQuery("#cboWeight_ID\\[9\\] option:selected").val();
      $strWeight_ID = $strWeight_ID + "&Weight_ID[10]=" + jQuery("#cboWeight_ID\\[10\\] option:selected").val();
      $strWeight_ID = $strWeight_ID + "&Weight_ID[7]=" + jQuery("#cboWeight_ID\\[7\\] option:selected").val();
      $strWeight_ID = $strWeight_ID + "&Weight_ID[8]=" + jQuery("#cboWeight_ID\\[8\\] option:selected").val();

      //alert($strWeight_ID);

      // Validation
      var $bitValidated = true;

      if ($intDeparture_Location_ID < 0) {
        jQuery("#cboDeparture_Location_ID").addClass("ui-error");
        $bitValidated = false;
      }

      if ($intArrival_Location_ID < 0) {
        jQuery("#cboArrival_Location_ID").addClass("ui-error");
        $bitValidated = false;
      }

      if (isNaN(Date.parse($strDate_Departure))) {
        jQuery("#txtDate_Departure").addClass("ui-error");
        $bitValidated = false;
      }

      if ($bitReturn == 1) {
        if (isNaN(Date.parse($strDate_Return))) {
          jQuery("#txtDate_Return").addClass("ui-error");
          $bitValidated = false;
        }
      }

      if ($intLocks == 0) {
        jQuery("#cboWeight_ID\\[9\\]").addClass("ui-error");
        jQuery("#cboWeight_ID\\[10\\]").addClass("ui-error");
        $bitValidated = false;
      }

      if ($intAdult == 0 && $intChild > 0) {
        jQuery("#cboWeight_ID\\[7\\]").addClass("ui-error");
        $bitValidated = false;
      }

      if ($intAdult == 0 && $intInfant > 0) {
        jQuery("#cboWeight_ID\\[8\\]").addClass("ui-error");
        $bitValidated = false;
      }

      if (!$bitValidated) {
        return false;
      }

      //
      var $strLink = "https://" + $strHost + ".blueskybooking.net/Booking.aspx";

      $strLink = $strLink + "?Company_ID=" + $intCompany_ID;
      $strLink = $strLink + "&Action=Booking";

      //        $strLink = $strLink + "&MinimumMinutes=840";
      //        $strLink = $strLink + "&BookingMinimumMinutesNew=840";
      //        $strLink = $strLink + "&BookingMinimumMinutesChange=840";
      //        $strLink = $strLink + "&BookingMinimumMinutesCancel=840";
      //        $strLink = $strLink + "&UI=classy-blue";

      $strLink = $strLink + "&Departure_Location_ID=" + $intDeparture_Location_ID;
      $strLink = $strLink + "&Arrival_Location_ID=" + $intArrival_Location_ID;
      $strLink = $strLink + "&Departure_Date=" + $strDate_Departure;
      $strLink = $strLink + "&Departure_Date_Range=" + $intDate_Departure_Range;
      $strLink = $strLink + "&Departure_Date_Time=" + $strDate_Departure_Time;
      $strLink = $strLink + "&Return_Date=" + $strDate_Return;
      $strLink = $strLink + "&Return_Date_Range=" + $intDate_Return_Range;
      $strLink = $strLink + "&Return_Date_Time=" + $strDate_Return_Time;
      $strLink = $strLink + "&Return=" + $bitReturn;
      $strLink = $strLink + "&Sorting=" + $bitSorting;
      $strLink = $strLink + "" + $strWeight_ID;

      //        alert($strLink);

      $this.attr("href", $strLink);
    });

    var dates = jQuery(".ui-field-search-date-departure, .ui-field-search-date-return").datepicker({
      //showOn: 'button',
      buttonImage: '/Images/calendar.gif',
      //buttonImageOnly: true,
      showAnim: 'slideDown',
      showButtonPanel: false,
      minDate: -0,
      defaultDate: "+1d",
      numberOfMonths: 1,
      //showOtherMonths: true,
      //selectOtherMonths: true,
      dateFormat: "mm/dd/yy",
      onSelect: function (selectedDate) {
        var option = this.id == "txtDate_Departure" ? "minDate" : "maxDate",
            instance = jQuery(this).data("datepicker"),
            date = jQuery.datepicker.parseDate(instance.settings.dateFormat || jQuery.datepicker._defaults.dateFormat, selectedDate, instance.settings);
        dates.not(this).datepicker("option", option, date);
        jQuery(".ui-field-search-date-return").removeClass("ui-state-error");
      }
    });

    jQuery(".ui-field-search-return-state").click(function () {
      var $this = jQuery(this)
      if ($this.is(":checked")) {
        jQuery(".ui-field-search-date-return").removeAttr("disabled");
        jQuery("#cboDate_Return_Range").removeAttr("disabled");
        jQuery("#cboDate_Return_Time").removeAttr("disabled");
      } else {
        jQuery(".ui-field-search-date-return").attr("disabled", "disabled");
        jQuery(".ui-field-search-date-return").val("");
        jQuery(".ui-field-search-date-return").removeClass("ui-error");
        jQuery("#cboDate_Return_Range").attr("disabled", "disabled");
        jQuery("#cboDate_Return_Time").attr("disabled", "disabled");
      }
    });


    // Login / Validation

    function Status(data, $bitLogin) {
      //alert(data.Contact.Contact_ID);
      jQuery("#pnlValidation").hide();

      if (data.Contact.Contact_ID != -1) {
        //jQuery(".ui-login-status").text("Logged In!")
        //jQuery(".ui-login-name").text(data.Contact.Contact_ID + ' : ' + data.Contact.Name);
        jQuery("#pnlLogin").hide();
        jQuery("#pnlReview").slideDown();
        jQuery("#txtPassword").val("");

        if ($bitLogin) {
          jQuery(".ui-button-review").trigger("click");
        };
      } else {
        jQuery("#pnlLogin").slideDown();
        jQuery("#pnlReview").hide();
        //          jQuery(".ui-login-status").text("Not logged in...")
        //          jQuery(".ui-login-name").text("");

        if ($bitLogin) {
          switch (data.Status) {
            case -1:
              jQuery("#txtEmail").addClass("ui-error");
              jQuery("#txtMember").addClass("ui-error");
              break;
            case -2:
              jQuery("#txtEmail").addClass("ui-error");
              jQuery("#txtMember").addClass("ui-error");
              break;
            case -3:
              jQuery("#txtPassword").addClass("ui-error");
              break;
            case -4:
              alert("This login account does not have login permissions, please call for service.");
              break;
          }
        }
      }
    }

    jQuery("#chkAgent").click(function () {
      jQuery("#pnlContact").toggle();
      jQuery("#pnlAgent").toggle();
    }).each(function (e) {
      var $this = jQuery(this);
      if ($this.is(":checked")) {
        jQuery("#pnlContact").hide();
        jQuery("#pnlAgent").show();
      } else {
        jQuery("#pnlContact").show();
        jQuery("#pnlAgent").hide();
      };
    });

    function getStatusJSONP() {
      jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Status.aspx?Company_ID=" + $intCompany_ID + "&callback=?",
      function (data) { Status(data, false) });
    }

    function getLoginContactJSONP($strEmail, $strPassword, $bitAutomatic) {
      jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Login.aspx?Company_ID=" + $intCompany_ID + "&Method=Email&Email=" + $strEmail + "&Password=" + $strPassword + "&Automatic=" + $bitAutomatic + "&callback=?",
      function (data) { Status(data, true) });
    }

    function getLoginAgentJSONP($strService, $strMember, $strPassword, $bitAutomatic) {
      jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Login.aspx?Company_ID=" + $intCompany_ID + "&Method=Agent&Service=" + $strService + "&Member=" + $strMember + "&Password=" + $strPassword + "&Automatic=" + $bitAutomatic + "&callback=?",
      function (data) { Status(data, true) });
    }

    function getLogoutJSONP() {
      jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Logout.aspx?Company_ID=" + $intCompany_ID + "&callback=?",
      function (data) { Status(data, false) });
    }

    jQuery("#txtPassword").keydown(function (event) {
      if (event.keyCode == 13) {
        getLoginContactJSONP(jQuery("#txtEmail").val(), jQuery("#txtPassword").val(), jQuery("#chkAutomatic").is(":checked"));
      }
    });

    jQuery("#btnLogin").click(function (e) {
      if (jQuery("#chkAgent").is(":checked")) {
        getLoginAgentJSONP("Agent", jQuery("#txtMember").val(), jQuery("#txtPassword").val(), jQuery("#chkAutomatic").is(":checked"));
      } else {
        getLoginContactJSONP(jQuery("#txtEmail").val(), jQuery("#txtPassword").val(), jQuery("#chkAutomatic").is(":checked"));
      }
    });

    jQuery("#btnLogout").click(function (e) {
      getLogoutJSONP();
    });

    jQuery("#btnStatus").click(function (e) {
      getStatusJSONP();
    });

    // Startup
    getStatusJSONP();

    // Automatic Window Close
    function listener(event) {
      // Valid Origin | Temporarily disabled for testing
      // if (event.origin !== "https://" + $strHost + ".blueskybooking.net/")
      //   return

      //alert(event.origin + " : " + event.data);

      // Add code for closing Iframe window
      if (event.data == "onclose") {
        // jQuery.dialog("close");
        jQuery.fancybox.close();
      }
    }

    if (top.addEventListener) {
      top.addEventListener("message", listener, false)
    } else {
      top.attachEvent("onmessage", listener)
    }

    jQuery(".button").button();
  });

As you can see we've started off the script with the jQuery.noConflict() method call. This allows us to add our external scripts without having any conflict with any other library previously loaded onto the page. Once our method has been complete the $ used in jQuery is released.

This script needs some modification and it also overrides some of the jQuery that was included in the "book now" button tutorial. The company_ID once again needs to be added. You may want to consider doing the same thing as the previous script and rework the javascript for auto detection of the company_ID based on the class mark up of the the input element.


<script type="text/javascript">
//jQuery.noConflict();
   jQuery(document).ready(function () {
    var $intCompany_ID = 4;
....................................
<script>

The Weight_ID's also have to be modified to coincide with your company's set weight_ID's

Nevertheless, the take home message/code that should be focused on is the code below:

   
jQuery(".ui-button-book").click(function () {
      var $this = jQuery(this);

      var $intDeparture_Location_ID = jQuery("#cboDeparture_Location_ID option:selected").val();
      var $intArrival_Location_ID = jQuery("#cboArrival_Location_ID option:selected").val();
      var $strDate_Departure = jQuery("#txtDate_Departure").val();
      var $intDate_Departure_Range = jQuery("#cboDate_Departure_Range").val();
      var $strDate_Departure_Time = jQuery("#cboDate_Departure_Time").val();
      var $strDate_Return = jQuery("#txtDate_Return").val();
      var $intDate_Return_Range = jQuery("#cboDate_Return_Range").val();
      var $strDate_Return_Time = jQuery("#cboDate_Return_Time").val();
      var $bitReturn = 0;
      if (jQuery("#chkReturn").is(":checked") == true) {
        $bitReturn = 1;
      }
      var $bitSorting = 0;
      if (jQuery("#chkSorting").is(":checked") == true) {
        $bitSorting = 1;
      }

      var $intLocks = 0;
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[9\\] option:selected").val());
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[10\\] option:selected").val());
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[7\\] option:selected").val());
      $intLocks = $intLocks + parseInt(jQuery("#cboWeight_ID\\[8\\] option:selected").val());

      var $intAdult = 0;
      $intAdult = $intAdult + parseInt(jQuery("#cboWeight_ID\\[9\\] option:selected").val());
      $intAdult = $intAdult + parseInt(jQuery("#cboWeight_ID\\[10\\] option:selected").val());

      var $intChild = 0;
      $intChild = $intChild + parseInt(jQuery("#cboWeight_ID\\[7\\] option:selected").val());

      var $intInfant = 0;
      $intInfant = $intInfant + parseInt(jQuery("#cboWeight_ID\\[8\\] option:selected").val());

      //        alert($intLocks);

      var $strWeight_ID = ""
      $strWeight_ID = $strWeight_ID + "&Weight_ID[9]=" + jQuery("#cboWeight_ID\\[9\\] option:selected").val();
      $strWeight_ID = $strWeight_ID + "&Weight_ID[10]=" + jQuery("#cboWeight_ID\\[10\\] option:selected").val();
      $strWeight_ID = $strWeight_ID + "&Weight_ID[7]=" + jQuery("#cboWeight_ID\\[7\\] option:selected").val();
      $strWeight_ID = $strWeight_ID + "&Weight_ID[8]=" + jQuery("#cboWeight_ID\\[8\\] option:selected").val();

      var $strLink = "https://" + $strHost + ".blueskybooking.net/Booking.aspx";

      $strLink = $strLink + "?Company_ID=" + $intCompany_ID;
      $strLink = $strLink + "&Action=Booking";

      //        $strLink = $strLink + "&MinimumMinutes=840";
      //        $strLink = $strLink + "&BookingMinimumMinutesNew=840";
      //        $strLink = $strLink + "&BookingMinimumMinutesChange=840";
      //        $strLink = $strLink + "&BookingMinimumMinutesCancel=840";
      //        $strLink = $strLink + "&UI=classy-blue";

      $strLink = $strLink + "&Departure_Location_ID=" + $intDeparture_Location_ID;
      $strLink = $strLink + "&Arrival_Location_ID=" + $intArrival_Location_ID;
      $strLink = $strLink + "&Departure_Date=" + $strDate_Departure;
      $strLink = $strLink + "&Departure_Date_Range=" + $intDate_Departure_Range;
      $strLink = $strLink + "&Departure_Date_Time=" + $strDate_Departure_Time;
      $strLink = $strLink + "&Return_Date=" + $strDate_Return;
      $strLink = $strLink + "&Return_Date_Range=" + $intDate_Return_Range;
      $strLink = $strLink + "&Return_Date_Time=" + $strDate_Return_Time;
      $strLink = $strLink + "&Return=" + $bitReturn;
      $strLink = $strLink + "&Sorting=" + $bitSorting;
      $strLink = $strLink + "" + $strWeight_ID;

      //        alert($strLink);

      $this.attr("href", $strLink);
    });

   

Lets quickly go through this script. Basically it validates each field selected and stores the value as a variable. It then concatenates the search requests into a long string which is sent to the url bar which then produces a request to the server for flight details. The results are returned in a separte pop-up fancybox window.

That's it! Next we will look at adding a View Reservation Button and Login Button

View Demo

The next tutorial will include the integration of Login/My Reservations section

tails.png

Login Integration


Login Integration


How to Integrate Blue Sky Booking Login Button into your Website

Purpose

The following documentation is intended to be a simple step-by-step guide on how to integerate Blue Sky Booking Reservation Systems "Login Button" into your website. This allows a corporate website to track the login status of a user or agent on their pages.

Outline of elements that will be added to or modified on the website

  1. A subsequent section will be added to the form or table established in the previous tutorial.
  2. Specific markup of input fields for JSONP to access

The installation of the "Search Button" allowed for a simple but effective way for enhancing your websites booking experience via the Blue Sky Booking application. It permits a customizable form to be directly integrated into your page which, in turn, bypasses the need for the simple book now button.

This tutorial aims to integrate another section into your search form that allows your company to provide your users with an even more personalized customer interaction.

Note: The following examples follow a basic guideline. It's in place to allow the customer to get the the functionality of the features working; however, it's up to the customer to customize and style to match the themes of their pages.

Lets quickly summarize what was added in our previous tutorial for the "Search" button and how we will expand on it

  • First you accessed and recorded all important company information needed to incorperate the search button into your webpage.
  • You determined what fields you want to add to your page based on the options provided by the documentation
  • You built the form and marked it up properly.
  • You inserted a script needed to autoload the destination/arrival fields
  • You inserted a script that creates a url of concatenated strings that is passed to the server that requests information from the server
  • And lastly, you launched fancybox and returned the results with a click of a button.

As this is a continuation of the search button, all the files that were previously embedded will be required for the Login addition too.

So lets begin:

Once again, since the search results are customized to your company's fields we will have to access some background information through your desktop Blue Sky Booking application. This background information will be incorperated into the code so make sure you jot it down.

First, you will need to locate Finding Company_ID, License and API Key (this feature will be in the next upgrade).

To do this:

  1. In the Booking Agent, click File > Configuration > Services.
  2. Click Settings
  3. Make note of the Company_ID, License and API Key.

You'll need this information in order to access company specific API's for values required for parameters to be passed to the server

Below is the root url required for the Login access to work successfully.

    https://{bookings|mobile}.blueskybooking.net/authentication/
    
Additional concatenation is required for this option to work. There are 4 JSNOP pages that can be requested using the script provided.

  • Login.aspx
  • Status.aspx
  • Logout.aspx
  • Settings.aspx

With this in mind, lets do a quick overview of what happens when a customer accesses a page containing the search and login buttons. The entire script can be view in search button integration tutorial.

4 main functions are called upon accessing the page:

  • getStatusJSONP()
  • getLoginContactJSONP()
  • getLoginAgentJSONP()
  • getLogoutJSONP()

These functions use javascript callbacks to login, logout and get the current status of the user from our servers

Customer navigates to your corporate site

  1. The script calls a method which abbrogates a JSONP request to the status.aspx page.
  2. If the status.aspx returns logged in, the My Reservations section and appropriate Review Bookings and Logout buttons are updated. The username and password fields are hidden.

Customer clicks "login" from the site

  1. A JSONP request is made to the login.aspx page with their login details.
  2. Any validation of the login is returned along and with their status if successful.
  3. If the login.aspx returns logged in, the My Reservations section and appropriate Sign In/Logout buttons are updated.

The Customer opens, then closes the online bookings window

  1. When the "fancybox" booking window closes, a JSONP request is made to the status.aspx. It is important to know if you are logged in/out in the iFrame.
  2. If the status.aspx returns logged in, the My Reservations section and appropriate Sign In/Logout buttons are updated. The username and password fields are hidden.

For reference, the following code re-checks the current status of the user once they exit the booking window.

        
jQuery(".fancybox").fancybox({
onCancel: function () { alert('Cancel'); return false },
//beforeClose: function () { alert('hi'); return false;  },
afterClose: function () { getStatusJSONP(); },
        
    

Customer logs out from the site

  1. A JSONP request is made to the logout.aspx page.
  2. If the logout.aspx returns success, the My Reservations section and appropriate Sign In/Logout buttons are updated.

Lets go through the pages that require some attention and present what parameters are required. Options and examples are provided for each parameter.

Login.aspx

Several options for the Login.aspx page request are listed below.

  1. Company_ID={Company_ID}
  2. Method={Contact_ID|Email|Agent}
  3. Contact_ID={Contact_ID}
  4. Email={Email}
  5. Service={Agent Service}
  6. Member={Agent Member}
  7. Password={Password}
  8. Automatic={True|False} "Keep me logged in" on future visits/sessions (Default is False)
As you can probably see, in point#2 there are 3 login methods, {Contact_ID|Email|Agent}. Contact_ID is a personal account number provided to the customer for easy access. The Email method allows the customer to use their email address. On the other hand, Agents will be provided with usernames that can be used for login. Lets go through some examples of each login type and their requirements.

Customers by Contact_ID

Method=Contact_ID
Contact_ID={Contact_ID}
Password={Password}

Example:
Company_ID=4
Method=Contact_ID
Contact_ID=1075841
Password=1234

Customer by Email

Method=Email
Contact_ID={Email}
Password={Password}

Example:
Company_ID=4
Method=Email
Email=####@gmail.com
Password=1234

Customer by Agent

Method=Agent
Contact_ID={Agent Service}
Member={Agent Member}
Password={Password}

Example:
Company_ID=4
Method=Agent
Service=Agent
Member12345678
Password=abc

Status.aspx

There are a total of 6 parameters for the Status.aspx call that can be used in the validation method. They include:

  • 1 ---> Success
  • 0 ---> Unknown
  • -1 ---> Invalid Parameter
  • -2 ---> Not Found
  • -3 ---> Invalid Password
  • -4 ---> No Web Permissions

Now that we know our options lets look at the functionality of our script. The following code is an example of a simple Login Button combined with the search button already discussed in the previous tutorial. We use JSNOP pages in order to access the personalized information. For the sake of this tutorial we've only focused on the Login/Validation section of the script. Again the full script can be found on the search button integration tutorial

        
// Login / Validation
 
    function Status(data, $bitLogin) {
      //alert(data.Contact.Contact_ID);
      jQuery("#pnlValidation").hide();
 
      if (data.Contact.Contact_ID != -1) {
        //jQuery(".ui-login-status").text("Logged In!")
        //jQuery(".ui-login-name").text(data.Contact.Contact_ID + ' : ' + data.Contact.Name);
        jQuery("#pnlLogin").hide();
        jQuery("#pnlReview").slideDown();
        jQuery("#txtPassword").val("");
 
        if ($bitLogin) {
          jQuery(".ui-button-review").trigger("click");
        };
      } else {
        jQuery("#pnlLogin").slideDown();
        jQuery("#pnlReview").hide();
        //          jQuery(".ui-login-status").text("Not logged in...")
        //          jQuery(".ui-login-name").text("");
 
        if ($bitLogin) {
          switch (data.Status) {
            case -1:
              jQuery("#txtEmail").addClass("ui-error");
              jQuery("#txtMember").addClass("ui-error");
              break;
            case -2:
              jQuery("#txtEmail").addClass("ui-error");
              jQuery("#txtMember").addClass("ui-error");
              break;
            case -3:
              jQuery("#txtPassword").addClass("ui-error");
              break;
            case -4:
              alert("This login account does not have login permissions, please call for service.");
              break;
          }
        }
      }
    }
function getStatusJSONP() {
                jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Status.aspx?Company_ID=" + $intCompany_ID + "&callback=?",
                function (data) { Status(data, false) });
                }
               
                function getLoginContactJSONP($strEmail, $strPassword, $bitAutomatic) {
                jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Login.aspx?Company_ID=" + $intCompany_ID + "&Method=Email&Email=" + $strEmail + "&Password=" + $strPassword + "&Automatic=" + $bitAutomatic + "&callback=?",
                function (data) { Status(data, true) });
                }
               
                function getLoginAgentJSONP($strService, $strMember, $strPassword, $bitAutomatic) {
                jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Login.aspx?Company_ID=" + $intCompany_ID + "&Method=Agent&Service=" + $strService + "&Member=" + $strMember + "&Password=" + $strPassword + "&Automatic=" + $bitAutomatic + "&callback=?",
                function (data) { Status(data, true) });
                }
               
                function getLogoutJSONP() {
                jQuery.getJSON("https://" + $strHost + ".blueskybooking.net/authentication/Logout.aspx?Company_ID=" + $intCompany_ID + "&callback=?",
                function (data) { Status(data, false) });
                }
               
                jQuery("#txtPassword").keydown(function (event) {
                if (event.keyCode == 13) {
                getLoginContactJSONP(jQuery("#txtEmail").val(), jQuery("#txtPassword").val(), jQuery("#chkAutomatic").is(":checked"));
                }
                });
               
                jQuery("#btnLogin").click(function (e) {
                if (jQuery("#chkAgent").is(":checked")) {
                getLoginAgentJSONP("Agent", jQuery("#txtMember").val(), jQuery("#txtPassword").val(), jQuery("#chkAutomatic").is(":checked"));
                } else {
                getLoginContactJSONP(jQuery("#txtEmail").val(), jQuery("#txtPassword").val(), jQuery("#chkAutomatic").is(":checked"));
                }
                });
               
                jQuery("#btnLogout").click(function (e) {
                getLogoutJSONP();
                });
               
                jQuery("#btnStatus").click(function (e) {
                getStatusJSONP();
                });
               
                // Startup
                getStatusJSONP();
        
    

Below is the demo page for an integrated search button and the "My Reservations" Login button.

Login Button Demo

Our next tutorial will wrap up the integration of the booking widget. The FLIGHT STATUS tutorial will provide the customer with a way to add button to the form which accesses the status of status of flights. In doing so we will also peer into the list of available APIs.

The following sites were used as references for this tutorial

https://web.archive.org/web/20130622031212/
http://saltybeagle.com/2009/09/cross-origin-resource-sharing-demo

tails.png

Flight Status Integration


Flight Status Integration


How to Integrate Blue Sky Booking FLIGHT STATUS section/button into your Website

Purpose

The following documentation is intended to be a simple step-by-step guide on how to integerate Blue Sky Booking Reservation Systems "Flight Status Button" into your website. This allows a user to confirm the status of their flight prior to arriving at the departure/arrival location.

Outline of elements that will be added to or modified on the website

  1. A subsequent section will be added to the form or table established in the previous tutorial.
  2. Access to the company's API and subsequent options for results posted

Summary of Previous Tutorial

The installation of the "Login Button" was a simple but effective way for allowing a corporate website to track the login status of a user or agent on their pages. It permited a customizable form to allow for a more personal and interactive experiemce when accessing the home page.

This tutorial aims to integrate another section into your search form that allows your company to provide users with an even more personalized customer interaction.

Note: The following examples follow a basic guideline. It's in place to allow the customer to get the the functionality of the features working; however, it's up to the customer to customize and style to match the themes of their pages.

Lets quickly summarize what was added in our previous tutorial for the "Login" button and how we will expand on it

  • Another section was added to the original "search button" form. This section contained another button that allowed for personalized booking profiles.
  • When submitted, the login will perform validation and return the customers bookings and flight status.

As this is a continuation of the search and login buttons; all the files that were previously embedded will be required for the flight status addition too.

So lets begin:

The main components for the flight status integration come directly from the company's API. All information located in the database can be accessed through accessing the API.

Accessing the API should now be a familiar procedure since we have completed this step in the previous tutorials.

  1. In the Booking Agent, click File > Configuration > Services.
  2. Click Settings
  3. Copy the Company_ID, License and API Key.

You'll need this information in order to access company specific API's for values required for parameters to be passed to the server

Open your browser and past the following base url into the url bar. You will need to include a specific API to access.

https://api.blueskybooking.net

Below is a list of the available APIs. Each point below is the respective base url required for accessing the information from the database. The list items are company specific and require the Company_ID ({ID}) to complete the call.

  • https://api.blueskybooking.net/routes/{ID}
  • https://api.blueskybooking.net/equipment/{ID}
  • https://api.blueskybooking.net/genders/{ID}
  • https://api.blueskybooking.net/segments/{ID}
  • https://api.blueskybooking.net/tiers/{ID}
  • https://api.blueskybooking.net/locations/{ID}
  • https://api.blueskybooking.net/schedules/{ID}
  • https://api.blueskybooking.net/status/{ID}

When you try to access the API an authentication box will pop-up. Paste your License and API key to authenticate your account.

Once the authenication is successful you will have access to many of your company's APIs. It is up you to decide what information you would like to pull from the database and present to the user.

The API will return XML or JSON, depending on the request method.

Here is a quick definition of each API. For the purpose of this tutorial and creating a simple flight status section the most important categories are locations, schedule and status.

Routes

A route is similar to a schedule. A customer could be flying from Point A to Point B and then Point B to Point C. The Route is considered Point A to Point C with two flight schedules involved, one for the first flight and another for the second flight.

Available Filters:

  • Date_Start
  • Date_Finish
  • Departure_Date_Start
  • Departure_Date_End
  • Arrival_Date_Start
  • Arrival_Date_End
  • Departure_Location_ID
  • Arrival_Location_ID
  • Class_ID
  • Web (0,1,2)

Equipment

The equipment API will show you all the different types of aircrafts in the fleet.

Available Filters:

  • Equipement_ID
  • Active={true|false}

Genders

The gender API will provide you with all the information for each gender. It includes the gender_ID and dedicated weight_ID for each.

Available Filter:

  • Web={true|false}

Segments

The segment API will provide you with all the information for each segment. The segment parameter is used for differet types of trips.

Available Filters:

  • Segment
  • {Tag}
  • Web={true|false}

Tiers

The tier API will provide you with all the information for each tier. Tier is usually used for different levels of ticket pricing. For example you may have the Tier set for Fair Type which could then include; All Fares, Regular Fares and Discounted Fares.

Available Filters:

  • tier
  • Active={true|false}

Locations

The locations API will provide you with all the departure and arrival locations in your database. When accessing the locations API you can scroll down to a specific depature/arrival location. Each location contains a location number and a location_ID. The "autofill" javascript that was implemented in the previous two tutorials accessed the locations via the API using the two specific identification keys stated above. However if you just wanted to view each entry you can do so by accessing the locations page.

Available Filters:

  • Location
  • Web={true|false}
  • Active={true|false}

Schedules

The schedule API will provide you with all the possible schedules including departure times, locations and dates. A search parameter can be implemented to narrow down the list of schedules by location if the location_ID is passed. An example of a simple search parameter can be seen below:


https://api.blueskybooking.net/schedules/?Departure_Location_ID-3

When you search for the schedule based of the Location_ID=3, the database will return several different schedules displaying such fields as Flight Number, Departure location, Arrival location and Status(On-time, delayed or cancelled).

Available Filters:

  • Date_Start
  • Date_Finish
  • Departure_Date_Start
  • Departure_Date_End
  • Arrival_Date_Start
  • Arrival_Date_End
  • Departure_Location_ID
  • Arrival_Location_ID
  • Schedule
  • Segment
  • Segment_ID
  • Equipment_ID
  • Status_ID

It is up to the customer to decide what information they would like to pull from the database.

If you would like to customize the search parameter to be within a certain time frame then it is possible to do so. The example below shows how to query the database for schedules with

  • a Departure_Location_ID = 3
  • Arrival_Location_ID = 18
  • a Date_Start = 2015-01-20 at 08:00am
  • to a Date_Finish = 2015-01-20 at 15:00.

https://api.blueskybooking.net/schedules/Departure_Location_ID-3&Arrival_Location_ID-18&Date_Start-2015-01-20%2008:00&Date_Finish-2015-01-20%2017:00

An example of how the information is pulled from the API and displayed to the user can be seen below.

flight status example

Just a reminder the schedules are written in 24 hour time clock.

For simplicity sake, it might be easier to pull everything from the departure_location based on the current date seen in the example above.

Status

The status API will provide you with all the flight status options.

Available Filters:

  • Status
  • Tag={true|false}
  • Active={true|false}

It should be noted that the the access of the API's can't be pulled directly from the page. When the page is pulling information from the API it is being authenticated and that needs to be protected. If it is not protected then it is allowing for security holes, so it has to be called from a back end script not javascript or on the page itself.

Another use for the API's is to use them for an internal flight board. If your company's waiting area contains a screen then it is quite easy to develop a custom script to access the API's and pull in the status of all the departures and arrivals.

internal flight status example

So there you have it! We started of with a simple "book now" button/link that guided the customer to a basic form. When the form is filled out and validated it returns the flights specific to the entered parameters. Then we decided to advance the simple "book now" to an integrated customizable search form. The first section of the form actually integrated the search parameters directly into the page. The second sections allows for a login process permitting a more personalized expierence. Lastly, we added the flight status section so customers have the capability to check on their flights easily.

If you have any more questions or comments about these tutorials please email support@blueskybooking.net