Skip to content

Instantly share code, notes, and snippets.

@leegee
Last active November 2, 2017 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leegee/df49d7ac9836c8926cb391c4ca7eef2e to your computer and use it in GitHub Desktop.
Save leegee/df49d7ac9836c8926cb391c4ca7eef2e to your computer and use it in GitHub Desktop.
var Wizard = function (state) {
this.state = {};
// pageName: null,
// lastPageName: null
// window.history.popstate();?
Object.keys(state).forEach((key) => {
this.state[key] = state[key];
});
this.pageEl = null;
this.el = {
main: document.getElementById('main'),
ctrlNext: document.getElementById('ctrl-next'),
ctrlBack: document.getElementById('ctrl-back'),
ctrlCancel: document.getElementById('ctrl-cancel'),
spinner: document.getElementById('spinner'),
};
this.hideSpinner();
this.el.main.setAttribute('style', 'display:block"');
window.popstate = (e) => {
console.log('POPSTATE ', e);
return false; //pushstate
};
}
Wizard.prototype.callMethod = function (method, ...args) {
console.log('callMethod ', method, args);
if (typeof method === 'string') {
method = window[method];
}
return method.apply(this, args);
}
/**
* Hides the current page, and processes and shows the template for the element
* for the page element whose * `id` attribute matches
* the prefix `page-` suffixed with the incremented page number. If a function
* exists matching the suffix `page` with the prefix of the page number, it
* will be called after the template has been processed and displayed.
*
* If the numbered page does not exist, the page with the next-highest number is shown.
*
* Also, if no arg supplied, tries to find data-next-page='name|number' from the current page.
*
* @param {number} [pageNumber] - Optional page number to which to jump.
* @return void
*/
Wizard.prototype.nextPage = async function (pageName, ...passOnArgs) {
console.log('Enter Wizard.nextPage with %s -----------------------------------------', pageName);
// If not told where to go, check the current template for instructions
if (! pageName && this.pageEl.nextPageName) {
pageName = this.pageEl.nextPageName;
console.log('Got next-page pageName from data-next-page: ', pageName);
}
this.pageEl = document.querySelector('script[type="text/handlebars"][data-page-name="' + pageName + '"]');
if (! this.pageEl) {
this.el.main.innerHTML = '<h2>Error</h2><p>Could not find the requested page, ' + pageName + '</p>';
return;
}
this.state.nextPageName = this.pageEl.dataset.nextPage || null;
this.state.pageName = pageName;
var fnNames = [
'page-' + this.state.pageName,
'page-' + this.state.pageName + '-before-render'
];
await this._execute(fnNames, passOnArgs);
this.render();
if (this.state.pageName) {
await this._execute('page-' + this.state.pageName + '-after-render', passOnArgs);
}
this.state.lastPageName = this.state.pageName;
window.location.hash = this.state.pageName;
window.history.pushState( this.state, 'Page '+this.state.pageName, window.location.toString() );
console.log('Leave nextPage with page = ', this.state.pageName);
}
Wizard.prototype._execute = async function (fns, passOnArgs) {
console.log('Wizard._execute', fns);
if (! fns) return;
var promises = [];
if (typeof fns === 'string') fns = [fns];
for (f of fns) {
var fn = this._antsToCamelCase(f);
console.log('Look for ', fn);
if (typeof window[fn] === 'function') {
console.log('Found %s, calling....', fn);
promises.push( window[fn].call(this, passOnArgs) );
console.log('...called %s', fn);
} else {
console.log('Did not find ', fn);
}
}
if (promises) {
console.log('Waiting on ', promises.length, promises);
await Promise.all(promises);
console.log('Done all promises');
}
else {
console.log('Leave now');
return Promise.resolve();
}
};
// {{#wizardIncludeTemplate "publish-tables-and-skus"}}{{/wizardIncludeTemplate}}
Handlebars.registerHelper('wizardIncludeTemplate', function(templateId) {
var html = Handlebars.compile(
document.getElementById(templateId).innerHTML.toString()
)(
{ wizard: this.wizard }
);
return new Handlebars.SafeString(html);
});
// Wizard.prototype.includeTemplate = function () {
// console.log('-------', this);
// }
Wizard.prototype.render = function () {
console.log('Enter render');
try {
// this.el.main.innerHTML = handlebars.render(
// this.pageEl.innerHTML.toString(),
// { wizard: this }
// );
// No caching:
this.el.main.innerHTML = Handlebars.compile(
this.pageEl.innerHTML.toString()
)(
{ wizard: this }
);
var links = document.querySelectorAll('[data-goto-page]');
for (var el of links) {
el.setAttribute('style',
el.getAttribute('style') + ';cursor:pointer;'
);
el.onclick = (e) => {
this.showSpinner();
this.nextPage(e.target.dataset.gotoPage, e);
this.hideSpinner();
};
};
} catch (e) {
console.error(e);
}
}
Wizard.prototype.showSpinner = function () {
this.el.spinner.style = 'display: block;';
};
Wizard.prototype.hideSpinner = function () {
this.el.spinner.style = 'display: none;';
};
Wizard.prototype._antsToCamelCase = function (str) {
return str.replace(/-(\w)/g, (_, initial) => {
return initial.toUpperCase();
});
}
/** Thanks https://projects.lukehaas.me/css-loaders/ **/
.loader {
display: 0;
color: #ffffff;
font-size: 90px;
text-indent: -9999em;
overflow: hidden;
width: 1em;
height: 1em;
border-radius: 50%;
margin: 72px auto;
position: relative;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation: load6 1.7s infinite ease, round 1.7s infinite ease;
animation: load6 1.7s infinite ease, round 1.7s infinite ease;
}
@-webkit-keyframes load6 {
0% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
5%,
95% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
10%,
59% {
box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em;
}
20% {
box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em;
}
38% {
box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em;
}
100% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
}
@keyframes load6 {
0% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
5%,
95% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
10%,
59% {
box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em;
}
20% {
box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em;
}
38% {
box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em;
}
100% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
}
@-webkit-keyframes round {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes round {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment