mirror of
https://github.com/13hannes11/UU_hci_prototype.git
synced 2024-09-04 01:11:00 +02:00
first commit
This commit is contained in:
15
README.md
Normal file
15
README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Schedule Template
|
||||
|
||||
A simple template that lets you display events on a timeline, as well as organize them in groups (week days, conference rooms etc…).
|
||||
|
||||
[Article on CodyHouse](https://codyhouse.co/gem/schedule-template)
|
||||
|
||||
[Demo](https://codyhouse.co/demo/schedule-template)
|
||||
|
||||
[License](https://codyhouse.co/license)
|
||||
|
||||
## Dependencies
|
||||
|
||||
This experiment is built upon the [CodyHouse Framework](https://github.com/CodyHouse/codyhouse-framework).
|
||||
|
||||
Make sure to include both the style.scss and util.js files of the framework.
|
||||
1
assets/css/style.css
Normal file
1
assets/css/style.css
Normal file
File diff suppressed because one or more lines are too long
561
assets/css/style.scss
Normal file
561
assets/css/style.scss
Normal file
@@ -0,0 +1,561 @@
|
||||
@import '../../../../../codyhouse-framework/main/assets/css/style.scss'; // ⚠️ make sure to import the CodyHouse framework
|
||||
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600'); // custom font
|
||||
|
||||
// --------------------------------
|
||||
|
||||
// Schedule Template - by CodyHouse.co
|
||||
|
||||
// --------------------------------
|
||||
|
||||
:root {
|
||||
// colors
|
||||
@include defineColorHSL(--cd-color-event-1, 199, 25%, 46%); // Smalt Blue
|
||||
@include defineColorHSL(--cd-color-event-2, 271, 23%, 26%); // Martinique
|
||||
@include defineColorHSL(--cd-color-event-3, 162, 14%, 68%); // Edward
|
||||
@include defineColorHSL(--cd-color-event-4, 31, 89%, 68%); // Rajah
|
||||
@include defineColorHSL(--cd-color-text, 0, 0%, 13%); // Black
|
||||
@include defineColorHSL(--cd-color-border, 0, 0%, 92%); // Grey
|
||||
|
||||
// font
|
||||
--font-primary: 'Source Sans Pro', sans-serif;
|
||||
|
||||
//schedule template
|
||||
--schedule-rows-number: 19;
|
||||
--schedule-rows-height: 50px;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--cd-color-text);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--cd-color-event-3);
|
||||
}
|
||||
|
||||
.cd-schedule {
|
||||
position: relative;
|
||||
|
||||
&::before { // never visible - this is used in js to check the current MQ
|
||||
content: 'mobile';
|
||||
display: none;
|
||||
}
|
||||
|
||||
.js & {
|
||||
@include breakpoint(md) {
|
||||
width: calc(100% - 2*var(--component-padding));
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: var(--max-width-xl);
|
||||
|
||||
&::before {
|
||||
content: 'desktop';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__timeline { // events time
|
||||
display: none;
|
||||
|
||||
.js & {
|
||||
@include breakpoint(md) {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding-top: var(--schedule-rows-height);
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
height: var(--schedule-rows-height);
|
||||
|
||||
&::after { // this is used to create the table horizontal lines
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: var(--cd-color-border);
|
||||
}
|
||||
|
||||
&:last-of-type::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(lg) {
|
||||
li {
|
||||
|
||||
&::after {
|
||||
width: calc(100% - 60px);
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
transform: translateY(-50%);
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
|
||||
&:nth-of-type(2n) span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__events {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
.js & {
|
||||
@include breakpoint(md) {
|
||||
width: 100%;
|
||||
|
||||
> ul {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(lg) {
|
||||
width: calc(100% - 60px); // 60px is the .cd-schedule__timeline > li::after element left
|
||||
margin-left: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__group { // group of same day events
|
||||
margin-bottom: var(--space-lg);
|
||||
|
||||
.js & {
|
||||
@include breakpoint(md) {
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
border: 1px solid var(--cd-color-border);
|
||||
margin-bottom: 0; // reset style
|
||||
|
||||
&:not(:first-of-type) {
|
||||
border-left-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__group > ul {
|
||||
position: relative;
|
||||
padding: 0 var(--component-padding);
|
||||
display: flex;
|
||||
overflow-x: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&::after { // never visible - used to add a right padding to .cd-schedule__group > ul
|
||||
display: inline-block;
|
||||
content: '-';
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.js & {
|
||||
@include breakpoint(md) {
|
||||
height: calc(var(--schedule-rows-height)*var(--schedule-rows-number));
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
|
||||
&::after { // reset style
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__top-info { // day label
|
||||
width: 100%;
|
||||
padding: 0 var(--component-padding);
|
||||
|
||||
> span {
|
||||
display: inline-block;
|
||||
margin-bottom: var(--space-sm);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.js & {
|
||||
@include breakpoint(md) {
|
||||
// vertically center its content
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: var(--schedule-rows-height);
|
||||
border-bottom: 1px solid var(--cd-color-border);
|
||||
padding: 0; // reset style
|
||||
|
||||
> span {
|
||||
font-weight: normal;
|
||||
font-size: var(--text-sm);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__event {
|
||||
flex-shrink: 0; // force them to stay on one line
|
||||
float: left; // flex fallback
|
||||
height: 150px;
|
||||
width: 70%;
|
||||
max-width: 300px;
|
||||
margin-right: var(--space-md);
|
||||
transition: opacity .2s, background .2s;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
height: 100%;
|
||||
padding: var(--space-sm);
|
||||
box-shadow: inset 0 -3px 0 rgba(#000, .2);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a::before { // event start/end date
|
||||
content: attr(data-start)' - 'attr(data-end);
|
||||
}
|
||||
|
||||
.js & {
|
||||
@include breakpoint(sm) {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
@include breakpoint(md) {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
width: calc(100% + 2px); // top position and height will be set using js
|
||||
left: -1px;
|
||||
max-width: none; // reset style
|
||||
margin-right: 0;
|
||||
|
||||
a {
|
||||
padding: var(--space-sm);
|
||||
box-shadow: 0 10px 20px rgba(#000, .1), inset 0 -3px 0 rgba(#000, .2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.js {
|
||||
@include breakpoint(md) {
|
||||
.cd-schedule__event--selected { // classes added when an user select the event
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.cd-schedule--loading .cd-schedule__event {
|
||||
// the class .cd-schedule--loading is added by default to the .cd-schedule element
|
||||
// it is removed as soon as the single events are placed in the schedule plan (using javascript)
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__name, // event name in the schedule template
|
||||
.cd-schedule__event a::before, // event date in the schedule template
|
||||
.cd-schedule-modal__name, // event name in the modal element
|
||||
.cd-schedule-modal__date { // event date in the modal element
|
||||
display: block;
|
||||
color: var(--color-white);
|
||||
font-weight: bold;
|
||||
@include fontSmooth;
|
||||
}
|
||||
|
||||
.cd-schedule__name,
|
||||
.cd-schedule-modal__name {
|
||||
font-size: var(--text-lg);
|
||||
|
||||
@include breakpoint(md) {
|
||||
font-size: calc(var(--text-sm)*1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__date, // not included in the the HTML but added using JavScript
|
||||
.cd-schedule__event a::before {
|
||||
opacity: .7;
|
||||
margin-bottom: var(--space-xxxs);
|
||||
|
||||
@include breakpoint(md) {
|
||||
font-size: calc(var(--text-xs)*1.05);
|
||||
margin-bottom: var(--space-xxxxs);
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__event [data-event="event-1"],
|
||||
.cd-schedule-modal[data-event="event-1"] .cd-schedule-modal__header-bg {
|
||||
// this is used to set a background color for the event and the modal window
|
||||
background: var(--cd-color-event-1);
|
||||
}
|
||||
|
||||
.cd-schedule__event [data-event="event-2"],
|
||||
.cd-schedule-modal[data-event="event-2"] .cd-schedule-modal__header-bg {
|
||||
background: var(--cd-color-event-2);
|
||||
}
|
||||
|
||||
.cd-schedule__event [data-event="event-3"],
|
||||
.cd-schedule-modal[data-event="event-3"] .cd-schedule-modal__header-bg {
|
||||
background: var(--cd-color-event-3);
|
||||
}
|
||||
|
||||
.cd-schedule__event [data-event="event-4"],
|
||||
.cd-schedule-modal[data-event="event-4"] .cd-schedule-modal__header-bg {
|
||||
background: var(--cd-color-event-4);
|
||||
}
|
||||
|
||||
.cd-schedule-modal {
|
||||
position: fixed;
|
||||
z-index: 3;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
visibility: hidden;
|
||||
transform: translateZ(0); // Force Hardware acceleration
|
||||
|
||||
transform: translateX(100%);
|
||||
transition: transform .4s, visibility .4s;
|
||||
transition-timing-function: cubic-bezier(.5,0,.1,1);
|
||||
|
||||
@include breakpoint(md) {
|
||||
// reset style
|
||||
right: auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
transform: translateX(0);
|
||||
will-change: transform, width, height;
|
||||
transition: height .4s, width .4s, transform .4s, visibility .4s;
|
||||
transition-timing-function: cubic-bezier(.5,0,.1,1);
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__header {
|
||||
position: relative;
|
||||
height: 70px;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
width: 100%;
|
||||
|
||||
@include breakpoint(md) {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__content {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--space-sm) var(--component-padding);
|
||||
|
||||
@include breakpoint(md) {
|
||||
// reset style
|
||||
display: block;
|
||||
padding: var(--space-sm);
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__body {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100% - 70px); // 70px is the .cd-schedule-modal__header height
|
||||
|
||||
@include breakpoint(md) {
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__event-info {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
line-height: var(--body-line-height);
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: calc(var(--text-sm) * 1.2);
|
||||
|
||||
> div {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
padding: var(--space-md) var(--component-padding);
|
||||
}
|
||||
|
||||
@include breakpoint(md) {
|
||||
opacity: 0;
|
||||
font-size: var(--text-sm);
|
||||
|
||||
> div {
|
||||
padding: calc(var(--space-md)*1.3) calc(var(--space-lg)*1.2) calc(var(--space-md)*1.3) calc(var(--space-md)*1.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__header-bg,
|
||||
.cd-schedule-modal__body-bg { // these are the morphing backgrounds - visible on desktop only
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@include breakpoint(md) {
|
||||
// Force Hardware acceleration
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__header-bg {
|
||||
z-index: 2;
|
||||
transform-origin: top center;
|
||||
|
||||
@include breakpoint(md) {
|
||||
transition: transform .4s;
|
||||
transition-timing-function: cubic-bezier(.5,0,.1,1);
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__body-bg {
|
||||
z-index: 1;
|
||||
background: var(--color-white);
|
||||
transform-origin: top left;
|
||||
|
||||
@include breakpoint(md) {
|
||||
opacity: 0;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal--no-transition {
|
||||
transition: none;
|
||||
|
||||
.cd-schedule-modal__header-bg,
|
||||
.cd-schedule-modal__body-bg {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__date {
|
||||
display: none;
|
||||
|
||||
@include breakpoint(md) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal__close { // close modal icon
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
background: alpha(var(--color-black), .1);
|
||||
|
||||
&::before, &::after { // these are the two lines of the 'X' icon
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 2px;
|
||||
height: 22px;
|
||||
background: var(--color-white);
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
&::before {
|
||||
transform: translateX(-50%) translateY(-50%) rotate(45deg);
|
||||
}
|
||||
|
||||
&::after {
|
||||
transform: translateX(-50%) translateY(-50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
@include breakpoint(md) {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: transparent;
|
||||
opacity: 0;
|
||||
|
||||
&::after, &::before {
|
||||
background: var(--cd-color-text);
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule-modal--open { // this class is added as soon as an event is selected
|
||||
transform: translateX(0);
|
||||
visibility: visible;
|
||||
|
||||
.cd-schedule-modal__event-info > div { // smooth scroll on iOS touch deviceS
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(md) {
|
||||
.cd-schedule-modal--animation-completed .cd-schedule-modal__close,
|
||||
.cd-schedule-modal--content-loaded.cd-schedule-modal--animation-completed .cd-schedule-modal__event-info {
|
||||
// the .cd-schedule-modal--animation-completed class is added when the modal animation is completed
|
||||
// the .cd-schedule-modal--content-loaded class is added when the modal content has been loaded (using ajax)
|
||||
opacity: 1;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
.cd-schedule-modal--open .cd-schedule-modal__body-bg {
|
||||
opacity: 1;
|
||||
transition: transform .4s;
|
||||
transition-timing-function: cubic-bezier(.5,0,.1,1);
|
||||
}
|
||||
}
|
||||
|
||||
.cd-schedule__cover-layer { // layer between the content and the modal window
|
||||
position: fixed;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: alpha(var(--color-black), 0.8);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity .4s, visibility .4s;
|
||||
}
|
||||
|
||||
.cd-schedule-modal--open + .cd-schedule__cover-layer {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
//demo style
|
||||
.cd-main-header h1 {
|
||||
color: var(--cd-color-text);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.cd-article-link {
|
||||
font-size: var(--text-sm);
|
||||
transition: opacity .2s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
376
assets/js/main.js
Normal file
376
assets/js/main.js
Normal file
@@ -0,0 +1,376 @@
|
||||
// Schedule Template - by CodyHouse.co
|
||||
function ScheduleTemplate( element ) {
|
||||
this.element = element;
|
||||
this.timelineItems = this.element.getElementsByClassName('cd-schedule__timeline')[0].getElementsByTagName('li');
|
||||
this.timelineStart = getScheduleTimestamp(this.timelineItems[0].textContent);
|
||||
this.timelineUnitDuration = getScheduleTimestamp(this.timelineItems[1].textContent) - getScheduleTimestamp(this.timelineItems[0].textContent);
|
||||
|
||||
this.topInfoElement = this.element.getElementsByClassName('cd-schedule__top-info')[0];
|
||||
this.singleEvents = this.element.getElementsByClassName('cd-schedule__event');
|
||||
|
||||
this.modal = this.element.getElementsByClassName('cd-schedule-modal')[0];
|
||||
this.modalHeader = this.element.getElementsByClassName('cd-schedule-modal__header')[0];
|
||||
this.modalHeaderBg = this.element.getElementsByClassName('cd-schedule-modal__header-bg')[0];
|
||||
this.modalBody = this.element.getElementsByClassName('cd-schedule-modal__body')[0];
|
||||
this.modalBodyBg = this.element.getElementsByClassName('cd-schedule-modal__body-bg')[0];
|
||||
this.modalClose = this.modal.getElementsByClassName('cd-schedule-modal__close')[0];
|
||||
this.modalDate = this.modal.getElementsByClassName('cd-schedule-modal__date')[0];
|
||||
this.modalEventName = this.modal.getElementsByClassName('cd-schedule-modal__name')[0];
|
||||
this.coverLayer = this.element.getElementsByClassName('cd-schedule__cover-layer')[0];
|
||||
|
||||
this.modalMaxWidth = 800;
|
||||
this.modalMaxHeight = 480;
|
||||
|
||||
this.animating = false;
|
||||
this.supportAnimation = Util.cssSupports('transition');
|
||||
|
||||
this.initSchedule();
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.initSchedule = function() {
|
||||
this.scheduleReset();
|
||||
this.initEvents();
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.scheduleReset = function() {
|
||||
// according to the mq value, init the style of the template
|
||||
var mq = this.mq(),
|
||||
loaded = Util.hasClass(this.element, 'js-schedule-loaded'),
|
||||
modalOpen = Util.hasClass(this.modal, 'cd-schedule-modal--open');
|
||||
if( mq == 'desktop' && !loaded ) {
|
||||
Util.addClass(this.element, 'js-schedule-loaded');
|
||||
this.placeEvents();
|
||||
modalOpen && this.checkEventModal(modalOpen);
|
||||
} else if( mq == 'mobile' && loaded) {
|
||||
//in this case you are on a mobile version (first load or resize from desktop)
|
||||
Util.removeClass(this.element, 'cd-schedule--loading js-schedule-loaded');
|
||||
this.resetEventsStyle();
|
||||
modalOpen && this.checkEventModal();
|
||||
} else if( mq == 'desktop' && modalOpen ) {
|
||||
//on a mobile version with modal open - need to resize/move modal window
|
||||
this.checkEventModal(modalOpen);
|
||||
Util.removeClass(this.element, 'cd-schedule--loading');
|
||||
} else {
|
||||
Util.removeClass(this.element, 'cd-schedule--loading');
|
||||
}
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.resetEventsStyle = function() {
|
||||
// remove js style applied to the single events
|
||||
for(var i = 0; i < this.singleEvents.length; i++) {
|
||||
this.singleEvents[i].removeAttribute('style');
|
||||
}
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.placeEvents = function() {
|
||||
// on big devices - place events in the template according to their time/day
|
||||
var self = this,
|
||||
slotHeight = this.topInfoElement.offsetHeight;
|
||||
for(var i = 0; i < this.singleEvents.length; i++) {
|
||||
var anchor = this.singleEvents[i].getElementsByTagName('a')[0];
|
||||
var start = getScheduleTimestamp(anchor.getAttribute('data-start')),
|
||||
duration = getScheduleTimestamp(anchor.getAttribute('data-end')) - start;
|
||||
|
||||
var eventTop = slotHeight*(start - self.timelineStart)/self.timelineUnitDuration,
|
||||
eventHeight = slotHeight*duration/self.timelineUnitDuration;
|
||||
|
||||
this.singleEvents[i].setAttribute('style', 'top: '+(eventTop-1)+'px; height: '+(eventHeight +1)+'px');
|
||||
}
|
||||
|
||||
Util.removeClass(this.element, 'cd-schedule--loading');
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.initEvents = function() {
|
||||
var self = this;
|
||||
for(var i = 0; i < this.singleEvents.length; i++) {
|
||||
// open modal when user selects an event
|
||||
this.singleEvents[i].addEventListener('click', function(event){
|
||||
event.preventDefault();
|
||||
//if(!self.animating) self.openModal(this.getElementsByTagName('a')[0]);
|
||||
});
|
||||
}
|
||||
//close modal window
|
||||
this.modalClose.addEventListener('click', function(event){
|
||||
event.preventDefault();
|
||||
if( !self.animating ) self.closeModal();
|
||||
});
|
||||
this.coverLayer.addEventListener('click', function(event){
|
||||
event.preventDefault();
|
||||
if( !self.animating ) self.closeModal();
|
||||
});
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.openModal = function(target) {
|
||||
var self = this;
|
||||
var mq = self.mq();
|
||||
this.animating = true;
|
||||
|
||||
//update event name and time
|
||||
this.modalEventName.textContent = target.getElementsByTagName('em')[0].textContent;
|
||||
this.modalDate.textContent = target.getAttribute('data-start')+' - '+target.getAttribute('data-end');
|
||||
this.modal.setAttribute('data-event', target.getAttribute('data-event'));
|
||||
|
||||
//update event content
|
||||
this.loadEventContent(target.getAttribute('data-content'));
|
||||
|
||||
Util.addClass(this.modal, 'cd-schedule-modal--open');
|
||||
|
||||
setTimeout(function(){
|
||||
//fixes a flash when an event is selected - desktop version only
|
||||
Util.addClass(target.closest('li'), 'cd-schedule__event--selected');
|
||||
}, 10);
|
||||
|
||||
if( mq == 'mobile' ) {
|
||||
self.modal.addEventListener('transitionend', function cb(){
|
||||
self.animating = false;
|
||||
self.modal.removeEventListener('transitionend', cb);
|
||||
});
|
||||
} else {
|
||||
var eventPosition = target.getBoundingClientRect(),
|
||||
eventTop = eventPosition.top,
|
||||
eventLeft = eventPosition.left,
|
||||
eventHeight = target.offsetHeight,
|
||||
eventWidth = target.offsetWidth;
|
||||
|
||||
var windowWidth = window.innerWidth,
|
||||
windowHeight = window.innerHeight;
|
||||
|
||||
var modalWidth = ( windowWidth*.8 > self.modalMaxWidth ) ? self.modalMaxWidth : windowWidth*.8,
|
||||
modalHeight = ( windowHeight*.8 > self.modalMaxHeight ) ? self.modalMaxHeight : windowHeight*.8;
|
||||
|
||||
var modalTranslateX = parseInt((windowWidth - modalWidth)/2 - eventLeft),
|
||||
modalTranslateY = parseInt((windowHeight - modalHeight)/2 - eventTop);
|
||||
|
||||
var HeaderBgScaleY = modalHeight/eventHeight,
|
||||
BodyBgScaleX = (modalWidth - eventWidth);
|
||||
|
||||
//change modal height/width and translate it
|
||||
self.modal.setAttribute('style', 'top:'+eventTop+'px;left:'+eventLeft+'px;height:'+modalHeight+'px;width:'+modalWidth+'px;transform: translateY('+modalTranslateY+'px) translateX('+modalTranslateX+'px)');
|
||||
//set modalHeader width
|
||||
self.modalHeader.setAttribute('style', 'width:'+eventWidth+'px');
|
||||
//set modalBody left margin
|
||||
self.modalBody.setAttribute('style', 'margin-left:'+eventWidth+'px');
|
||||
//change modalBodyBg height/width ans scale it
|
||||
self.modalBodyBg.setAttribute('style', 'height:'+eventHeight+'px; width: 1px; transform: scaleY('+HeaderBgScaleY+') scaleX('+BodyBgScaleX+')');
|
||||
//change modal modalHeaderBg height/width and scale it
|
||||
self.modalHeaderBg.setAttribute('style', 'height: '+eventHeight+'px; width: '+eventWidth+'px; transform: scaleY('+HeaderBgScaleY+')');
|
||||
|
||||
self.modalHeaderBg.addEventListener('transitionend', function cb(){
|
||||
//wait for the end of the modalHeaderBg transformation and show the modal content
|
||||
self.animating = false;
|
||||
Util.addClass(self.modal, 'cd-schedule-modal--animation-completed');
|
||||
self.modalHeaderBg.removeEventListener('transitionend', cb);
|
||||
});
|
||||
}
|
||||
|
||||
//if browser do not support transitions -> no need to wait for the end of it
|
||||
this.animationFallback();
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.closeModal = function() {
|
||||
var self = this;
|
||||
var mq = self.mq();
|
||||
|
||||
var item = self.element.getElementsByClassName('cd-schedule__event--selected')[0],
|
||||
target = item.getElementsByTagName('a')[0];
|
||||
|
||||
this.animating = true;
|
||||
|
||||
if( mq == 'mobile' ) {
|
||||
Util.removeClass(this.modal, 'cd-schedule-modal--open');
|
||||
self.modal.addEventListener('transitionend', function cb(){
|
||||
Util.removeClass(self.modal, 'cd-schedule-modal--content-loaded');
|
||||
Util.removeClass(item, 'cd-schedule__event--selected');
|
||||
self.animating = false;
|
||||
self.modal.removeEventListener('transitionend', cb);
|
||||
});
|
||||
} else {
|
||||
var eventPosition = target.getBoundingClientRect(),
|
||||
eventTop = eventPosition.top,
|
||||
eventLeft = eventPosition.left,
|
||||
eventHeight = target.offsetHeight,
|
||||
eventWidth = target.offsetWidth;
|
||||
|
||||
var modalStyle = window.getComputedStyle(self.modal),
|
||||
modalTop = Number(modalStyle.getPropertyValue('top').replace('px', '')),
|
||||
modalLeft = Number(modalStyle.getPropertyValue('left').replace('px', ''));
|
||||
|
||||
var modalTranslateX = eventLeft - modalLeft,
|
||||
modalTranslateY = eventTop - modalTop;
|
||||
|
||||
Util.removeClass(this.modal, 'cd-schedule-modal--open cd-schedule-modal--animation-completed');
|
||||
|
||||
//change modal width/height and translate it
|
||||
self.modal.style.width = eventWidth+'px';self.modal.style.height = eventHeight+'px';self.modal.style.transform = 'translateX('+modalTranslateX+'px) translateY('+modalTranslateY+'px)';
|
||||
//scale down modalBodyBg element
|
||||
self.modalBodyBg.style.transform = 'scaleX(0) scaleY(1)';
|
||||
//scale down modalHeaderBg element
|
||||
// self.modalHeaderBg.setAttribute('style', 'transform: scaleY(1)');
|
||||
self.modalHeaderBg.style.transform = 'scaleY(1)';
|
||||
|
||||
self.modalHeaderBg.addEventListener('transitionend', function cb(){
|
||||
//wait for the end of the modalHeaderBg transformation and reset modal style
|
||||
Util.addClass(self.modal, 'cd-schedule-modal--no-transition');
|
||||
setTimeout(function(){
|
||||
self.modal.removeAttribute('style');
|
||||
self.modalBody.removeAttribute('style');
|
||||
self.modalHeader.removeAttribute('style');
|
||||
self.modalHeaderBg.removeAttribute('style');
|
||||
self.modalBodyBg.removeAttribute('style');
|
||||
}, 10);
|
||||
setTimeout(function(){
|
||||
Util.removeClass(self.modal, 'cd-schedule-modal--no-transition');
|
||||
}, 20);
|
||||
self.animating = false;
|
||||
Util.removeClass(self.modal, 'cd-schedule-modal--content-loaded');
|
||||
Util.removeClass(item, 'cd-schedule__event--selected');
|
||||
self.modalHeaderBg.removeEventListener('transitionend', cb);
|
||||
});
|
||||
}
|
||||
|
||||
//if browser do not support transitions -> no need to wait for the end of it
|
||||
this.animationFallback();
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.checkEventModal = function(modalOpen) {
|
||||
// this function is used on resize to reset events/modal style
|
||||
this.animating = true;
|
||||
var self = this;
|
||||
var mq = this.mq();
|
||||
if( mq == 'mobile' ) {
|
||||
//reset modal style on mobile
|
||||
self.modal.removeAttribute('style');
|
||||
self.modalBody.removeAttribute('style');
|
||||
self.modalHeader.removeAttribute('style');
|
||||
self.modalHeaderBg.removeAttribute('style');
|
||||
self.modalBodyBg.removeAttribute('style');
|
||||
Util.removeClass(self.modal, 'cd-schedule-modal--no-transition');
|
||||
self.animating = false;
|
||||
} else if( mq == 'desktop' && modalOpen) {
|
||||
Util.addClass(self.modal, 'cd-schedule-modal--no-transition cd-schedule-modal--animation-completed');
|
||||
var item = self.element.getElementsByClassName('cd-schedule__event--selected')[0],
|
||||
target = item.getElementsByTagName('a')[0];
|
||||
|
||||
var eventPosition = target.getBoundingClientRect(),
|
||||
eventTop = eventPosition.top,
|
||||
eventLeft = eventPosition.left,
|
||||
eventHeight = target.offsetHeight,
|
||||
eventWidth = target.offsetWidth;
|
||||
|
||||
var windowWidth = window.innerWidth,
|
||||
windowHeight = window.innerHeight;
|
||||
|
||||
var modalWidth = ( windowWidth*.8 > self.modalMaxWidth ) ? self.modalMaxWidth : windowWidth*.8,
|
||||
modalHeight = ( windowHeight*.8 > self.modalMaxHeight ) ? self.modalMaxHeight : windowHeight*.8;
|
||||
|
||||
var HeaderBgScaleY = modalHeight/eventHeight,
|
||||
BodyBgScaleX = (modalWidth - eventWidth);
|
||||
|
||||
|
||||
setTimeout(function(){
|
||||
self.modal.setAttribute('style', 'top:'+(windowHeight/2 - modalHeight/2)+'px;left:'+(windowWidth/2 - modalWidth/2)+'px;height:'+modalHeight+'px;width:'+modalWidth+'px;transform: translateY(0) translateX(0)');
|
||||
//change modal modalBodyBg height/width
|
||||
self.modalBodyBg.style.height = modalHeight+'px';self.modalBodyBg.style.transform = 'scaleY(1) scaleX('+BodyBgScaleX+')';self.modalBodyBg.style.width = '1px';
|
||||
//set modalHeader width
|
||||
self.modalHeader.setAttribute('style', 'width:'+eventWidth+'px');
|
||||
//set modalBody left margin
|
||||
self.modalBody.setAttribute('style', 'margin-left:'+eventWidth+'px');
|
||||
//change modal modalHeaderBg height/width and scale it
|
||||
self.modalHeaderBg.setAttribute('style', 'height: '+eventHeight+'px;width:'+eventWidth+'px; transform:scaleY('+HeaderBgScaleY+');');
|
||||
}, 10);
|
||||
|
||||
setTimeout(function(){
|
||||
Util.removeClass(self.modal, 'cd-schedule-modal--no-transition');
|
||||
self.animating = false;
|
||||
}, 20);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.loadEventContent = function(content) {
|
||||
// load the content of an event when user selects it
|
||||
var self = this;
|
||||
|
||||
httpRequest = new XMLHttpRequest();
|
||||
httpRequest.onreadystatechange = function() {
|
||||
if (httpRequest.readyState === XMLHttpRequest.DONE) {
|
||||
if (httpRequest.status === 200) {
|
||||
self.modal.getElementsByClassName('cd-schedule-modal__event-info')[0].innerHTML = self.getEventContent(httpRequest.responseText);
|
||||
Util.addClass(self.modal, 'cd-schedule-modal--content-loaded');
|
||||
}
|
||||
}
|
||||
};
|
||||
httpRequest.open('GET', content+'.html');
|
||||
httpRequest.send();
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.getEventContent = function(string) {
|
||||
// reset the loaded event content so that it can be inserted in the modal
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = string.trim();
|
||||
return div.getElementsByClassName('cd-schedule-modal__event-info')[0].innerHTML;
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.animationFallback = function() {
|
||||
if( !this.supportAnimation ) { // fallback for browsers not supporting transitions
|
||||
var event = new CustomEvent('transitionend');
|
||||
self.modal.dispatchEvent(event);
|
||||
self.modalHeaderBg.dispatchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
ScheduleTemplate.prototype.mq = function(){
|
||||
//get MQ value ('desktop' or 'mobile')
|
||||
var self = this;
|
||||
return window.getComputedStyle(this.element, '::before').getPropertyValue('content').replace(/'|"/g, "");
|
||||
};
|
||||
|
||||
function getScheduleTimestamp(time) {
|
||||
//accepts hh:mm format - convert hh:mm to timestamp
|
||||
time = time.replace(/ /g,'');
|
||||
var timeArray = time.split(':');
|
||||
var timeStamp = parseInt(timeArray[0])*60 + parseInt(timeArray[1]);
|
||||
return timeStamp;
|
||||
};
|
||||
|
||||
function init() {
|
||||
|
||||
var scheduleTemplate = document.getElementsByClassName('js-cd-schedule'),
|
||||
scheduleTemplateArray = [],
|
||||
resizing = false;
|
||||
if( scheduleTemplate.length > 0 ) { // init ScheduleTemplate objects
|
||||
for( var i = 0; i < scheduleTemplate.length; i++) {
|
||||
(function(i){
|
||||
scheduleTemplateArray.push(new ScheduleTemplate(scheduleTemplate[i]));
|
||||
})(i);
|
||||
}
|
||||
|
||||
window.addEventListener('resize', function(event) {
|
||||
// on resize - update events position and modal position (if open)
|
||||
if( !resizing ) {
|
||||
resizing = true;
|
||||
(!window.requestAnimationFrame) ? setTimeout(checkResize, 250) : window.requestAnimationFrame(checkResize);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('keyup', function(event){
|
||||
// close event modal when pressing escape key
|
||||
if( event.keyCode && event.keyCode == 27 || event.key && event.key.toLowerCase() == 'escape' ) {
|
||||
for(var i = 0; i < scheduleTemplateArray.length; i++) {
|
||||
scheduleTemplateArray[i].closeModal();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function checkResize(){
|
||||
for(var i = 0; i < scheduleTemplateArray.length; i++) {
|
||||
scheduleTemplateArray[i].scheduleReset();
|
||||
}
|
||||
resizing = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
// after changes call .scheduleReset();
|
||||
174
assets/js/util.js
Normal file
174
assets/js/util.js
Normal file
@@ -0,0 +1,174 @@
|
||||
// Utility function
|
||||
function Util () {};
|
||||
|
||||
/*
|
||||
class manipulation functions
|
||||
*/
|
||||
Util.hasClass = function(el, className) {
|
||||
if (el.classList) return el.classList.contains(className);
|
||||
else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
|
||||
};
|
||||
|
||||
Util.addClass = function(el, className) {
|
||||
var classList = className.split(' ');
|
||||
if (el.classList) el.classList.add(classList[0]);
|
||||
else if (!Util.hasClass(el, classList[0])) el.className += " " + classList[0];
|
||||
if (classList.length > 1) Util.addClass(el, classList.slice(1).join(' '));
|
||||
};
|
||||
|
||||
Util.removeClass = function(el, className) {
|
||||
var classList = className.split(' ');
|
||||
if (el.classList) el.classList.remove(classList[0]);
|
||||
else if(Util.hasClass(el, classList[0])) {
|
||||
var reg = new RegExp('(\\s|^)' + classList[0] + '(\\s|$)');
|
||||
el.className=el.className.replace(reg, ' ');
|
||||
}
|
||||
if (classList.length > 1) Util.removeClass(el, classList.slice(1).join(' '));
|
||||
};
|
||||
|
||||
Util.toggleClass = function(el, className, bool) {
|
||||
if(bool) Util.addClass(el, className);
|
||||
else Util.removeClass(el, className);
|
||||
};
|
||||
|
||||
Util.setAttributes = function(el, attrs) {
|
||||
for(var key in attrs) {
|
||||
el.setAttribute(key, attrs[key]);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
DOM manipulation
|
||||
*/
|
||||
Util.getChildrenByClassName = function(el, className) {
|
||||
var children = el.children,
|
||||
childrenByClass = [];
|
||||
for (var i = 0; i < el.children.length; i++) {
|
||||
if (Util.hasClass(el.children[i], className)) childrenByClass.push(el.children[i]);
|
||||
}
|
||||
return childrenByClass;
|
||||
};
|
||||
|
||||
/*
|
||||
Animate height of an element
|
||||
*/
|
||||
Util.setHeight = function(start, to, element, duration, cb) {
|
||||
var change = to - start,
|
||||
currentTime = null;
|
||||
|
||||
var animateHeight = function(timestamp){
|
||||
if (!currentTime) currentTime = timestamp;
|
||||
var progress = timestamp - currentTime;
|
||||
var val = parseInt((progress/duration)*change + start);
|
||||
element.setAttribute("style", "height:"+val+"px;");
|
||||
if(progress < duration) {
|
||||
window.requestAnimationFrame(animateHeight);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
//set the height of the element before starting animation -> fix bug on Safari
|
||||
element.setAttribute("style", "height:"+start+"px;");
|
||||
window.requestAnimationFrame(animateHeight);
|
||||
};
|
||||
|
||||
/*
|
||||
Smooth Scroll
|
||||
*/
|
||||
|
||||
Util.scrollTo = function(final, duration, cb) {
|
||||
var start = window.scrollY || document.documentElement.scrollTop,
|
||||
currentTime = null;
|
||||
|
||||
var animateScroll = function(timestamp){
|
||||
if (!currentTime) currentTime = timestamp;
|
||||
var progress = timestamp - currentTime;
|
||||
if(progress > duration) progress = duration;
|
||||
var val = Math.easeInOutQuad(progress, start, final-start, duration);
|
||||
window.scrollTo(0, val);
|
||||
if(progress < duration) {
|
||||
window.requestAnimationFrame(animateScroll);
|
||||
} else {
|
||||
cb && cb();
|
||||
}
|
||||
};
|
||||
|
||||
window.requestAnimationFrame(animateScroll);
|
||||
};
|
||||
|
||||
/*
|
||||
Focus utility classes
|
||||
*/
|
||||
|
||||
//Move focus to an element
|
||||
Util.moveFocus = function (element) {
|
||||
if( !element ) element = document.getElementsByTagName("body")[0];
|
||||
element.focus();
|
||||
if (document.activeElement !== element) {
|
||||
element.setAttribute('tabindex','-1');
|
||||
element.focus();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Misc
|
||||
*/
|
||||
|
||||
Util.getIndexInArray = function(array, el) {
|
||||
return Array.prototype.indexOf.call(array, el);
|
||||
};
|
||||
|
||||
Util.cssSupports = function(property, value) {
|
||||
if('CSS' in window) {
|
||||
return CSS.supports(property, value);
|
||||
} else {
|
||||
var jsProperty = property.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase();});
|
||||
return jsProperty in document.body.style;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Polyfills
|
||||
*/
|
||||
//Closest() method
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||||
}
|
||||
|
||||
if (!Element.prototype.closest) {
|
||||
Element.prototype.closest = function(s) {
|
||||
var el = this;
|
||||
if (!document.documentElement.contains(el)) return null;
|
||||
do {
|
||||
if (el.matches(s)) return el;
|
||||
el = el.parentElement || el.parentNode;
|
||||
} while (el !== null && el.nodeType === 1);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
//Custom Event() constructor
|
||||
if ( typeof window.CustomEvent !== "function" ) {
|
||||
|
||||
function CustomEvent ( event, params ) {
|
||||
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||
var evt = document.createEvent( 'CustomEvent' );
|
||||
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
|
||||
return evt;
|
||||
}
|
||||
|
||||
CustomEvent.prototype = window.Event.prototype;
|
||||
|
||||
window.CustomEvent = CustomEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
Animation curves
|
||||
*/
|
||||
Math.easeInOutQuad = function (t, b, c, d) {
|
||||
t /= d/2;
|
||||
if (t < 1) return c/2*t*t + b;
|
||||
t--;
|
||||
return -c/2 * (t*(t-2) - 1) + b;
|
||||
};
|
||||
3
event-abs-circuit.html
Executable file
3
event-abs-circuit.html
Executable file
@@ -0,0 +1,3 @@
|
||||
<div class="cd-schedule-modal__event-info">
|
||||
<div>Abs Circuit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, unde, nulla. Vel unde deleniti, distinctio inventore quis molestiae perferendis, eum quo harum dolorum reiciendis sunt dicta maiores similique! Officiis repellat iure odio debitis enim eius commodi quae deserunt quam assumenda, ab asperiores reiciendis minima maxime odit laborum, libero veniam non? </div>
|
||||
</div>
|
||||
3
event-restorative-yoga.html
Executable file
3
event-restorative-yoga.html
Executable file
@@ -0,0 +1,3 @@
|
||||
<div class="cd-schedule-modal__event-info">
|
||||
<div>Restorative Yoga. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, unde, nulla. Vel unde deleniti, distinctio inventore quis molestiae perferendis, eum quo harum dolorum reiciendis sunt dicta maiores similique! Officiis repellat iure odio debitis enim eius commodi quae deserunt quam assumenda, ab asperiores reiciendis minima maxime odit laborum, libero veniam non?</div>
|
||||
</div>
|
||||
3
event-rowing-workout.html
Executable file
3
event-rowing-workout.html
Executable file
@@ -0,0 +1,3 @@
|
||||
<div class="cd-schedule-modal__event-info">
|
||||
<div>Rowing Workout. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, unde, nulla. Vel unde deleniti, distinctio inventore quis molestiae perferendis, eum quo harum dolorum reiciendis sunt dicta maiores similique! Officiis repellat iure odio debitis enim eius commodi quae deserunt quam assumenda, ab asperiores reiciendis minima maxime odit laborum, libero veniam non?</div>
|
||||
</div>
|
||||
3
event-yoga-1.html
Executable file
3
event-yoga-1.html
Executable file
@@ -0,0 +1,3 @@
|
||||
<div class="cd-schedule-modal__event-info">
|
||||
<div>Yoga 1. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, unde, nulla. Vel unde deleniti, distinctio inventore quis molestiae perferendis, eum quo harum dolorum reiciendis sunt dicta maiores similique! Officiis repellat iure odio debitis enim eius commodi quae deserunt quam assumenda, ab asperiores reiciendis minima maxime odit laborum, libero veniam non?</div>
|
||||
</div>
|
||||
329
index.html
Normal file
329
index.html
Normal file
@@ -0,0 +1,329 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script>document.getElementsByTagName("html")[0].className += " js";</script>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<title>Schedule Template | CodyHouse</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Buttons to add to scheduled elements -->
|
||||
|
||||
<div class="cd-schedule cd-schedule--loading margin-top-lg margin-bottom-lg js-cd-schedule">
|
||||
<div class="cd-schedule__timeline">
|
||||
<ul>
|
||||
<li><span>09:00</span></li>
|
||||
<li><span>09:30</span></li>
|
||||
<li><span>10:00</span></li>
|
||||
<li><span>10:30</span></li>
|
||||
<li><span>11:00</span></li>
|
||||
<li><span>11:30</span></li>
|
||||
<li><span>12:00</span></li>
|
||||
<li><span>12:30</span></li>
|
||||
<li><span>13:00</span></li>
|
||||
<li><span>13:30</span></li>
|
||||
<li><span>14:00</span></li>
|
||||
<li><span>14:30</span></li>
|
||||
<li><span>15:00</span></li>
|
||||
<li><span>15:30</span></li>
|
||||
<li><span>16:00</span></li>
|
||||
<li><span>16:30</span></li>
|
||||
<li><span>17:00</span></li>
|
||||
<li><span>17:30</span></li>
|
||||
<li><span>18:00</span></li>
|
||||
</ul>
|
||||
</div> <!-- .cd-schedule__timeline -->
|
||||
|
||||
<!--<div class="cd-schedule__events">
|
||||
<ul>
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Monday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="09:30" data-end="10:30" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="11:00" data-end="12:30" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="14:00" data-end="15:15" data-content="event-yoga-1" data-event="event-3" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Tuesday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="10:00" data-end="11:00" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="11:30" data-end="13:00" data-content="event-restorative-yoga" data-event="event-4" href="#0">
|
||||
<em class="cd-schedule__name">Restorative Yoga</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="13:30" data-end="15:00" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="15:45" data-end="16:45" data-content="event-yoga-1" data-event="event-3" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Wednesday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="09:00" data-end="10:15" data-content="event-restorative-yoga" data-event="event-4" href="#0">
|
||||
<em class="cd-schedule__name">Restorative Yoga</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="10:45" data-end="11:45" data-content="event-yoga-1" data-event="event-3" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
<div style="white-space: nowrap;">
|
||||
<button onclick="this.parentElement.style.visibility = 'hidden'">Accept</button>
|
||||
<button onclick="this.parentElement.parentElement.style.visibility = 'hidden'">Remove</button>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="8:00" data-end="10:45" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="13:45" data-end="15:00" data-content="event-yoga-1" data-event="event-3" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Thursday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="09:30" data-end="10:30" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="12:00" data-end="13:45" data-content="event-restorative-yoga" data-event="event-4" href="#0">
|
||||
<em class="cd-schedule__name">Restorative Yoga</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="15:30" data-end="16:30" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="17:00" data-end="18:30" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Friday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="10:00" data-end="11:00" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="12:30" data-end="14:00" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="15:45" data-end="16:45" data-content="event-yoga-1" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Saturday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="09:30" data-end="10:30" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="11:00" data-end="12:30" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="14:00" data-end="15:15" data-content="event-yoga-1" data-event="event-3" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__group">
|
||||
<div class="cd-schedule__top-info"><span>Sunday</span></div>
|
||||
|
||||
<ul>
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="09:30" data-end="10:30" data-content="event-abs-circuit" data-event="event-1" href="#0">
|
||||
<em class="cd-schedule__name">Abs Circuit</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="11:00" data-end="12:30" data-content="event-rowing-workout" data-event="event-2" href="#0">
|
||||
<em class="cd-schedule__name">Rowing Workout</em>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="cd-schedule__event">
|
||||
<a data-start="14:00" data-end="15:15" data-content="event-yoga-1" data-event="event-3" href="#0">
|
||||
<em class="cd-schedule__name">Yoga Level 1</em>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
-->
|
||||
<div id="calendar_wrapper" class="cd-schedule__events">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="cd-schedule-modal">
|
||||
<header class="cd-schedule-modal__header">
|
||||
<div class="cd-schedule-modal__content">
|
||||
<span class="cd-schedule-modal__date"></span>
|
||||
<h3 class="cd-schedule-modal__name"></h3>
|
||||
</div>
|
||||
|
||||
<div class="cd-schedule-modal__header-bg"></div>
|
||||
</header>
|
||||
|
||||
<div class="cd-schedule-modal__body">
|
||||
<div class="cd-schedule-modal__event-info"></div>
|
||||
<div class="cd-schedule-modal__body-bg"></div>
|
||||
</div>
|
||||
|
||||
<a href="#0" class="cd-schedule-modal__close text-replace">Close</a>
|
||||
</div>
|
||||
|
||||
<div class="cd-schedule__cover-layer"></div>
|
||||
</div> <!-- .cd-schedule -->
|
||||
<script>
|
||||
class Appointment {
|
||||
constructor(name, start, end, type = 1) {
|
||||
this.name = name;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.type = type; //needs to be in [1, 4]
|
||||
}
|
||||
|
||||
as_html = function() {
|
||||
return `<li class="cd-schedule__event">
|
||||
<a data-start="${ this.start }" data-end="${ this.end }" data-content="event-yoga-1" data-event="event-${this.type}" href="#0">
|
||||
<em class="cd-schedule__name">${this.name}</em>
|
||||
</a>
|
||||
</li>`
|
||||
}
|
||||
}
|
||||
class Day {
|
||||
constructor(name, appointment_list) {
|
||||
this.name = name
|
||||
this.appointment_list = appointment_list;
|
||||
}
|
||||
as_html = function() {
|
||||
var result = `<li class="cd-schedule__group"><div class="cd-schedule__top-info"><span> ${ this.name }</span></div><ul>`;
|
||||
this.appointment_list.forEach(appoinment => {
|
||||
result += appoinment.as_html();
|
||||
});
|
||||
result += '</ul></li>';
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class Schedule {
|
||||
constructor(day_list){
|
||||
this.day_list = day_list
|
||||
}
|
||||
as_html = function() {
|
||||
var result = '<ul>';
|
||||
this.day_list.forEach(day => {
|
||||
result += day.as_html();
|
||||
});
|
||||
result += '</ul>';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
document.getElementById("calendar_wrapper").innerHTML += new Schedule([
|
||||
new Day("Monday", [
|
||||
new Appointment("Test", "9:00", "10:00", 1),
|
||||
new Appointment("Test", "17:00", "18:00", 1),
|
||||
]),
|
||||
new Day("Tuesday", [
|
||||
|
||||
]),
|
||||
new Day("Wednesday", [
|
||||
|
||||
]),
|
||||
new Day("Thursday", [
|
||||
|
||||
]),
|
||||
new Day("Friday", [
|
||||
|
||||
]),
|
||||
new Day("Saturday", [
|
||||
|
||||
]),
|
||||
new Day("Sunday", [
|
||||
|
||||
])
|
||||
]).as_html();
|
||||
</script>
|
||||
<script src="assets/js/util.js"></script> <!-- util functions included in the CodyHouse framework -->
|
||||
<script src="assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user