');
modal._increment++;
modal._count++;
this.$overlay[0].style.zindex = 1000 + modal._increment * 2;
this.$el[0].style.zindex = 1000 + modal._increment * 2 + 1;
this.setupeventhandlers();
}
_createclass(modal, [{
key: 'getinstance',
/**
* get instance
*/
value: function getinstance() {
return this;
}
/**
* teardown component
*/
}, {
key: 'destroy',
value: function destroy() {
this.removeeventhandlers();
this.$el[0].removeattribute('style');
if (!!this.$overlay[0].parentnode) {
this.$overlay[0].parentnode.removechild(this.$overlay[0]);
}
this.$el[0].m_modal = undefined;
modal._count--;
}
/**
* setup event handlers
*/
}, {
key: 'setupeventhandlers',
value: function setupeventhandlers() {
this.handleoverlayclickbound = this.handleoverlayclick.bind(this);
this.handlemodalcloseclickbound = this.handlemodalcloseclick.bind(this);
if (modal._count === 1) {
document.body.addeventlistener('click', this.handletriggerclick);
}
this.$overlay[0].addeventlistener('click', this.handleoverlayclickbound);
this.$el[0].addeventlistener('click', this.handlemodalcloseclickbound);
}
/**
* remove event handlers
*/
}, {
key: 'removeeventhandlers',
value: function removeeventhandlers() {
if (modal._count === 0) {
document.body.removeeventlistener('click', this.handletriggerclick);
}
this.$overlay[0].removeeventlistener('click', this.handleoverlayclickbound);
this.$el[0].removeeventlistener('click', this.handlemodalcloseclickbound);
}
/**
* handle trigger click
* @param {event} e
*/
}, {
key: 'handletriggerclick',
value: function handletriggerclick(e) {
var $trigger = $(e.target).closest('.modal-trigger');
if (e.target && $trigger.length) {
var modalid = $trigger[0].getattribute('href');
if (modalid) {
modalid = modalid.slice(1);
} else {
modalid = $trigger[0].getattribute('data-target');
}
var modalinstance = document.getelementbyid(modalid).m_modal;
if (modalinstance) {
modalinstance.open($trigger);
}
e.preventdefault();
}
}
/**
* handle overlay click
*/
}, {
key: 'handleoverlayclick',
value: function handleoverlayclick() {
if (this.options.dismissible) {
this.close();
}
}
/**
* handle modal close click
* @param {event} e
*/
}, {
key: 'handlemodalcloseclick',
value: function handlemodalcloseclick(e) {
var $closetrigger = $(e.target).closest('.modal-close');
if (e.target && $closetrigger.length) {
this.close();
}
}
/**
* handle keydown
* @param {event} e
*/
}, {
key: 'handlekeydown',
value: function handlekeydown(e) {
// esc key
if (e.keycode === 27 && this.options.dismissible) {
this.close();
}
}
/**
* animate in modal
*/
}, {
key: 'animatein',
value: function animatein() {
var _this = this;
// set initial styles
$.extend(this.$el[0].style, {
display: 'block',
opacity: 0
});
$.extend(this.$overlay[0].style, {
display: 'block',
opacity: 0
});
// animate overlay
vel(this.$overlay[0], { opacity: this.options.opacity }, { duration: this.options.induration, queue: false, ease: 'easeoutcubic' });
// define modal animation options
var entervelocityoptions = {
duration: this.options.induration,
queue: false,
ease: 'easeoutcubic',
// handle modal ready callback
complete: function () {
if (typeof _this.options.ready === 'function') {
_this.options.ready.call(_this, _this.$el, _this.openingtrigger);
}
}
};
// bottom sheet animation
if (this.$el[0].classlist.contains('bottom-sheet')) {
vel(this.$el[0], { bottom: 0, opacity: 1 }, entervelocityoptions);
// normal modal animation
} else {
vel.hook(this.$el[0], 'scalex', 0.7);
this.$el[0].style.top = this.options.startingtop;
vel(this.$el[0], { top: this.options.endingtop, opacity: 1, scalex: 1 }, entervelocityoptions);
}
}
/**
* animate out modal
*/
}, {
key: 'animateout',
value: function animateout() {
var _this2 = this;
// animate overlay
vel(this.$overlay[0], { opacity: 0 }, { duration: this.options.outduration, queue: false, ease: 'easeoutquart' });
// define modal animation options
var exitvelocityoptions = {
duration: this.options.outduration,
queue: false,
ease: 'easeoutcubic',
// handle modal ready callback
complete: function () {
_this2.$el[0].style.display = 'none';
// call complete callback
if (typeof _this2.options.complete === 'function') {
_this2.options.complete.call(_this2, _this2.$el);
}
_this2.$overlay[0].parentnode.removechild(_this2.$overlay[0]);
}
};
// bottom sheet animation
if (this.$el[0].classlist.contains('bottom-sheet')) {
vel(this.$el[0], { bottom: '-100%', opacity: 0 }, exitvelocityoptions);
// normal modal animation
} else {
vel(this.$el[0], { top: this.options.startingtop, opacity: 0, scalex: 0.7 }, exitvelocityoptions);
}
}
/**
* open modal
* @param {jquery} [$trigger]
*/
}, {
key: 'open',
value: function open($trigger) {
if (this.isopen) {
return;
}
this.isopen = true;
var body = document.body;
body.style.overflow = 'hidden';
this.$el[0].classlist.add('open');
body.appendchild(this.$overlay[0]);
// set opening trigger, undefined indicates modal was opened by javascript
this.openingtrigger = !!$trigger ? $trigger : undefined;
if (this.options.dismissible) {
this.handlekeydownbound = this.handlekeydown.bind(this);
document.addeventlistener('keydown', this.handlekeydownbound);
}
this.animatein();
return this;
}
/**
* close modal
*/
}, {
key: 'close',
value: function close() {
if (!this.isopen) {
return;
}
this.isopen = false;
this.$el[0].classlist.remove('open');
document.body.style.overflow = '';
if (this.options.dismissible) {
document.removeeventlistener('keydown', this.handlekeydownbound);
}
this.animateout();
return this;
}
}], [{
key: 'init',
value: function init($els, options) {
var arr = [];
$els.each(function () {
arr.push(new modal($(this), options));
});
return arr;
}
}, {
key: 'defaults',
get: function () {
return _defaults;
}
}]);
return modal;
}();
/**
* @static
* @memberof modal
*/
modal._increment = 0;
/**
* @static
* @memberof modal
*/
modal._count = 0;
materialize.modal = modal;
$.fn.modal = function (methodoroptions) {
// call plugin method if valid method name is passed in
if (modal.prototype[methodoroptions]) {
// getter methods
if (methodoroptions.slice(0, 3) === 'get') {
return this.first()[0].m_modal[methodoroptions]();
// void methods
} else {
return this.each(function () {
this.m_modal[methodoroptions]();
});
}
// initialize plugin if options or no argument is passed in
} else if (typeof methodoroptions === 'object' || !methodoroptions) {
modal.init(this, arguments[0]);
return this;
// return error if an unrecognized method name is passed in
} else {
$.error('method ' + methodoroptions + ' does not exist on jquery.modal');
}
};
})(jquery, materialize.vel);
;(function ($) {
$.fn.materialbox = function () {
return this.each(function () {
if ($(this).hasclass('initialized')) {
return;
}
$(this).addclass('initialized');
var overlayactive = false;
var doneanimating = true;
var induration = 275;
var outduration = 200;
var origin = $(this);
var placeholder = $('').addclass('material-placeholder');
var originalwidth = 0;
var originalheight = 0;
var ancestorschanged;
var ancestor;
var origininlinestyles = origin.attr('style');
origin.wrap(placeholder);
// start click handler
origin.on('click', function () {
var placeholder = origin.parent('.material-placeholder');
var windowwidth = window.innerwidth;
var windowheight = window.innerheight;
var originalwidth = origin.width();
var originalheight = origin.height();
// if already modal, return to original
if (doneanimating === false) {
returntooriginal();
return false;
} else if (overlayactive && doneanimating === true) {
returntooriginal();
return false;
}
// set states
doneanimating = false;
origin.addclass('active');
overlayactive = true;
// set positioning for placeholder
placeholder.css({
width: placeholder[0].getboundingclientrect().width,
height: placeholder[0].getboundingclientrect().height,
position: 'relative',
top: 0,
left: 0
});
// find ancestor with overflow: hidden; and remove it
ancestorschanged = undefined;
ancestor = placeholder[0].parentnode;
var count = 0;
while (ancestor !== null && !$(ancestor).is(document)) {
var curr = $(ancestor);
if (curr.css('overflow') !== 'visible') {
curr.css('overflow', 'visible');
if (ancestorschanged === undefined) {
ancestorschanged = curr;
} else {
ancestorschanged = ancestorschanged.add(curr);
}
}
ancestor = ancestor.parentnode;
}
// set css on origin
origin.css({
position: 'absolute',
'z-index': 1000,
'will-change': 'left, top, width, height'
}).data('width', originalwidth).data('height', originalheight);
// add overlay
var overlay = $('').css({
opacity: 0
}).click(function () {
if (doneanimating === true) returntooriginal();
});
// put before in origin image to preserve z-index layering.
origin.before(overlay);
// set dimensions if needed
var overlayoffset = overlay[0].getboundingclientrect();
overlay.css({
width: windowwidth,
height: windowheight,
left: -1 * overlayoffset.left,
top: -1 * overlayoffset.top
});
// animate overlay
overlay.velocity({ opacity: 1 }, { duration: induration, queue: false, easing: 'easeoutquad' });
// add and animate caption if it exists
if (origin.data('caption') !== "") {
var $photo_caption = $('');
$photo_caption.text(origin.data('caption'));
$('body').append($photo_caption);
$photo_caption.css({ "display": "inline" });
$photo_caption.velocity({ opacity: 1 }, { duration: induration, queue: false, easing: 'easeoutquad' });
}
// resize image
var ratio = 0;
var widthpercent = originalwidth / windowwidth;
var heightpercent = originalheight / windowheight;
var newwidth = 0;
var newheight = 0;
if (widthpercent > heightpercent) {
ratio = originalheight / originalwidth;
newwidth = windowwidth * 0.9;
newheight = windowwidth * 0.9 * ratio;
} else {
ratio = originalwidth / originalheight;
newwidth = windowheight * 0.9 * ratio;
newheight = windowheight * 0.9;
}
// animate image + set z-index
if (origin.hasclass('responsive-img')) {
origin.velocity({ 'max-width': newwidth, 'width': originalwidth }, { duration: 0, queue: false,
complete: function () {
origin.css({ left: 0, top: 0 }).velocity({
height: newheight,
width: newwidth,
left: $(document).scrollleft() + windowwidth / 2 - origin.parent('.material-placeholder').offset().left - newwidth / 2,
top: $(document).scrolltop() + windowheight / 2 - origin.parent('.material-placeholder').offset().top - newheight / 2
}, {
duration: induration,
queue: false,
easing: 'easeoutquad',
complete: function () {
doneanimating = true;
}
});
} // end complete
}); // end velocity
} else {
origin.css('left', 0).css('top', 0).velocity({
height: newheight,
width: newwidth,
left: $(document).scrollleft() + windowwidth / 2 - origin.parent('.material-placeholder').offset().left - newwidth / 2,
top: $(document).scrolltop() + windowheight / 2 - origin.parent('.material-placeholder').offset().top - newheight / 2
}, {
duration: induration,
queue: false,
easing: 'easeoutquad',
complete: function () {
doneanimating = true;
}
}); // end velocity
}
// handle exit triggers
$(window).on('scroll.materialbox', function () {
if (overlayactive) {
returntooriginal();
}
});
$(window).on('resize.materialbox', function () {
if (overlayactive) {
returntooriginal();
}
});
$(document).on('keyup.materialbox', function (e) {
// esc key
if (e.keycode === 27 && doneanimating === true && overlayactive) {
returntooriginal();
}
});
}); // end click handler
// this function returns the modaled image to the original spot
function returntooriginal() {
doneanimating = false;
var placeholder = origin.parent('.material-placeholder');
var windowwidth = window.innerwidth;
var windowheight = window.innerheight;
var originalwidth = origin.data('width');
var originalheight = origin.data('height');
origin.velocity("stop", true);
$('#materialbox-overlay').velocity("stop", true);
$('.materialbox-caption').velocity("stop", true);
// disable exit handlers
$(window).off('scroll.materialbox');
$(document).off('keyup.materialbox');
$(window).off('resize.materialbox');
$('#materialbox-overlay').velocity({ opacity: 0 }, {
duration: outduration, // delay prevents animation overlapping
queue: false, easing: 'easeoutquad',
complete: function () {
// remove overlay
overlayactive = false;
$(this).remove();
}
});
// resize image
origin.velocity({
width: originalwidth,
height: originalheight,
left: 0,
top: 0
}, {
duration: outduration,
queue: false, easing: 'easeoutquad',
complete: function () {
placeholder.css({
height: '',
width: '',
position: '',
top: '',
left: ''
});
origin.removeattr('style');
origin.attr('style', origininlinestyles);
// remove class
origin.removeclass('active');
doneanimating = true;
// remove overflow overrides on ancestors
if (ancestorschanged) {
ancestorschanged.css('overflow', '');
}
}
});
// remove caption + reset css settings on image
$('.materialbox-caption').velocity({ opacity: 0 }, {
duration: outduration, // delay prevents animation overlapping
queue: false, easing: 'easeoutquad',
complete: function () {
$(this).remove();
}
});
}
});
};
$(document).ready(function () {
$('.materialboxed').materialbox();
});
})(jquery);
;(function ($) {
$.fn.parallax = function () {
var window_width = $(window).width();
// parallax scripts
return this.each(function (i) {
var $this = $(this);
$this.addclass('parallax');
function updateparallax(initial) {
var container_height;
if (window_width < 601) {
container_height = $this.height() > 0 ? $this.height() : $this.children("img").height();
} else {
container_height = $this.height() > 0 ? $this.height() : 500;
}
var $img = $this.children("img").first();
var img_height = $img.height();
var parallax_dist = img_height - container_height;
var bottom = $this.offset().top + container_height;
var top = $this.offset().top;
var scrolltop = $(window).scrolltop();
var windowheight = window.innerheight;
var windowbottom = scrolltop + windowheight;
var percentscrolled = (windowbottom - top) / (container_height + windowheight);
var parallax = math.round(parallax_dist * percentscrolled);
if (initial) {
$img.css('display', 'block');
}
if (bottom > scrolltop && top < scrolltop + windowheight) {
$img.css('transform', "translate3d(-50%," + parallax + "px, 0)");
}
}
// wait for image load
$this.children("img").one("load", function () {
updateparallax(true);
}).each(function () {
if (this.complete) $(this).trigger("load");
});
$(window).scroll(function () {
window_width = $(window).width();
updateparallax(false);
});
$(window).resize(function () {
window_width = $(window).width();
updateparallax(false);
});
});
};
})(jquery);
;(function ($) {
var methods = {
init: function (options) {
var defaults = {
onshow: null,
swipeable: false,
responsivethreshold: infinity // breakpoint for swipeable
};
options = $.extend(defaults, options);
var namespace = materialize.objectselectorstring($(this));
return this.each(function (i) {
var uniquenamespace = namespace + i;
// for each set of tabs, we want to keep track of
// which tab is active and its associated content
var $this = $(this),
window_width = $(window).width();
var $active,
$content,
$links = $this.find('li.tab a'),
$tabs_width = $this.width(),
$tabs_content = $(),
$tabs_wrapper,
$tab_width = math.max($tabs_width, $this[0].scrollwidth) / $links.length,
$indicator,
index = 0,
prev_index = 0,
clicked = false,
clickedtimeout,
transition = 300;
// finds right attribute for indicator based on active tab.
// el: jquery object
var calcrightpos = function (el) {
return math.ceil($tabs_width - el.position().left - el[0].getboundingclientrect().width - $this.scrollleft());
};
// finds left attribute for indicator based on active tab.
// el: jquery object
var calcleftpos = function (el) {
return math.floor(el.position().left + $this.scrollleft());
};
// animates indicator to active tab.
// prev_index: number
var animateindicator = function (prev_index) {
if (index - prev_index >= 0) {
$indicator.velocity({ "right": calcrightpos($active) }, { duration: transition, queue: false, easing: 'easeoutquad' });
$indicator.velocity({ "left": calcleftpos($active) }, { duration: transition, queue: false, easing: 'easeoutquad', delay: 90 });
} else {
$indicator.velocity({ "left": calcleftpos($active) }, { duration: transition, queue: false, easing: 'easeoutquad' });
$indicator.velocity({ "right": calcrightpos($active) }, { duration: transition, queue: false, easing: 'easeoutquad', delay: 90 });
}
};
// change swipeable according to responsive threshold
if (options.swipeable) {
if (window_width > options.responsivethreshold) {
options.swipeable = false;
}
}
// if the location.hash matches one of the links, use that as the active tab.
$active = $($links.filter('[href="' + location.hash + '"]'));
// if no match is found, use the first link or any with class 'active' as the initial active tab.
if ($active.length === 0) {
$active = $(this).find('li.tab a.active').first();
}
if ($active.length === 0) {
$active = $(this).find('li.tab a').first();
}
$active.addclass('active');
index = $links.index($active);
if (index < 0) {
index = 0;
}
if ($active[0] !== undefined) {
$content = $($active[0].hash);
$content.addclass('active');
}
// append indicator then set indicator width to tab width
if (!$this.find('.indicator').length) {
$this.append('');
}
$indicator = $this.find('.indicator');
// we make sure that the indicator is at the end of the tabs
$this.append($indicator);
if ($this.is(":visible")) {
// $indicator.css({"right": $tabs_width - ((index + 1) * $tab_width)});
// $indicator.css({"left": index * $tab_width});
settimeout(function () {
$indicator.css({ "right": calcrightpos($active) });
$indicator.css({ "left": calcleftpos($active) });
}, 0);
}
$(window).off('resize.tabs-' + uniquenamespace).on('resize.tabs-' + uniquenamespace, function () {
$tabs_width = $this.width();
$tab_width = math.max($tabs_width, $this[0].scrollwidth) / $links.length;
if (index < 0) {
index = 0;
}
if ($tab_width !== 0 && $tabs_width !== 0) {
$indicator.css({ "right": calcrightpos($active) });
$indicator.css({ "left": calcleftpos($active) });
}
});
// initialize tabs content.
if (options.swipeable) {
// todo: duplicate calls with swipeable? handle multiple div wrapping.
$links.each(function () {
var $curr_content = $(materialize.escapehash(this.hash));
$curr_content.addclass('carousel-item');
$tabs_content = $tabs_content.add($curr_content);
});
$tabs_wrapper = $tabs_content.wrapall('');
$tabs_content.css('display', '');
$('.tabs-content.carousel').carousel({
fullwidth: true,
nowrap: true,
oncycleto: function (item) {
if (!clicked) {
var prev_index = index;
index = $tabs_wrapper.index(item);
$active.removeclass('active');
$active = $links.eq(index);
$active.addclass('active');
animateindicator(prev_index);
if (typeof options.onshow === "function") {
options.onshow.call($this[0], $content);
}
}
}
});
} else {
// hide the remaining content
$links.not($active).each(function () {
$(materialize.escapehash(this.hash)).hide();
});
}
// bind the click event handler
$this.off('click.tabs').on('click.tabs', 'a', function (e) {
if ($(this).parent().hasclass('disabled')) {
e.preventdefault();
return;
}
// act as regular link if target attribute is specified.
if (!!$(this).attr("target")) {
return;
}
clicked = true;
$tabs_width = $this.width();
$tab_width = math.max($tabs_width, $this[0].scrollwidth) / $links.length;
// make the old tab inactive.
$active.removeclass('active');
var $oldcontent = $content;
// update the variables with the new link and content
$active = $(this);
$content = $(materialize.escapehash(this.hash));
$links = $this.find('li.tab a');
var activerect = $active.position();
// make the tab active.
$active.addclass('active');
prev_index = index;
index = $links.index($(this));
if (index < 0) {
index = 0;
}
// change url to current tab
// window.location.hash = $active.attr('href');
// swap content
if (options.swipeable) {
if ($tabs_content.length) {
$tabs_content.carousel('set', index, function () {
if (typeof options.onshow === "function") {
options.onshow.call($this[0], $content);
}
});
}
} else {
if ($content !== undefined) {
$content.show();
$content.addclass('active');
if (typeof options.onshow === "function") {
options.onshow.call(this, $content);
}
}
if ($oldcontent !== undefined && !$oldcontent.is($content)) {
$oldcontent.hide();
$oldcontent.removeclass('active');
}
}
// reset clicked state
clickedtimeout = settimeout(function () {
clicked = false;
}, transition);
// update indicator
animateindicator(prev_index);
// prevent the anchor's default click action
e.preventdefault();
});
});
},
select_tab: function (id) {
this.find('a[href="#' + id + '"]').trigger('click');
}
};
$.fn.tabs = function (methodoroptions) {
if (methods[methodoroptions]) {
return methods[methodoroptions].apply(this, array.prototype.slice.call(arguments, 1));
} else if (typeof methodoroptions === 'object' || !methodoroptions) {
// default to "init"
return methods.init.apply(this, arguments);
} else {
$.error('method ' + methodoroptions + ' does not exist on jquery.tabs');
}
};
$(document).ready(function () {
$('ul.tabs').tabs();
});
})(jquery);
;(function ($) {
$.fn.tooltip = function (options) {
var timeout = null,
margin = 5;
// defaults
var defaults = {
delay: 350,
tooltip: '',
position: 'bottom',
html: false
};
// remove tooltip from the activator
if (options === "remove") {
this.each(function () {
$('#' + $(this).attr('data-tooltip-id')).remove();
$(this).removeattr('data-tooltip-id');
$(this).off('mouseenter.tooltip mouseleave.tooltip');
});
return false;
}
options = $.extend(defaults, options);
return this.each(function () {
var tooltipid = materialize.guid();
var origin = $(this);
// destroy old tooltip
if (origin.attr('data-tooltip-id')) {
$('#' + origin.attr('data-tooltip-id')).remove();
}
origin.attr('data-tooltip-id', tooltipid);
// get attributes.
var allowhtml, tooltipdelay, tooltipposition, tooltiptext, tooltipel, backdrop;
var setattributes = function () {
allowhtml = origin.attr('data-html') ? origin.attr('data-html') === 'true' : options.html;
tooltipdelay = origin.attr('data-delay');
tooltipdelay = tooltipdelay === undefined || tooltipdelay === '' ? options.delay : tooltipdelay;
tooltipposition = origin.attr('data-position');
tooltipposition = tooltipposition === undefined || tooltipposition === '' ? options.position : tooltipposition;
tooltiptext = origin.attr('data-tooltip');
tooltiptext = tooltiptext === undefined || tooltiptext === '' ? options.tooltip : tooltiptext;
};
setattributes();
var rendertooltipel = function () {
var tooltip = $('');
// create text span
if (allowhtml) {
tooltiptext = $('').html(tooltiptext);
} else {
tooltiptext = $('').text(tooltiptext);
}
// create tooltip
tooltip.append(tooltiptext).appendto($('body')).attr('id', tooltipid);
// create backdrop
backdrop = $('');
backdrop.appendto(tooltip);
return tooltip;
};
tooltipel = rendertooltipel();
// destroy previously binded events
origin.off('mouseenter.tooltip mouseleave.tooltip');
// mouse in
var started = false,
timeoutref;
origin.on({ 'mouseenter.tooltip': function (e) {
var showtooltip = function () {
setattributes();
started = true;
tooltipel.velocity('stop');
backdrop.velocity('stop');
tooltipel.css({ visibility: 'visible', left: '0px', top: '0px' });
// tooltip positioning
var originwidth = origin.outerwidth();
var originheight = origin.outerheight();
var tooltipheight = tooltipel.outerheight();
var tooltipwidth = tooltipel.outerwidth();
var tooltipverticalmovement = '0px';
var tooltiphorizontalmovement = '0px';
var backdropoffsetwidth = backdrop[0].offsetwidth;
var backdropoffsetheight = backdrop[0].offsetheight;
var scalexfactor = 8;
var scaleyfactor = 8;
var scalefactor = 0;
var targettop, targetleft, newcoordinates;
if (tooltipposition === "top") {
// top position
targettop = origin.offset().top - tooltipheight - margin;
targetleft = origin.offset().left + originwidth / 2 - tooltipwidth / 2;
newcoordinates = repositionwithinscreen(targetleft, targettop, tooltipwidth, tooltipheight);
tooltipverticalmovement = '-10px';
backdrop.css({
bottom: 0,
left: 0,
borderradius: '14px 14px 0 0',
transformorigin: '50% 100%',
margintop: tooltipheight,
marginleft: tooltipwidth / 2 - backdropoffsetwidth / 2
});
}
// left position
else if (tooltipposition === "left") {
targettop = origin.offset().top + originheight / 2 - tooltipheight / 2;
targetleft = origin.offset().left - tooltipwidth - margin;
newcoordinates = repositionwithinscreen(targetleft, targettop, tooltipwidth, tooltipheight);
tooltiphorizontalmovement = '-10px';
backdrop.css({
top: '-7px',
right: 0,
width: '14px',
height: '14px',
borderradius: '14px 0 0 14px',
transformorigin: '95% 50%',
margintop: tooltipheight / 2,
marginleft: tooltipwidth
});
}
// right position
else if (tooltipposition === "right") {
targettop = origin.offset().top + originheight / 2 - tooltipheight / 2;
targetleft = origin.offset().left + originwidth + margin;
newcoordinates = repositionwithinscreen(targetleft, targettop, tooltipwidth, tooltipheight);
tooltiphorizontalmovement = '+10px';
backdrop.css({
top: '-7px',
left: 0,
width: '14px',
height: '14px',
borderradius: '0 14px 14px 0',
transformorigin: '5% 50%',
margintop: tooltipheight / 2,
marginleft: '0px'
});
} else {
// bottom position
targettop = origin.offset().top + origin.outerheight() + margin;
targetleft = origin.offset().left + originwidth / 2 - tooltipwidth / 2;
newcoordinates = repositionwithinscreen(targetleft, targettop, tooltipwidth, tooltipheight);
tooltipverticalmovement = '+10px';
backdrop.css({
top: 0,
left: 0,
marginleft: tooltipwidth / 2 - backdropoffsetwidth / 2
});
}
// set tooptip css placement
tooltipel.css({
top: newcoordinates.y,
left: newcoordinates.x
});
// calculate scale to fill
scalexfactor = math.sqrt2 * tooltipwidth / parseint(backdropoffsetwidth);
scaleyfactor = math.sqrt2 * tooltipheight / parseint(backdropoffsetheight);
scalefactor = math.max(scalexfactor, scaleyfactor);
tooltipel.velocity({ translatey: tooltipverticalmovement, translatex: tooltiphorizontalmovement }, { duration: 350, queue: false }).velocity({ opacity: 1 }, { duration: 300, delay: 50, queue: false });
backdrop.css({ visibility: 'visible' }).velocity({ opacity: 1 }, { duration: 55, delay: 0, queue: false }).velocity({ scalex: scalefactor, scaley: scalefactor }, { duration: 300, delay: 0, queue: false, easing: 'easeinoutquad' });
};
timeoutref = settimeout(showtooltip, tooltipdelay); // end interval
// mouse out
},
'mouseleave.tooltip': function () {
// reset state
started = false;
cleartimeout(timeoutref);
// animate back
settimeout(function () {
if (started !== true) {
tooltipel.velocity({
opacity: 0, translatey: 0, translatex: 0 }, { duration: 225, queue: false });
backdrop.velocity({ opacity: 0, scalex: 1, scaley: 1 }, {
duration: 225,
queue: false,
complete: function () {
backdrop.css({ visibility: 'hidden' });
tooltipel.css({ visibility: 'hidden' });
started = false;
}
});
}
}, 225);
}
});
});
};
var repositionwithinscreen = function (x, y, width, height) {
var newx = x;
var newy = y;
if (newx < 0) {
newx = 4;
} else if (newx + width > window.innerwidth) {
newx -= newx + width - window.innerwidth;
}
if (newy < 0) {
newy = 4;
} else if (newy + height > window.innerheight + $(window).scrolltop) {
newy -= newy + height - window.innerheight;
}
return { x: newx, y: newy };
};
$(document).ready(function () {
$('.tooltipped').tooltip();
});
})(jquery);
; /*!
* waves v0.6.4
* http://fian.my.id/waves
*
* copyright 2014 alfiana e. sibuea and other contributors
* released under the mit license
* https://github.com/fians/waves/blob/master/license
*/
;(function (window) {
'use strict';
var waves = waves || {};
var $$ = document.queryselectorall.bind(document);
// find exact position of element
function iswindow(obj) {
return obj !== null && obj === obj.window;
}
function getwindow(elem) {
return iswindow(elem) ? elem : elem.nodetype === 9 && elem.defaultview;
}
function offset(elem) {
var docelem,
win,
box = { top: 0, left: 0 },
doc = elem && elem.ownerdocument;
docelem = doc.documentelement;
if (typeof elem.getboundingclientrect !== typeof undefined) {
box = elem.getboundingclientrect();
}
win = getwindow(doc);
return {
top: box.top + win.pageyoffset - docelem.clienttop,
left: box.left + win.pagexoffset - docelem.clientleft
};
}
function convertstyle(obj) {
var style = '';
for (var a in obj) {
if (obj.hasownproperty(a)) {
style += a + ':' + obj[a] + ';';
}
}
return style;
}
var effect = {
// effect delay
duration: 750,
show: function (e, element) {
// disable right click
if (e.button === 2) {
return false;
}
var el = element || this;
// create ripple
var ripple = document.createelement('div');
ripple.classname = 'waves-ripple';
el.appendchild(ripple);
// get click coordinate and element witdh
var pos = offset(el);
var relativey = e.pagey - pos.top;
var relativex = e.pagex - pos.left;
var scale = 'scale(' + el.clientwidth / 100 * 10 + ')';
// support for touch devices
if ('touches' in e) {
relativey = e.touches[0].pagey - pos.top;
relativex = e.touches[0].pagex - pos.left;
}
// attach data to element
ripple.setattribute('data-hold', date.now());
ripple.setattribute('data-scale', scale);
ripple.setattribute('data-x', relativex);
ripple.setattribute('data-y', relativey);
// set ripple position
var ripplestyle = {
'top': relativey + 'px',
'left': relativex + 'px'
};
ripple.classname = ripple.classname + ' waves-notransition';
ripple.setattribute('style', convertstyle(ripplestyle));
ripple.classname = ripple.classname.replace('waves-notransition', '');
// scale the ripple
ripplestyle['-webkit-transform'] = scale;
ripplestyle['-moz-transform'] = scale;
ripplestyle['-ms-transform'] = scale;
ripplestyle['-o-transform'] = scale;
ripplestyle.transform = scale;
ripplestyle.opacity = '1';
ripplestyle['-webkit-transition-duration'] = effect.duration + 'ms';
ripplestyle['-moz-transition-duration'] = effect.duration + 'ms';
ripplestyle['-o-transition-duration'] = effect.duration + 'ms';
ripplestyle['transition-duration'] = effect.duration + 'ms';
ripplestyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
ripplestyle['-moz-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
ripplestyle['-o-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
ripplestyle['transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
ripple.setattribute('style', convertstyle(ripplestyle));
},
hide: function (e) {
touchhandler.touchup(e);
var el = this;
var width = el.clientwidth * 1.4;
// get first ripple
var ripple = null;
var ripples = el.getelementsbyclassname('waves-ripple');
if (ripples.length > 0) {
ripple = ripples[ripples.length - 1];
} else {
return false;
}
var relativex = ripple.getattribute('data-x');
var relativey = ripple.getattribute('data-y');
var scale = ripple.getattribute('data-scale');
// get delay beetween mousedown and mouse leave
var diff = date.now() - number(ripple.getattribute('data-hold'));
var delay = 350 - diff;
if (delay < 0) {
delay = 0;
}
// fade out ripple after delay
settimeout(function () {
var style = {
'top': relativey + 'px',
'left': relativex + 'px',
'opacity': '0',
// duration
'-webkit-transition-duration': effect.duration + 'ms',
'-moz-transition-duration': effect.duration + 'ms',
'-o-transition-duration': effect.duration + 'ms',
'transition-duration': effect.duration + 'ms',
'-webkit-transform': scale,
'-moz-transform': scale,
'-ms-transform': scale,
'-o-transform': scale,
'transform': scale
};
ripple.setattribute('style', convertstyle(style));
settimeout(function () {
try {
el.removechild(ripple);
} catch (e) {
return false;
}
}, effect.duration);
}, delay);
},
// little hack to make can perform waves effect
wrapinput: function (elements) {
for (var a = 0; a < elements.length; a++) {
var el = elements[a];
if (el.tagname.tolowercase() === 'input') {
var parent = el.parentnode;
// if input already have parent just pass through
if (parent.tagname.tolowercase() === 'i' && parent.classname.indexof('waves-effect') !== -1) {
continue;
}
// put element class and style to the specified parent
var wrapper = document.createelement('i');
wrapper.classname = el.classname + ' waves-input-wrapper';
var elementstyle = el.getattribute('style');
if (!elementstyle) {
elementstyle = '';
}
wrapper.setattribute('style', elementstyle);
el.classname = 'waves-button-input';
el.removeattribute('style');
// put element as child
parent.replacechild(wrapper, el);
wrapper.appendchild(el);
}
}
}
};
/**
* disable mousedown event for 500ms during and after touch
*/
var touchhandler = {
/* uses an integer rather than bool so there's no issues with
* needing to clear timeouts if another touch event occurred
* within the 500ms. cannot mouseup between touchstart and
* touchend, nor in the 500ms after touchend. */
touches: 0,
allowevent: function (e) {
var allow = true;
if (e.type === 'touchstart') {
touchhandler.touches += 1; //push
} else if (e.type === 'touchend' || e.type === 'touchcancel') {
settimeout(function () {
if (touchhandler.touches > 0) {
touchhandler.touches -= 1; //pop after 500ms
}
}, 500);
} else if (e.type === 'mousedown' && touchhandler.touches > 0) {
allow = false;
}
return allow;
},
touchup: function (e) {
touchhandler.allowevent(e);
}
};
/**
* delegated click handler for .waves-effect element.
* returns null when .waves-effect element not in "click tree"
*/
function getwaveseffectelement(e) {
if (touchhandler.allowevent(e) === false) {
return null;
}
var element = null;
var target = e.target || e.srcelement;
while (target.parentnode !== null) {
if (!(target instanceof svgelement) && target.classname.indexof('waves-effect') !== -1) {
element = target;
break;
}
target = target.parentnode;
}
return element;
}
/**
* bubble the click and show effect if .waves-effect elem was found
*/
function showeffect(e) {
var element = getwaveseffectelement(e);
if (element !== null) {
effect.show(e, element);
if ('ontouchstart' in window) {
element.addeventlistener('touchend', effect.hide, false);
element.addeventlistener('touchcancel', effect.hide, false);
}
element.addeventlistener('mouseup', effect.hide, false);
element.addeventlistener('mouseleave', effect.hide, false);
element.addeventlistener('dragend', effect.hide, false);
}
}
waves.displayeffect = function (options) {
options = options || {};
if ('duration' in options) {
effect.duration = options.duration;
}
//wrap input inside tag
effect.wrapinput($$('.waves-effect'));
if ('ontouchstart' in window) {
document.body.addeventlistener('touchstart', showeffect, false);
}
document.body.addeventlistener('mousedown', showeffect, false);
};
/**
* attach waves to an input element (or any element which doesn't
* bubble mouseup/mousedown events).
* intended to be used with dynamically loaded forms/inputs, or
* where the user doesn't want a delegated click handler.
*/
waves.attach = function (element) {
//future: automatically add waves classes and allow users
// to specify them with an options param? eg. light/classic/button
if (element.tagname.tolowercase() === 'input') {
effect.wrapinput([element]);
element = element.parentnode;
}
if ('ontouchstart' in window) {
element.addeventlistener('touchstart', showeffect, false);
}
element.addeventlistener('mousedown', showeffect, false);
};
window.waves = waves;
document.addeventlistener('domcontentloaded', function () {
waves.displayeffect();
}, false);
})(window);
;(function ($, vel) {
'use strict';
var _defaults = {
displaylength: infinity,
induration: 300,
outduration: 375,
classname: undefined,
completecallback: undefined,
activationpercent: 0.8
};
var toast = function () {
function toast(message, displaylength, classname, completecallback) {
_classcallcheck(this, toast);
if (!message) {
return;
}
/**
* options for the toast
* @member toast#options
*/
this.options = {
displaylength: displaylength,
classname: classname,
completecallback: completecallback
};
this.options = $.extend({}, toast.defaults, this.options);
this.message = message;
/**
* describes current pan state toast
* @type {boolean}
*/
this.panning = false;
/**
* time remaining until toast is removed
*/
this.timeremaining = this.options.displaylength;
if (toast._toasts.length === 0) {
toast._createcontainer();
}
// create new toast
toast._toasts.push(this);
var toastelement = this.createtoast();
toastelement.m_toast = this;
this.el = toastelement;
this._animatein();
this.settimer();
}
_createclass(toast, [{
key: 'createtoast',
/**
* create toast and append it to toast container
*/
value: function createtoast() {
var toast = document.createelement('div');
toast.classlist.add('toast');
// add custom classes onto toast
if (this.options.classname) {
var classes = this.options.classname.split(' ');
var i = void 0,
count = void 0;
for (i = 0, count = classes.length; i < count; i++) {
toast.classlist.add(classes[i]);
}
}
// set content
if (typeof htmlelement === 'object' ? this.message instanceof htmlelement : this.message && typeof this.message === 'object' && this.message !== null && this.message.nodetype === 1 && typeof this.message.nodename === 'string') {
toast.appendchild(this.message);
// check if it is jquery object
} else if (this.message instanceof jquery) {
$(toast).append(this.message);
// insert as text;
} else {
toast.innerhtml = this.message;
}
// append toasft
toast._container.appendchild(toast);
return toast;
}
/**
* animate in toast
*/
}, {
key: '_animatein',
value: function _animatein() {
// animate toast in
vel(this.el, { top: 0, opacity: 1 }, {
duration: 300,
easing: 'easeoutcubic',
queue: false
});
}
/**
* create setinterval which automatically removes toast when timeremaining >= 0
* has been reached
*/
}, {
key: 'settimer',
value: function settimer() {
var _this3 = this;
if (this.timeremaining !== infinity) {
this.counterinterval = setinterval(function () {
// if toast is not being dragged, decrease its time remaining
if (!_this3.panning) {
_this3.timeremaining -= 20;
}
// animate toast out
if (_this3.timeremaining <= 0) {
_this3.remove();
}
}, 20);
}
}
/**
* dismiss toast with animation
*/
}, {
key: 'remove',
value: function remove() {
var _this4 = this;
window.clearinterval(this.counterinterval);
var activationdistance = this.el.offsetwidth * this.options.activationpercent;
if (this.wasswiped) {
this.el.style.transition = 'transform .05s, opacity .05s';
this.el.style.transform = 'translatex(' + activationdistance + 'px)';
this.el.style.opacity = 0;
}
vel(this.el, { opacity: 0, margintop: '-40px' }, {
duration: this.options.outduration,
easing: 'easeoutexpo',
queue: false,
complete: function () {
// call the optional callback
if (typeof _this4.options.completecallback === 'function') {
_this4.options.completecallback();
}
// remove toast from dom
_this4.el.parentnode.removechild(_this4.el);
toast._toasts.splice(toast._toasts.indexof(_this4), 1);
if (toast._toasts.length === 0) {
toast._removecontainer();
}
}
});
}
}], [{
key: '_createcontainer',
/**
* append toast container and add event handlers
*/
value: function _createcontainer() {
var container = document.createelement('div');
container.setattribute('id', 'toast-container');
// add event handler
container.addeventlistener('touchstart', toast._ondragstart);
container.addeventlistener('touchmove', toast._ondragmove);
container.addeventlistener('touchend', toast._ondragend);
container.addeventlistener('mousedown', toast._ondragstart);
document.addeventlistener('mousemove', toast._ondragmove);
document.addeventlistener('mouseup', toast._ondragend);
document.body.appendchild(container);
toast._container = container;
}
/**
* remove toast container and event handlers
*/
}, {
key: '_removecontainer',
value: function _removecontainer() {
// add event handler
document.removeeventlistener('mousemove', toast._ondragmove);
document.removeeventlistener('mouseup', toast._ondragend);
toast._container.parentnode.removechild(toast._container);
toast._container = null;
}
/**
* begin drag handler
* @param {event} e
*/
}, {
key: '_ondragstart',
value: function _ondragstart(e) {
if (e.target && $(e.target).closest('.toast').length) {
var $toast = $(e.target).closest('.toast');
var toast = $toast[0].m_toast;
toast.panning = true;
toast._draggedtoast = toast;
toast.el.classlist.add('panning');
toast.el.style.transition = '';
toast.startingxpos = toast._xpos(e);
toast.time = date.now();
toast.xpos = toast._xpos(e);
}
}
/**
* drag move handler
* @param {event} e
*/
}, {
key: '_ondragmove',
value: function _ondragmove(e) {
if (!!toast._draggedtoast) {
e.preventdefault();
var toast = toast._draggedtoast;
toast.deltax = math.abs(toast.xpos - toast._xpos(e));
toast.xpos = toast._xpos(e);
toast.velocityx = toast.deltax / (date.now() - toast.time);
toast.time = date.now();
var totaldeltax = toast.xpos - toast.startingxpos;
var activationdistance = toast.el.offsetwidth * toast.options.activationpercent;
toast.el.style.transform = 'translatex(' + totaldeltax + 'px)';
toast.el.style.opacity = 1 - math.abs(totaldeltax / activationdistance);
}
}
/**
* end drag handler
* @param {event} e
*/
}, {
key: '_ondragend',
value: function _ondragend(e) {
if (!!toast._draggedtoast) {
var toast = toast._draggedtoast;
toast.panning = false;
toast.el.classlist.remove('panning');
var totaldeltax = toast.xpos - toast.startingxpos;
var activationdistance = toast.el.offsetwidth * toast.options.activationpercent;
var shouldbedismissed = math.abs(totaldeltax) > activationdistance || toast.velocityx > 1;
// remove toast
if (shouldbedismissed) {
toast.wasswiped = true;
toast.remove();
// animate toast back to original position
} else {
toast.el.style.transition = 'transform .2s, opacity .2s';
toast.el.style.transform = '';
toast.el.style.opacity = '';
}
toast._draggedtoast = null;
}
}
/**
* get x position of mouse or touch event
* @param {event} e
*/
}, {
key: '_xpos',
value: function _xpos(e) {
if (e.targettouches && e.targettouches.length >= 1) {
return e.targettouches[0].clientx;
}
// mouse event
return e.clientx;
}
/**
* remove all toasts
*/
}, {
key: 'removeall',
value: function removeall() {
for (var toastindex in toast._toasts) {
toast._toasts[toastindex].remove();
}
}
}, {
key: 'defaults',
get: function () {
return _defaults;
}
}]);
return toast;
}();
/**
* @static
* @memberof toast
* @type {array.}
*/
toast._toasts = [];
/**
* @static
* @memberof toast
*/
toast._container = null;
/**
* @static
* @memberof toast
* @type {toast}
*/
toast._draggedtoast = null;
materialize.toast = toast;
materialize.toast = function (message, displaylength, classname, completecallback) {
return new toast(message, displaylength, classname, completecallback);
};
})(jquery, materialize.vel);
;(function ($) {
var methods = {
init: function (options) {
var defaults = {
menuwidth: 300,
edge: 'left',
closeonclick: false,
draggable: true,
onopen: null,
onclose: null
};
options = $.extend(defaults, options);
$(this).each(function () {
var $this = $(this);
var menuid = $this.attr('data-activates');
var menu = $("#" + menuid);
// set to width
if (options.menuwidth != 300) {
menu.css('width', options.menuwidth);
}
// add touch area
var $dragtarget = $('.drag-target[data-sidenav="' + menuid + '"]');
if (options.draggable) {
// regenerate dragtarget
if ($dragtarget.length) {
$dragtarget.remove();
}
$dragtarget = $('').attr('data-sidenav', menuid);
$('body').append($dragtarget);
} else {
$dragtarget = $();
}
if (options.edge == 'left') {
menu.css('transform', 'translatex(-100%)');
$dragtarget.css({ 'left': 0 }); // add touch area
} else {
menu.addclass('right-aligned') // change text-alignment to right
.css('transform', 'translatex(100%)');
$dragtarget.css({ 'right': 0 }); // add touch area
}
// if fixed sidenav, bring menu out
if (menu.hasclass('fixed')) {
if (window.innerwidth > 992) {
menu.css('transform', 'translatex(0)');
}
}
// window resize to reset on large screens fixed
if (menu.hasclass('fixed')) {
$(window).resize(function () {
if (window.innerwidth > 992) {
// close menu if window is resized bigger than 992 and user has fixed sidenav
if ($('#sidenav-overlay').length !== 0 && menuout) {
removemenu(true);
} else {
// menu.removeattr('style');
menu.css('transform', 'translatex(0%)');
// menu.css('width', options.menuwidth);
}
} else if (menuout === false) {
if (options.edge === 'left') {
menu.css('transform', 'translatex(-100%)');
} else {
menu.css('transform', 'translatex(100%)');
}
}
});
}
// if closeonclick, then add close event for all a tags in side sidenav
if (options.closeonclick === true) {
menu.on("click.itemclick", "a:not(.collapsible-header)", function () {
if (!(window.innerwidth > 992 && menu.hasclass('fixed'))) {
removemenu();
}
});
}
var removemenu = function (restorenav) {
panning = false;
menuout = false;
// reenable scrolling
$('body').css({
overflow: '',
width: ''
});
$('#sidenav-overlay').velocity({ opacity: 0 }, { duration: 200,
queue: false, easing: 'easeoutquad',
complete: function () {
$(this).remove();
} });
if (options.edge === 'left') {
// reset phantom div
$dragtarget.css({ width: '', right: '', left: '0' });
menu.velocity({ 'translatex': '-100%' }, { duration: 200,
queue: false,
easing: 'easeoutcubic',
complete: function () {
if (restorenav === true) {
// restore fixed sidenav
menu.removeattr('style');
menu.css('width', options.menuwidth);
}
}
});
} else {
// reset phantom div
$dragtarget.css({ width: '', right: '0', left: '' });
menu.velocity({ 'translatex': '100%' }, { duration: 200,
queue: false,
easing: 'easeoutcubic',
complete: function () {
if (restorenav === true) {
// restore fixed sidenav
menu.removeattr('style');
menu.css('width', options.menuwidth);
}
}
});
}
// callback
if (typeof options.onclose === 'function') {
options.onclose.call(this, menu);
}
};
// touch event
var panning = false;
var menuout = false;
if (options.draggable) {
$dragtarget.on('click', function () {
if (menuout) {
removemenu();
}
});
$dragtarget.hammer({
prevent_default: false
}).on('pan', function (e) {
if (e.gesture.pointertype == "touch") {
var direction = e.gesture.direction;
var x = e.gesture.center.x;
var y = e.gesture.center.y;
var velocityx = e.gesture.velocityx;
// vertical scroll bugfix
if (x === 0 && y === 0) {
return;
}
// disable scrolling
var $body = $('body');
var $overlay = $('#sidenav-overlay');
var oldwidth = $body.innerwidth();
$body.css('overflow', 'hidden');
$body.width(oldwidth);
// if overlay does not exist, create one and if it is clicked, close menu
if ($overlay.length === 0) {
$overlay = $('');
$overlay.css('opacity', 0).click(function () {
removemenu();
});
// run 'onopen' when sidenav is opened via touch/swipe if applicable
if (typeof options.onopen === 'function') {
options.onopen.call(this, menu);
}
$('body').append($overlay);
}
// keep within boundaries
if (options.edge === 'left') {
if (x > options.menuwidth) {
x = options.menuwidth;
} else if (x < 0) {
x = 0;
}
}
if (options.edge === 'left') {
// left direction
if (x < options.menuwidth / 2) {
menuout = false;
}
// right direction
else if (x >= options.menuwidth / 2) {
menuout = true;
}
menu.css('transform', 'translatex(' + (x - options.menuwidth) + 'px)');
} else {
// left direction
if (x < window.innerwidth - options.menuwidth / 2) {
menuout = true;
}
// right direction
else if (x >= window.innerwidth - options.menuwidth / 2) {
menuout = false;
}
var rightpos = x - options.menuwidth / 2;
if (rightpos < 0) {
rightpos = 0;
}
menu.css('transform', 'translatex(' + rightpos + 'px)');
}
// percentage overlay
var overlayperc;
if (options.edge === 'left') {
overlayperc = x / options.menuwidth;
$overlay.velocity({ opacity: overlayperc }, { duration: 10, queue: false, easing: 'easeoutquad' });
} else {
overlayperc = math.abs((x - window.innerwidth) / options.menuwidth);
$overlay.velocity({ opacity: overlayperc }, { duration: 10, queue: false, easing: 'easeoutquad' });
}
}
}).on('panend', function (e) {
if (e.gesture.pointertype == "touch") {
var $overlay = $('#sidenav-overlay');
var velocityx = e.gesture.velocityx;
var x = e.gesture.center.x;
var leftpos = x - options.menuwidth;
var rightpos = x - options.menuwidth / 2;
if (leftpos > 0) {
leftpos = 0;
}
if (rightpos < 0) {
rightpos = 0;
}
panning = false;
if (options.edge === 'left') {
// if velocityx <= 0.3 then the user is flinging the menu closed so ignore menuout
if (menuout && velocityx <= 0.3 || velocityx < -0.5) {
// return menu to open
if (leftpos !== 0) {
menu.velocity({ 'translatex': [0, leftpos] }, { duration: 300, queue: false, easing: 'easeoutquad' });
}
$overlay.velocity({ opacity: 1 }, { duration: 50, queue: false, easing: 'easeoutquad' });
$dragtarget.css({ width: '50%', right: 0, left: '' });
menuout = true;
} else if (!menuout || velocityx > 0.3) {
// enable scrolling
$('body').css({
overflow: '',
width: ''
});
// slide menu closed
menu.velocity({ 'translatex': [-1 * options.menuwidth - 10, leftpos] }, { duration: 200, queue: false, easing: 'easeoutquad' });
$overlay.velocity({ opacity: 0 }, { duration: 200, queue: false, easing: 'easeoutquad',
complete: function () {
// run 'onclose' when sidenav is closed via touch/swipe if applicable
if (typeof options.onclose === 'function') {
options.onclose.call(this, menu);
}
$(this).remove();
} });
$dragtarget.css({ width: '10px', right: '', left: 0 });
}
} else {
if (menuout && velocityx >= -0.3 || velocityx > 0.5) {
// return menu to open
if (rightpos !== 0) {
menu.velocity({ 'translatex': [0, rightpos] }, { duration: 300, queue: false, easing: 'easeoutquad' });
}
$overlay.velocity({ opacity: 1 }, { duration: 50, queue: false, easing: 'easeoutquad' });
$dragtarget.css({ width: '50%', right: '', left: 0 });
menuout = true;
} else if (!menuout || velocityx < -0.3) {
// enable scrolling
$('body').css({
overflow: '',
width: ''
});
// slide menu closed
menu.velocity({ 'translatex': [options.menuwidth + 10, rightpos] }, { duration: 200, queue: false, easing: 'easeoutquad' });
$overlay.velocity({ opacity: 0 }, { duration: 200, queue: false, easing: 'easeoutquad',
complete: function () {
// run 'onclose' when sidenav is closed via touch/swipe if applicable
if (typeof options.onclose === 'function') {
options.onclose.call(this, menu);
}
$(this).remove();
} });
$dragtarget.css({ width: '10px', right: 0, left: '' });
}
}
}
});
}
$this.off('click.sidenav').on('click.sidenav', function () {
if (menuout === true) {
menuout = false;
panning = false;
removemenu();
} else {
// disable scrolling
var $body = $('body');
var $overlay = $('');
var oldwidth = $body.innerwidth();
$body.css('overflow', 'hidden');
$body.width(oldwidth);
// push current drag target on top of dom tree
$('body').append($dragtarget);
if (options.edge === 'left') {
$dragtarget.css({ width: '50%', right: 0, left: '' });
menu.velocity({ 'translatex': [0, -1 * options.menuwidth] }, { duration: 300, queue: false, easing: 'easeoutquad' });
} else {
$dragtarget.css({ width: '50%', right: '', left: 0 });
menu.velocity({ 'translatex': [0, options.menuwidth] }, { duration: 300, queue: false, easing: 'easeoutquad' });
}
// overlay close on click
$overlay.css('opacity', 0).click(function () {
menuout = false;
panning = false;
removemenu();
$overlay.velocity({ opacity: 0 }, { duration: 300, queue: false, easing: 'easeoutquad',
complete: function () {
$(this).remove();
}
});
});
// append body
$('body').append($overlay);
$overlay.velocity({ opacity: 1 }, { duration: 300, queue: false, easing: 'easeoutquad',
complete: function () {
menuout = true;
panning = false;
}
});
// callback
if (typeof options.onopen === 'function') {
options.onopen.call(this, menu);
}
}
return false;
});
});
},
destroy: function () {
var $overlay = $('#sidenav-overlay');
var $dragtarget = $('.drag-target[data-sidenav="' + $(this).attr('data-activates') + '"]');
$overlay.trigger('click');
$dragtarget.remove();
$(this).off('click');
$overlay.remove();
},
show: function () {
this.trigger('click');
},
hide: function () {
$('#sidenav-overlay').trigger('click');
}
};
$.fn.sidenav = function (methodoroptions) {
if (methods[methodoroptions]) {
return methods[methodoroptions].apply(this, array.prototype.slice.call(arguments, 1));
} else if (typeof methodoroptions === 'object' || !methodoroptions) {
// default to "init"
return methods.init.apply(this, arguments);
} else {
$.error('method ' + methodoroptions + ' does not exist on jquery.sidenav');
}
}; // plugin end
})(jquery);
; /**
* extend jquery with a scrollspy plugin.
* this watches the window scroll and fires events when elements are scrolled into viewport.
*
* throttle() and gettime() taken from underscore.js
* https://github.com/jashkenas/underscore
*
* @author copyright 2013 john smart
* @license https://raw.github.com/thesmart/jquery-scrollspy/master/license
* @see https://github.com/thesmart
* @version 0.1.2
*/
(function ($) {
var jwindow = $(window);
var elements = [];
var elementsinview = [];
var isspying = false;
var ticks = 0;
var unique_id = 1;
var offset = {
top: 0,
right: 0,
bottom: 0,
left: 0
/**
* find elements that are within the boundary
* @param {number} top
* @param {number} right
* @param {number} bottom
* @param {number} left
* @return {jquery} a collection of elements
*/
};function findelements(top, right, bottom, left) {
var hits = $();
$.each(elements, function (i, element) {
if (element.height() > 0) {
var eltop = element.offset().top,
elleft = element.offset().left,
elright = elleft + element.width(),
elbottom = eltop + element.height();
var isintersect = !(elleft > right || elright < left || eltop > bottom || elbottom < top);
if (isintersect) {
hits.push(element);
}
}
});
return hits;
}
/**
* called when the user scrolls the window
*/
function onscroll(scrolloffset) {
// unique tick id
++ticks;
// viewport rectangle
var top = jwindow.scrolltop(),
left = jwindow.scrollleft(),
right = left + jwindow.width(),
bottom = top + jwindow.height();
// determine which elements are in view
var intersections = findelements(top + offset.top + scrolloffset || 200, right + offset.right, bottom + offset.bottom, left + offset.left);
$.each(intersections, function (i, element) {
var lasttick = element.data('scrollspy:ticks');
if (typeof lasttick != 'number') {
// entered into view
element.triggerhandler('scrollspy:enter');
}
// update tick id
element.data('scrollspy:ticks', ticks);
});
// determine which elements are no longer in view
$.each(elementsinview, function (i, element) {
var lasttick = element.data('scrollspy:ticks');
if (typeof lasttick == 'number' && lasttick !== ticks) {
// exited from view
element.triggerhandler('scrollspy:exit');
element.data('scrollspy:ticks', null);
}
});
// remember elements in view for next tick
elementsinview = intersections;
}
/**
* called when window is resized
*/
function onwinsize() {
jwindow.trigger('scrollspy:winsize');
}
/**
* enables scrollspy using a selector
* @param {jquery|string} selector the elements collection, or a selector
* @param {object=} options optional.
throttle : number -> scrollspy throttling. default: 100 ms
offsettop : number -> offset from top. default: 0
offsetright : number -> offset from right. default: 0
offsetbottom : number -> offset from bottom. default: 0
offsetleft : number -> offset from left. default: 0
activeclass : string -> class name to be added to the active link. default: active
* @returns {jquery}
*/
$.scrollspy = function (selector, options) {
var defaults = {
throttle: 100,
scrolloffset: 200, // offset - 200 allows elements near bottom of page to scroll
activeclass: 'active',
getactiveelement: function (id) {
return 'a[href="#' + id + '"]';
}
};
options = $.extend(defaults, options);
var visible = [];
selector = $(selector);
selector.each(function (i, element) {
elements.push($(element));
$(element).data("scrollspy:id", i);
// smooth scroll to section
$('a[href="#' + $(element).attr('id') + '"]').click(function (e) {
e.preventdefault();
var offset = $(materialize.escapehash(this.hash)).offset().top + 1;
$('html, body').animate({ scrolltop: offset - options.scrolloffset }, { duration: 400, queue: false, easing: 'easeoutcubic' });
});
});
offset.top = options.offsettop || 0;
offset.right = options.offsetright || 0;
offset.bottom = options.offsetbottom || 0;
offset.left = options.offsetleft || 0;
var throttledscroll = materialize.throttle(function () {
onscroll(options.scrolloffset);
}, options.throttle || 100);
var readyscroll = function () {
$(document).ready(throttledscroll);
};
if (!isspying) {
jwindow.on('scroll', readyscroll);
jwindow.on('resize', readyscroll);
isspying = true;
}
// perform a scan once, after current execution context, and after dom is ready
settimeout(readyscroll, 0);
selector.on('scrollspy:enter', function () {
visible = $.grep(visible, function (value) {
return value.height() != 0;
});
var $this = $(this);
if (visible[0]) {
$(options.getactiveelement(visible[0].attr('id'))).removeclass(options.activeclass);
if ($this.data('scrollspy:id') < visible[0].data('scrollspy:id')) {
visible.unshift($(this));
} else {
visible.push($(this));
}
} else {
visible.push($(this));
}
$(options.getactiveelement(visible[0].attr('id'))).addclass(options.activeclass);
});
selector.on('scrollspy:exit', function () {
visible = $.grep(visible, function (value) {
return value.height() != 0;
});
if (visible[0]) {
$(options.getactiveelement(visible[0].attr('id'))).removeclass(options.activeclass);
var $this = $(this);
visible = $.grep(visible, function (value) {
return value.attr('id') != $this.attr('id');
});
if (visible[0]) {
// check if empty
$(options.getactiveelement(visible[0].attr('id'))).addclass(options.activeclass);
}
}
});
return selector;
};
/**
* listen for window resize events
* @param {object=} options optional. set { throttle: number } to change throttling. default: 100 ms
* @returns {jquery} $(window)
*/
$.winsizespy = function (options) {
$.winsizespy = function () {
return jwindow;
}; // lock from multiple calls
options = options || {
throttle: 100
};
return jwindow.on('resize', materialize.throttle(onwinsize, options.throttle || 100));
};
/**
* enables scrollspy on a collection of elements
* e.g. $('.scrollspy').scrollspy()
* @param {object=} options optional.
throttle : number -> scrollspy throttling. default: 100 ms
offsettop : number -> offset from top. default: 0
offsetright : number -> offset from right. default: 0
offsetbottom : number -> offset from bottom. default: 0
offsetleft : number -> offset from left. default: 0
* @returns {jquery}
*/
$.fn.scrollspy = function (options) {
return $.scrollspy($(this), options);
};
})(jquery);
;(function ($) {
$(document).ready(function () {
// function to update labels of text fields
materialize.updatetextfields = function () {
var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
$(input_selector).each(function (index, element) {
var $this = $(this);
if ($(element).val().length > 0 || $(element).is(':focus') || element.autofocus || $this.attr('placeholder') !== undefined) {
$this.siblings('label').addclass('active');
} else if ($(element)[0].validity) {
$this.siblings('label').toggleclass('active', $(element)[0].validity.badinput === true);
} else {
$this.siblings('label').removeclass('active');
}
});
};
// text based inputs
var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
// add active if form auto complete
$(document).on('change', input_selector, function () {
if ($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
$(this).siblings('label').addclass('active');
}
validate_field($(this));
});
// add active if input element has been pre-populated on document ready
$(document).ready(function () {
materialize.updatetextfields();
});
// html dom form reset handling
$(document).on('reset', function (e) {
var formreset = $(e.target);
if (formreset.is('form')) {
formreset.find(input_selector).removeclass('valid').removeclass('invalid');
formreset.find(input_selector).each(function () {
if ($(this).attr('value') === '') {
$(this).siblings('label').removeclass('active');
}
});
// reset select
formreset.find('select.initialized').each(function () {
var reset_text = formreset.find('option[selected]').text();
formreset.siblings('input.select-dropdown').val(reset_text);
});
}
});
// add active when element has focus
$(document).on('focus', input_selector, function () {
$(this).siblings('label, .prefix').addclass('active');
});
$(document).on('blur', input_selector, function () {
var $inputelement = $(this);
var selector = ".prefix";
if ($inputelement.val().length === 0 && $inputelement[0].validity.badinput !== true && $inputelement.attr('placeholder') === undefined) {
selector += ", label";
}
$inputelement.siblings(selector).removeclass('active');
validate_field($inputelement);
});
window.validate_field = function (object) {
var haslength = object.attr('data-length') !== undefined;
var lenattr = parseint(object.attr('data-length'));
var len = object.val().length;
if (object.val().length === 0 && object[0].validity.badinput === false && !object.is(':required')) {
if (object.hasclass('validate')) {
object.removeclass('valid');
object.removeclass('invalid');
}
} else {
if (object.hasclass('validate')) {
// check for character counter attributes
if (object.is(':valid') && haslength && len <= lenattr || object.is(':valid') && !haslength) {
object.removeclass('invalid');
object.addclass('valid');
} else {
object.removeclass('valid');
object.addclass('invalid');
}
}
}
};
// radio and checkbox focus class
var radio_checkbox = 'input[type=radio], input[type=checkbox]';
$(document).on('keyup.radio', radio_checkbox, function (e) {
// tab, check if tabbing to radio or checkbox.
if (e.which === 9) {
$(this).addclass('tabbed');
var $this = $(this);
$this.one('blur', function (e) {
$(this).removeclass('tabbed');
});
return;
}
});
// textarea auto resize
var hiddendiv = $('.hiddendiv').first();
if (!hiddendiv.length) {
hiddendiv = $('');
$('body').append(hiddendiv);
}
var text_area_selector = '.materialize-textarea';
function textareaautoresize($textarea) {
// set font properties of hiddendiv
var fontfamily = $textarea.css('font-family');
var fontsize = $textarea.css('font-size');
var lineheight = $textarea.css('line-height');
var padding = $textarea.css('padding');
if (fontsize) {
hiddendiv.css('font-size', fontsize);
}
if (fontfamily) {
hiddendiv.css('font-family', fontfamily);
}
if (lineheight) {
hiddendiv.css('line-height', lineheight);
}
if (padding) {
hiddendiv.css('padding', padding);
}
// set original-height, if none
if (!$textarea.data('original-height')) {
$textarea.data('original-height', $textarea.height());
}
if ($textarea.attr('wrap') === 'off') {
hiddendiv.css('overflow-wrap', 'normal').css('white-space', 'pre');
}
hiddendiv.text($textarea.val() + '\n');
var content = hiddendiv.html().replace(/\n/g, ' ');
hiddendiv.html(content);
// when textarea is hidden, width goes crazy.
// approximate with half of window size
if ($textarea.is(':visible')) {
hiddendiv.css('width', $textarea.width());
} else {
hiddendiv.css('width', $(window).width() / 2);
}
/**
* resize if the new height is greater than the
* original height of the textarea
*/
if ($textarea.data('original-height') <= hiddendiv.height()) {
$textarea.css('height', hiddendiv.height());
} else if ($textarea.val().length < $textarea.data('previous-length')) {
/**
* in case the new height is less than original height, it
* means the textarea has less text than before
* so we set the height to the original one
*/
$textarea.css('height', $textarea.data('original-height'));
}
$textarea.data('previous-length', $textarea.val().length);
}
$(text_area_selector).each(function () {
var $textarea = $(this);
/**
* instead of resizing textarea on document load,
* store the original height and the original length
*/
$textarea.data('original-height', $textarea.height());
$textarea.data('previous-length', $textarea.val().length);
});
$('body').on('keyup keydown autoresize', text_area_selector, function () {
textareaautoresize($(this));
});
// file input path
$(document).on('change', '.file-field input[type="file"]', function () {
var file_field = $(this).closest('.file-field');
var path_input = file_field.find('input.file-path');
var files = $(this)[0].files;
var file_names = [];
for (var i = 0; i < files.length; i++) {
file_names.push(files[i].name);
}
path_input.val(file_names.join(", "));
path_input.trigger('change');
});
/****************
* range input *
****************/
var range_type = 'input[type=range]';
var range_mousedown = false;
var left;
$(range_type).each(function () {
var thumb = $('');
$(this).after(thumb);
});
var showrangebubble = function (thumb) {
var paddingleft = parseint(thumb.parent().css('padding-left'));
var marginleft = -7 + paddingleft + 'px';
thumb.velocity({ height: "30px", width: "30px", top: "-30px", marginleft: marginleft }, { duration: 300, easing: 'easeoutexpo' });
};
var calcrangeoffset = function (range) {
var width = range.width() - 15;
var max = parsefloat(range.attr('max'));
var min = parsefloat(range.attr('min'));
var percent = (parsefloat(range.val()) - min) / (max - min);
return percent * width;
};
var range_wrapper = '.range-field';
$(document).on('change', range_type, function (e) {
var thumb = $(this).siblings('.thumb');
thumb.find('.value').html($(this).val());
if (!thumb.hasclass('active')) {
showrangebubble(thumb);
}
var offsetleft = calcrangeoffset($(this));
thumb.addclass('active').css('left', offsetleft);
});
$(document).on('mousedown touchstart', range_type, function (e) {
var thumb = $(this).siblings('.thumb');
// if thumb indicator does not exist yet, create it
if (thumb.length <= 0) {
thumb = $('');
$(this).after(thumb);
}
// set indicator value
thumb.find('.value').html($(this).val());
range_mousedown = true;
$(this).addclass('active');
if (!thumb.hasclass('active')) {
showrangebubble(thumb);
}
if (e.type !== 'input') {
var offsetleft = calcrangeoffset($(this));
thumb.addclass('active').css('left', offsetleft);
}
});
$(document).on('mouseup touchend', range_wrapper, function () {
range_mousedown = false;
$(this).removeclass('active');
});
$(document).on('input mousemove touchmove', range_wrapper, function (e) {
var thumb = $(this).children('.thumb');
var left;
var input = $(this).find(range_type);
if (range_mousedown) {
if (!thumb.hasclass('active')) {
showrangebubble(thumb);
}
var offsetleft = calcrangeoffset(input);
thumb.addclass('active').css('left', offsetleft);
thumb.find('.value').html(thumb.siblings(range_type).val());
}
});
$(document).on('mouseout touchleave', range_wrapper, function () {
if (!range_mousedown) {
var thumb = $(this).children('.thumb');
var paddingleft = parseint($(this).css('padding-left'));
var marginleft = 7 + paddingleft + 'px';
if (thumb.hasclass('active')) {
thumb.velocity({ height: '0', width: '0', top: '10px', marginleft: marginleft }, { duration: 100 });
}
thumb.removeclass('active');
}
});
/**************************
* auto complete plugin *
*************************/
$.fn.autocomplete = function (options) {
// defaults
var defaults = {
data: {},
limit: infinity,
onautocomplete: null,
minlength: 1
};
options = $.extend(defaults, options);
return this.each(function () {
var $input = $(this);
var data = options.data,
count = 0,
activeindex = -1,
oldval,
$inputdiv = $input.closest('.input-field'); // div to append on
// check if data isn't empty
if (!$.isemptyobject(data)) {
var $autocomplete = $('
');
var $oldautocomplete;
// append autocomplete element.
// prevent double structure init.
if ($inputdiv.length) {
$oldautocomplete = $inputdiv.children('.autocomplete-content.dropdown-content').first();
if (!$oldautocomplete.length) {
$inputdiv.append($autocomplete); // set ul in body
}
} else {
$oldautocomplete = $input.next('.autocomplete-content.dropdown-content');
if (!$oldautocomplete.length) {
$input.after($autocomplete);
}
}
if ($oldautocomplete.length) {
$autocomplete = $oldautocomplete;
}
// highlight partial match.
var highlight = function (string, $el) {
var img = $el.find('img');
var matchstart = $el.text().tolowercase().indexof("" + string.tolowercase() + ""),
matchend = matchstart + string.length - 1,
beforematch = $el.text().slice(0, matchstart),
matchtext = $el.text().slice(matchstart, matchend + 1),
aftermatch = $el.text().slice(matchend + 1);
$el.html("" + beforematch + "" + matchtext + "" + aftermatch + "");
if (img.length) {
$el.prepend(img);
}
};
// reset current element position
var resetcurrentelement = function () {
activeindex = -1;
$autocomplete.find('.active').removeclass('active');
};
// remove autocomplete elements
var removeautocomplete = function () {
$autocomplete.empty();
resetcurrentelement();
oldval = undefined;
};
$input.off('blur.autocomplete').on('blur.autocomplete', function () {
removeautocomplete();
});
// perform search
$input.off('keyup.autocomplete focus.autocomplete').on('keyup.autocomplete focus.autocomplete', function (e) {
// reset count.
count = 0;
var val = $input.val().tolowercase();
// don't capture enter or arrow key usage.
if (e.which === 13 || e.which === 38 || e.which === 40) {
return;
}
// check if the input isn't empty
if (oldval !== val) {
removeautocomplete();
if (val.length >= options.minlength) {
for (var key in data) {
if (data.hasownproperty(key) && key.tolowercase().indexof(val) !== -1) {
// break if past limit
if (count >= options.limit) {
break;
}
var autocompleteoption = $('');
if (!!data[key]) {
autocompleteoption.append('' + key + '');
} else {
autocompleteoption.append('' + key + '');
}
$autocomplete.append(autocompleteoption);
highlight(val, autocompleteoption);
count++;
}
}
}
}
// update oldval
oldval = val;
});
$input.off('keydown.autocomplete').on('keydown.autocomplete', function (e) {
// arrow keys and enter key usage
var keycode = e.which,
lielement,
numitems = $autocomplete.children('li').length,
$active = $autocomplete.children('.active').first();
// select element on enter
if (keycode === 13 && activeindex >= 0) {
lielement = $autocomplete.children('li').eq(activeindex);
if (lielement.length) {
lielement.trigger('mousedown.autocomplete');
e.preventdefault();
}
return;
}
// capture up and down key
if (keycode === 38 || keycode === 40) {
e.preventdefault();
if (keycode === 38 && activeindex > 0) {
activeindex--;
}
if (keycode === 40 && activeindex < numitems - 1) {
activeindex++;
}
$active.removeclass('active');
if (activeindex >= 0) {
$autocomplete.children('li').eq(activeindex).addclass('active');
}
}
});
// set input value
$autocomplete.off('mousedown.autocomplete touchstart.autocomplete').on('mousedown.autocomplete touchstart.autocomplete', 'li', function () {
var text = $(this).text().trim();
$input.val(text);
$input.trigger('change');
removeautocomplete();
// handle onautocomplete callback.
if (typeof options.onautocomplete === "function") {
options.onautocomplete.call(this, text);
}
});
// empty data
} else {
$input.off('keyup.autocomplete focus.autocomplete');
}
});
};
}); // end of $(document).ready
/*******************
* select plugin *
******************/
$.fn.material_select = function (callback) {
$(this).each(function () {
var $select = $(this);
if ($select.hasclass('browser-default')) {
return; // continue to next (return false breaks out of entire loop)
}
var multiple = $select.attr('multiple') ? true : false,
lastid = $select.attr('data-select-id'); // tear down structure if select needs to be rebuilt
if (lastid) {
$select.parent().find('span.caret').remove();
$select.parent().find('input').remove();
$select.unwrap();
$('ul#select-options-' + lastid).remove();
}
// if destroying the select, remove the selelct-id and reset it to it's uninitialized state.
if (callback === 'destroy') {
$select.removeattr('data-select-id').removeclass('initialized');
$(window).off('click.select');
return;
}
var uniqueid = materialize.guid();
$select.attr('data-select-id', uniqueid);
var wrapper = $('');
wrapper.addclass($select.attr('class'));
if ($select.is(':disabled')) wrapper.addclass('disabled');
var options = $('
'),
selectchildren = $select.children('option, optgroup'),
valuesselected = [],
optionshover = false;
var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";
// function that renders and appends the option taking into
// account type and possible image icon.
var appendoptionwithicon = function (select, option, type) {
// add disabled attr if disabled
var disabledclass = option.is(':disabled') ? 'disabled ' : '';
var optgroupclass = type === 'optgroup-option' ? 'optgroup-option ' : '';
var multiplecheckbox = multiple ? '' : '';
// add icons
var icon_url = option.data('icon');
var classes = option.attr('class');
if (!!icon_url) {
var classstring = '';
if (!!classes) classstring = ' class="' + classes + '"';
// check for multiple type.
options.append($('
' + multiplecheckbox + option.html() + '
'));
return true;
}
// check for multiple type.
options.append($('
' + multiplecheckbox + option.html() + '
'));
};
/* create dropdown structure. */
if (selectchildren.length) {
selectchildren.each(function () {
if ($(this).is('option')) {
// direct descendant option.
if (multiple) {
appendoptionwithicon($select, $(this), 'multiple');
} else {
appendoptionwithicon($select, $(this));
}
} else if ($(this).is('optgroup')) {
// optgroup.
var selectoptions = $(this).children('option');
options.append($('
' + $(this).attr('label') + '
'));
selectoptions.each(function () {
appendoptionwithicon($select, $(this), 'optgroup-option');
});
}
});
}
options.find('li:not(.optgroup)').each(function (i) {
$(this).click(function (e) {
// check if option element is disabled
if (!$(this).hasclass('disabled') && !$(this).hasclass('optgroup')) {
var selected = true;
if (multiple) {
$('input[type="checkbox"]', this).prop('checked', function (i, v) {
return !v;
});
selected = toggleentryfromarray(valuesselected, i, $select);
$newselect.trigger('focus');
} else {
options.find('li').removeclass('active');
$(this).toggleclass('active');
$newselect.val($(this).text());
}
activateoption(options, $(this));
$select.find('option').eq(i).prop('selected', selected);
// trigger onchange() event
$select.trigger('change');
if (typeof callback !== 'undefined') callback();
}
e.stoppropagation();
});
});
// wrap elements
$select.wrap(wrapper);
// add select display element
var dropdownicon = $('▼');
// escape double quotes
var sanitizedlabelhtml = label.replace(/"/g, '"');
var $newselect = $('');
$select.before($newselect);
$newselect.before(dropdownicon);
$newselect.after(options);
// check if section element is disabled
if (!$select.is(':disabled')) {
$newselect.dropdown({ 'hover': false });
}
// copy tabindex
if ($select.attr('tabindex')) {
$($newselect[0]).attr('tabindex', $select.attr('tabindex'));
}
$select.addclass('initialized');
$newselect.on({
'focus': function () {
if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
$('input.select-dropdown').trigger('close');
$(window).off('click.select');
}
if (!options.is(':visible')) {
$(this).trigger('open', ['focus']);
var label = $(this).val();
if (multiple && label.indexof(',') >= 0) {
label = label.split(',')[0];
}
var selectedoption = options.find('li').filter(function () {
return $(this).text().tolowercase() === label.tolowercase();
})[0];
activateoption(options, selectedoption, true);
$(window).off('click.select').on('click.select', function () {
multiple && (optionshover || $newselect.trigger('close'));
$(window).off('click.select');
});
}
},
'click': function (e) {
e.stoppropagation();
}
});
$newselect.on('blur', function () {
if (!multiple) {
$(this).trigger('close');
$(window).off('click.select');
}
options.find('li.selected').removeclass('selected');
});
options.hover(function () {
optionshover = true;
}, function () {
optionshover = false;
});
// add initial multiple selections.
if (multiple) {
$select.find("option:selected:not(:disabled)").each(function () {
var index = this.index;
toggleentryfromarray(valuesselected, index, $select);
options.find("li:not(.optgroup)").eq(index).find(":checkbox").prop("checked", true);
});
}
/**
* make option as selected and scroll to selected position
* @param {jquery} collection select options jquery element
* @param {element} newoption element of the new option
* @param {boolean} firstactivation if on first activation of select
*/
var activateoption = function (collection, newoption, firstactivation) {
if (newoption) {
collection.find('li.selected').removeclass('selected');
var option = $(newoption);
option.addclass('selected');
if (!multiple || !!firstactivation) {
options.scrollto(option);
}
}
};
// allow user to search by typing
// this array is cleared after 1 second
var filterquery = [],
onkeydown = function (e) {
// tab - switch to another input
if (e.which == 9) {
$newselect.trigger('close');
return;
}
// arrow down when select is closed - open select options
if (e.which == 40 && !options.is(':visible')) {
$newselect.trigger('open');
return;
}
// enter when select is closed - submit form
if (e.which == 13 && !options.is(':visible')) {
return;
}
e.preventdefault();
// case when user type letters
var letter = string.fromcharcode(e.which).tolowercase(),
nonletters = [9, 13, 27, 38, 40];
if (letter && nonletters.indexof(e.which) === -1) {
filterquery.push(letter);
var string = filterquery.join(''),
newoption = options.find('li').filter(function () {
return $(this).text().tolowercase().indexof(string) === 0;
})[0];
if (newoption) {
activateoption(options, newoption);
}
}
// enter - select option and close when select options are opened
if (e.which == 13) {
var activeoption = options.find('li.selected:not(.disabled)')[0];
if (activeoption) {
$(activeoption).trigger('click');
if (!multiple) {
$newselect.trigger('close');
}
}
}
// arrow down - move to next not disabled option
if (e.which == 40) {
if (options.find('li.selected').length) {
newoption = options.find('li.selected').next('li:not(.disabled)')[0];
} else {
newoption = options.find('li:not(.disabled)')[0];
}
activateoption(options, newoption);
}
// esc - close options
if (e.which == 27) {
$newselect.trigger('close');
}
// arrow up - move to previous not disabled option
if (e.which == 38) {
newoption = options.find('li.selected').prev('li:not(.disabled)')[0];
if (newoption) activateoption(options, newoption);
}
// automaticaly clean filter query so user can search again by starting letters
settimeout(function () {
filterquery = [];
}, 1000);
};
$newselect.on('keydown', onkeydown);
});
function toggleentryfromarray(entriesarray, entryindex, select) {
var index = entriesarray.indexof(entryindex),
notadded = index === -1;
if (notadded) {
entriesarray.push(entryindex);
} else {
entriesarray.splice(index, 1);
}
select.siblings('ul.dropdown-content').find('li:not(.optgroup)').eq(entryindex).toggleclass('active');
// use notadded instead of true (to detect if the option is selected or not)
select.find('option').eq(entryindex).prop('selected', notadded);
setvaluetoinput(entriesarray, select);
return notadded;
}
function setvaluetoinput(entriesarray, select) {
var value = '';
for (var i = 0, count = entriesarray.length; i < count; i++) {
var text = select.find('option').eq(entriesarray[i]).text();
i === 0 ? value += text : value += ', ' + text;
}
if (value === '') {
value = select.find('option:disabled').eq(0).text();
}
select.siblings('input.select-dropdown').val(value);
}
};
})(jquery);
;(function ($) {
var methods = {
init: function (options) {
var defaults = {
indicators: true,
height: 400,
transition: 500,
interval: 6000
};
options = $.extend(defaults, options);
return this.each(function () {
// for each slider, we want to keep track of
// which slide is active and its associated content
var $this = $(this);
var $slider = $this.find('ul.slides').first();
var $slides = $slider.find('> li');
var $active_index = $slider.find('.active').index();
var $active, $indicators, $interval;
if ($active_index != -1) {
$active = $slides.eq($active_index);
}
// transitions the caption depending on alignment
function captiontransition(caption, duration) {
if (caption.hasclass("center-align")) {
caption.velocity({ opacity: 0, translatey: -100 }, { duration: duration, queue: false });
} else if (caption.hasclass("right-align")) {
caption.velocity({ opacity: 0, translatex: 100 }, { duration: duration, queue: false });
} else if (caption.hasclass("left-align")) {
caption.velocity({ opacity: 0, translatex: -100 }, { duration: duration, queue: false });
}
}
// this function will transition the slide to any index of the next slide
function movetoslide(index) {
// wrap around indices.
if (index >= $slides.length) index = 0;else if (index < 0) index = $slides.length - 1;
$active_index = $slider.find('.active').index();
// only do if index changes
if ($active_index != index) {
$active = $slides.eq($active_index);
$caption = $active.find('.caption');
$active.removeclass('active');
$active.velocity({ opacity: 0 }, { duration: options.transition, queue: false, easing: 'easeoutquad',
complete: function () {
$slides.not('.active').velocity({ opacity: 0, translatex: 0, translatey: 0 }, { duration: 0, queue: false });
} });
captiontransition($caption, options.transition);
// update indicators
if (options.indicators) {
$indicators.eq($active_index).removeclass('active');
}
$slides.eq(index).velocity({ opacity: 1 }, { duration: options.transition, queue: false, easing: 'easeoutquad' });
$slides.eq(index).find('.caption').velocity({ opacity: 1, translatex: 0, translatey: 0 }, { duration: options.transition, delay: options.transition, queue: false, easing: 'easeoutquad' });
$slides.eq(index).addclass('active');
// update indicators
if (options.indicators) {
$indicators.eq(index).addclass('active');
}
}
}
// set height of slider
// if fullscreen, do nothing
if (!$this.hasclass('fullscreen')) {
if (options.indicators) {
// add height if indicators are present
$this.height(options.height + 40);
} else {
$this.height(options.height);
}
$slider.height(options.height);
}
// set initial positions of captions
$slides.find('.caption').each(function () {
captiontransition($(this), 0);
});
// move img src into background-image
$slides.find('img').each(function () {
var placeholderbase64 = 'data:image/gif;base64,r0lgodlhaqabaiabap///waaach5baekaaealaaaaaabaaeaaaictaeaow==';
if ($(this).attr('src') !== placeholderbase64) {
$(this).css('background-image', 'url("' + $(this).attr('src') + '")');
$(this).attr('src', placeholderbase64);
}
});
// dynamically add indicators
if (options.indicators) {
$indicators = $('
');
$slides.each(function (index) {
var $indicator = $('');
// handle clicks on indicators
$indicator.click(function () {
var $parent = $slider.parent();
var curr_index = $parent.find($(this)).index();
movetoslide(curr_index);
// reset interval
clearinterval($interval);
$interval = setinterval(function () {
$active_index = $slider.find('.active').index();
if ($slides.length == $active_index + 1) $active_index = 0; // loop to start
else $active_index += 1;
movetoslide($active_index);
}, options.transition + options.interval);
});
$indicators.append($indicator);
});
$this.append($indicators);
$indicators = $this.find('ul.indicators').find('li.indicator-item');
}
if ($active) {
$active.show();
} else {
$slides.first().addclass('active').velocity({ opacity: 1 }, { duration: options.transition, queue: false, easing: 'easeoutquad' });
$active_index = 0;
$active = $slides.eq($active_index);
// update indicators
if (options.indicators) {
$indicators.eq($active_index).addclass('active');
}
}
// adjust height to current slide
$active.find('img').each(function () {
$active.find('.caption').velocity({ opacity: 1, translatex: 0, translatey: 0 }, { duration: options.transition, queue: false, easing: 'easeoutquad' });
});
// auto scroll
$interval = setinterval(function () {
$active_index = $slider.find('.active').index();
movetoslide($active_index + 1);
}, options.transition + options.interval);
// hammerjs, swipe navigation
// touch event
var panning = false;
var swipeleft = false;
var swiperight = false;
$this.hammer({
prevent_default: false
}).on('pan', function (e) {
if (e.gesture.pointertype === "touch") {
// reset interval
clearinterval($interval);
var direction = e.gesture.direction;
var x = e.gesture.deltax;
var velocityx = e.gesture.velocityx;
var velocityy = e.gesture.velocityy;
$curr_slide = $slider.find('.active');
if (math.abs(velocityx) > math.abs(velocityy)) {
$curr_slide.velocity({ translatex: x
}, { duration: 50, queue: false, easing: 'easeoutquad' });
}
// swipe left
if (direction === 4 && (x > $this.innerwidth() / 2 || velocityx < -0.65)) {
swiperight = true;
}
// swipe right
else if (direction === 2 && (x < -1 * $this.innerwidth() / 2 || velocityx > 0.65)) {
swipeleft = true;
}
// make slide behind active slide visible
var next_slide;
if (swipeleft) {
next_slide = $curr_slide.next();
if (next_slide.length === 0) {
next_slide = $slides.first();
}
next_slide.velocity({ opacity: 1
}, { duration: 300, queue: false, easing: 'easeoutquad' });
}
if (swiperight) {
next_slide = $curr_slide.prev();
if (next_slide.length === 0) {
next_slide = $slides.last();
}
next_slide.velocity({ opacity: 1
}, { duration: 300, queue: false, easing: 'easeoutquad' });
}
}
}).on('panend', function (e) {
if (e.gesture.pointertype === "touch") {
$curr_slide = $slider.find('.active');
panning = false;
curr_index = $slider.find('.active').index();
if (!swiperight && !swipeleft || $slides.length <= 1) {
// return to original spot
$curr_slide.velocity({ translatex: 0
}, { duration: 300, queue: false, easing: 'easeoutquad' });
} else if (swipeleft) {
movetoslide(curr_index + 1);
$curr_slide.velocity({ translatex: -1 * $this.innerwidth() }, { duration: 300, queue: false, easing: 'easeoutquad',
complete: function () {
$curr_slide.velocity({ opacity: 0, translatex: 0 }, { duration: 0, queue: false });
} });
} else if (swiperight) {
movetoslide(curr_index - 1);
$curr_slide.velocity({ translatex: $this.innerwidth() }, { duration: 300, queue: false, easing: 'easeoutquad',
complete: function () {
$curr_slide.velocity({ opacity: 0, translatex: 0 }, { duration: 0, queue: false });
} });
}
swipeleft = false;
swiperight = false;
// restart interval
clearinterval($interval);
$interval = setinterval(function () {
$active_index = $slider.find('.active').index();
if ($slides.length == $active_index + 1) $active_index = 0; // loop to start
else $active_index += 1;
movetoslide($active_index);
}, options.transition + options.interval);
}
});
$this.on('sliderpause', function () {
clearinterval($interval);
});
$this.on('sliderstart', function () {
clearinterval($interval);
$interval = setinterval(function () {
$active_index = $slider.find('.active').index();
if ($slides.length == $active_index + 1) $active_index = 0; // loop to start
else $active_index += 1;
movetoslide($active_index);
}, options.transition + options.interval);
});
$this.on('slidernext', function () {
$active_index = $slider.find('.active').index();
movetoslide($active_index + 1);
});
$this.on('sliderprev', function () {
$active_index = $slider.find('.active').index();
movetoslide($active_index - 1);
});
});
},
pause: function () {
$(this).trigger('sliderpause');
},
start: function () {
$(this).trigger('sliderstart');
},
next: function () {
$(this).trigger('slidernext');
},
prev: function () {
$(this).trigger('sliderprev');
}
};
$.fn.slider = function (methodoroptions) {
if (methods[methodoroptions]) {
return methods[methodoroptions].apply(this, array.prototype.slice.call(arguments, 1));
} else if (typeof methodoroptions === 'object' || !methodoroptions) {
// default to "init"
return methods.init.apply(this, arguments);
} else {
$.error('method ' + methodoroptions + ' does not exist on jquery.tooltip');
}
}; // plugin end
})(jquery);
;(function ($) {
$(document).ready(function () {
$(document).on('click.card', '.card', function (e) {
if ($(this).find('> .card-reveal').length) {
var $card = $(e.target).closest('.card');
if ($card.data('initialoverflow') === undefined) {
$card.data('initialoverflow', $card.css('overflow') === undefined ? '' : $card.css('overflow'));
}
if ($(e.target).is($('.card-reveal .card-title')) || $(e.target).is($('.card-reveal .card-title i'))) {
// make reveal animate down and display none
$(this).find('.card-reveal').velocity({ translatey: 0 }, {
duration: 225,
queue: false,
easing: 'easeinoutquad',
complete: function () {
$(this).css({ display: 'none' });
$card.css('overflow', $card.data('initialoverflow'));
}
});
} else if ($(e.target).is($('.card .activator')) || $(e.target).is($('.card .activator i'))) {
$card.css('overflow', 'hidden');
$(this).find('.card-reveal').css({ display: 'block' }).velocity("stop", false).velocity({ translatey: '-100%' }, { duration: 300, queue: false, easing: 'easeinoutquad' });
}
}
});
});
})(jquery);
;(function ($) {
var materialchipsdefaults = {
data: [],
placeholder: '',
secondaryplaceholder: '',
autocompleteoptions: {}
};
$(document).ready(function () {
// handle removal of static chips.
$(document).on('click', '.chip .close', function (e) {
var $chips = $(this).closest('.chips');
if ($chips.attr('data-initialized')) {
return;
}
$(this).closest('.chip').remove();
});
});
$.fn.material_chip = function (options) {
var self = this;
this.$el = $(this);
this.$document = $(document);
this.sels = {
chips: '.chips',
chip: '.chip',
input: 'input',
delete: '.material-icons',
selected_chip: '.selected'
};
if ('data' === options) {
return this.$el.data('chips');
}
var curr_options = $.extend({}, materialchipsdefaults, options);
self.hasautocomplete = !$.isemptyobject(curr_options.autocompleteoptions.data);
// initialize
this.init = function () {
var i = 0;
var chips;
self.$el.each(function () {
var $chips = $(this);
var chipid = materialize.guid();
self.chipid = chipid;
if (!curr_options.data || !(curr_options.data instanceof array)) {
curr_options.data = [];
}
$chips.data('chips', curr_options.data);
$chips.attr('data-index', i);
$chips.attr('data-initialized', true);
if (!$chips.hasclass(self.sels.chips)) {
$chips.addclass('chips');
}
self.chips($chips, chipid);
i++;
});
};
this.handleevents = function () {
var sels = self.sels;
self.$document.off('click.chips-focus', sels.chips).on('click.chips-focus', sels.chips, function (e) {
$(e.target).find(sels.input).focus();
});
self.$document.off('click.chips-select', sels.chip).on('click.chips-select', sels.chip, function (e) {
var $chip = $(e.target);
if ($chip.length) {
var wasselected = $chip.hasclass('selected');
var $chips = $chip.closest(sels.chips);
$(sels.chip).removeclass('selected');
if (!wasselected) {
self.selectchip($chip.index(), $chips);
}
}
});
self.$document.off('keydown.chips').on('keydown.chips', function (e) {
if ($(e.target).is('input, textarea')) {
return;
}
// delete
var $chip = self.$document.find(sels.chip + sels.selected_chip);
var $chips = $chip.closest(sels.chips);
var length = $chip.siblings(sels.chip).length;
var index;
if (!$chip.length) {
return;
}
if (e.which === 8 || e.which === 46) {
e.preventdefault();
index = $chip.index();
self.deletechip(index, $chips);
var selectindex = null;
if (index + 1 < length) {
selectindex = index;
} else if (index === length || index + 1 === length) {
selectindex = length - 1;
}
if (selectindex < 0) selectindex = null;
if (null !== selectindex) {
self.selectchip(selectindex, $chips);
}
if (!length) $chips.find('input').focus();
// left
} else if (e.which === 37) {
index = $chip.index() - 1;
if (index < 0) {
return;
}
$(sels.chip).removeclass('selected');
self.selectchip(index, $chips);
// right
} else if (e.which === 39) {
index = $chip.index() + 1;
$(sels.chip).removeclass('selected');
if (index > length) {
$chips.find('input').focus();
return;
}
self.selectchip(index, $chips);
}
});
self.$document.off('focusin.chips', sels.chips + ' ' + sels.input).on('focusin.chips', sels.chips + ' ' + sels.input, function (e) {
var $currchips = $(e.target).closest(sels.chips);
$currchips.addclass('focus');
$currchips.siblings('label, .prefix').addclass('active');
$(sels.chip).removeclass('selected');
});
self.$document.off('focusout.chips', sels.chips + ' ' + sels.input).on('focusout.chips', sels.chips + ' ' + sels.input, function (e) {
var $currchips = $(e.target).closest(sels.chips);
$currchips.removeclass('focus');
// remove active if empty
if ($currchips.data('chips') === undefined || !$currchips.data('chips').length) {
$currchips.siblings('label').removeclass('active');
}
$currchips.siblings('.prefix').removeclass('active');
});
self.$document.off('keydown.chips-add', sels.chips + ' ' + sels.input).on('keydown.chips-add', sels.chips + ' ' + sels.input, function (e) {
var $target = $(e.target);
var $chips = $target.closest(sels.chips);
var chipslength = $chips.children(sels.chip).length;
// enter
if (13 === e.which) {
// override enter if autocompleting.
if (self.hasautocomplete && $chips.find('.autocomplete-content.dropdown-content').length && $chips.find('.autocomplete-content.dropdown-content').children().length) {
return;
}
e.preventdefault();
self.addchip({ tag: $target.val() }, $chips);
$target.val('');
return;
}
// delete or left
if ((8 === e.keycode || 37 === e.keycode) && '' === $target.val() && chipslength) {
e.preventdefault();
self.selectchip(chipslength - 1, $chips);
$target.blur();
return;
}
});
// click on delete icon in chip.
self.$document.off('click.chips-delete', sels.chips + ' ' + sels.delete).on('click.chips-delete', sels.chips + ' ' + sels.delete, function (e) {
var $target = $(e.target);
var $chips = $target.closest(sels.chips);
var $chip = $target.closest(sels.chip);
e.stoppropagation();
self.deletechip($chip.index(), $chips);
$chips.find('input').focus();
});
};
this.chips = function ($chips, chipid) {
$chips.empty();
$chips.data('chips').foreach(function (elem) {
$chips.append(self.renderchip(elem));
});
$chips.append($(''));
self.setplaceholder($chips);
// set for attribute for label
var label = $chips.next('label');
if (label.length) {
label.attr('for', chipid);
if ($chips.data('chips') !== undefined && $chips.data('chips').length) {
label.addclass('active');
}
}
// setup autocomplete if needed.
var input = $('#' + chipid);
if (self.hasautocomplete) {
curr_options.autocompleteoptions.onautocomplete = function (val) {
self.addchip({ tag: val }, $chips);
input.val('');
input.focus();
};
input.autocomplete(curr_options.autocompleteoptions);
}
};
/**
* render chip jquery element.
* @param {object} elem
* @return {jquery}
*/
this.renderchip = function (elem) {
if (!elem.tag) return;
var $renderedchip = $('');
$renderedchip.text(elem.tag);
if (elem.image) {
$renderedchip.prepend($('').attr('src', elem.image));
}
$renderedchip.append($('close'));
return $renderedchip;
};
this.setplaceholder = function ($chips) {
if ($chips.data('chips') !== undefined && !$chips.data('chips').length && curr_options.placeholder) {
$chips.find('input').prop('placeholder', curr_options.placeholder);
} else if (($chips.data('chips') === undefined || !!$chips.data('chips').length) && curr_options.secondaryplaceholder) {
$chips.find('input').prop('placeholder', curr_options.secondaryplaceholder);
}
};
this.isvalid = function ($chips, elem) {
var chips = $chips.data('chips');
var exists = false;
for (var i = 0; i < chips.length; i++) {
if (chips[i].tag === elem.tag) {
exists = true;
return;
}
}
return '' !== elem.tag && !exists;
};
this.addchip = function (elem, $chips) {
if (!self.isvalid($chips, elem)) {
return;
}
var $renderedchip = self.renderchip(elem);
var newdata = [];
var olddata = $chips.data('chips');
for (var i = 0; i < olddata.length; i++) {
newdata.push(olddata[i]);
}
newdata.push(elem);
$chips.data('chips', newdata);
$renderedchip.insertbefore($chips.find('input'));
$chips.trigger('chip.add', elem);
self.setplaceholder($chips);
};
this.deletechip = function (chipindex, $chips) {
var chip = $chips.data('chips')[chipindex];
$chips.find('.chip').eq(chipindex).remove();
var newdata = [];
var olddata = $chips.data('chips');
for (var i = 0; i < olddata.length; i++) {
if (i !== chipindex) {
newdata.push(olddata[i]);
}
}
$chips.data('chips', newdata);
$chips.trigger('chip.delete', chip);
self.setplaceholder($chips);
};
this.selectchip = function (chipindex, $chips) {
var $chip = $chips.find('.chip').eq(chipindex);
if ($chip && false === $chip.hasclass('selected')) {
$chip.addclass('selected');
$chips.trigger('chip.select', $chips.data('chips')[chipindex]);
}
};
this.getchipselement = function (index, $chips) {
return $chips.eq(index);
};
// init
this.init();
this.handleevents();
};
})(jquery);
;(function ($) {
$.fn.pushpin = function (options) {
// defaults
var defaults = {
top: 0,
bottom: infinity,
offset: 0
};
// remove pushpin event and classes
if (options === "remove") {
this.each(function () {
if (id = $(this).data('pushpin-id')) {
$(window).off('scroll.' + id);
$(this).removedata('pushpin-id').removeclass('pin-top pinned pin-bottom').removeattr('style');
}
});
return false;
}
options = $.extend(defaults, options);
$index = 0;
return this.each(function () {
var $uniqueid = materialize.guid(),
$this = $(this),
$original_offset = $(this).offset().top;
function removepinclasses(object) {
object.removeclass('pin-top');
object.removeclass('pinned');
object.removeclass('pin-bottom');
}
function updateelements(objects, scrolled) {
objects.each(function () {
// add position fixed (because its between top and bottom)
if (options.top <= scrolled && options.bottom >= scrolled && !$(this).hasclass('pinned')) {
removepinclasses($(this));
$(this).css('top', options.offset);
$(this).addclass('pinned');
}
// add pin-top (when scrolled position is above top)
if (scrolled < options.top && !$(this).hasclass('pin-top')) {
removepinclasses($(this));
$(this).css('top', 0);
$(this).addclass('pin-top');
}
// add pin-bottom (when scrolled position is below bottom)
if (scrolled > options.bottom && !$(this).hasclass('pin-bottom')) {
removepinclasses($(this));
$(this).addclass('pin-bottom');
$(this).css('top', options.bottom - $original_offset);
}
});
}
$(this).data('pushpin-id', $uniqueid);
updateelements($this, $(window).scrolltop());
$(window).on('scroll.' + $uniqueid, function () {
var $scrolled = $(window).scrolltop() + options.offset;
updateelements($this, $scrolled);
});
});
};
})(jquery);;(function ($) {
$(document).ready(function () {
// jquery reverse
$.fn.reverse = [].reverse;
// hover behaviour: make sure this doesn't work on .click-to-toggle fabs!
$(document).on('mouseenter.fixedactionbtn', '.fixed-action-btn:not(.click-to-toggle):not(.toolbar)', function (e) {
var $this = $(this);
openfabmenu($this);
});
$(document).on('mouseleave.fixedactionbtn', '.fixed-action-btn:not(.click-to-toggle):not(.toolbar)', function (e) {
var $this = $(this);
closefabmenu($this);
});
// toggle-on-click behaviour.
$(document).on('click.fabclicktoggle', '.fixed-action-btn.click-to-toggle > a', function (e) {
var $this = $(this);
var $menu = $this.parent();
if ($menu.hasclass('active')) {
closefabmenu($menu);
} else {
openfabmenu($menu);
}
});
// toolbar transition behaviour.
$(document).on('click.fabtoolbar', '.fixed-action-btn.toolbar > a', function (e) {
var $this = $(this);
var $menu = $this.parent();
fabtotoolbar($menu);
});
});
$.fn.extend({
openfab: function () {
openfabmenu($(this));
},
closefab: function () {
closefabmenu($(this));
},
opentoolbar: function () {
fabtotoolbar($(this));
},
closetoolbar: function () {
toolbartofab($(this));
}
});
var openfabmenu = function (btn) {
var $this = btn;
if ($this.hasclass('active') === false) {
// get direction option
var horizontal = $this.hasclass('horizontal');
var offsety, offsetx;
if (horizontal === true) {
offsetx = 40;
} else {
offsety = 40;
}
$this.addclass('active');
$this.find('ul .btn-floating').velocity({ scaley: ".4", scalex: ".4", translatey: offsety + 'px', translatex: offsetx + 'px' }, { duration: 0 });
var time = 0;
$this.find('ul .btn-floating').reverse().each(function () {
$(this).velocity({ opacity: "1", scalex: "1", scaley: "1", translatey: "0", translatex: '0' }, { duration: 80, delay: time });
time += 40;
});
}
};
var closefabmenu = function (btn) {
var $this = btn;
// get direction option
var horizontal = $this.hasclass('horizontal');
var offsety, offsetx;
if (horizontal === true) {
offsetx = 40;
} else {
offsety = 40;
}
$this.removeclass('active');
var time = 0;
$this.find('ul .btn-floating').velocity("stop", true);
$this.find('ul .btn-floating').velocity({ opacity: "0", scalex: ".4", scaley: ".4", translatey: offsety + 'px', translatex: offsetx + 'px' }, { duration: 80 });
};
/**
* transform fab into toolbar
* @param {object} object jquery object
*/
var fabtotoolbar = function (btn) {
if (btn.attr('data-open') === "true") {
return;
}
var offsetx, offsety, scalefactor;
var windowwidth = window.innerwidth;
var windowheight = window.innerheight;
var btnrect = btn[0].getboundingclientrect();
var anchor = btn.find('> a').first();
var menu = btn.find('> ul').first();
var backdrop = $('');
var fabcolor = anchor.css('background-color');
anchor.append(backdrop);
offsetx = btnrect.left - windowwidth / 2 + btnrect.width / 2;
offsety = windowheight - btnrect.bottom;
scalefactor = windowwidth / backdrop.width();
btn.attr('data-origin-bottom', btnrect.bottom);
btn.attr('data-origin-left', btnrect.left);
btn.attr('data-origin-width', btnrect.width);
// set initial state
btn.addclass('active');
btn.attr('data-open', true);
btn.css({
'text-align': 'center',
width: '100%',
bottom: 0,
left: 0,
transform: 'translatex(' + offsetx + 'px)',
transition: 'none'
});
anchor.css({
transform: 'translatey(' + -offsety + 'px)',
transition: 'none'
});
backdrop.css({
'background-color': fabcolor
});
settimeout(function () {
btn.css({
transform: '',
transition: 'transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s'
});
anchor.css({
overflow: 'visible',
transform: '',
transition: 'transform .2s'
});
settimeout(function () {
btn.css({
overflow: 'hidden',
'background-color': fabcolor
});
backdrop.css({
transform: 'scale(' + scalefactor + ')',
transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)'
});
menu.find('> li > a').css({
opacity: 1
});
// scroll to close.
$(window).on('scroll.fabtoolbarclose', function () {
toolbartofab(btn);
$(window).off('scroll.fabtoolbarclose');
$(document).off('click.fabtoolbarclose');
});
$(document).on('click.fabtoolbarclose', function (e) {
if (!$(e.target).closest(menu).length) {
toolbartofab(btn);
$(window).off('scroll.fabtoolbarclose');
$(document).off('click.fabtoolbarclose');
}
});
}, 100);
}, 0);
};
/**
* transform toolbar back into fab
* @param {object} object jquery object
*/
var toolbartofab = function (btn) {
if (btn.attr('data-open') !== "true") {
return;
}
var offsetx, offsety, scalefactor;
var windowwidth = window.innerwidth;
var windowheight = window.innerheight;
var btnwidth = btn.attr('data-origin-width');
var btnbottom = btn.attr('data-origin-bottom');
var btnleft = btn.attr('data-origin-left');
var anchor = btn.find('> .btn-floating').first();
var menu = btn.find('> ul').first();
var backdrop = btn.find('.fab-backdrop');
var fabcolor = anchor.css('background-color');
offsetx = btnleft - windowwidth / 2 + btnwidth / 2;
offsety = windowheight - btnbottom;
scalefactor = windowwidth / backdrop.width();
// hide backdrop
btn.removeclass('active');
btn.attr('data-open', false);
btn.css({
'background-color': 'transparent',
transition: 'none'
});
anchor.css({
transition: 'none'
});
backdrop.css({
transform: 'scale(0)',
'background-color': fabcolor
});
menu.find('> li > a').css({
opacity: ''
});
settimeout(function () {
backdrop.remove();
// set initial state.
btn.css({
'text-align': '',
width: '',
bottom: '',
left: '',
overflow: '',
'background-color': '',
transform: 'translate3d(' + -offsetx + 'px,0,0)'
});
anchor.css({
overflow: '',
transform: 'translate3d(0,' + offsety + 'px,0)'
});
settimeout(function () {
btn.css({
transform: 'translate3d(0,0,0)',
transition: 'transform .2s'
});
anchor.css({
transform: 'translate3d(0,0,0)',
transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)'
});
}, 20);
}, 200);
};
})(jquery);
;(function ($) {
// image transition function
materialize.fadeinimage = function (selectororel) {
var element;
if (typeof selectororel === 'string') {
element = $(selectororel);
} else if (typeof selectororel === 'object') {
element = selectororel;
} else {
return;
}
element.css({ opacity: 0 });
$(element).velocity({ opacity: 1 }, {
duration: 650,
queue: false,
easing: 'easeoutsine'
});
$(element).velocity({ opacity: 1 }, {
duration: 1300,
queue: false,
easing: 'swing',
step: function (now, fx) {
fx.start = 100;
var grayscale_setting = now / 100;
var brightness_setting = 150 - (100 - now) / 1.75;
if (brightness_setting < 100) {
brightness_setting = 100;
}
if (now >= 0) {
$(this).css({
"-webkit-filter": "grayscale(" + grayscale_setting + ")" + "brightness(" + brightness_setting + "%)",
"filter": "grayscale(" + grayscale_setting + ")" + "brightness(" + brightness_setting + "%)"
});
}
}
});
};
// horizontal staggered list
materialize.showstaggeredlist = function (selectororel) {
var element;
if (typeof selectororel === 'string') {
element = $(selectororel);
} else if (typeof selectororel === 'object') {
element = selectororel;
} else {
return;
}
var time = 0;
element.find('li').velocity({ translatex: "-100px" }, { duration: 0 });
element.find('li').each(function () {
$(this).velocity({ opacity: "1", translatex: "0" }, { duration: 800, delay: time, easing: [60, 10] });
time += 120;
});
};
$(document).ready(function () {
// hardcoded .staggered-list scrollfire
// var staggeredlistoptions = [];
// $('ul.staggered-list').each(function (i) {
// var label = 'scrollfire-' + i;
// $(this).addclass(label);
// staggeredlistoptions.push(
// {selector: 'ul.staggered-list.' + label,
// offset: 200,
// callback: 'showstaggeredlist("ul.staggered-list.' + label + '")'});
// });
// scrollfire(staggeredlistoptions);
// hammerjs, swipe navigation
// touch event
var swipeleft = false;
var swiperight = false;
// dismissible collections
$('.dismissable').each(function () {
$(this).hammer({
prevent_default: false
}).on('pan', function (e) {
if (e.gesture.pointertype === "touch") {
var $this = $(this);
var direction = e.gesture.direction;
var x = e.gesture.deltax;
var velocityx = e.gesture.velocityx;
$this.velocity({ translatex: x
}, { duration: 50, queue: false, easing: 'easeoutquad' });
// swipe left
if (direction === 4 && (x > $this.innerwidth() / 2 || velocityx < -0.75)) {
swipeleft = true;
}
// swipe right
if (direction === 2 && (x < -1 * $this.innerwidth() / 2 || velocityx > 0.75)) {
swiperight = true;
}
}
}).on('panend', function (e) {
// reset if collection is moved back into original position
if (math.abs(e.gesture.deltax) < $(this).innerwidth() / 2) {
swiperight = false;
swipeleft = false;
}
if (e.gesture.pointertype === "touch") {
var $this = $(this);
if (swipeleft || swiperight) {
var fullwidth;
if (swipeleft) {
fullwidth = $this.innerwidth();
} else {
fullwidth = -1 * $this.innerwidth();
}
$this.velocity({ translatex: fullwidth
}, { duration: 100, queue: false, easing: 'easeoutquad', complete: function () {
$this.css('border', 'none');
$this.velocity({ height: 0, padding: 0
}, { duration: 200, queue: false, easing: 'easeoutquad', complete: function () {
$this.remove();
}
});
}
});
} else {
$this.velocity({ translatex: 0
}, { duration: 100, queue: false, easing: 'easeoutquad' });
}
swipeleft = false;
swiperight = false;
}
});
});
// time = 0
// // vertical staggered list
// $('ul.staggered-list.vertical li').velocity(
// { translatey: "100px"},
// { duration: 0 });
// $('ul.staggered-list.vertical li').each(function() {
// $(this).velocity(
// { opacity: "1", translatey: "0"},
// { duration: 800, delay: time, easing: [60, 25] });
// time += 120;
// });
// // fade in and scale
// $('.fade-in.scale').velocity(
// { scalex: .4, scaley: .4, translatex: -600},
// { duration: 0});
// $('.fade-in').each(function() {
// $(this).velocity(
// { opacity: "1", scalex: 1, scaley: 1, translatex: 0},
// { duration: 800, easing: [60, 10] });
// });
});
})(jquery);
;(function ($) {
var scrollfireeventshandled = false;
// input: array of json objects {selector, offset, callback}
materialize.scrollfire = function (options) {
var onscroll = function () {
var windowscroll = window.pageyoffset + window.innerheight;
for (var i = 0; i < options.length; i++) {
// get options from each line
var value = options[i];
var selector = value.selector,
offset = value.offset,
callback = value.callback;
var currentelement = document.queryselector(selector);
if (currentelement !== null) {
var elementoffset = currentelement.getboundingclientrect().top + window.pageyoffset;
if (windowscroll > elementoffset + offset) {
if (value.done !== true) {
if (typeof callback === 'function') {
callback.call(this, currentelement);
} else if (typeof callback === 'string') {
var callbackfunc = new function(callback);
callbackfunc(currentelement);
}
value.done = true;
}
}
}
}
};
var throttledscroll = materialize.throttle(function () {
onscroll();
}, options.throttle || 100);
if (!scrollfireeventshandled) {
window.addeventlistener("scroll", throttledscroll);
window.addeventlistener("resize", throttledscroll);
scrollfireeventshandled = true;
}
// perform a scan once, after current execution context, and after dom is ready
settimeout(throttledscroll, 0);
};
})(jquery);
; /*!
* pickadate.js v3.5.0, 2014/04/13
* by amsul, http://amsul.ca
* hosted on http://amsul.github.io/pickadate.js
* licensed under mit
*/
(function (factory) {
materialize.picker = factory(jquery);
})(function ($) {
var $window = $(window);
var $document = $(document);
var $html = $(document.documentelement);
/**
* the picker constructor that creates a blank picker.
*/
function pickerconstructor(element, name, component, options) {
// if there’s no element, return the picker constructor.
if (!element) return pickerconstructor;
var is_default_theme = false,
// the state of the picker.
state = {
id: element.id || 'p' + math.abs(~~(math.random() * new date()))
},
// merge the defaults and options passed.
settings = component ? $.extend(true, {}, component.defaults, options) : options || {},
// merge the default classes with the settings classes.
classes = $.extend({}, pickerconstructor.klasses(), settings.klass),
// the element node wrapper into a jquery object.
$element = $(element),
// pseudo picker constructor.
pickerinstance = function () {
return this.start();
},
// the picker prototype.
p = pickerinstance.prototype = {
constructor: pickerinstance,
$node: $element,
/**
* initialize everything
*/
start: function () {
// if it’s already started, do nothing.
if (state && state.start) return p;
// update the picker states.
state.methods = {};
state.start = true;
state.open = false;
state.type = element.type;
// confirm focus state, convert into text input to remove ua stylings,
// and set as readonly to prevent keyboard popup.
element.autofocus = element == getactiveelement();
element.readonly = !settings.editable;
element.id = element.id || state.id;
if (element.type != 'text') {
element.type = 'text';
}
// create a new picker component with the settings.
p.component = new component(p, settings);
// create the picker root with a holder and then prepare it.
p.$root = $(pickerconstructor._.node('div', createwrappedcomponent(), classes.picker, 'id="' + element.id + '_root" tabindex="0"'));
prepareelementroot();
// if there’s a format for the hidden input element, create the element.
if (settings.formatsubmit) {
prepareelementhidden();
}
// prepare the input element.
prepareelement();
// insert the root as specified in the settings.
if (settings.container) $(settings.container).append(p.$root);else $element.before(p.$root);
// bind the default component and settings events.
p.on({
start: p.component.onstart,
render: p.component.onrender,
stop: p.component.onstop,
open: p.component.onopen,
close: p.component.onclose,
set: p.component.onset
}).on({
start: settings.onstart,
render: settings.onrender,
stop: settings.onstop,
open: settings.onopen,
close: settings.onclose,
set: settings.onset
});
// once we’re all set, check the theme in use.
is_default_theme = isusingdefaulttheme(p.$root.children()[0]);
// if the element has autofocus, open the picker.
if (element.autofocus) {
p.open();
}
// trigger queued the “start” and “render” events.
return p.trigger('start').trigger('render');
}, //start
/**
* render a new picker
*/
render: function (entirecomponent) {
// insert a new component holder in the root or box.
if (entirecomponent) p.$root.html(createwrappedcomponent());else p.$root.find('.' + classes.box).html(p.component.nodes(state.open));
// trigger the queued “render” events.
return p.trigger('render');
}, //render
/**
* destroy everything
*/
stop: function () {
// if it’s already stopped, do nothing.
if (!state.start) return p;
// then close the picker.
p.close();
// remove the hidden field.
if (p._hidden) {
p._hidden.parentnode.removechild(p._hidden);
}
// remove the root.
p.$root.remove();
// remove the input class, remove the stored data, and unbind
// the events (after a tick for ie - see `p.close`).
$element.removeclass(classes.input).removedata(name);
settimeout(function () {
$element.off('.' + state.id);
}, 0);
// restore the element state
element.type = state.type;
element.readonly = false;
// trigger the queued “stop” events.
p.trigger('stop');
// reset the picker states.
state.methods = {};
state.start = false;
return p;
}, //stop
/**
* open up the picker
*/
open: function (dontgivefocus) {
// if it’s already open, do nothing.
if (state.open) return p;
// add the “active” class.
$element.addclass(classes.active);
aria(element, 'expanded', true);
// * a firefox bug, when `html` has `overflow:hidden`, results in
// killing transitions :(. so add the “opened” state on the next tick.
// bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
settimeout(function () {
// add the “opened” class to the picker root.
p.$root.addclass(classes.opened);
aria(p.$root[0], 'hidden', false);
}, 0);
// if we have to give focus, bind the element and doc events.
if (dontgivefocus !== false) {
// set it as open.
state.open = true;
// prevent the page from scrolling.
if (is_default_theme) {
$html.css('overflow', 'hidden').css('padding-right', '+=' + getscrollbarwidth());
}
// pass focus to the root element’s jquery object.
// * workaround for ios8 to bring the picker’s root into view.
p.$root.eq(0).focus();
// bind the document events.
$document.on('click.' + state.id + ' focusin.' + state.id, function (event) {
var target = event.target;
// if the target of the event is not the element, close the picker picker.
// * don’t worry about clicks or focusins on the root because those don’t bubble up.
// also, for firefox, a click on an `option` element bubbles up directly
// to the doc. so make sure the target wasn't the doc.
// * in firefox stoppropagation() doesn’t prevent right-click events from bubbling,
// which causes the picker to unexpectedly close when right-clicking it. so make
// sure the event wasn’t a right-click.
if (target != element && target != document && event.which != 3) {
// if the target was the holder that covers the screen,
// keep the element focused to maintain tabindex.
p.close(target === p.$root.children()[0]);
}
}).on('keydown.' + state.id, function (event) {
var
// get the keycode.
keycode = event.keycode,
// translate that to a selection change.
keycodetomove = p.component.key[keycode],
// grab the target.
target = event.target;
// on escape, close the picker and give focus.
if (keycode == 27) {
p.close(true);
}
// check if there is a key movement or “enter” keypress on the element.
else if (target == p.$root[0] && (keycodetomove || keycode == 13)) {
// prevent the default action to stop page movement.
event.preventdefault();
// trigger the key movement action.
if (keycodetomove) {
pickerconstructor._.trigger(p.component.key.go, p, [pickerconstructor._.trigger(keycodetomove)]);
}
// on “enter”, if the highlighted item isn’t disabled, set the value and close.
else if (!p.$root.find('.' + classes.highlighted).hasclass(classes.disabled)) {
p.set('select', p.component.item.highlight);
if (settings.closeonselect) {
p.close(true);
}
}
}
// if the target is within the root and “enter” is pressed,
// prevent the default action and trigger a click on the target instead.
else if ($.contains(p.$root[0], target) && keycode == 13) {
event.preventdefault();
target.click();
}
});
}
// trigger the queued “open” events.
return p.trigger('open');
}, //open
/**
* close the picker
*/
close: function (givefocus) {
// if we need to give focus, do it before changing states.
if (givefocus) {
// ....ah yes! it would’ve been incomplete without a crazy workaround for ie :|
// the focus is triggered *after* the close has completed - causing it
// to open again. so unbind and rebind the event at the next tick.
p.$root.off('focus.toopen').eq(0).focus();
settimeout(function () {
p.$root.on('focus.toopen', handlefocustoopenevent);
}, 0);
}
// remove the “active” class.
$element.removeclass(classes.active);
aria(element, 'expanded', false);
// * a firefox bug, when `html` has `overflow:hidden`, results in
// killing transitions :(. so remove the “opened” state on the next tick.
// bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
settimeout(function () {
// remove the “opened” and “focused” class from the picker root.
p.$root.removeclass(classes.opened + ' ' + classes.focused);
aria(p.$root[0], 'hidden', true);
}, 0);
// if it’s already closed, do nothing more.
if (!state.open) return p;
// set it as closed.
state.open = false;
// allow the page to scroll.
if (is_default_theme) {
$html.css('overflow', '').css('padding-right', '-=' + getscrollbarwidth());
}
// unbind the document events.
$document.off('.' + state.id);
// trigger the queued “close” events.
return p.trigger('close');
}, //close
/**
* clear the values
*/
clear: function (options) {
return p.set('clear', null, options);
}, //clear
/**
* set something
*/
set: function (thing, value, options) {
var thingitem,
thingvalue,
thingisobject = $.isplainobject(thing),
thingobject = thingisobject ? thing : {};
// make sure we have usable options.
options = thingisobject && $.isplainobject(value) ? value : options || {};
if (thing) {
// if the thing isn’t an object, make it one.
if (!thingisobject) {
thingobject[thing] = value;
}
// go through the things of items to set.
for (thingitem in thingobject) {
// grab the value of the thing.
thingvalue = thingobject[thingitem];
// first, if the item exists and there’s a value, set it.
if (thingitem in p.component.item) {
if (thingvalue === undefined) thingvalue = null;
p.component.set(thingitem, thingvalue, options);
}
// then, check to update the element value and broadcast a change.
if (thingitem == 'select' || thingitem == 'clear') {
$element.val(thingitem == 'clear' ? '' : p.get(thingitem, settings.format)).trigger('change');
}
}
// render a new picker.
p.render();
}
// when the method isn’t muted, trigger queued “set” events and pass the `thingobject`.
return options.muted ? p : p.trigger('set', thingobject);
}, //set
/**
* get something
*/
get: function (thing, format) {
// make sure there’s something to get.
thing = thing || 'value';
// if a picker state exists, return that.
if (state[thing] != null) {
return state[thing];
}
// return the submission value, if that.
if (thing == 'valuesubmit') {
if (p._hidden) {
return p._hidden.value;
}
thing = 'value';
}
// return the value, if that.
if (thing == 'value') {
return element.value;
}
// check if a component item exists, return that.
if (thing in p.component.item) {
if (typeof format == 'string') {
var thingvalue = p.component.get(thing);
return thingvalue ? pickerconstructor._.trigger(p.component.formats.tostring, p.component, [format, thingvalue]) : '';
}
return p.component.get(thing);
}
}, //get
/**
* bind events on the things.
*/
on: function (thing, method, internal) {
var thingname,
thingmethod,
thingisobject = $.isplainobject(thing),
thingobject = thingisobject ? thing : {};
if (thing) {
// if the thing isn’t an object, make it one.
if (!thingisobject) {
thingobject[thing] = method;
}
// go through the things to bind to.
for (thingname in thingobject) {
// grab the method of the thing.
thingmethod = thingobject[thingname];
// if it was an internal binding, prefix it.
if (internal) {
thingname = '_' + thingname;
}
// make sure the thing methods collection exists.
state.methods[thingname] = state.methods[thingname] || [];
// add the method to the relative method collection.
state.methods[thingname].push(thingmethod);
}
}
return p;
}, //on
/**
* unbind events on the things.
*/
off: function () {
var i,
thingname,
names = arguments;
for (i = 0, namescount = names.length; i < namescount; i += 1) {
thingname = names[i];
if (thingname in state.methods) {
delete state.methods[thingname];
}
}
return p;
},
/**
* fire off method events.
*/
trigger: function (name, data) {
var _trigger = function (name) {
var methodlist = state.methods[name];
if (methodlist) {
methodlist.map(function (method) {
pickerconstructor._.trigger(method, p, [data]);
});
}
};
_trigger('_' + name);
_trigger(name);
return p;
} //trigger
//pickerinstance.prototype
/**
* wrap the picker holder components together.
*/
};function createwrappedcomponent() {
// create a picker wrapper holder
return pickerconstructor._.node('div',
// create a picker wrapper node
pickerconstructor._.node('div',
// create a picker frame
pickerconstructor._.node('div',
// create a picker box node
pickerconstructor._.node('div',
// create the components nodes.
p.component.nodes(state.open),
// the picker box class
classes.box),
// picker wrap class
classes.wrap),
// picker frame class
classes.frame),
// picker holder class
classes.holder); //endreturn
} //createwrappedcomponent
/**
* prepare the input element with all bindings.
*/
function prepareelement() {
$element.
// store the picker data by component name.
data(name, p).
// add the “input” class name.
addclass(classes.input).
// remove the tabindex.
attr('tabindex', -1).
// if there’s a `data-value`, update the value of the element.
val($element.data('value') ? p.get('select', settings.format) : element.value);
// only bind keydown events if the element isn’t editable.
if (!settings.editable) {
$element.
// on focus/click, focus onto the root to open it up.
on('focus.' + state.id + ' click.' + state.id, function (event) {
event.preventdefault();
p.$root.eq(0).focus();
}).
// handle keyboard event based on the picker being opened or not.
on('keydown.' + state.id, handlekeydownevent);
}
// update the aria attributes.
aria(element, {
haspopup: true,
expanded: false,
readonly: false,
owns: element.id + '_root'
});
}
/**
* prepare the root picker element with all bindings.
*/
function prepareelementroot() {
p.$root.on({
// for ios8.
keydown: handlekeydownevent,
// when something within the root is focused, stop from bubbling
// to the doc and remove the “focused” state from the root.
focusin: function (event) {
p.$root.removeclass(classes.focused);
event.stoppropagation();
},
// when something within the root holder is clicked, stop it
// from bubbling to the doc.
'mousedown click': function (event) {
var target = event.target;
// make sure the target isn’t the root holder so it can bubble up.
if (target != p.$root.children()[0]) {
event.stoppropagation();
// * for mousedown events, cancel the default action in order to
// prevent cases where focus is shifted onto external elements
// when using things like jquery mobile or magnificpopup (ref: #249 & #120).
// also, for firefox, don’t prevent action on the `option` element.
if (event.type == 'mousedown' && !$(target).is('input, select, textarea, button, option')) {
event.preventdefault();
// re-focus onto the root so that users can click away
// from elements focused within the picker.
p.$root.eq(0).focus();
}
}
}
}).
// add/remove the “target” class on focus and blur.
on({
focus: function () {
$element.addclass(classes.target);
},
blur: function () {
$element.removeclass(classes.target);
}
}).
// open the picker and adjust the root “focused” state
on('focus.toopen', handlefocustoopenevent).
// if there’s a click on an actionable element, carry out the actions.
on('click', '[data-pick], [data-nav], [data-clear], [data-close]', function () {
var $target = $(this),
targetdata = $target.data(),
targetdisabled = $target.hasclass(classes.navdisabled) || $target.hasclass(classes.disabled),
// * for ie, non-focusable elements can be active elements as well
// (http://stackoverflow.com/a/2684561).
activeelement = getactiveelement();
activeelement = activeelement && (activeelement.type || activeelement.href) && activeelement;
// if it’s disabled or nothing inside is actively focused, re-focus the element.
if (targetdisabled || activeelement && !$.contains(p.$root[0], activeelement)) {
p.$root.eq(0).focus();
}
// if something is superficially changed, update the `highlight` based on the `nav`.
if (!targetdisabled && targetdata.nav) {
p.set('highlight', p.component.item.highlight, { nav: targetdata.nav });
}
// if something is picked, set `select` then close with focus.
else if (!targetdisabled && 'pick' in targetdata) {
p.set('select', targetdata.pick);
if (settings.closeonselect) {
p.close(true);
}
}
// if a “clear” button is pressed, empty the values and close with focus.
else if (targetdata.clear) {
p.clear();
if (settings.closeonselect) {
p.close(true);
}
} else if (targetdata.close) {
p.close(true);
}
}); //p.$root
aria(p.$root[0], 'hidden', true);
}
/**
* prepare the hidden input element along with all bindings.
*/
function prepareelementhidden() {
var name;
if (settings.hiddenname === true) {
name = element.name;
element.name = '';
} else {
name = [typeof settings.hiddenprefix == 'string' ? settings.hiddenprefix : '', typeof settings.hiddensuffix == 'string' ? settings.hiddensuffix : '_submit'];
name = name[0] + element.name + name[1];
}
p._hidden = $('')[0];
$element.
// if the value changes, update the hidden input with the correct format.
on('change.' + state.id, function () {
p._hidden.value = element.value ? p.get('select', settings.formatsubmit) : '';
});
// insert the hidden input as specified in the settings.
if (settings.container) $(settings.container).append(p._hidden);else $element.before(p._hidden);
}
// for ios8.
function handlekeydownevent(event) {
var keycode = event.keycode,
// check if one of the delete keys was pressed.
iskeycodedelete = /^(8|46)$/.test(keycode);
// for some reason ie clears the input value on “escape”.
if (keycode == 27) {
p.close();
return false;
}
// check if `space` or `delete` was pressed or the picker is closed with a key movement.
if (keycode == 32 || iskeycodedelete || !state.open && p.component.key[keycode]) {
// prevent it from moving the page and bubbling to doc.
event.preventdefault();
event.stoppropagation();
// if `delete` was pressed, clear the values and close the picker.
// otherwise open the picker.
if (iskeycodedelete) {
p.clear().close();
} else {
p.open();
}
}
}
// separated for ie
function handlefocustoopenevent(event) {
// stop the event from propagating to the doc.
event.stoppropagation();
// if it’s a focus event, add the “focused” class to the root.
if (event.type == 'focus') {
p.$root.addclass(classes.focused);
}
// and then finally open the picker.
p.open();
}
// return a new picker instance.
return new pickerinstance();
} //pickerconstructor
/**
* the default classes and prefix to use for the html classes.
*/
pickerconstructor.klasses = function (prefix) {
prefix = prefix || 'picker';
return {
picker: prefix,
opened: prefix + '--opened',
focused: prefix + '--focused',
input: prefix + '__input',
active: prefix + '__input--active',
target: prefix + '__input--target',
holder: prefix + '__holder',
frame: prefix + '__frame',
wrap: prefix + '__wrap',
box: prefix + '__box'
};
}; //pickerconstructor.klasses
/**
* check if the default theme is being used.
*/
function isusingdefaulttheme(element) {
var theme,
prop = 'position';
// for ie.
if (element.currentstyle) {
theme = element.currentstyle[prop];
}
// for normal browsers.
else if (window.getcomputedstyle) {
theme = getcomputedstyle(element)[prop];
}
return theme == 'fixed';
}
/**
* get the width of the browser’s scrollbar.
* taken from: https://github.com/vodkabears/remodal/blob/master/src/jquery.remodal.js
*/
function getscrollbarwidth() {
if ($html.height() <= $window.height()) {
return 0;
}
var $outer = $('').appendto('body');
// get the width without scrollbars.
var widthwithoutscroll = $outer[0].offsetwidth;
// force adding scrollbars.
$outer.css('overflow', 'scroll');
// add the inner div.
var $inner = $('').appendto($outer);
// get the width with scrollbars.
var widthwithscroll = $inner[0].offsetwidth;
// remove the divs.
$outer.remove();
// return the difference between the widths.
return widthwithoutscroll - widthwithscroll;
}
/**
* pickerconstructor helper methods.
*/
pickerconstructor._ = {
/**
* create a group of nodes. expects:
* `
{
min: {integer},
max: {integer},
i: {integer},
node: {string},
item: {function}
}
* `
*/
group: function (groupobject) {
var
// scope for the looped object
loopobjectscope,
// create the nodes list
nodeslist = '',
// the counter starts from the `min`
counter = pickerconstructor._.trigger(groupobject.min, groupobject);
// loop from the `min` to `max`, incrementing by `i`
for (; counter <= pickerconstructor._.trigger(groupobject.max, groupobject, [counter]); counter += groupobject.i) {
// trigger the `item` function within scope of the object
loopobjectscope = pickerconstructor._.trigger(groupobject.item, groupobject, [counter]);
// splice the subgroup and create nodes out of the sub nodes
nodeslist += pickerconstructor._.node(groupobject.node, loopobjectscope[0], // the node
loopobjectscope[1], // the classes
loopobjectscope[2] // the attributes
);
}
// return the list of nodes
return nodeslist;
}, //group
/**
* create a dom node string
*/
node: function (wrapper, item, klass, attribute) {
// if the item is false-y, just return an empty string
if (!item) return '';
// if the item is an array, do a join
item = $.isarray(item) ? item.join('') : item;
// check for the class
klass = klass ? ' class="' + klass + '"' : '';
// check for any attributes
attribute = attribute ? ' ' + attribute : '';
// return the wrapped item
return '<' + wrapper + klass + attribute + '>' + item + '' + wrapper + '>';
}, //node
/**
* lead numbers below 10 with a zero.
*/
lead: function (number) {
return (number < 10 ? '0' : '') + number;
},
/**
* trigger a function otherwise return the value.
*/
trigger: function (callback, scope, args) {
return typeof callback == 'function' ? callback.apply(scope, args || []) : callback;
},
/**
* if the second character is a digit, length is 2 otherwise 1.
*/
digits: function (string) {
return (/\d/.test(string[1]) ? 2 : 1
);
},
/**
* tell if something is a date object.
*/
isdate: function (value) {
return {}.tostring.call(value).indexof('date') > -1 && this.isinteger(value.getdate());
},
/**
* tell if something is an integer.
*/
isinteger: function (value) {
return {}.tostring.call(value).indexof('number') > -1 && value % 1 === 0;
},
/**
* create aria attribute strings.
*/
ariaattr: ariaattr //pickerconstructor._
/**
* extend the picker with a component and defaults.
*/
};pickerconstructor.extend = function (name, component) {
// extend jquery.
$.fn[name] = function (options, action) {
// grab the component data.
var componentdata = this.data(name);
// if the picker is requested, return the data object.
if (options == 'picker') {
return componentdata;
}
// if the component data exists and `options` is a string, carry out the action.
if (componentdata && typeof options == 'string') {
return pickerconstructor._.trigger(componentdata[options], componentdata, [action]);
}
// otherwise go through each matched element and if the component
// doesn’t exist, create a new picker using `this` element
// and merging the defaults and options with a deep copy.
return this.each(function () {
var $this = $(this);
if (!$this.data(name)) {
new pickerconstructor(this, name, component, options);
}
});
};
// set the defaults.
$.fn[name].defaults = component.defaults;
}; //pickerconstructor.extend
function aria(element, attribute, value) {
if ($.isplainobject(attribute)) {
for (var key in attribute) {
ariaset(element, key, attribute[key]);
}
} else {
ariaset(element, attribute, value);
}
}
function ariaset(element, attribute, value) {
element.setattribute((attribute == 'role' ? '' : 'aria-') + attribute, value);
}
function ariaattr(attribute, data) {
if (!$.isplainobject(attribute)) {
attribute = { attribute: data };
}
data = '';
for (var key in attribute) {
var attr = (key == 'role' ? '' : 'aria-') + key,
attrval = attribute[key];
data += attrval == null ? '' : attr + '="' + attribute[key] + '"';
}
return data;
}
// ie8 bug throws an error for activeelements within iframes.
function getactiveelement() {
try {
return document.activeelement;
} catch (err) {}
}
// expose the picker constructor.
return pickerconstructor;
});
; /*!
* date picker for pickadate.js v3.5.0
* http://amsul.github.io/pickadate.js/date.htm
*/
(function (factory) {
factory(materialize.picker, jquery);
})(function (picker, $) {
/**
* globals and constants
*/
var days_in_week = 7,
weeks_in_calendar = 6,
_ = picker._;
/**
* the date picker constructor
*/
function datepicker(picker, settings) {
var calendar = this,
element = picker.$node[0],
elementvalue = element.value,
elementdatavalue = picker.$node.data('value'),
valuestring = elementdatavalue || elementvalue,
formatstring = elementdatavalue ? settings.formatsubmit : settings.format,
isrtl = function () {
return element.currentstyle ?
// for ie.
element.currentstyle.direction == 'rtl' :
// for normal browsers.
getcomputedstyle(picker.$root[0]).direction == 'rtl';
};
calendar.settings = settings;
calendar.$node = picker.$node;
// the queue of methods that will be used to build item objects.
calendar.queue = {
min: 'measure create',
max: 'measure create',
now: 'now create',
select: 'parse create validate',
highlight: 'parse navigate create validate',
view: 'parse create validate viewset',
disable: 'deactivate',
enable: 'activate'
// the component's item object.
};calendar.item = {};
calendar.item.clear = null;
calendar.item.disable = (settings.disable || []).slice(0);
calendar.item.enable = -function (collectiondisabled) {
return collectiondisabled[0] === true ? collectiondisabled.shift() : -1;
}(calendar.item.disable);
calendar.set('min', settings.min).set('max', settings.max).set('now');
// when there’s a value, set the `select`, which in turn
// also sets the `highlight` and `view`.
if (valuestring) {
calendar.set('select', valuestring, { format: formatstring });
}
// if there’s no value, default to highlighting “today”.
else {
calendar.set('select', null).set('highlight', calendar.item.now);
}
// the keycode to movement mapping.
calendar.key = {
40: 7, // down
38: -7, // up
39: function () {
return isrtl() ? -1 : 1;
}, // right
37: function () {
return isrtl() ? 1 : -1;
}, // left
go: function (timechange) {
var highlightedobject = calendar.item.highlight,
targetdate = new date(highlightedobject.year, highlightedobject.month, highlightedobject.date + timechange);
calendar.set('highlight', targetdate, { interval: timechange });
this.render();
}
// bind some picker events.
};picker.on('render', function () {
picker.$root.find('.' + settings.klass.selectmonth).on('change', function () {
var value = this.value;
if (value) {
picker.set('highlight', [picker.get('view').year, value, picker.get('highlight').date]);
picker.$root.find('.' + settings.klass.selectmonth).trigger('focus');
}
});
picker.$root.find('.' + settings.klass.selectyear).on('change', function () {
var value = this.value;
if (value) {
picker.set('highlight', [value, picker.get('view').month, picker.get('highlight').date]);
picker.$root.find('.' + settings.klass.selectyear).trigger('focus');
}
});
}, 1).on('open', function () {
var includetoday = '';
if (calendar.disabled(calendar.get('now'))) {
includetoday = ':not(.' + settings.klass.buttontoday + ')';
}
picker.$root.find('button' + includetoday + ', select').attr('disabled', false);
}, 1).on('close', function () {
picker.$root.find('button, select').attr('disabled', true);
}, 1);
} //datepicker
/**
* set a datepicker item object.
*/
datepicker.prototype.set = function (type, value, options) {
var calendar = this,
calendaritem = calendar.item;
// if the value is `null` just set it immediately.
if (value === null) {
if (type == 'clear') type = 'select';
calendaritem[type] = value;
return calendar;
}
// otherwise go through the queue of methods, and invoke the functions.
// update this as the time unit, and set the final value as this item.
// * in the case of `enable`, keep the queue but set `disable` instead.
// and in the case of `flip`, keep the queue but set `enable` instead.
calendaritem[type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type] = calendar.queue[type].split(' ').map(function (method) {
value = calendar[method](type, value, options);
return value;
}).pop();
// check if we need to cascade through more updates.
if (type == 'select') {
calendar.set('highlight', calendaritem.select, options);
} else if (type == 'highlight') {
calendar.set('view', calendaritem.highlight, options);
} else if (type.match(/^(flip|min|max|disable|enable)$/)) {
if (calendaritem.select && calendar.disabled(calendaritem.select)) {
calendar.set('select', calendaritem.select, options);
}
if (calendaritem.highlight && calendar.disabled(calendaritem.highlight)) {
calendar.set('highlight', calendaritem.highlight, options);
}
}
return calendar;
}; //datepicker.prototype.set
/**
* get a datepicker item object.
*/
datepicker.prototype.get = function (type) {
return this.item[type];
}; //datepicker.prototype.get
/**
* create a picker date object.
*/
datepicker.prototype.create = function (type, value, options) {
var isinfinitevalue,
calendar = this;
// if there’s no value, use the type as the value.
value = value === undefined ? type : value;
// if it’s infinity, update the value.
if (value == -infinity || value == infinity) {
isinfinitevalue = value;
}
// if it’s an object, use the native date object.
else if ($.isplainobject(value) && _.isinteger(value.pick)) {
value = value.obj;
}
// if it’s an array, convert it into a date and make sure
// that it’s a valid date – otherwise default to today.
else if ($.isarray(value)) {
value = new date(value[0], value[1], value[2]);
value = _.isdate(value) ? value : calendar.create().obj;
}
// if it’s a number or date object, make a normalized date.
else if (_.isinteger(value) || _.isdate(value)) {
value = calendar.normalize(new date(value), options);
}
// if it’s a literal true or any other case, set it to now.
else /*if ( value === true )*/{
value = calendar.now(type, value, options);
}
// return the compiled object.
return {
year: isinfinitevalue || value.getfullyear(),
month: isinfinitevalue || value.getmonth(),
date: isinfinitevalue || value.getdate(),
day: isinfinitevalue || value.getday(),
obj: isinfinitevalue || value,
pick: isinfinitevalue || value.gettime()
};
}; //datepicker.prototype.create
/**
* create a range limit object using an array, date object,
* literal “true”, or integer relative to another time.
*/
datepicker.prototype.createrange = function (from, to) {
var calendar = this,
createdate = function (date) {
if (date === true || $.isarray(date) || _.isdate(date)) {
return calendar.create(date);
}
return date;
};
// create objects if possible.
if (!_.isinteger(from)) {
from = createdate(from);
}
if (!_.isinteger(to)) {
to = createdate(to);
}
// create relative dates.
if (_.isinteger(from) && $.isplainobject(to)) {
from = [to.year, to.month, to.date + from];
} else if (_.isinteger(to) && $.isplainobject(from)) {
to = [from.year, from.month, from.date + to];
}
return {
from: createdate(from),
to: createdate(to)
};
}; //datepicker.prototype.createrange
/**
* check if a date unit falls within a date range object.
*/
datepicker.prototype.withinrange = function (range, dateunit) {
range = this.createrange(range.from, range.to);
return dateunit.pick >= range.from.pick && dateunit.pick <= range.to.pick;
};
/**
* check if two date range objects overlap.
*/
datepicker.prototype.overlapranges = function (one, two) {
var calendar = this;
// convert the ranges into comparable dates.
one = calendar.createrange(one.from, one.to);
two = calendar.createrange(two.from, two.to);
return calendar.withinrange(one, two.from) || calendar.withinrange(one, two.to) || calendar.withinrange(two, one.from) || calendar.withinrange(two, one.to);
};
/**
* get the date today.
*/
datepicker.prototype.now = function (type, value, options) {
value = new date();
if (options && options.rel) {
value.setdate(value.getdate() + options.rel);
}
return this.normalize(value, options);
};
/**
* navigate to next/prev month.
*/
datepicker.prototype.navigate = function (type, value, options) {
var targetdateobject,
targetyear,
targetmonth,
targetdate,
istargetarray = $.isarray(value),
istargetobject = $.isplainobject(value),
viewsetobject = this.item.view; /*,
safety = 100*/
if (istargetarray || istargetobject) {
if (istargetobject) {
targetyear = value.year;
targetmonth = value.month;
targetdate = value.date;
} else {
targetyear = +value[0];
targetmonth = +value[1];
targetdate = +value[2];
}
// if we’re navigating months but the view is in a different
// month, navigate to the view’s year and month.
if (options && options.nav && viewsetobject && viewsetobject.month !== targetmonth) {
targetyear = viewsetobject.year;
targetmonth = viewsetobject.month;
}
// figure out the expected target year and month.
targetdateobject = new date(targetyear, targetmonth + (options && options.nav ? options.nav : 0), 1);
targetyear = targetdateobject.getfullyear();
targetmonth = targetdateobject.getmonth();
// if the month we’re going to doesn’t have enough days,
// keep decreasing the date until we reach the month’s last date.
while ( /*safety &&*/new date(targetyear, targetmonth, targetdate).getmonth() !== targetmonth) {
targetdate -= 1;
/*safety -= 1
if ( !safety ) {
throw 'fell into an infinite loop while navigating to ' + new date( targetyear, targetmonth, targetdate ) + '.'
}*/
}
value = [targetyear, targetmonth, targetdate];
}
return value;
}; //datepicker.prototype.navigate
/**
* normalize a date by setting the hours to midnight.
*/
datepicker.prototype.normalize = function (value /*, options*/) {
value.sethours(0, 0, 0, 0);
return value;
};
/**
* measure the range of dates.
*/
datepicker.prototype.measure = function (type, value /*, options*/) {
var calendar = this;
// if it’s anything false-y, remove the limits.
if (!value) {
value = type == 'min' ? -infinity : infinity;
}
// if it’s a string, parse it.
else if (typeof value == 'string') {
value = calendar.parse(type, value);
}
// if it's an integer, get a date relative to today.
else if (_.isinteger(value)) {
value = calendar.now(type, value, { rel: value });
}
return value;
}; ///datepicker.prototype.measure
/**
* create a viewset object based on navigation.
*/
datepicker.prototype.viewset = function (type, dateobject /*, options*/) {
return this.create([dateobject.year, dateobject.month, 1]);
};
/**
* validate a date as enabled and shift if needed.
*/
datepicker.prototype.validate = function (type, dateobject, options) {
var calendar = this,
// keep a reference to the original date.
originaldateobject = dateobject,
// make sure we have an interval.
interval = options && options.interval ? options.interval : 1,
// check if the calendar enabled dates are inverted.
isflippedbase = calendar.item.enable === -1,
// check if we have any enabled dates after/before now.
hasenabledbeforetarget,
hasenabledaftertarget,
// the min & max limits.
minlimitobject = calendar.item.min,
maxlimitobject = calendar.item.max,
// check if we’ve reached the limit during shifting.
reachedmin,
reachedmax,
// check if the calendar is inverted and at least one weekday is enabled.
hasenabledweekdays = isflippedbase && calendar.item.disable.filter(function (value) {
// if there’s a date, check where it is relative to the target.
if ($.isarray(value)) {
var datetime = calendar.create(value).pick;
if (datetime < dateobject.pick) hasenabledbeforetarget = true;else if (datetime > dateobject.pick) hasenabledaftertarget = true;
}
// return only integers for enabled weekdays.
return _.isinteger(value);
}).length; /*,
safety = 100*/
// cases to validate for:
// [1] not inverted and date disabled.
// [2] inverted and some dates enabled.
// [3] not inverted and out of range.
//
// cases to **not** validate for:
// • navigating months.
// • not inverted and date enabled.
// • inverted and all dates disabled.
// • ..and anything else.
if (!options || !options.nav) if (
/* 1 */!isflippedbase && calendar.disabled(dateobject) ||
/* 2 */isflippedbase && calendar.disabled(dateobject) && (hasenabledweekdays || hasenabledbeforetarget || hasenabledaftertarget) ||
/* 3 */!isflippedbase && (dateobject.pick <= minlimitobject.pick || dateobject.pick >= maxlimitobject.pick)) {
// when inverted, flip the direction if there aren’t any enabled weekdays
// and there are no enabled dates in the direction of the interval.
if (isflippedbase && !hasenabledweekdays && (!hasenabledaftertarget && interval > 0 || !hasenabledbeforetarget && interval < 0)) {
interval *= -1;
}
// keep looping until we reach an enabled date.
while ( /*safety &&*/calendar.disabled(dateobject)) {
/*safety -= 1
if ( !safety ) {
throw 'fell into an infinite loop while validating ' + dateobject.obj + '.'
}*/
// if we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
if (math.abs(interval) > 1 && (dateobject.month < originaldateobject.month || dateobject.month > originaldateobject.month)) {
dateobject = originaldateobject;
interval = interval > 0 ? 1 : -1;
}
// if we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
if (dateobject.pick <= minlimitobject.pick) {
reachedmin = true;
interval = 1;
dateobject = calendar.create([minlimitobject.year, minlimitobject.month, minlimitobject.date + (dateobject.pick === minlimitobject.pick ? 0 : -1)]);
} else if (dateobject.pick >= maxlimitobject.pick) {
reachedmax = true;
interval = -1;
dateobject = calendar.create([maxlimitobject.year, maxlimitobject.month, maxlimitobject.date + (dateobject.pick === maxlimitobject.pick ? 0 : 1)]);
}
// if we’ve reached both limits, just break out of the loop.
if (reachedmin && reachedmax) {
break;
}
// finally, create the shifted date using the interval and keep looping.
dateobject = calendar.create([dateobject.year, dateobject.month, dateobject.date + interval]);
}
} //endif
// return the date object settled on.
return dateobject;
}; //datepicker.prototype.validate
/**
* check if a date is disabled.
*/
datepicker.prototype.disabled = function (datetoverify) {
var calendar = this,
// filter through the disabled dates to check if this is one.
isdisabledmatch = calendar.item.disable.filter(function (datetodisable) {
// if the date is a number, match the weekday with 0index and `firstday` check.
if (_.isinteger(datetodisable)) {
return datetoverify.day === (calendar.settings.firstday ? datetodisable : datetodisable - 1) % 7;
}
// if it’s an array or a native js date, create and match the exact date.
if ($.isarray(datetodisable) || _.isdate(datetodisable)) {
return datetoverify.pick === calendar.create(datetodisable).pick;
}
// if it’s an object, match a date within the “from” and “to” range.
if ($.isplainobject(datetodisable)) {
return calendar.withinrange(datetodisable, datetoverify);
}
});
// if this date matches a disabled date, confirm it’s not inverted.
isdisabledmatch = isdisabledmatch.length && !isdisabledmatch.filter(function (datetodisable) {
return $.isarray(datetodisable) && datetodisable[3] == 'inverted' || $.isplainobject(datetodisable) && datetodisable.inverted;
}).length;
// check the calendar “enabled” flag and respectively flip the
// disabled state. then also check if it’s beyond the min/max limits.
return calendar.item.enable === -1 ? !isdisabledmatch : isdisabledmatch || datetoverify.pick < calendar.item.min.pick || datetoverify.pick > calendar.item.max.pick;
}; //datepicker.prototype.disabled
/**
* parse a string into a usable type.
*/
datepicker.prototype.parse = function (type, value, options) {
var calendar = this,
parsingobject = {};
// if it’s already parsed, we’re good.
if (!value || typeof value != 'string') {
return value;
}
// we need a `.format` to parse the value with.
if (!(options && options.format)) {
options = options || {};
options.format = calendar.settings.format;
}
// convert the format into an array and then map through it.
calendar.formats.toarray(options.format).map(function (label) {
var
// grab the formatting label.
formattinglabel = calendar.formats[label],
// the format length is from the formatting label function or the
// label length without the escaping exclamation (!) mark.
formatlength = formattinglabel ? _.trigger(formattinglabel, calendar, [value, parsingobject]) : label.replace(/^!/, '').length;
// if there's a format label, split the value up to the format length.
// then add it to the parsing object with appropriate label.
if (formattinglabel) {
parsingobject[label] = value.substr(0, formatlength);
}
// update the value as the substring from format length to end.
value = value.substr(formatlength);
});
// compensate for month 0index.
return [parsingobject.yyyy || parsingobject.yy, +(parsingobject.mm || parsingobject.m) - 1, parsingobject.dd || parsingobject.d];
}; //datepicker.prototype.parse
/**
* various formats to display the object in.
*/
datepicker.prototype.formats = function () {
// return the length of the first word in a collection.
function getwordlengthfromcollection(string, collection, dateobject) {
// grab the first word from the string.
var word = string.match(/\w+/)[0];
// if there's no month index, add it to the date object
if (!dateobject.mm && !dateobject.m) {
dateobject.m = collection.indexof(word) + 1;
}
// return the length of the word.
return word.length;
}
// get the length of the first word in a string.
function getfirstwordlength(string) {
return string.match(/\w+/)[0].length;
}
return {
d: function (string, dateobject) {
// if there's string, then get the digits length.
// otherwise return the selected date.
return string ? _.digits(string) : dateobject.date;
},
dd: function (string, dateobject) {
// if there's a string, then the length is always 2.
// otherwise return the selected date with a leading zero.
return string ? 2 : _.lead(dateobject.date);
},
ddd: function (string, dateobject) {
// if there's a string, then get the length of the first word.
// otherwise return the short selected weekday.
return string ? getfirstwordlength(string) : this.settings.weekdaysshort[dateobject.day];
},
dddd: function (string, dateobject) {
// if there's a string, then get the length of the first word.
// otherwise return the full selected weekday.
return string ? getfirstwordlength(string) : this.settings.weekdaysfull[dateobject.day];
},
m: function (string, dateobject) {
// if there's a string, then get the length of the digits
// otherwise return the selected month with 0index compensation.
return string ? _.digits(string) : dateobject.month + 1;
},
mm: function (string, dateobject) {
// if there's a string, then the length is always 2.
// otherwise return the selected month with 0index and leading zero.
return string ? 2 : _.lead(dateobject.month + 1);
},
mmm: function (string, dateobject) {
var collection = this.settings.monthsshort;
// if there's a string, get length of the relevant month from the short
// months collection. otherwise return the selected month from that collection.
return string ? getwordlengthfromcollection(string, collection, dateobject) : collection[dateobject.month];
},
mmmm: function (string, dateobject) {
var collection = this.settings.monthsfull;
// if there's a string, get length of the relevant month from the full
// months collection. otherwise return the selected month from that collection.
return string ? getwordlengthfromcollection(string, collection, dateobject) : collection[dateobject.month];
},
yy: function (string, dateobject) {
// if there's a string, then the length is always 2.
// otherwise return the selected year by slicing out the first 2 digits.
return string ? 2 : ('' + dateobject.year).slice(2);
},
yyyy: function (string, dateobject) {
// if there's a string, then the length is always 4.
// otherwise return the selected year.
return string ? 4 : dateobject.year;
},
// create an array by splitting the formatting string passed.
toarray: function (formatstring) {
return formatstring.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g);
},
// format an object into a string using the formatting options.
tostring: function (formatstring, itemobject) {
var calendar = this;
return calendar.formats.toarray(formatstring).map(function (label) {
return _.trigger(calendar.formats[label], calendar, [0, itemobject]) || label.replace(/^!/, '');
}).join('');
}
};
}(); //datepicker.prototype.formats
/**
* check if two date units are the exact.
*/
datepicker.prototype.isdateexact = function (one, two) {
var calendar = this;
// when we’re working with weekdays, do a direct comparison.
if (_.isinteger(one) && _.isinteger(two) || typeof one == 'boolean' && typeof two == 'boolean') {
return one === two;
}
// when we’re working with date representations, compare the “pick” value.
if ((_.isdate(one) || $.isarray(one)) && (_.isdate(two) || $.isarray(two))) {
return calendar.create(one).pick === calendar.create(two).pick;
}
// when we’re working with range objects, compare the “from” and “to”.
if ($.isplainobject(one) && $.isplainobject(two)) {
return calendar.isdateexact(one.from, two.from) && calendar.isdateexact(one.to, two.to);
}
return false;
};
/**
* check if two date units overlap.
*/
datepicker.prototype.isdateoverlap = function (one, two) {
var calendar = this,
firstday = calendar.settings.firstday ? 1 : 0;
// when we’re working with a weekday index, compare the days.
if (_.isinteger(one) && (_.isdate(two) || $.isarray(two))) {
one = one % 7 + firstday;
return one === calendar.create(two).day + 1;
}
if (_.isinteger(two) && (_.isdate(one) || $.isarray(one))) {
two = two % 7 + firstday;
return two === calendar.create(one).day + 1;
}
// when we’re working with range objects, check if the ranges overlap.
if ($.isplainobject(one) && $.isplainobject(two)) {
return calendar.overlapranges(one, two);
}
return false;
};
/**
* flip the “enabled” state.
*/
datepicker.prototype.flipenable = function (val) {
var itemobject = this.item;
itemobject.enable = val || (itemobject.enable == -1 ? 1 : -1);
};
/**
* mark a collection of dates as “disabled”.
*/
datepicker.prototype.deactivate = function (type, datestodisable) {
var calendar = this,
disableditems = calendar.item.disable.slice(0);
// if we’re flipping, that’s all we need to do.
if (datestodisable == 'flip') {
calendar.flipenable();
} else if (datestodisable === false) {
calendar.flipenable(1);
disableditems = [];
} else if (datestodisable === true) {
calendar.flipenable(-1);
disableditems = [];
}
// otherwise go through the dates to disable.
else {
datestodisable.map(function (unittodisable) {
var matchfound;
// when we have disabled items, check for matches.
// if something is matched, immediately break out.
for (var index = 0; index < disableditems.length; index += 1) {
if (calendar.isdateexact(unittodisable, disableditems[index])) {
matchfound = true;
break;
}
}
// if nothing was found, add the validated unit to the collection.
if (!matchfound) {
if (_.isinteger(unittodisable) || _.isdate(unittodisable) || $.isarray(unittodisable) || $.isplainobject(unittodisable) && unittodisable.from && unittodisable.to) {
disableditems.push(unittodisable);
}
}
});
}
// return the updated collection.
return disableditems;
}; //datepicker.prototype.deactivate
/**
* mark a collection of dates as “enabled”.
*/
datepicker.prototype.activate = function (type, datestoenable) {
var calendar = this,
disableditems = calendar.item.disable,
disableditemscount = disableditems.length;
// if we’re flipping, that’s all we need to do.
if (datestoenable == 'flip') {
calendar.flipenable();
} else if (datestoenable === true) {
calendar.flipenable(1);
disableditems = [];
} else if (datestoenable === false) {
calendar.flipenable(-1);
disableditems = [];
}
// otherwise go through the disabled dates.
else {
datestoenable.map(function (unittoenable) {
var matchfound, disabledunit, index, isexactrange;
// go through the disabled items and try to find a match.
for (index = 0; index < disableditemscount; index += 1) {
disabledunit = disableditems[index];
// when an exact match is found, remove it from the collection.
if (calendar.isdateexact(disabledunit, unittoenable)) {
matchfound = disableditems[index] = null;
isexactrange = true;
break;
}
// when an overlapped match is found, add the “inverted” state to it.
else if (calendar.isdateoverlap(disabledunit, unittoenable)) {
if ($.isplainobject(unittoenable)) {
unittoenable.inverted = true;
matchfound = unittoenable;
} else if ($.isarray(unittoenable)) {
matchfound = unittoenable;
if (!matchfound[3]) matchfound.push('inverted');
} else if (_.isdate(unittoenable)) {
matchfound = [unittoenable.getfullyear(), unittoenable.getmonth(), unittoenable.getdate(), 'inverted'];
}
break;
}
}
// if a match was found, remove a previous duplicate entry.
if (matchfound) for (index = 0; index < disableditemscount; index += 1) {
if (calendar.isdateexact(disableditems[index], unittoenable)) {
disableditems[index] = null;
break;
}
}
// in the event that we’re dealing with an exact range of dates,
// make sure there are no “inverted” dates because of it.
if (isexactrange) for (index = 0; index < disableditemscount; index += 1) {
if (calendar.isdateoverlap(disableditems[index], unittoenable)) {
disableditems[index] = null;
break;
}
}
// if something is still matched, add it into the collection.
if (matchfound) {
disableditems.push(matchfound);
}
});
}
// return the updated collection.
return disableditems.filter(function (val) {
return val != null;
});
}; //datepicker.prototype.activate
/**
* create a string for the nodes in the picker.
*/
datepicker.prototype.nodes = function (isopen) {
var calendar = this,
settings = calendar.settings,
calendaritem = calendar.item,
nowobject = calendaritem.now,
selectedobject = calendaritem.select,
highlightedobject = calendaritem.highlight,
viewsetobject = calendaritem.view,
disabledcollection = calendaritem.disable,
minlimitobject = calendaritem.min,
maxlimitobject = calendaritem.max,
// create the calendar table head using a copy of weekday labels collection.
// * we do a copy so we don't mutate the original array.
tablehead = function (collection, fullcollection) {
// if the first day should be monday, move sunday to the end.
if (settings.firstday) {
collection.push(collection.shift());
fullcollection.push(fullcollection.shift());
}
// create and return the table head group.
return _.node('thead', _.node('tr', _.group({
min: 0,
max: days_in_week - 1,
i: 1,
node: 'th',
item: function (counter) {
return [collection[counter], settings.klass.weekdays, 'scope=col title="' + fullcollection[counter] + '"'];
}
}))); //endreturn
// materialize modified
}((settings.showweekdaysfull ? settings.weekdaysfull : settings.weekdaysletter).slice(0), settings.weekdaysfull.slice(0)),
//tablehead
// create the nav for next/prev month.
createmonthnav = function (next) {
// otherwise, return the created month tag.
return _.node('div', ' ', settings.klass['nav' + (next ? 'next' : 'prev')] + (
// if the focused month is outside the range, disabled the button.
next && viewsetobject.year >= maxlimitobject.year && viewsetobject.month >= maxlimitobject.month || !next && viewsetobject.year <= minlimitobject.year && viewsetobject.month <= minlimitobject.month ? ' ' + settings.klass.navdisabled : ''), 'data-nav=' + (next || -1) + ' ' + _.ariaattr({
role: 'button',
controls: calendar.$node[0].id + '_table'
}) + ' ' + 'title="' + (next ? settings.labelmonthnext : settings.labelmonthprev) + '"'); //endreturn
},
//createmonthnav
// create the month label.
//materialize modified
createmonthlabel = function (override) {
var monthscollection = settings.showmonthsshort ? settings.monthsshort : settings.monthsfull;
// materialize modified
if (override == "short_months") {
monthscollection = settings.monthsshort;
}
// if there are months to select, add a dropdown menu.
if (settings.selectmonths && override == undefined) {
return _.node('select', _.group({
min: 0,
max: 11,
i: 1,
node: 'option',
item: function (loopedmonth) {
return [
// the looped month and no classes.
monthscollection[loopedmonth], 0,
// set the value and selected index.
'value=' + loopedmonth + (viewsetobject.month == loopedmonth ? ' selected' : '') + (viewsetobject.year == minlimitobject.year && loopedmonth < minlimitobject.month || viewsetobject.year == maxlimitobject.year && loopedmonth > maxlimitobject.month ? ' disabled' : '')];
}
}), settings.klass.selectmonth + ' browser-default', (isopen ? '' : 'disabled') + ' ' + _.ariaattr({ controls: calendar.$node[0].id + '_table' }) + ' ' + 'title="' + settings.labelmonthselect + '"');
}
// materialize modified
if (override == "short_months") if (selectedobject != null) return monthscollection[selectedobject.month];else return monthscollection[viewsetobject.month];
// if there's a need for a month selector
return _.node('div', monthscollection[viewsetobject.month], settings.klass.month);
},
//createmonthlabel
// create the year label.
// materialize modified
createyearlabel = function (override) {
var focusedyear = viewsetobject.year,
// if years selector is set to a literal "true", set it to 5. otherwise
// divide in half to get half before and half after focused year.
numberyears = settings.selectyears === true ? 5 : ~~(settings.selectyears / 2);
// if there are years to select, add a dropdown menu.
if (numberyears) {
var minyear = minlimitobject.year,
maxyear = maxlimitobject.year,
lowestyear = focusedyear - numberyears,
highestyear = focusedyear + numberyears;
// if the min year is greater than the lowest year, increase the highest year
// by the difference and set the lowest year to the min year.
if (minyear > lowestyear) {
highestyear += minyear - lowestyear;
lowestyear = minyear;
}
// if the max year is less than the highest year, decrease the lowest year
// by the lower of the two: available and needed years. then set the
// highest year to the max year.
if (maxyear < highestyear) {
var availableyears = lowestyear - minyear,
neededyears = highestyear - maxyear;
lowestyear -= availableyears > neededyears ? neededyears : availableyears;
highestyear = maxyear;
}
if (settings.selectyears && override == undefined) {
return _.node('select', _.group({
min: lowestyear,
max: highestyear,
i: 1,
node: 'option',
item: function (loopedyear) {
return [
// the looped year and no classes.
loopedyear, 0,
// set the value and selected index.
'value=' + loopedyear + (focusedyear == loopedyear ? ' selected' : '')];
}
}), settings.klass.selectyear + ' browser-default', (isopen ? '' : 'disabled') + ' ' + _.ariaattr({ controls: calendar.$node[0].id + '_table' }) + ' ' + 'title="' + settings.labelyearselect + '"');
}
}
// materialize modified
if (override === 'raw' && selectedobject != null) {
return _.node('div', selectedobject.year);
}
// otherwise just return the year focused
return _.node('div', focusedyear, settings.klass.year);
}; //createyearlabel
// materialize modified
createdaylabel = function () {
if (selectedobject != null) return selectedobject.date;else return nowobject.date;
};
createweekdaylabel = function () {
var display_day;
if (selectedobject != null) display_day = selectedobject.day;else display_day = nowobject.day;
var weekday = settings.weekdaysshort[display_day];
return weekday;
};
// create and return the entire calendar.
return _.node(
// date presentation view
'div', _.node(
// div for year
'div', createyearlabel("raw"), settings.klass.year_display) + _.node('span', createweekdaylabel() + ', ', "picker__weekday-display") + _.node(
// div for short month
'span', createmonthlabel("short_months") + ' ', settings.klass.month_display) + _.node(
// div for day
'span', createdaylabel(), settings.klass.day_display), settings.klass.date_display) +
// calendar container
_.node('div', _.node('div', _.node('div', (settings.selectyears ? createmonthlabel() + createyearlabel() : createmonthlabel() + createyearlabel()) + createmonthnav() + createmonthnav(1), settings.klass.header) + _.node('table', tablehead + _.node('tbody', _.group({
min: 0,
max: weeks_in_calendar - 1,
i: 1,
node: 'tr',
item: function (rowcounter) {
// if monday is the first day and the month starts on sunday, shift the date back a week.
var shiftdateby = settings.firstday && calendar.create([viewsetobject.year, viewsetobject.month, 1]).day === 0 ? -7 : 0;
return [_.group({
min: days_in_week * rowcounter - viewsetobject.day + shiftdateby + 1, // add 1 for weekday 0index
max: function () {
return this.min + days_in_week - 1;
},
i: 1,
node: 'td',
item: function (targetdate) {
// convert the time date from a relative date to a target date.
targetdate = calendar.create([viewsetobject.year, viewsetobject.month, targetdate + (settings.firstday ? 1 : 0)]);
var isselected = selectedobject && selectedobject.pick == targetdate.pick,
ishighlighted = highlightedobject && highlightedobject.pick == targetdate.pick,
isdisabled = disabledcollection && calendar.disabled(targetdate) || targetdate.pick < minlimitobject.pick || targetdate.pick > maxlimitobject.pick,
formatteddate = _.trigger(calendar.formats.tostring, calendar, [settings.format, targetdate]);
return [_.node('div', targetdate.date, function (klasses) {
// add the `infocus` or `outfocus` classes based on month in view.
klasses.push(viewsetobject.month == targetdate.month ? settings.klass.infocus : settings.klass.outfocus);
// add the `today` class if needed.
if (nowobject.pick == targetdate.pick) {
klasses.push(settings.klass.now);
}
// add the `selected` class if something's selected and the time matches.
if (isselected) {
klasses.push(settings.klass.selected);
}
// add the `highlighted` class if something's highlighted and the time matches.
if (ishighlighted) {
klasses.push(settings.klass.highlighted);
}
// add the `disabled` class if something's disabled and the object matches.
if (isdisabled) {
klasses.push(settings.klass.disabled);
}
return klasses.join(' ');
}([settings.klass.day]), 'data-pick=' + targetdate.pick + ' ' + _.ariaattr({
role: 'gridcell',
label: formatteddate,
selected: isselected && calendar.$node.val() === formatteddate ? true : null,
activedescendant: ishighlighted ? true : null,
disabled: isdisabled ? true : null
}) + ' ' + (isdisabled ? '' : 'tabindex="0"')), '', _.ariaattr({ role: 'presentation' })]; //endreturn
}
})]; //endreturn
}
})), settings.klass.table, 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaattr({
role: 'grid',
controls: calendar.$node[0].id,
readonly: true
})), settings.klass.calendar_container) // end calendar
+
// * for firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
_.node('div', _.node('button', settings.today, "btn-flat picker__today waves-effect", 'type=button data-pick=' + nowobject.pick + (isopen && !calendar.disabled(nowobject) ? '' : ' disabled') + ' ' + _.ariaattr({ controls: calendar.$node[0].id })) + _.node('button', settings.clear, "btn-flat picker__clear waves-effect", 'type=button data-clear=1' + (isopen ? '' : ' disabled') + ' ' + _.ariaattr({ controls: calendar.$node[0].id })) + _.node('button', settings.close, "btn-flat picker__close waves-effect", 'type=button data-close=true ' + (isopen ? '' : ' disabled') + ' ' + _.ariaattr({ controls: calendar.$node[0].id })), settings.klass.footer), 'picker__container__wrapper'); //endreturn
}; //datepicker.prototype.nodes
/**
* the date picker defaults.
*/
datepicker.defaults = function (prefix) {
return {
// the title label to use for the month nav buttons
labelmonthnext: 'next month',
labelmonthprev: 'previous month',
// the title label to use for the dropdown selectors
labelmonthselect: 'select a month',
labelyearselect: 'select a year',
// months and weekdays
monthsfull: ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
monthsshort: ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],
weekdaysfull: ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'],
weekdaysshort: ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
// materialize modified
weekdaysletter: ['s', 'm', 't', 'w', 't', 'f', 's'],
// today and clear
today: 'today',
clear: 'clear',
close: 'ok',
// picker close behavior (prevent a change in behaviour for backwards compatibility)
closeonselect: false,
// the format to show on the `input` element
format: 'd mmmm, yyyy',
// classes
klass: {
table: prefix + 'table',
header: prefix + 'header',
// materialize added klasses
date_display: prefix + 'date-display',
day_display: prefix + 'day-display',
month_display: prefix + 'month-display',
year_display: prefix + 'year-display',
calendar_container: prefix + 'calendar-container',
// end
navprev: prefix + 'nav--prev',
navnext: prefix + 'nav--next',
navdisabled: prefix + 'nav--disabled',
month: prefix + 'month',
year: prefix + 'year',
selectmonth: prefix + 'select--month',
selectyear: prefix + 'select--year',
weekdays: prefix + 'weekday',
day: prefix + 'day',
disabled: prefix + 'day--disabled',
selected: prefix + 'day--selected',
highlighted: prefix + 'day--highlighted',
now: prefix + 'day--today',
infocus: prefix + 'day--infocus',
outfocus: prefix + 'day--outfocus',
footer: prefix + 'footer',
buttonclear: prefix + 'button--clear',
buttontoday: prefix + 'button--today',
buttonclose: prefix + 'button--close'
}
};
}(picker.klasses().picker + '__');
/**
* extend the picker to add the date picker.
*/
picker.extend('pickadate', datepicker);
});
; /*!
* clockpicker v0.0.7 (http://weareoutman.github.io/clockpicker/)
* copyright 2014 wang shenwei.
* licensed under mit (https://github.com/weareoutman/clockpicker/blob/gh-pages/license)
*
* further modified
* copyright 2015 ching yaw hao.
*/
(function ($) {
var $win = $(window),
$doc = $(document);
// can i use inline svg ?
var svgns = 'http://www.w3.org/2000/svg',
svgsupported = 'svgangle' in window && function () {
var supported,
el = document.createelement('div');
el.innerhtml = '';
supported = (el.firstchild && el.firstchild.namespaceuri) == svgns;
el.innerhtml = '';
return supported;
}();
// can i use transition ?
var transitionsupported = function () {
var style = document.createelement('div').style;
return 'transition' in style || 'webkittransition' in style || 'moztransition' in style || 'mstransition' in style || 'otransition' in style;
}();
// listen touch events in touch screen device, instead of mouse events in desktop.
var touchsupported = 'ontouchstart' in window,
mousedownevent = 'mousedown' + (touchsupported ? ' touchstart' : ''),
mousemoveevent = 'mousemove.clockpicker' + (touchsupported ? ' touchmove.clockpicker' : ''),
mouseupevent = 'mouseup.clockpicker' + (touchsupported ? ' touchend.clockpicker' : '');
// vibrate the device if supported
var vibrate = navigator.vibrate ? 'vibrate' : navigator.webkitvibrate ? 'webkitvibrate' : null;
function createsvgelement(name) {
return document.createelementns(svgns, name);
}
function leadingzero(num) {
return (num < 10 ? '0' : '') + num;
}
// get a unique id
var idcounter = 0;
function uniqueid(prefix) {
var id = ++idcounter + '';
return prefix ? prefix + id : id;
}
// clock size
var dialradius = 135,
outerradius = 105,
// innerradius = 80 on 12 hour clock
innerradius = 70,
tickradius = 20,
diameter = dialradius * 2,
duration = transitionsupported ? 350 : 1;
// popover template
var tpl = ['