2. Setting Up and Embedding the First Timetable

The Live Timetable is an iFrame that you can add to any webpage. By adding the Live Timetable code to your webpage (instructions on doing that are below), and configuring the different options, you can add, amend and change timetables across multiple webpages yourself, giving you maximum control.

It's a good idea to set up one of the Live Timetables, ideally on a demo page you can control but is not visible to the public, so you can test that your open data feed is working as expected and that the changes you are making to the data is having the desired effect within the Live Timetable.

Configuring the Live Timetable

The Live Timetable has several configurable options designed to give you flexibility in what you want to show to the customer (these are all to be included in the options object).

Below is a list of the available fields, complete with descriptions and example values. Further down the page you will find template code for both the Sessions and Facilities TImetables, into which you can add the relevant values for your chosen fields.

Variable / FieldField functionExample value

apiKey

Your unique key for accessing imin services. This will be provided to you by us.

accessibleName

To meet accessibility standards, you can add a descriptive label to your timetables. This will be read by assistive technologies, satisfying WCAG requirements for non-text content by ensuring that screen readers can describe the content to visually impaired users. Leave the field empty to use the default value (Timetable).

'Hereford Leisure Centre Swimming Timetable'

customStyle

You can choose fonts and colours to match your existing website branding.

fonts

You can choose to make specific fonts available to use within the Live Timetables

height

The height you want for the Live Timetable on the webpage, in pixels. Leave the field empty ('') to automatically adjust the timetable height based on the number of rows available. This responsive behaviour ensures the height is adapted dynamically, creating an optimal viewing experience without the need for manual adjustments.

500

location

Leave the field empty ('') if you want the timetable to show a dropdown for the customer to select from all centres. Otherwise, adding a latitude and longitude value will lock the timetable to show activities from that location only. Is in the format 'lat,lng,radius'.

'52.955116,-1.138528,0'

activity

Leave the field empty ('') if you want the timetable to show all activities at the location(s). Add a value if you want the timetable to show a specific activity only. Use high level groupings such as 'Group Exercise' to show multiple activities but exclude others.

'Yoga'

iminTag

Include custom values provided by imin at an additional cost to groups items in specific and custom sessions timetables. See Setting up the Rest of Your Timetables for more details.

Please reach out to us at support@imin.co for your own unique values.

showActivityTypes

Set to true if you want to hide the activity search dropdown and the reference to activity type in each row of the Live Timetable. NB the default behaviour of the Live Timetable is to show both the dropdown and activity types.

true / false

shouldShowExactAvailability

Set to true if you would like the Live Timetable to show the exact number of sessions left for activities being displayed. We recommend setting the value to true so users know exactly how many spaces are remaining.

true / false

shouldShowNoAvailability

Set to true if you would like the Live Timetable to show no availability information at all.

true / false

shouldNotShowDeepLinkButton

Set to false if you would like the Live Timetable to show at least one button for each activity directing the user to your booking system

true / false

shouldShowBookAsMemberButton

Set to true if you would like to show a member booking button. NB This field is only available in the Facilities Timetable.

true / false

bookableProviders

In the Live Sessions Timetable, this field determines the presence of the guest booking button (see further information here). In the Live Facilities Timetable, this field dictates the presence of both the guest and member booking button.

Please reach out to us at support@imin.co for your own unique value.

memberDeepLinks

Where shouldNotShowDeepLinkButton is set to false, you can include the URL for where you want to direct users.

Please reach out to us at support@imin.co for support.

showPrintButton

A button where the current view of the timetable will be exported to PDF in order to print off physically.

true / false

admissionsPolicyUrl

If you wish to enforce all users agree to a booking policy, once a booking button is pressed a pop-up will display asking the user to tick a box saying they agree to the link policy.

'https://www.exampleleisurecentre.com/bookings-policy'

Code Templates

We recommend leaving the values included in the code templates below as they are to ensure optimum user experience.

You can click the button in the top right-hand corner to copy the entire code block.

Sessions (classes, group exercise, swimming, gym workout, etc.)

<!-- Element to hold the timetable -->
<div id="timetable"></div>

<script>!function i(u,c,f){function a(t,e){if(!c[t]){if(!u[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(s)return s(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var o=c[t]={exports:{}};u[t][0].call(o.exports,function(e){return a(u[t][1][e]||e)},o,o.exports,i,u,c,f)}return c[t].exports}for(var s="function"==typeof require&&require,e=0;e<f.length;e++)a(f[e]);return a}({1:[function(e,t,n){var r,o,i=t.exports={};function u(){throw new Error("setTimeout has not been defined")}function c(){throw new Error("clearTimeout has not been defined")}function f(t){if(r===setTimeout)return setTimeout(t,0);if((r===u||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:u}catch(e){r=u}try{o="function"==typeof clearTimeout?clearTimeout:c}catch(e){o=c}}();var a,s=[],l=!1,d=-1;function h(){l&&a&&(l=!1,a.length?s=a.concat(s):d=-1,s.length&&m())}function m(){if(!l){var e=f(h);l=!0;for(var t=s.length;t;){for(a=s,s=[];++d<t;)a&&a[d].run();d=-1,t=s.length}a=null,l=!1,function(t){if(o===clearTimeout)return clearTimeout(t);if((o===c||!o)&&clearTimeout)return o=clearTimeout,clearTimeout(t);try{o(t)}catch(e){try{return o.call(null,t)}catch(e){return o.call(this,t)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function y(){}i.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];s.push(new p(e,t)),1!==s.length||l||f(m)},p.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=y,i.addListener=y,i.once=y,i.off=y,i.removeListener=y,i.removeAllListeners=y,i.emit=y,i.prependListener=y,i.prependOnceListener=y,i.listeners=function(e){return[]},i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},{}],2:[function(e,t,n){(function(t){"use strict";var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};window.iminTimetable=function(r,o){if("function"!=typeof document.querySelector)throw Error("The timetable could not be loaded: your browser does not support document.querySelector!");var i=t&&t.env&&t.env.EMBED_APP_TIMETABLE_URL||"https://imin-timetable-prod.herokuapp.com";if(!i)throw Error("The timetable could not be loaded: no URL was configured for the iframe.");var u=!1,e=function(){if(!u){u=!0;var e=document.querySelector(r),t=document.createElement("iframe"),n=void 0;for("object"===(void 0===o?"undefined":c(o))&&"string"==typeof o.height&&o.height.match(/^[0-9]+px$/)?n="height: "+o.height:"object"===(void 0===o?"undefined":c(o))&&"number"==typeof o.height&&(n="height: "+o.height+"px"),t.scrolling=!1,t.style="width: 100%;border: none;"+n,t.src=i+"/?embed=1","object"===(void 0===o?"undefined":c(o))&&"string"==typeof o.accessibleName?t.title=o.accessibleName:t.title="Timetable",t.onload=function(){t.contentWindow.postMessage(JSON.stringify(o||{}),i),n||window.addEventListener("message",function(e){e.origin===i&&"number"==typeof e.data&&(t.style.height=e.data+"px")})};e.firstChild;)e.removeChild(e.firstChild);e.appendChild(t)}};"interactive"===document.readyState||"complete"===document.readyState?e():document.addEventListener("readystatechange",e)}}).call(this,e("_process"))},{_process:1}]},{},[2]);</script>
<!-- Set options and attach to the element -->
<script type="text/javascript">
var options = {
  apiKey: '',
  accessibleName: '',
  cache: true,
  customStyle: {
    button: {
      color: '',
      backgroundColor: '',
      ':hover': {
        color: '',
      },
      fontFamily: '',
    },
    filter: {
      fontFamily: '',
    },
    base: {
      fontFamily: '',
    },
    timetable: {
      color: '',
      backgroundColor: '',
    },
  },
  fonts: [],
  height: '',
  location: '',
  activity: '',
  iminTag: '{upon request from imin}',
  showActivityTypes: false,
  shouldShowExactAvailability: true,
  shouldShowNoAvailability: false,
  shouldNotShowDeepLinkButton: ,
  bookableProviders: ['{upon request from imin}'],
  memberDeepLinks: {
    {upon request from imin}: '{URL to provided by imin}',
  },
};
iminTimetable('#timetable', options);
</script>

Facilities (sports hall, pitches, courts, etc.)

The Facilities Timetable shares many of the same variables as the session timetable (and has fewer configuration options overall). You can use the code template below and update the variables accordingly.

<!-- Element to hold the timetable -->
<div id="timetable"></div>
  
<script>!function i(u,c,f){function a(t,e){if(!c[t]){if(!u[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(s)return s(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var o=c[t]={exports:{}};u[t][0].call(o.exports,function(e){return a(u[t][1][e]||e)},o,o.exports,i,u,c,f)}return c[t].exports}for(var s="function"==typeof require&&require,e=0;e<f.length;e++)a(f[e]);return a}({1:[function(e,t,n){var r,o,i=t.exports={};function u(){throw new Error("setTimeout has not been defined")}function c(){throw new Error("clearTimeout has not been defined")}function f(t){if(r===setTimeout)return setTimeout(t,0);if((r===u||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:u}catch(e){r=u}try{o="function"==typeof clearTimeout?clearTimeout:c}catch(e){o=c}}();var a,s=[],l=!1,d=-1;function h(){l&&a&&(l=!1,a.length?s=a.concat(s):d=-1,s.length&&m())}function m(){if(!l){var e=f(h);l=!0;for(var t=s.length;t;){for(a=s,s=[];++d<t;)a&&a[d].run();d=-1,t=s.length}a=null,l=!1,function(t){if(o===clearTimeout)return clearTimeout(t);if((o===c||!o)&&clearTimeout)return o=clearTimeout,clearTimeout(t);try{o(t)}catch(e){try{return o.call(null,t)}catch(e){return o.call(this,t)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function y(){}i.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];s.push(new p(e,t)),1!==s.length||l||f(m)},p.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=y,i.addListener=y,i.once=y,i.off=y,i.removeListener=y,i.removeAllListeners=y,i.emit=y,i.prependListener=y,i.prependOnceListener=y,i.listeners=function(e){return[]},i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},{}],2:[function(e,t,n){(function(t){"use strict";var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};window.iminTimetable=function(r,o){if("function"!=typeof document.querySelector)throw Error("The timetable could not be loaded: your browser does not support document.querySelector!");var i=t&&t.env&&t.env.EMBED_APP_TIMETABLE_URL||"https://facilities-timetable-prod.herokuapp.com";if(!i)throw Error("The timetable could not be loaded: no URL was configured for the iframe.");var u=!1,e=function(){if(!u){u=!0;var e=document.querySelector(r),t=document.createElement("iframe"),n=void 0;for("object"===(void 0===o?"undefined":c(o))&&"string"==typeof o.height&&o.height.match(/^[0-9]+px$/)?n="height: "+o.height:"object"===(void 0===o?"undefined":c(o))&&"number"==typeof o.height&&(n="height: "+o.height+"px"),t.scrolling=!1,t.style="width: 100%;border: none;"+n,t.src=i+"/?embed=1","object"===(void 0===o?"undefined":c(o))&&"string"==typeof o.accessibleName?t.title=o.accessibleName:t.title="Timetable",t.onload=function(){t.contentWindow.postMessage(JSON.stringify(o||{}),i),n||window.addEventListener("message",function(e){e.origin===i&&"number"==typeof e.data&&(t.style.height=e.data+"px")})};e.firstChild;)e.removeChild(e.firstChild);e.appendChild(t)}};"interactive"===document.readyState||"complete"===document.readyState?e():document.addEventListener("readystatechange",e)}}).call(this,e("_process"))},{_process:1}]},{},[2]);</script>
<!-- Set options and attach to the element -->
<script type="text/javascript">
  var options = {
    apiKey: '',
    accessibleName: '',
    cache: true,
    customStyle: {
      button: {
      	color: '',
      	backgroundColor: '',
        ':hover': {
          color: '',
        },
        fontFamily: '',
      },
      filter: {
        fontFamily: '',
      },
      base: {
        fontFamily: '',
      },
      timetable: {
        backgroundColor: '',
      },
      unavailableTimetableSlot: {
        color: '',
        backgroundColor: '',
      },
    },
  fonts: [],
  height: '',
  location: '',
  activity: '',
  iminTag: '{upon request from imin}',
  shouldShowNoAvailability: false,
  shouldShowBookAsMemberButton: ,
  bookableProviders: ['{upon request from imin}'],
  memberDeepLinks: {
    {upon request from imin}: '{URL to provided by imin}',
  },
};
iminTimetable('#timetable', options);
</script>

In order to show the member booking button in the Facilities Timetable using memberDeepLinks, shouldShowBookAsMemberButton must be set to true and the bookableProviders field must include a relevant value. Please note that this functionality differs to the Sessions Timetable.

How to Embed the Live Timetable onto your Webpage

  1. Make sure you are on the editing view of the page you put the timetable on. We will call this the main page.

  2. Copy and paste the prepped Live Timetable code into the main page HTML where you want the timetable. You will most likely want to create a specific "div" box at the right position on the page to paste the code into. The width of this div box is important - if the box is too narrow, the timetable will display in responsive mode (i.e. it will show a more compact version suitable for smaller device screens).

  3. Click Save (or the equivalent of).

  4. Empty the cache and hard reload your main page, and you should see your timetable. See FAQs for troubleshooting.

The minified script tags in both the Sessions and Facilities Timetable code includes the information required for the iframes to have title attributes to cater for accessibility requirements.

Last updated