2. Setting up and Embedding your 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.
apiKey
Your unique key for accessing imin services. This will be provided to you by us. Please refer to our FAQs for tips on how to hide your API key.
Please reach out to us at [email protected] for your own unique values.
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. Values should be included in Title Case.
'Group Exercise'
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 [email protected] 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.
We recommend setting the value to false
for those timetables that only show one activity type, e.g. swimming and gym workout.
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
shouldShowBookAsGuestButton
Set to true
if you would like to show a guest booking button.
true
/ false
shouldShowBookAsMemberButton
Set to true
if you would like to show a member booking button.
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 [email protected] 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 [email protected] 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
You can click the button in the top right-hand corner to copy the entire code block.
If you are using our dummy dataset, you must include the following fields and values, along with your API key:
location: '51.7502,-1.2674,0.1',
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: false,
//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.)
<!-- 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: false,
//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
Make sure you are on the editing view of the page you put the timetable on. We will call this the main page.
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).
Click Save (or the equivalent of).
Empty the cache and hard reload your main page, and you should see your timetable. See FAQs for troubleshooting.
Last updated