Skip to content

Instantly share code, notes, and snippets.

@darcher-
Last active February 13, 2018 14:16
Show Gist options
  • Save darcher-/1a6e9861913ff830449373dd2f5bb5d9 to your computer and use it in GitHub Desktop.
Save darcher-/1a6e9861913ff830449373dd2f5bb5d9 to your computer and use it in GitHub Desktop.
Panel and Landing page javascript includes
/* classList Polyfill: https://gist.github.com/k-gun/c2ea7c49edf7b757fe9561ba37cb19ca */ ;
(function() {
var trim = function(s) {
return s.replace(/^\s+|\s+$/g, '');
},
regExp = function(name) {
return new RegExp('(^|\\s+)' + name + '(\\s+|$)');
},
forEach = function(list, fn, scope) {
for (var i = 0; i < list.length; i++) {
fn.call(scope, list[i]);
}
};
function ClassList(element) {
this.element = element;
}
ClassList.prototype = {
add: function() {
forEach(arguments, function(name) {
if (!this.contains(name)) {
this.element.className = trim(this.element.className + ' ' + name);
}
}, this);
},
remove: function() {
forEach(arguments, function(name) {
this.element.className = trim(this.element.className.replace(regExp(name), ' '));
}, this);
},
toggle: function(name) {
return this.contains(name) ? (this.remove(name), false) : (this.add(name), true);
},
contains: function(name) {
return regExp(name).test(this.element.className);
},
item: function(i) {
return this.element.className.split(/\s+/)[i] || null;
},
replace: function(oldName, newName) {
this.remove(oldName), this.add(newName);
}
};
if (!('classList' in Element.prototype)) {
Object.defineProperty(Element.prototype, 'classList', {
get: function() {
return new ClassList(this);
}
});
}
if (window.DOMTokenList && !DOMTokenList.prototype.replace) {
DOMTokenList.prototype.replace = ClassList.prototype.replace;
}
})();
/* clear console errors */
console.clear();
/* Anonymous, self-executing Function */
/*
if you're using jQuery:
(function($, Z, undefined){
*/
(function(Z, undefined) {
/* global variables & private punctions */
var d = document,
/*! these are the 3 required elements to run these functions */
// update below to "z_wrapper" as needed.
wrapper = d.getElementById('zWrapper'),
// the following is a dynamically generated ID and should NOT change.
form = d.getElementById('zFormId'),
copyright = d.getElementById('zCopyrightYear'),
viewportMeta = d.querySelectorAll('meta[name=viewport]')[0],
required = d.querySelectorAll('[required="required"]'),
loopFn = function(collection, callback, scope) {
/* loop arrays/objects/collections/elements/etc. use like forEach() or $.each() */
if (Object.prototype.toString.call(collection) === '[object Object]') {
for (var property in collection) {
if (Object.prototype.hasOwnProperty.call(collection, property)) {
callback.call(scope, collection[property], property, collection);
}
}
} else {
for (var index = 0; index < collection.length; index++) {
callback.call(scope, collection[index], index, collection);
}
}
},
debounce = function(func, wait, immediate) {
/* wait for event to finish before execution---prevents event bubbling */
var timeout;
return function() {
var context = this,
args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
}, wait);
if (immediate && !timeout) {
func.apply(context, args);
}
};
},
resizeWaitFn = debounce(function() {
/* set in own variable to run on resize/load within Z.landingFn()*/
Z.wrapWidth(wrapper);
}, 66),
createMetaFn = function() {
/* create viewport meta tag to be used */
var meta = d.createElement('meta');
meta.name = "viewport";
meta.content = "width=device-width, initial-scale=1, shrink-to-fit=no";
d.head.appendChild(meta);
},
elNodeExistsFn = function(nodeList, Fn) {
/* ensure element node exists, use when using d.querySelectorAll() */
if (nodeList.length) {
return Fn;
}
},
elExistsFn = function(el, Fn) {
/* ensure element exists, use when using d.querySelector() */
if (el) {
return Fn;
}
},
elReplaceFn = function(el, Fn) {
/* ensure element exists */
if (el) {
el.parentNode.removeChild(el);
return Fn;
} else {
return Fn;
}
};
/*! Public Functions */
Z.wrapWidth = function(el) {
/* update class on wrapper based on wrapper element size, panels require this as they aren't dependend on window widths in most cases */
var elWidth = el.offsetWidth;
el.classList.toggle('zxl', elWidth > 1200);
el.classList.toggle('zlg', elWidth > 992);// && (elWidth < 1199));
el.classList.toggle('zmd', elWidth > 768);// && (elWidth < 991));
el.classList.toggle('zsm', elWidth > 544);// && (elWidth < 767));
el.classList.toggle('zxs', elWidth < 543);
/* this is more for debugging, but adds data attribute to show width */
el.setAttribute('data-px-width', elWidth);
};
Z.copyrightYearFn = function(c) {
// get and insert current year
var a = new Date(),
b = a.getFullYear();
c.innerHTML = b;
};
Z.metaViewportUpdate = function(el) {
/* override viewport meta if present, inject if not present */
elReplaceFn(el, createMetaFn());
};
Z.chromeFormReset = function(el) {
// check for Chrome Browser
if (/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)) {
// if Chrome clear form fields to avoid chrome bug
setTimeout(function() {
el.reset();
}, 250);
}
};
Z.fullfilledFormFn = function(el) {
/* form validation: allow html5 validation, prevent empty fields */
var button = form.querySelector('button'),
// store onclick value to add back after form validates
clickAction = button.getAttribute('onclick'),
cleanseBtnFn = function(btn) {
// remove onclick so html5 validation can trigger
btn.removeAttribute('onclick');
};
// prevent button cleansing if no required fields
if (required.length) {
// cleanse button if required found
cleanseBtnFn(button);
}
loopFn(required, function(index) {
/*!
this works on initial load only in chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=669724
- chromeFormReset() function is to circumvent this bug in chrome, it removes shadow values by form reset.
*/
if ((!index.value || !index.checkValidity()) || index.value === 'undefined') {
// set as invalid
index.setAttribute('aria-invalid', 'true');
// add parent class to toggle displayed validation (use CSS to add styling)
index.parentNode.classList.add('invalid');
} else {
// set as valid
index.setAttribute('aria-invalid', 'false');
// add parent class to toggle displayed validation (use CSS to add styling)
index.parentNode.classList.add('valid');
}
index.addEventListener('input', function() {
// replace aria-states on input
if ((!this.value || !this.checkValidity()) || this.value === 'undefined') {
// set as invalid
this.setAttribute('aria-invalid', 'true');
// replace parent class to toggle displayed validation (use CSS to add styling)
this.parentNode.classList.replace('valid', 'invalid');
} else {
// set as valid
this.setAttribute('aria-invalid', 'false');
// replace parent class to toggle displayed validation (use CSS to add styling)
this.parentNode.classList.replace('invalid', 'valid');
}
// find valid inputs via aria-state
var valid = d.querySelectorAll('[aria-invalid="false"]');
// if valid amount is same as required amount add submit function back.
if (valid.length === required.length) {
button.setAttribute('onclick', clickAction);
} else {
// if returns to invalid, remove onClick from button again
cleanseBtnFn(button);
}
});
});
};
Z.cleanFn = function(node) {
/* clean whitespace and empty elements in DOM */
for (var n = 0; n < node.childNodes.length; n++) {
var child = node.childNodes[n];
if (child.nodeType === 8 || (child.nodeType === 3 && !/\S/.test(child.nodeValue))) {
node.removeChild(child);
n--;
} else if (child.nodeType === 1) {
Z.cleanFn(child);
}
}
};
Z.includesFn = function() {
/*! houses all private/public functions into one call */
elExistsFn(form, this.chromeFormReset(form));
elExistsFn(form, this.fullfilledFormFn(form));
elExistsFn(copyright, this.copyrightYearFn(copyright));
// check onload and resize
elExistsFn(wrapper, resizeWaitFn());
window.addEventListener("resize", resizeWaitFn, false);
this.metaViewportUpdate(viewportMeta);
this.cleanFn(d);
};
/*
if you're using jQuery:
}(jQuery, window.Z = window.Z || {}));
*/
}(window.Z = window.Z || {}));
/* use below to init: Or only call functions that are needed, via Z.cleanFn(document) or any of the other public functions, etc.*/
//addZiftLoadEvent(function() { Z.includesFn(); });
@darcher-
Copy link
Author

Hosted at: //s3.amazonaws.com/static.ziftsolutions.com/codebase/js/zIncludes.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment