<div class="find-courses hidden" data-redirect-url="/components/preview/efl-venue-results-page" data-course-name="W1VC" data-radius="25" data-behaviour="bing-map-search" data-course-blockid="" data-course-isprocourse="False">
<button class="lightbox-overlay__close" id="close">
<span class="visually-hidden">Close dialog</span>
</button>
<div class="find-courses__image-wrapper">
<img src="/assets/example-content/find-courses-bg.png" loading="lazy">
</div>
<div class="find-courses__search">
<div class="find-courses__search--pin"></div>
<div class="steps search-step-1">
<div class="default-steps">
<h2>Let’s find a course</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vestibulum</p>
</div>
<div class="error-steps hidden">
<h2>Sorry, no courses found</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vestibulum.
<a href="/" target="_blank" class="contactus">Contact Us</a>
</p>
</div>
<a href="/" class="cta cta--primary location-denied hidden" id="location-denied" tabindex="0">location blocked by browser</a>
<a href="/" class="cta cta--primary current-location-found hidden" id="current-location-found" tabindex="0">Location found</a>
<a href="/" class="cta cta--primary use-current-location" id="use-current-location" tabindex="0">Use Current location</a>
<a href="/" class="cta cta--secondary enter-postcode" id="enter-postcode" tabindex="0">Enter postcode</a>
</div>
<div class="steps search-step-2 hidden">
<h2>Let’s find a course near you</h2>
<div class="find-courses__postcode">
<div id="searchBoxContainer">
<input type="text" id="searchBox" class="find-courses__postcode-input" placeholder="Enter your postcode" autocomplete="off" />
</div>
</div>
<a href="/" class="cta cta--primary postcode-search" id="postcode-search" tabindex="0">Search</a>
</div>
<div class="steps search-step-3 hidden">
<h2>Searching...</h2>
<div class="loading">
<div class="loader"></div>
<div class="efl-logo"></div>
</div>
</div>
</div>
</div>
No notes defined.
{
"cta1": {
"copy": "Use Current location",
"modifier": "primary",
"id": "use-current-location",
"additionalClass": "use-current-location"
},
"cta2": {
"copy": "Enter postcode",
"modifier": "secondary",
"id": "enter-postcode",
"additionalClass": "enter-postcode"
},
"cta3": {
"copy": "Search",
"modifier": "primary",
"id": "postcode-search",
"additionalClass": "postcode-search"
},
"cta4": {
"copy": "Location found",
"modifier": "primary",
"id": "current-location-found",
"additionalClass": "current-location-found hidden"
},
"cta5": {
"copy": "Confirmation and Payment",
"modifier": "primary",
"id": "confirmation-and-payment",
"additionalClass": "confirmation-and-payment"
},
"cta6": {
"copy": "location blocked by browser",
"modifier": "primary",
"id": "location-denied",
"additionalClass": "location-denied hidden"
}
}
import { Dialog } from '../lightbox-overlay/lightbox-overlay';
import bingMap from '../bing-map/bing-map';
export default parentElement => {
const DIALOG_ID = 'find-courses-dialog';
const headers = {
// 'Ocp-Apim-Subscription-Key': '8279c7fab35f432daf1a0bd395a9ae48',
};
const preReqModal = document.querySelector(
'[data-behaviour="pre-req-modal"]'
);
const swithScreen = ({ screen }) => {
const modalWindow = document.querySelector('#find-courses-dialog');
const allSteps = modalWindow.querySelector('.find-courses__search');
allSteps.querySelectorAll('.steps').forEach(steps => {
steps.classList.add('hidden');
});
screen.classList.remove('hidden');
};
const searchByCurrentLocation = target => {
const allSteps = target.closest('.find-courses__search');
const screen = allSteps.querySelector('.search-step-1 ');
const deniedCta = screen.querySelector('.location-denied');
const Cta = screen.querySelector('#use-current-location');
const onDeniedClick = e => {
e.preventDefault();
};
deniedCta.addEventListener('click', onDeniedClick);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
position => {
const modalWindow = document.querySelector('#find-courses-dialog');
modalWindow.querySelector('.search-longitude').value =
position.coords.longitude;
modalWindow.querySelector('.search-latitude').value =
position.coords.latitude;
const cta = screen.querySelector('.current-location-found');
target.querySelector('.loading').remove();
target.classList.remove('searching');
target.classList.add('hidden');
cta.classList.remove('hidden');
setTimeout(() => {
cta.click();
}, 1000);
},
error => {
Cta.classList.add('hidden');
deniedCta.classList.remove('hidden');
console.log(error);
}
);
} else {
// eslint-disable-next-line no-console
console.log('Geolocation is not supported by this browser.');
}
};
const searchByLocation = event => {
event.preventDefault();
const { target } = event;
target.classList.add('searching');
target.insertAdjacentHTML(
'beforeend',
'<div class="loading"><span class="efl-logo"></span><span class="loader"></span></div>'
);
searchByCurrentLocation(target);
};
const searchByPostcode = event => {
event.preventDefault();
const { target } = event;
const allSteps = target.closest('.find-courses__search');
const screen = allSteps.querySelector('.search-step-2');
const map = screen.querySelector('.MicrosoftMap');
const inputBox = screen.querySelector('.find-courses__postcode-input');
const btn = screen.querySelector('.postcode-search');
swithScreen({ screen });
screen
.querySelector('.postcode-search')
.setAttribute('disabled', 'disabled');
if (!map) {
bingMap('bingMapsearchBox', 'bingMapsearchBoxContainer');
}
inputBox.focus();
// input value empty check
inputBox.addEventListener('input', e => {
if (!e.target.value) {
btn.setAttribute('disabled', 'disabled');
}
});
};
async function searchVenueCallback(longitude, latitude) {
const modalWindow = document.querySelector('#find-courses-dialog');
const {
courseName,
courseBlockid,
courseIsprocourse,
} = modalWindow.querySelector('.find-courses').dataset;
let blockid = '';
// replace url with `/seachVenue/` in development to see results
// const url = `/Courses/GetAvailableCourses/?postCodeLon=${longitude}
// &postCodeLat=${latitude}&courseName=${courseName}`;
if (courseBlockid) {
blockid = `&blockId=${courseBlockid}`;
}
const url = `${
window.location.origin
}/Courses/GetAvailableCourses/?postCodeLon=${longitude}&postCodeLat=${latitude}&courseName=${courseName}&isProCourse=${courseIsprocourse}${blockid}`;
// eslint-disable-next-line compat/compat
const response = await fetch(url, {
headers,
});
return response.json();
}
const checkVenueAvailable = (longitude, latitude) => {
const modalWindow = document.querySelector('#find-courses-dialog');
const allSteps = modalWindow.querySelector('.find-courses__search');
try {
searchVenueCallback(longitude, latitude).then(response => {
if (response && response.isCourseAvailable) {
const {
redirectUrl,
courseName,
courseBlockid,
courseIsprocourse,
} = modalWindow.querySelector('.find-courses').dataset;
let blockid = '';
if (courseBlockid) {
blockid = `&blockId=${courseBlockid}`;
}
// eslint-disable-next-line no-restricted-globals
location.href = `${redirectUrl}?postCodeLon=${longitude}&postCodeLat=${latitude}&courseName=${courseName}&isProCourse=${courseIsprocourse}${blockid}`;
} else {
const screen = allSteps.querySelector('.search-step-1');
screen.querySelector('.default-steps').classList.add('hidden');
screen.querySelector('.error-steps').classList.remove('hidden');
const cta = screen.querySelector('.current-location-found');
const currentCta = screen.querySelector('.use-current-location');
const deniedCta = screen.querySelector('.location-denied');
if (deniedCta.classList.contains('hidden')) {
currentCta.classList.remove('hidden');
} else {
currentCta.classList.add('hidden');
}
cta.classList.add('hidden');
swithScreen({ screen });
currentCta.focus();
}
});
} catch (e) {
throw new Error('Uable to retrive match score ::', e);
}
};
const searchVenue = event => {
event.preventDefault();
const { target } = event;
const allSteps = target.closest('.find-courses__search');
const screen = allSteps.querySelector('.search-step-3');
const modalWindow = document.querySelector('#find-courses-dialog');
const longitude = modalWindow.querySelector('.search-longitude').value;
const latitude = modalWindow.querySelector('.search-latitude').value;
swithScreen({ screen });
checkVenueAvailable(longitude, latitude);
};
const generateLightBox = labelId => {
let html = parentElement.outerHTML;
html = html.replace('find-courses hidden', 'find-courses');
html = html.replace('id="searchBox"', 'id="bingMapsearchBox"');
html = html.replace(
'id="searchBoxContainer"',
'id="bingMapsearchBoxContainer"'
);
return `
<div role="dialog" id="${DIALOG_ID}" aria-labelledby="${labelId}" aria-modal="true" class="lightbox-overlay">
${html}
<input type="hidden" class="search-longitude" value=""/>
<input type="hidden" class="search-latitude" value=""/>
</div>`;
};
const removeLightBox = () => {
document.getElementById(DIALOG_ID).remove();
if (document.querySelector('#find-course-near-me')) {
document
.querySelector('#find-course-near-me')
.closest('a')
.focus();
}
};
const searchButton = document.querySelector('#find-course-near-me');
if (!searchButton) {
return;
}
if (
preReqModal &&
preReqModal.getAttribute('data-pre-req-check') === 'false'
) {
return;
}
const openLightbox = focusBtn => {
// Create the lightbox
const lightboxContainer = document.createElement('div');
lightboxContainer.innerHTML = generateLightBox({
labelId: focusBtn.getAttribute('id'),
});
document.body.appendChild(lightboxContainer);
// eslint-disable-next-line no-new
new Dialog({
dialogId: DIALOG_ID,
focusAfterClosed: focusBtn,
focusFirst: 'close',
closeCallBack: () => removeLightBox(),
});
const postcodeBtn = lightboxContainer.querySelector('.enter-postcode');
const searchBtn = lightboxContainer.querySelector('.postcode-search');
const currentBtn = lightboxContainer.querySelector('.use-current-location');
const currentSearchBtn = lightboxContainer.querySelector(
'.current-location-found'
);
lightboxContainer.querySelector('#close').focus();
// Find current location coordinates
currentBtn.addEventListener('click', e => {
searchByLocation(e);
});
// search venue by current location
currentSearchBtn.addEventListener('click', e => {
searchVenue(e);
});
// load map screen
postcodeBtn.addEventListener('click', e => {
searchByPostcode(e);
});
// search venue by longitude and latitude
searchBtn.addEventListener('click', e => {
if (searchBtn.getAttribute('disabled') === 'disabled') {
e.preventDefault();
return;
}
searchVenue(e);
});
};
if (searchButton) {
searchButton.addEventListener('keyup', event => {
if (event.keyCode === 13) {
// Cancel the default action, if needed
event.preventDefault();
searchButton.click();
}
});
searchButton.addEventListener('click', event => {
event.preventDefault();
const allSteps = parentElement.querySelector('.find-courses__search');
const screen = allSteps.querySelector('.search-step-1');
allSteps.querySelectorAll('.steps').forEach(steps => {
steps.classList.add('hidden');
});
screen.classList.remove('hidden');
openLightbox(searchButton);
});
}
};
/* stylelint-disable no-descending-specificity */
.find-courses {
display: flex;
flex-direction: column;
border-radius: 0.8rem;
box-shadow: 0 4px 6px rgba(91, 104, 133, 0.1);
max-width: 34.3rem;
background-color: $white;
position: relative;
max-height: 51.1rem;
min-width: 34.3rem;
.lightbox-overlay__close {
top: 1.6rem;
right: 1.6rem;
width: 3.2rem;
height: 3.2rem;
&::before {
width: 3.2rem;
height: 3.2rem;
}
}
&__image-wrapper {
height: 17rem;
width: 100%;
border-radius: 0.8rem 0.8rem 0 0;
overflow: hidden;
img {
height: 100%;
object-fit: cover;
width: 100%;
}
}
&__search {
padding: 2.4rem;
padding-bottom: 5.2rem;
text-align: center;
position: relative;
height: 34.1rem;
&--pin {
background: url('./assets/images/map-pin.svg') no-repeat center;
width: 7.2rem;
height: 7.2rem;
display: flex;
margin: 0 auto;
top: -3.6rem;
position: absolute;
left: 0;
right: 0;
}
&--success {
padding: 3.5rem;
img {
margin: 0 auto;
width: 6.5rem;
height: 6.5rem;
margin-top: 2.4rem;
}
}
.steps {
img {
margin: 0 auto;
width: 8.6rem;
height: 8.6rem;
}
}
h2 {
@extend .efl-heading-2;
color: $blue;
margin-top: 2.4rem;
}
p {
@extend .efl-p-1;
color: $color-interface-light;
margin-top: 0.8rem;
}
.error-steps {
p {
margin-top: 1.6rem;
}
a {
text-decoration: underline;
color: $crest-blue;
}
a.redlink {
color: $red;
}
}
.cta--primary {
background-color: $blue-accent3;
margin: 0 auto;
margin-top: 3.2rem;
color: $white;
}
.cta--secondary {
margin: 0 auto;
margin-top: 1.6rem;
&:hover {
background-color: transparent;
color: $blue;
}
}
.cta {
&.use-current-location {
position: relative;
&::after {
content: '';
background: url('./assets/images/location-pin-white.svg') no-repeat
center right;
width: 1.4rem;
height: 2rem;
position: absolute;
right: 1.6rem;
left: initial;
bottom: initial;
top: initial;
}
.loading {
position: absolute;
width: 2.8rem;
height: 2.8rem;
right: 1.6rem;
.efl-logo {
background-image: url('./assets/images/efl-loader-logo.svg');
background-size: 1.13rem 1.37rem;
}
.loader {
position: absolute;
left: 0;
&::after {
background: $blue-accent3;
}
}
}
&.searching {
&::after {
display: none;
}
}
}
&.current-location-found {
&::after {
content: '';
background: url('./assets/images/tick-circle.svg') no-repeat center
right;
width: 2.1rem;
height: 2.1rem;
position: absolute;
right: 1.6rem;
left: initial;
bottom: initial;
top: initial;
}
}
&.confirmation-and-payment {
&::after {
content: '';
background: url('./assets/images/tick-circle.svg') no-repeat center
right;
width: 2.1rem;
height: 2.1rem;
position: absolute;
right: 1.6rem;
left: initial;
bottom: initial;
top: initial;
}
}
&.postcode-search {
&[disabled] {
border: none;
color: $light-blue;
background-color: $grey-light;
cursor: default;
}
}
&.location-denied {
border: none;
color: $color-interface-light;
background-color: $grey-light;
cursor: default;
}
}
&.location-denied .hidden {
display: none !important;
}
input {
@extend .efl-p-1;
color: $crest-blue;
padding: 1.2rem 2.5rem 1.1rem 1rem;
border: none;
width: 100%;
border-bottom: 1px solid $color-interface-light;
margin-top: 4rem;
background: url('./assets/images/postcode-search.svg') no-repeat 98%
center;
box-sizing: border-box !important;
line-height: 1.6rem;
font-weight: 700;
&::-webkit-search-cancel-button {
-webkit-appearance: none;
background: url('./assets/images/icon-close-blue.svg') no-repeat center
right;
width: 1.4rem;
height: 1.4rem;
padding: 0.5rem;
background-size: 1.6rem;
background-color: $white;
margin-right: -1.9rem;
cursor: pointer;
}
}
}
#bingMapsearchBoxContainer {
position: relative;
.MicrosoftMap {
position: initial !important;
}
.MicrosoftMap .as_container_search {
width: 100% !important;
text-align: left;
}
.MicrosoftMap .as_container .line1 {
@extend .efl-p-1;
color: $black;
}
.MicrosoftMap .as_container .line2 {
@extend .efl-p-1;
color: $color-interface-light;
margin-top: 0.1rem;
}
.MicrosoftMap .as_img.maps_address {
background-image: url('./assets/images/location-pin.svg');
width: 1.5rem !important;
height: 2.2rem !important;
margin-right: 0.8rem;
}
.MicrosoftMap .as_container .bingLogoContainer {
display: none !important;
}
.MicrosoftMap .as_container .suggestLink {
padding: 1.6rem 2.4rem;
&:hover {
background-color: $grey-light;
}
}
}
.loading {
position: relative;
margin: 4rem auto;
width: 10.4em;
height: 10.4em;
&.show {
display: block;
}
.efl-logo {
background-image: url('./assets/images/ef-logo.svg');
background-repeat: no-repeat;
background-position: center;
position: absolute;
z-index: 2;
top: 0;
left: 0;
background-size: 4.2rem 5.1rem;
width: 100%;
height: 100%;
}
.loader {
font-size: 10px;
text-indent: -9999em;
width: 100%;
height: 100%;
border-radius: 100%;
overflow: hidden;
background: rgb(236, 238, 243);
position: relative;
-webkit-animation: load3 1.4s infinite linear;
animation: load3 1.4s infinite linear;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
}
.loader::before {
width: 100%;
height: 50%;
background: -linear-gradient(0deg, #004aa3 0%, #eceef3 50%);
background: -moz-linear-gradient(0deg, #004aa3 0%, #eceef3 50%);
background: -o-linear-gradient(0deg, #004aa3 0%, #eceef3 50%);
background: -ms-linear-gradient(0deg, #004aa3 0%, #eceef3 50%);
background: -webkit-linear-gradient(0deg, #004aa3 0%, #eceef3 50%);
transform-origin: bottom right;
position: absolute;
top: 0;
left: 0;
content: '';
}
.loader::after {
background: #fff;
width: 85%;
height: 85%;
border-radius: 50%;
content: '';
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
@-webkit-keyframes load3 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load3 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
}
&[data-behaviour='pre-req-modal'] {
.find-courses__search {
h2 {
@include text-limit(3);
}
}
}
@media screen and (min-width: $mq-medium) {
flex-direction: row;
max-width: 95.2rem;
max-height: 43.6rem;
.lightbox-overlay__close {
&::before {
background-image: url('./assets/images/search-modal-close.svg');
}
}
&__image-wrapper {
height: 43.6rem;
width: 46.2rem;
border-radius: 0.8rem 0 0 0.8rem;
}
&__search {
padding: 5.2rem 9rem;
width: 49rem;
height: 43.6rem;
&--pin {
position: initial;
top: initial;
}
h2 {
font-size: 3.2rem;
line-height: 3.6rem;
}
input {
font-size: 2rem;
line-height: 2.8rem;
font-weight: 500;
padding: 1.2rem 2.7rem 1.1rem 1rem;
}
}
&[data-behaviour='pre-req-modal'] {
.find-courses__search {
width: 59rem;
padding: 3.2rem 7rem;
}
}
}
}
<div class="find-courses hidden" data-redirect-url="/components/preview/efl-venue-results-page" data-course-name="W1VC" data-radius="25" data-behaviour="bing-map-search" data-course-blockid="" data-course-isprocourse="False">
<button class="lightbox-overlay__close" id="close">
<span class="visually-hidden">Close dialog</span>
</button>
<div class="find-courses__image-wrapper">
<img src="/assets/example-content/find-courses-bg.png" loading="lazy">
</div>
<div class="find-courses__search">
<div class="find-courses__search--pin"></div>
<div class="steps search-step-1">
<div class="default-steps">
<h2>Let’s find a course</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vestibulum</p>
</div>
<div class="error-steps hidden">
<h2>Sorry, no courses found</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vestibulum.
<a href="/" target="_blank" class="contactus">Contact Us</a>
</p>
</div>
{{render '@cta' cta6 merge="true"}}
{{render '@cta' cta4 merge="true"}}
{{render '@cta' cta1 merge="true"}}
{{render '@cta' cta2 merge="true"}}
</div>
<div class="steps search-step-2 hidden">
<h2>Let’s find a course near you</h2>
<div class="find-courses__postcode">
<div id="searchBoxContainer">
<input type="text" id="searchBox" class="find-courses__postcode-input" placeholder="Enter your postcode" autocomplete="off"/>
</div>
</div>
{{render '@cta' cta3 merge="true"}}
</div>
<div class="steps search-step-3 hidden">
<h2>Searching...</h2>
<div class="loading">
<div class="loader"></div>
<div class="efl-logo"></div>
</div>
</div>
</div>
</div>