Archive: Namaste PHP AMQP framework v1.0 (2017-2020)
952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
This commit is contained in:
10
html/js/modules (optional)/animations.js
Normal file
10
html/js/modules (optional)/animations.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// Animations
|
||||
|
||||
$(function() {
|
||||
$('.arrow-r').on('click', function() {
|
||||
//Reset all but the current
|
||||
$('.arrow-r').not(this).find('.fa-angle-down').removeClass('rotate-element');
|
||||
//Rotate/reset the clicked one
|
||||
$(this).find('.fa-angle-down').toggleClass('rotate-element');
|
||||
})
|
||||
})
|
||||
82
html/js/modules (optional)/autocomplete.js
Normal file
82
html/js/modules (optional)/autocomplete.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Material Design for Bootstrap
|
||||
* MDB Autocomplete Plugin
|
||||
*/
|
||||
|
||||
$.fn.mdb_autocomplete = function (options) {
|
||||
|
||||
// Default options
|
||||
var defaults = {
|
||||
data: {}
|
||||
};
|
||||
|
||||
// Get options
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
// text input
|
||||
var $input = $(this);
|
||||
|
||||
// assign data from options
|
||||
var data = options.data;
|
||||
|
||||
if (Object.keys(data).length) {
|
||||
|
||||
var $autocomplete = $('<ul class="mdb-autocomplete-wrap"></ul>');
|
||||
|
||||
$autocomplete.insertAfter($(this));
|
||||
};
|
||||
|
||||
// Listen if key was pressed
|
||||
$input.on('keyup', function (e) {
|
||||
|
||||
// get value from input
|
||||
var q = $input.val();
|
||||
|
||||
$autocomplete.empty();
|
||||
|
||||
// check if input isn't empty
|
||||
if (q.length) {
|
||||
|
||||
for (var item in data) {
|
||||
|
||||
// check if item contains value that we're looking for
|
||||
if (data[item].toLowerCase().indexOf(q.toLowerCase()) !== -1) {
|
||||
var option = $('<li>' + data[item] + '</li>');
|
||||
|
||||
$autocomplete.append(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e.which == 13) {
|
||||
$autocomplete.children(":first").trigger('click');
|
||||
$autocomplete.empty();
|
||||
}
|
||||
|
||||
if (q.length == 0) {
|
||||
$('.mdb-autocomplete-clear').css('visibility', 'hidden');
|
||||
} else {
|
||||
$('.mdb-autocomplete-clear').css('visibility', 'visible');
|
||||
}
|
||||
});
|
||||
|
||||
$autocomplete.on('click', 'li', function () {
|
||||
|
||||
// Set input value after click
|
||||
$input.val($(this).text());
|
||||
|
||||
// Clear autocomplete
|
||||
$autocomplete.empty();
|
||||
});
|
||||
|
||||
$('.mdb-autocomplete-clear').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$input.val('');
|
||||
$(this).css('visibility', 'hidden');
|
||||
$autocomplete.empty();
|
||||
$(this).parent().find('label').removeClass('active');
|
||||
});
|
||||
});
|
||||
};
|
||||
157
html/js/modules (optional)/buttons.js
Executable file
157
html/js/modules (optional)/buttons.js
Executable file
@@ -0,0 +1,157 @@
|
||||
'use strict';
|
||||
|
||||
(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)', function () {
|
||||
var $this = $(this);
|
||||
openFABMenu($this);
|
||||
});
|
||||
$(document).on('mouseleave.fixedActionBtn', '.fixed-action-btn:not(.click-to-toggle)', function () {
|
||||
var $this = $(this);
|
||||
closeFABMenu($this);
|
||||
});
|
||||
|
||||
// Toggle-on-click behaviour.
|
||||
$(document).on('click.fixedActionBtn', '.fixed-action-btn.click-to-toggle > a', function () {
|
||||
var $this = $(this);
|
||||
var $menu = $this.parent();
|
||||
if ($menu.hasClass('active')) {
|
||||
closeFABMenu($menu);
|
||||
} else {
|
||||
openFABMenu($menu);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$.fn.extend({
|
||||
openFAB: function openFAB() {
|
||||
openFABMenu($(this));
|
||||
},
|
||||
closeFAB: function closeFAB() {
|
||||
closeFABMenu($(this));
|
||||
}
|
||||
});
|
||||
|
||||
var openFABMenu = function openFABMenu(btn) {
|
||||
var $this = btn;
|
||||
if ($this.hasClass('active') === false) {
|
||||
|
||||
// Get direction option
|
||||
var horizontal = $this.hasClass('horizontal');
|
||||
var offsetY = void 0,
|
||||
offsetX = void 0;
|
||||
|
||||
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 closeFABMenu(btn) {
|
||||
$this = btn;
|
||||
// Get direction option
|
||||
var horizontal = $this.hasClass('horizontal');
|
||||
var offsetY = void 0,
|
||||
offsetX = void 0;
|
||||
|
||||
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
|
||||
});
|
||||
};
|
||||
|
||||
$('.fixed-action-btn').on({
|
||||
click: function click(e) {
|
||||
e.preventDefault();
|
||||
toggleFABMenu($('.fixed-action-btn'));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
function toggleFABMenu(btn) {
|
||||
|
||||
$this = btn;
|
||||
if ($this.hasClass('active') === false) {
|
||||
$this.addClass('active');
|
||||
$this.find('ul .btn-floating').velocity({
|
||||
scaleY: '.4',
|
||||
scaleX: '.4',
|
||||
translateY: '40px'
|
||||
}, {
|
||||
duration: 0
|
||||
});
|
||||
|
||||
var time = 0;
|
||||
$this.find('ul .btn-floating').reverse().each(function () {
|
||||
$(this).velocity({
|
||||
opacity: '1',
|
||||
scaleX: '1',
|
||||
scaleY: '1',
|
||||
translateY: '0'
|
||||
}, {
|
||||
duration: 80,
|
||||
delay: time
|
||||
});
|
||||
time += 40;
|
||||
});
|
||||
} else {
|
||||
$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: '40px'
|
||||
}, {
|
||||
duration: 80
|
||||
});
|
||||
}
|
||||
}
|
||||
})(jQuery);
|
||||
50
html/js/modules (optional)/card-reveal.js
Normal file
50
html/js/modules (optional)/card-reveal.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/* CARD REVEAL */
|
||||
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
|
||||
$(document).on('click.card', '.card', function (e) {
|
||||
if ($(this).find('.card-reveal').length) {
|
||||
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'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if ($(e.target).is($('.card .activator')) ||
|
||||
$(e.target).is($('.card .activator i'))) {
|
||||
$(this).find('.card-reveal').css({
|
||||
display: 'block'
|
||||
}).velocity("stop", false).velocity({
|
||||
translateY: '-100%'
|
||||
}, {
|
||||
duration: 300,
|
||||
queue: false,
|
||||
easing: 'easeInOutQuad'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}(jQuery));
|
||||
|
||||
//Social reveal
|
||||
$(document).ready(function ($) {
|
||||
|
||||
$('.card-share > a').on('click', function (e) {
|
||||
e.preventDefault() // prevent default action - hash doesn't appear in url
|
||||
$(this).parent().find('div').toggleClass('social-reveal-active');
|
||||
$(this).toggleClass('share-expanded');
|
||||
});
|
||||
});
|
||||
67
html/js/modules (optional)/cards.js
Executable file
67
html/js/modules (optional)/cards.js
Executable file
@@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
|
||||
/* CARD REVEAL */
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
|
||||
$(document).on('click.card', '.card', function (e) {
|
||||
|
||||
var $this = $(this);
|
||||
var isReveal = $this.find('.card-reveal').length;
|
||||
|
||||
if (isReveal) {
|
||||
|
||||
var $clicked = $(e.target);
|
||||
var isTitle = $clicked.is('.card-reveal .card-title');
|
||||
var isTitleIcon = $clicked.is('.card-reveal .card-title i');
|
||||
var isActivator = $clicked.is('.card .activator');
|
||||
var isActivatorIcon = $clicked.is('.card .activator i');
|
||||
|
||||
if (isTitle || isTitleIcon) {
|
||||
// down
|
||||
|
||||
$this.find('.card-reveal').velocity({
|
||||
translateY: 0
|
||||
}, {
|
||||
duration: 225,
|
||||
queue: false,
|
||||
easing: 'easeInOutQuad',
|
||||
complete: function complete() {
|
||||
$(this).css({
|
||||
display: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (isActivator || isActivatorIcon) {
|
||||
// up
|
||||
|
||||
$this.find('.card-reveal').css({
|
||||
display: 'block'
|
||||
}).velocity('stop', false).velocity({
|
||||
translateY: '-100%'
|
||||
}, {
|
||||
duration: 300,
|
||||
queue: false,
|
||||
easing: 'easeInOutQuad'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.rotate-btn').on('click', function () {
|
||||
|
||||
var cardId = $(this).attr('data-card');
|
||||
$('#' + cardId).toggleClass('flipped');
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
// Social reveal
|
||||
$(document).ready(function ($) {
|
||||
|
||||
$('.card-share > a').on('click', function (e) {
|
||||
e.preventDefault(); // prevent default action - hash doesn't appear in url
|
||||
$(this).parent().find('div').toggleClass('social-reveal-active');
|
||||
$(this).toggleClass('share-expanded');
|
||||
});
|
||||
});
|
||||
55
html/js/modules (optional)/character-counter.js
Executable file
55
html/js/modules (optional)/character-counter.js
Executable file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
/* CHARACTER COUNTER */
|
||||
|
||||
(function ($) {
|
||||
|
||||
$.fn.characterCounter = function () {
|
||||
return this.each(function () {
|
||||
|
||||
var itHasLengthAttribute = $(this).attr('length') !== undefined;
|
||||
|
||||
if (itHasLengthAttribute) {
|
||||
$(this).on('input', updateCounter);
|
||||
$(this).on('focus', updateCounter);
|
||||
$(this).on('blur', removeCounterElement);
|
||||
|
||||
addCounterElement($(this));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function updateCounter() {
|
||||
var maxLength = Number($(this).attr('length'));
|
||||
var actualLength = Number($(this).val().length);
|
||||
var isValidLength = actualLength <= maxLength;
|
||||
|
||||
$(this).parent().find('span[class="character-counter"]').html(actualLength + '/' + maxLength);
|
||||
|
||||
addInputStyle(isValidLength, $(this));
|
||||
}
|
||||
|
||||
function addCounterElement($input) {
|
||||
var $counterElement = $('<span/>').addClass('character-counter').css('float', 'right').css('font-size', '12px').css('height', 1);
|
||||
|
||||
$input.parent().append($counterElement);
|
||||
}
|
||||
|
||||
function removeCounterElement() {
|
||||
$(this).parent().find('span[class="character-counter"]').html('');
|
||||
}
|
||||
|
||||
function addInputStyle(isValidLength, $input) {
|
||||
var inputHasInvalidClass = $input.hasClass('invalid');
|
||||
if (isValidLength && inputHasInvalidClass) {
|
||||
$input.removeClass('invalid');
|
||||
} else if (!isValidLength && !inputHasInvalidClass) {
|
||||
$input.removeClass('valid');
|
||||
$input.addClass('invalid');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$('input, textarea').characterCounter();
|
||||
});
|
||||
})(jQuery);
|
||||
12757
html/js/modules (optional)/chart.js
Executable file
12757
html/js/modules (optional)/chart.js
Executable file
File diff suppressed because it is too large
Load Diff
284
html/js/modules (optional)/chips.js
Executable file
284
html/js/modules (optional)/chips.js
Executable file
@@ -0,0 +1,284 @@
|
||||
'use strict';
|
||||
|
||||
(function ($) {
|
||||
|
||||
var chipsHandleEvents = false;
|
||||
var materialChipsDefaults = {
|
||||
data: [],
|
||||
placeholder: '',
|
||||
secondaryPlaceholder: ''
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
// Handle removal of static chips.
|
||||
$(document).on('click', '.chip .close', function () {
|
||||
|
||||
var $this = $(this);
|
||||
var $chips = $this.closest('.chips');
|
||||
|
||||
if ($chips.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: '.fa',
|
||||
SELECTED_CHIP: '.selected'
|
||||
};
|
||||
|
||||
if (options === 'data') {
|
||||
return this.$el.data('chips');
|
||||
}
|
||||
|
||||
if (options === 'options') {
|
||||
return this.$el.data('options');
|
||||
}
|
||||
|
||||
this.$el.data('options', $.extend({}, materialChipsDefaults, options));
|
||||
|
||||
// Initialize
|
||||
this.init = function () {
|
||||
var i = 0;
|
||||
self.$el.each(function () {
|
||||
|
||||
var $chips = $(this);
|
||||
if ($chips.data('initialized')) {
|
||||
return;
|
||||
} // Prevent double initialization.
|
||||
|
||||
var options = $chips.data('options');
|
||||
if (!options.data || !(options.data instanceof Array)) {
|
||||
options.data = [];
|
||||
}
|
||||
|
||||
$chips.data('chips', options.data);
|
||||
$chips.data('index', i);
|
||||
$chips.data('initialized', true);
|
||||
|
||||
if (!$chips.hasClass(self.SELS.CHIPS)) {
|
||||
$chips.addClass('chips');
|
||||
}
|
||||
|
||||
self.chips($chips);
|
||||
i++;
|
||||
});
|
||||
};
|
||||
|
||||
this.handleEvents = function () {
|
||||
var SELS = self.SELS;
|
||||
|
||||
self.$document.on('click', SELS.CHIPS, function (e) {
|
||||
$(e.target).find(SELS.INPUT).focus();
|
||||
});
|
||||
|
||||
self.$document.on('click', SELS.CHIP, function () {
|
||||
$(SELS.CHIP).removeClass('selected');
|
||||
$(this).toggleClass('selected');
|
||||
});
|
||||
|
||||
self.$document.on('keydown', 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 = void 0;
|
||||
|
||||
if (!$chip.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isBackspaceOrDelete = e.which === 8 || e.which === 46;
|
||||
var isLeftArrow = e.which === 37;
|
||||
var isRightArrow = e.which === 39;
|
||||
|
||||
if (isBackspaceOrDelete) {
|
||||
e.preventDefault();
|
||||
var chipsIndex = $chips.data('index');
|
||||
index = $chip.index();
|
||||
self.deleteChip(chipsIndex, 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 (selectIndex !== null) {
|
||||
self.selectChip(chipsIndex, selectIndex, $chips);
|
||||
}
|
||||
if (!length) {
|
||||
$chips.find('input').focus();
|
||||
}
|
||||
} else if (isLeftArrow) {
|
||||
|
||||
index = $chip.index() - 1;
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
$(SELS.CHIP).removeClass('selected');
|
||||
self.selectChip($chips.data('index'), index, $chips);
|
||||
} else if (isRightArrow) {
|
||||
|
||||
index = $chip.index() + 1;
|
||||
$(SELS.CHIP).removeClass('selected');
|
||||
if (index > length) {
|
||||
$chips.find('input').focus();
|
||||
return;
|
||||
}
|
||||
self.selectChip($chips.data('index'), index, $chips);
|
||||
}
|
||||
});
|
||||
|
||||
self.$document.on('focusin', SELS.CHIPS + ' ' + SELS.INPUT, function (e) {
|
||||
$(e.target).closest(SELS.CHIPS).addClass('focus');
|
||||
$(SELS.CHIP).removeClass('selected');
|
||||
});
|
||||
|
||||
self.$document.on('focusout', SELS.CHIPS + ' ' + SELS.INPUT, function (e) {
|
||||
$(e.target).closest(SELS.CHIPS).removeClass('focus');
|
||||
});
|
||||
|
||||
self.$document.on('keydown', SELS.CHIPS + ' ' + SELS.INPUT, function (e) {
|
||||
var $target = $(e.target);
|
||||
var $chips = $target.closest(SELS.CHIPS);
|
||||
var chipsIndex = $chips.data('index');
|
||||
var chipsLength = $chips.children(SELS.CHIP).length;
|
||||
|
||||
var isEnter = e.which === 13;
|
||||
|
||||
if (isEnter) {
|
||||
e.preventDefault();
|
||||
self.addChip(chipsIndex, {
|
||||
tag: $target.val()
|
||||
}, $chips);
|
||||
$target.val('');
|
||||
return;
|
||||
}
|
||||
|
||||
var isLeftArrowOrDelete = e.keyCode === 8 || e.keyCode === 37;
|
||||
var isValueEmpty = $target.val() === '';
|
||||
|
||||
if (isLeftArrowOrDelete && isValueEmpty && chipsLength) {
|
||||
self.selectChip(chipsIndex, chipsLength - 1, $chips);
|
||||
$target.blur();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
self.$document.on('click', 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($chips.data('index'), $chip.index(), $chips);
|
||||
$chips.find('input').focus();
|
||||
});
|
||||
};
|
||||
|
||||
this.chips = function ($chips) {
|
||||
var html = '';
|
||||
$chips.data('chips').forEach(function (elem) {
|
||||
html += self.renderChip(elem);
|
||||
});
|
||||
html += '<input class="input" placeholder="">';
|
||||
$chips.html(html);
|
||||
self.setPlaceholder($chips);
|
||||
};
|
||||
|
||||
this.renderChip = function (elem) {
|
||||
if (!elem.tag) {
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '<div class="chip">' + elem.tag;
|
||||
|
||||
if (elem.image) {
|
||||
html += ' <img src="' + elem.image + '"> ';
|
||||
}
|
||||
|
||||
html += '<i class="close fa fa-times"></i>';
|
||||
html += '</div>';
|
||||
return html;
|
||||
};
|
||||
|
||||
this.setPlaceholder = function ($chips) {
|
||||
var options = $chips.data('options');
|
||||
if ($chips.data('chips').length && options.placeholder) {
|
||||
$chips.find('input').prop('placeholder', options.placeholder);
|
||||
} else if (!$chips.data('chips').length && options.secondaryPlaceholder) {
|
||||
$chips.find('input').prop('placeholder', 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 (chipsIndex, elem, $chips) {
|
||||
if (!self.isValid($chips, elem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var chipHtml = self.renderChip(elem);
|
||||
$chips.data('chips').push(elem);
|
||||
$(chipHtml).insertBefore($chips.find('input'));
|
||||
$chips.trigger('chip.add', elem);
|
||||
self.setPlaceholder($chips);
|
||||
};
|
||||
|
||||
this.deleteChip = function (chipsIndex, chipIndex, $chips) {
|
||||
var chip = $chips.data('chips')[chipIndex];
|
||||
$chips.find('.chip').eq(chipIndex).remove();
|
||||
$chips.data('chips').splice(chipIndex, 1);
|
||||
$chips.trigger('chip.delete', chip);
|
||||
self.setPlaceholder($chips);
|
||||
};
|
||||
|
||||
this.selectChip = function (chipsIndex, chipIndex, $chips) {
|
||||
var $chip = $chips.find('.chip').eq(chipIndex);
|
||||
if ($chip && $chip.hasClass('selected') === false) {
|
||||
$chip.addClass('selected');
|
||||
$chips.trigger('chip.select', $chips.data('chips')[chipIndex]);
|
||||
}
|
||||
};
|
||||
|
||||
this.getChipsElement = function (index, $chips) {
|
||||
return $chips.eq(index);
|
||||
};
|
||||
|
||||
// init
|
||||
this.init();
|
||||
|
||||
if (!chipsHandleEvents) {
|
||||
this.handleEvents();
|
||||
chipsHandleEvents = true;
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
160
html/js/modules (optional)/collapsible.js
Executable file
160
html/js/modules (optional)/collapsible.js
Executable file
@@ -0,0 +1,160 @@
|
||||
'use strict';
|
||||
|
||||
/* COLLAPSIBLE */
|
||||
|
||||
(function ($) {
|
||||
$.fn.collapsible = function (options) {
|
||||
var defaults = {
|
||||
accordion: undefined
|
||||
};
|
||||
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
var $this = $(this);
|
||||
|
||||
var $panel_headers = $(this).find('> li > .collapsible-header');
|
||||
|
||||
var collapsible_type = $this.data('collapsible');
|
||||
|
||||
// Turn off any existing event handlers
|
||||
$this.off('click.collapse', '.collapsible-header');
|
||||
$panel_headers.off('click.collapse');
|
||||
|
||||
/** **************
|
||||
Helper Functions
|
||||
****************/
|
||||
|
||||
// Accordion Open
|
||||
function accordionOpen(object) {
|
||||
$panel_headers = $this.find('> li > .collapsible-header');
|
||||
if (object.hasClass('active')) {
|
||||
object.parent().addClass('active');
|
||||
} else {
|
||||
object.parent().removeClass('active');
|
||||
}
|
||||
if (object.parent().hasClass('active')) {
|
||||
object.siblings('.collapsible-body').stop(true, false).slideDown({
|
||||
duration: 350,
|
||||
easing: 'easeOutQuart',
|
||||
queue: false,
|
||||
complete: function complete() {
|
||||
$(this).css('height', '');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
object.siblings('.collapsible-body').stop(true, false).slideUp({
|
||||
duration: 350,
|
||||
easing: 'easeOutQuart',
|
||||
queue: false,
|
||||
complete: function complete() {
|
||||
$(this).css('height', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$panel_headers.not(object).removeClass('active').parent().removeClass('active');
|
||||
$panel_headers.not(object).parent().children('.collapsible-body').stop(true, false).slideUp({
|
||||
duration: 350,
|
||||
easing: 'easeOutQuart',
|
||||
queue: false,
|
||||
complete: function complete() {
|
||||
$(this).css('height', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Expandable Open
|
||||
function expandableOpen(object) {
|
||||
if (object.hasClass('active')) {
|
||||
object.parent().addClass('active');
|
||||
} else {
|
||||
object.parent().removeClass('active');
|
||||
}
|
||||
if (object.parent().hasClass('active')) {
|
||||
object.siblings('.collapsible-body').stop(true, false).slideDown({
|
||||
duration: 350,
|
||||
easing: 'easeOutQuart',
|
||||
queue: false,
|
||||
complete: function complete() {
|
||||
$(this).css('height', '');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
object.siblings('.collapsible-body').stop(true, false).slideUp({
|
||||
duration: 350,
|
||||
easing: 'easeOutQuart',
|
||||
queue: false,
|
||||
complete: function complete() {
|
||||
$(this).css('height', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is children of panel header
|
||||
* @param {Object} object Jquery object
|
||||
* @return {Boolean} true if it is children
|
||||
*/
|
||||
function isChildrenOfPanelHeader(object) {
|
||||
|
||||
var panelHeader = getPanelHeader(object);
|
||||
|
||||
return panelHeader.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get panel header from a children element
|
||||
* @param {Object} object Jquery object
|
||||
* @return {Object} panel header object
|
||||
*/
|
||||
function getPanelHeader(object) {
|
||||
|
||||
return object.closest('li > .collapsible-header');
|
||||
}
|
||||
|
||||
/** *** End Helper Functions *****/
|
||||
|
||||
if (options.accordion || collapsible_type === 'accordion' || collapsible_type === undefined) {
|
||||
// Handle Accordion
|
||||
// Add click handler to only direct collapsible header children
|
||||
$panel_headers = $this.find('> li > .collapsible-header');
|
||||
$panel_headers.on('click.collapse', function (e) {
|
||||
var element = $(e.target);
|
||||
|
||||
if (isChildrenOfPanelHeader(element)) {
|
||||
element = getPanelHeader(element);
|
||||
}
|
||||
|
||||
element.toggleClass('active');
|
||||
accordionOpen(element);
|
||||
});
|
||||
// Open first active
|
||||
accordionOpen($panel_headers.filter('.active').first());
|
||||
} else {
|
||||
// Handle Expandables
|
||||
$panel_headers.each(function () {
|
||||
// Add click handler to only direct collapsible header children
|
||||
$(this).on('click.collapse', function (e) {
|
||||
var element = $(e.target);
|
||||
if (isChildrenOfPanelHeader(element)) {
|
||||
element = getPanelHeader(element);
|
||||
}
|
||||
element.toggleClass('active');
|
||||
expandableOpen(element);
|
||||
});
|
||||
// Open any bodies that have the active class
|
||||
if ($(this).hasClass('active')) {
|
||||
expandableOpen($(this));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.collapsible').collapsible();
|
||||
});
|
||||
})(jQuery);
|
||||
330
html/js/modules (optional)/dropdown.js
Executable file
330
html/js/modules (optional)/dropdown.js
Executable file
@@ -0,0 +1,330 @@
|
||||
'use strict';
|
||||
|
||||
/* DROPDOWN */
|
||||
|
||||
(function ($) {
|
||||
|
||||
// Add posibility to scroll to selected option
|
||||
// usefull for select for example
|
||||
$.fn.scrollTo = function (elem) {
|
||||
$(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.fn.dropdown = function (option) {
|
||||
var defaults = {
|
||||
inDuration: 300,
|
||||
outDuration: 225,
|
||||
constrain_width: true, // Constrains width of dropdown to the activator
|
||||
hover: false,
|
||||
gutter: 0, // Spacing from edge
|
||||
belowOrigin: false,
|
||||
alignment: 'left'
|
||||
};
|
||||
|
||||
this.each(function () {
|
||||
var origin = $(this);
|
||||
var options = $.extend({}, defaults, option);
|
||||
var isFocused = false;
|
||||
|
||||
// Dropdown menu
|
||||
var activates = $('#' + origin.attr('data-activates'));
|
||||
|
||||
function updateOptions() {
|
||||
if (origin.data('induration') !== undefined) {
|
||||
options.inDuration = origin.data('inDuration');
|
||||
}
|
||||
if (origin.data('outduration') !== undefined) {
|
||||
options.outDuration = origin.data('outDuration');
|
||||
}
|
||||
if (origin.data('constrainwidth') !== undefined) {
|
||||
options.constrain_width = origin.data('constrainwidth');
|
||||
}
|
||||
if (origin.data('hover') !== undefined) {
|
||||
options.hover = origin.data('hover');
|
||||
}
|
||||
if (origin.data('gutter') !== undefined) {
|
||||
options.gutter = origin.data('gutter');
|
||||
}
|
||||
if (origin.data('beloworigin') !== undefined) {
|
||||
options.belowOrigin = origin.data('beloworigin');
|
||||
}
|
||||
if (origin.data('alignment') !== undefined) {
|
||||
options.alignment = origin.data('alignment');
|
||||
}
|
||||
}
|
||||
|
||||
updateOptions();
|
||||
|
||||
// Attach dropdown to its activator
|
||||
origin.after(activates);
|
||||
|
||||
/*
|
||||
Helper function to position and resize dropdown.
|
||||
Used in hover and click handler.
|
||||
*/
|
||||
function placeDropdown(eventType) {
|
||||
// Check for simultaneous focus and click events.
|
||||
if (eventType === 'focus') {
|
||||
isFocused = true;
|
||||
}
|
||||
|
||||
// Check html data attributes
|
||||
updateOptions();
|
||||
|
||||
// Set Dropdown state
|
||||
activates.addClass('active');
|
||||
origin.addClass('active');
|
||||
|
||||
// Constrain width
|
||||
if (options.constrain_width === true) {
|
||||
activates.css('width', origin.outerWidth());
|
||||
} else {
|
||||
activates.css('white-space', 'nowrap');
|
||||
}
|
||||
|
||||
// Offscreen detection
|
||||
var windowHeight = window.innerHeight;
|
||||
var originHeight = origin.innerHeight();
|
||||
var offsetLeft = origin.offset().left;
|
||||
var offsetTop = origin.offset().top - $(window).scrollTop();
|
||||
var currAlignment = options.alignment;
|
||||
var gutterSpacing = 0;
|
||||
var leftPosition = 0;
|
||||
|
||||
// Below Origin
|
||||
var verticalOffset = 0;
|
||||
if (options.belowOrigin === true) {
|
||||
verticalOffset = originHeight;
|
||||
}
|
||||
|
||||
// Check for scrolling positioned container.
|
||||
var scrollOffset = 0;
|
||||
var wrapper = origin.parent();
|
||||
if (!wrapper.is('body') && wrapper[0].scrollHeight > wrapper[0].clientHeight) {
|
||||
scrollOffset = wrapper[0].scrollTop;
|
||||
}
|
||||
|
||||
if (offsetLeft + activates.innerWidth() > $(window).width()) {
|
||||
// Dropdown goes past screen on right, force right alignment
|
||||
currAlignment = 'right';
|
||||
} else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) {
|
||||
// Dropdown goes past screen on left, force left alignment
|
||||
currAlignment = 'left';
|
||||
}
|
||||
// Vertical bottom offscreen detection
|
||||
if (offsetTop + activates.innerHeight() > windowHeight) {
|
||||
// If going upwards still goes offscreen, just crop height of dropdown.
|
||||
if (offsetTop + originHeight - activates.innerHeight() < 0) {
|
||||
var adjustedHeight = windowHeight - offsetTop - verticalOffset;
|
||||
activates.css('max-height', adjustedHeight);
|
||||
} else {
|
||||
// Flow upwards.
|
||||
if (!verticalOffset) {
|
||||
verticalOffset += originHeight;
|
||||
}
|
||||
verticalOffset -= activates.innerHeight();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle edge alignment
|
||||
if (currAlignment === 'left') {
|
||||
gutterSpacing = options.gutter;
|
||||
leftPosition = origin.position().left + gutterSpacing;
|
||||
} else if (currAlignment === 'right') {
|
||||
var offsetRight = origin.position().left + origin.outerWidth() - activates.outerWidth();
|
||||
gutterSpacing = -options.gutter;
|
||||
leftPosition = offsetRight + gutterSpacing;
|
||||
}
|
||||
|
||||
// Position dropdown
|
||||
activates.css({
|
||||
position: 'absolute',
|
||||
top: origin.position().top + verticalOffset + scrollOffset,
|
||||
left: leftPosition
|
||||
});
|
||||
|
||||
// Show dropdown
|
||||
activates.stop(true, true).css('opacity', 0).slideDown({
|
||||
queue: false,
|
||||
duration: options.inDuration,
|
||||
easing: 'easeOutCubic',
|
||||
complete: function complete() {
|
||||
$(this).css('height', '');
|
||||
}
|
||||
}).animate({
|
||||
opacity: 1,
|
||||
scrollTop: 0
|
||||
}, {
|
||||
queue: false,
|
||||
duration: options.inDuration,
|
||||
easing: 'easeOutSine'
|
||||
});
|
||||
}
|
||||
|
||||
function hideDropdown() {
|
||||
// Check for simultaneous focus and click events.
|
||||
isFocused = false;
|
||||
activates.fadeOut(options.outDuration);
|
||||
activates.removeClass('active');
|
||||
origin.removeClass('active');
|
||||
setTimeout(function () {
|
||||
activates.css('max-height', '');
|
||||
}, options.outDuration);
|
||||
}
|
||||
|
||||
// Hover
|
||||
if (options.hover) {
|
||||
var open = false;
|
||||
origin.unbind('click.' + origin.attr('id'));
|
||||
// Hover handler to show dropdown
|
||||
origin.on('mouseenter', function () {
|
||||
// Mouse over
|
||||
if (open === false) {
|
||||
placeDropdown();
|
||||
open = true;
|
||||
}
|
||||
});
|
||||
origin.on('mouseleave', function (e) {
|
||||
// If hover on origin then to something other than dropdown content, then close
|
||||
var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element
|
||||
if (!$(toEl).closest('.dropdown-content').is(activates)) {
|
||||
activates.stop(true, true);
|
||||
hideDropdown();
|
||||
open = false;
|
||||
}
|
||||
});
|
||||
|
||||
activates.on('mouseleave', function (e) {
|
||||
// Mouse out
|
||||
var toEl = e.toElement || e.relatedTarget;
|
||||
if (!$(toEl).closest('.dropdown-button').is(origin)) {
|
||||
activates.stop(true, true);
|
||||
hideDropdown();
|
||||
open = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Click
|
||||
} else {
|
||||
// Click handler to show dropdown
|
||||
origin.unbind('click.' + origin.attr('id'));
|
||||
origin.bind('click.' + origin.attr('id'), function (e) {
|
||||
if (!isFocused) {
|
||||
if (origin[0] === e.currentTarget && !origin.hasClass('active') && $(e.target).closest('.dropdown-content').length === 0) {
|
||||
e.preventDefault(); // Prevents button click from moving window
|
||||
placeDropdown('click');
|
||||
}
|
||||
// If origin is clicked and menu is open, close menu
|
||||
else if (origin.hasClass('active')) {
|
||||
hideDropdown();
|
||||
$(document).unbind('click.' + activates.attr('id') + ' touchstart.' + activates.attr('id'));
|
||||
}
|
||||
// If menu open, add click close handler to document
|
||||
if (activates.hasClass('active')) {
|
||||
$(document).bind('click.' + activates.attr('id') + ' touchstart.' + activates.attr('id'), function (e) {
|
||||
if (!activates.is(e.target) && !origin.is(e.target) && !origin.find(e.target).length) {
|
||||
hideDropdown();
|
||||
$(document).unbind('click.' + activates.attr('id') + ' touchstart.' + activates.attr('id'));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} // End else
|
||||
|
||||
// Listen to open and close event - useful for select component
|
||||
origin.on('open', function (e, eventType) {
|
||||
placeDropdown(eventType);
|
||||
});
|
||||
origin.on('close', hideDropdown);
|
||||
});
|
||||
}; // End dropdown plugin
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.dropdown-button').dropdown();
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
var dropdownSelectors = $('.dropdown, .dropup');
|
||||
|
||||
// Custom function to read dropdown data
|
||||
// =========================
|
||||
function dropdownEffectData(target) {
|
||||
// @todo - page level global?
|
||||
var effectInDefault = 'fadeIn';
|
||||
var effectOutDefault = 'fadeOut';
|
||||
var dropdown = $(target);
|
||||
var dropdownMenu = $('.dropdown-menu', target);
|
||||
var parentUl = dropdown.parents('ul.nav');
|
||||
|
||||
// If parent is ul.nav allow global effect settings
|
||||
if (parentUl.height > 0) {
|
||||
effectInDefault = parentUl.data('dropdown-in') || null;
|
||||
effectOutDefault = parentUl.data('dropdown-out') || null;
|
||||
}
|
||||
|
||||
return {
|
||||
target: target,
|
||||
dropdown: dropdown,
|
||||
dropdownMenu: dropdownMenu,
|
||||
effectIn: dropdownMenu.data('dropdown-in') || effectInDefault,
|
||||
effectOut: dropdownMenu.data('dropdown-out') || effectOutDefault
|
||||
};
|
||||
}
|
||||
|
||||
// Custom function to start effect (in or out)
|
||||
// =========================
|
||||
function dropdownEffectStart(data, effectToStart) {
|
||||
if (effectToStart) {
|
||||
data.dropdown.addClass('dropdown-animating');
|
||||
data.dropdownMenu.addClass('animated');
|
||||
data.dropdownMenu.addClass(effectToStart);
|
||||
}
|
||||
}
|
||||
|
||||
// Custom function to read when animation is over
|
||||
// =========================
|
||||
function dropdownEffectEnd(data, callbackFunc) {
|
||||
var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
|
||||
data.dropdown.one(animationEnd, function () {
|
||||
data.dropdown.removeClass('dropdown-animating');
|
||||
data.dropdownMenu.removeClass('animated');
|
||||
data.dropdownMenu.removeClass(data.effectIn);
|
||||
data.dropdownMenu.removeClass(data.effectOut);
|
||||
|
||||
// Custom callback option, used to remove open class in out effect
|
||||
if (typeof callbackFunc === 'function') {
|
||||
callbackFunc();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Bootstrap API hooks
|
||||
// =========================
|
||||
dropdownSelectors.on({
|
||||
'show.bs.dropdown': function showBsDropdown() {
|
||||
// On show, start in effect
|
||||
var dropdown = dropdownEffectData(this);
|
||||
dropdownEffectStart(dropdown, dropdown.effectIn);
|
||||
},
|
||||
'shown.bs.dropdown': function shownBsDropdown() {
|
||||
// On shown, remove in effect once complete
|
||||
var dropdown = dropdownEffectData(this);
|
||||
if (dropdown.effectIn && dropdown.effectOut) {
|
||||
dropdownEffectEnd(dropdown);
|
||||
}
|
||||
},
|
||||
'hide.bs.dropdown': function hideBsDropdown(e) {
|
||||
// On hide, start out effect
|
||||
var dropdown = dropdownEffectData(this);
|
||||
if (dropdown.effectOut) {
|
||||
e.preventDefault();
|
||||
dropdownEffectStart(dropdown, dropdown.effectOut);
|
||||
dropdownEffectEnd(dropdown, function () {
|
||||
dropdown.dropdown.removeClass('show');
|
||||
dropdown.dropdownMenu.removeClass('show');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
26
html/js/modules (optional)/enhanced-modals.js
Executable file
26
html/js/modules (optional)/enhanced-modals.js
Executable file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Enhanced Bootstrap Modals
|
||||
https://mdbootstrap.com
|
||||
office@mdbootstrap.com
|
||||
*/
|
||||
|
||||
$('body').on('shown.bs.modal', '.modal', function() {
|
||||
if($('.modal-backdrop').length) {
|
||||
} else {
|
||||
|
||||
$modal_dialog = $(this).children('.modal-dialog')
|
||||
|
||||
if($modal_dialog.hasClass('modal-side')) {
|
||||
$(this).addClass('modal-scrolling');
|
||||
$('body').addClass('scrollable');
|
||||
}
|
||||
|
||||
if($modal_dialog.hasClass('modal-frame')) {
|
||||
$(this).addClass('modal-content-clickable');
|
||||
$('body').addClass('scrollable');
|
||||
}
|
||||
}
|
||||
});
|
||||
$('body').on('hidden.bs.modal', '.modal', function() {
|
||||
$('body').removeClass('scrollable');
|
||||
});
|
||||
22
html/js/modules (optional)/file-input.js
Executable file
22
html/js/modules (optional)/file-input.js
Executable file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
/** *****************
|
||||
* File input *
|
||||
******************/
|
||||
(function ($) {
|
||||
|
||||
$(document).on('change', '.file-field input[type="file"]', function (e) {
|
||||
|
||||
var $this = $(e.target);
|
||||
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++) {
|
||||
var file_name = files[i].name;
|
||||
file_names.push(file_name);
|
||||
}
|
||||
$path_input.val(file_names.join(', '));
|
||||
$path_input.trigger('change');
|
||||
});
|
||||
})(jQuery);
|
||||
158
html/js/modules (optional)/forms-basic.js
Normal file
158
html/js/modules (optional)/forms-basic.js
Normal file
@@ -0,0 +1,158 @@
|
||||
/* FORMS */
|
||||
|
||||
(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) {
|
||||
if ($(element).val().length > 0 || $(this).attr('placeholder') !== undefined || $(element)[0].validity.badInput === true) {
|
||||
$(this).siblings('label, i').addClass('active');
|
||||
} else {
|
||||
$(this).siblings('label, i').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';
|
||||
|
||||
// Handle HTML5 autofocus
|
||||
$('input[autofocus]').siblings('label, i').addClass('active');
|
||||
|
||||
// Add active if form auto complete
|
||||
$(document).on('change', input_selector, function () {
|
||||
if ($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
|
||||
$(this).siblings('label, i').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, i').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, i').addClass('active');
|
||||
});
|
||||
|
||||
$(document).on('blur', input_selector, function () {
|
||||
var $inputElement = $(this);
|
||||
if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') === undefined) {
|
||||
$inputElement.siblings('label, i').removeClass('active');
|
||||
}
|
||||
validate_field($inputElement);
|
||||
});
|
||||
|
||||
validate_field = function (object) {
|
||||
var hasLength = object.attr('length') !== undefined;
|
||||
var lenAttr = parseInt(object.attr('length'));
|
||||
var len = object.val().length;
|
||||
|
||||
if (object.val().length === 0 && object[0].validity.badInput === false) {
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Textarea Auto Resize
|
||||
var hiddenDiv = $('.hiddendiv').first();
|
||||
if (!hiddenDiv.length) {
|
||||
hiddenDiv = $('<div class="hiddendiv common"></div>');
|
||||
$('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');
|
||||
|
||||
if (fontSize) {
|
||||
hiddenDiv.css('font-size', fontSize);
|
||||
}
|
||||
if (fontFamily) {
|
||||
hiddenDiv.css('font-family', fontFamily);
|
||||
}
|
||||
|
||||
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, '<br>');
|
||||
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);
|
||||
}
|
||||
|
||||
$textarea.css('height', hiddenDiv.height());
|
||||
}
|
||||
|
||||
$(text_area_selector).each(function () {
|
||||
var $textarea = $(this);
|
||||
if ($textarea.val().length) {
|
||||
textareaAutoResize($textarea);
|
||||
}
|
||||
});
|
||||
|
||||
$('body').on('keyup keydown', text_area_selector, function () {
|
||||
textareaAutoResize($(this));
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}); // End of $(document).ready
|
||||
|
||||
}(jQuery));
|
||||
153
html/js/modules (optional)/forms-free.js
Executable file
153
html/js/modules (optional)/forms-free.js
Executable file
@@ -0,0 +1,153 @@
|
||||
'use strict';
|
||||
|
||||
/* FORMS */
|
||||
(function ($) {
|
||||
$(document).ready(function () {
|
||||
|
||||
// Text based inputs
|
||||
var input_selector = ['text', 'password', 'email', 'url', 'tel', 'number', 'search', 'search-md'].map(function (selector) {
|
||||
return 'input[type=' + selector + ']';
|
||||
}).join(', ') + ', textarea';
|
||||
|
||||
var text_area_selector = '.materialize-textarea';
|
||||
|
||||
var update_text_fields = function update_text_fields($input) {
|
||||
|
||||
var $labelAndIcon = $input.siblings('label, i');
|
||||
var hasValue = $input.val().length;
|
||||
var hasPlaceholder = $input.attr('placeholder');
|
||||
// let isValid = $input.validity.badInput === true;
|
||||
var addOrRemove = (hasValue || hasPlaceholder ? 'add' : 'remove') + 'Class';
|
||||
|
||||
$labelAndIcon[addOrRemove]('active');
|
||||
};
|
||||
|
||||
var validate_field = function validate_field($input) {
|
||||
|
||||
if ($input.hasClass('validate')) {
|
||||
var value = $input.val();
|
||||
var noValue = !value.length;
|
||||
var isValid = !$input[0].validity.badInput;
|
||||
|
||||
if (noValue && isValid) {
|
||||
$input.removeClass('valid').removeClass('invalid');
|
||||
} else {
|
||||
var valid = $input.is(':valid');
|
||||
var length = Number($input.attr('length')) || 0;
|
||||
|
||||
if (valid && (!length || length > value.length)) {
|
||||
$input.removeClass('invalid').addClass('valid');
|
||||
} else {
|
||||
$input.removeClass('valid').addClass('invalid');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var textarea_auto_resize = function textarea_auto_resize() {
|
||||
|
||||
var $textarea = $(undefined);
|
||||
if ($textarea.val().length) {
|
||||
var _$hiddenDiv = $('.hiddendiv');
|
||||
var fontFamily = $textarea.css('font-family');
|
||||
var fontSize = $textarea.css('font-size');
|
||||
|
||||
if (fontSize) {
|
||||
_$hiddenDiv.css('font-size', fontSize);
|
||||
}
|
||||
if (fontFamily) {
|
||||
_$hiddenDiv.css('font-family', fontFamily);
|
||||
}
|
||||
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, '<br>');
|
||||
_$hiddenDiv.html(content);
|
||||
|
||||
// When textarea is hidden, width goes crazy.
|
||||
// Approximate with half of window size
|
||||
_$hiddenDiv.css('width', $textarea.is(':visible') ? $textarea.width() : $(window).width() / 2);
|
||||
$textarea.css('height', _$hiddenDiv.height());
|
||||
}
|
||||
};
|
||||
|
||||
// Set active on labels and icons (DOM ready scope);
|
||||
$(input_selector).each(function (index, input) {
|
||||
var $this = $(input);
|
||||
var $labelAndIcon = $this.siblings('label, i');
|
||||
update_text_fields($this);
|
||||
var isValid = input.validity.badInput; // pure js
|
||||
if (isValid) {
|
||||
$labelAndIcon.addClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Add active when element has focus
|
||||
$(document).on('focus', input_selector, function (e) {
|
||||
$(e.target).siblings('label, i').addClass('active');
|
||||
});
|
||||
|
||||
// Remove active on blur when not needed or invalid
|
||||
$(document).on('blur', input_selector, function (e) {
|
||||
var $this = $(e.target);
|
||||
var noValue = !$this.val();
|
||||
var invalid = !e.target.validity.badInput;
|
||||
var noPlaceholder = $this.attr('placeholder') === undefined;
|
||||
|
||||
if (noValue && invalid && noPlaceholder) {
|
||||
$this.siblings('label, i').removeClass('active');
|
||||
}
|
||||
|
||||
validate_field($this);
|
||||
});
|
||||
|
||||
// Add active if form auto complete
|
||||
$(document).on('change', input_selector, function (e) {
|
||||
var $this = $(e.target);
|
||||
update_text_fields($this);
|
||||
validate_field($this);
|
||||
});
|
||||
|
||||
// Handle HTML5 autofocus
|
||||
$('input[autofocus]').siblings('label, i').addClass('active');
|
||||
|
||||
// HTML form reset
|
||||
$(document).on('reset', function (e) {
|
||||
var $formReset = $(e.target);
|
||||
if ($formReset.is('form')) {
|
||||
|
||||
var $formInputs = $formReset.find(input_selector);
|
||||
// Reset inputs
|
||||
$formInputs.removeClass('valid').removeClass('invalid').each(function (index, input) {
|
||||
var $this = $(input);
|
||||
var noDefaultValue = !$this.val();
|
||||
var noPlaceholder = !$this.attr('placeholder');
|
||||
if (noDefaultValue && noPlaceholder) {
|
||||
$this.siblings('label, i').removeClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Reset select
|
||||
$formReset.find('select.initialized').each(function (index, select) {
|
||||
var $select = $(select);
|
||||
var $visible_input = $select.siblings('input.select-dropdown');
|
||||
var default_value = $select.children('[selected]').val();
|
||||
|
||||
$select.val(default_value);
|
||||
$visible_input.val(default_value);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Textarea Auto Resize
|
||||
if (!$('.hiddendiv').first().length) {
|
||||
$hiddenDiv = $('<div class="hiddendiv common"></div>');
|
||||
$('body').append($hiddenDiv);
|
||||
}
|
||||
|
||||
$(text_area_selector).each(textarea_auto_resize);
|
||||
$('body').on('keyup keydown', text_area_selector, textarea_auto_resize);
|
||||
});
|
||||
})(jQuery);
|
||||
580
html/js/modules (optional)/forms.js
Normal file
580
html/js/modules (optional)/forms.js
Normal file
@@ -0,0 +1,580 @@
|
||||
/* FORMS */
|
||||
|
||||
;(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) {
|
||||
if ($(element).val().length > 0 || element.autofocus || $(this).attr('placeholder') !== undefined || $(element)[0].validity.badInput === true) {
|
||||
$(this).siblings('label, i').addClass('active')
|
||||
}else {
|
||||
$(this).siblings('label, i').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, i').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, i').addClass('active')
|
||||
})
|
||||
|
||||
$(document).on('blur', input_selector, function () {
|
||||
var $inputElement = $(this)
|
||||
if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') === undefined) {
|
||||
$inputElement.siblings('label, i').removeClass('active')
|
||||
}
|
||||
|
||||
if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') !== undefined) {
|
||||
$inputElement.siblings('i').removeClass('active')
|
||||
}
|
||||
validate_field($inputElement)
|
||||
})
|
||||
|
||||
window.validate_field = function (object) {
|
||||
var hasLength = object.attr('length') !== undefined
|
||||
var lenAttr = parseInt(object.attr('length'))
|
||||
var len = object.val().length
|
||||
|
||||
if (object.val().length === 0 && object[0].validity.badInput === false) {
|
||||
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')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Textarea Auto Resize
|
||||
var hiddenDiv = $('.hiddendiv').first()
|
||||
if (!hiddenDiv.length) {
|
||||
hiddenDiv = $('<div class="hiddendiv common"></div>')
|
||||
$('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')
|
||||
|
||||
if (fontSize) { hiddenDiv.css('font-size', fontSize); }
|
||||
if (fontFamily) { hiddenDiv.css('font-family', fontFamily); }
|
||||
|
||||
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, '<br>')
|
||||
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)
|
||||
}
|
||||
|
||||
$textarea.css('height', hiddenDiv.height())
|
||||
}
|
||||
|
||||
$(text_area_selector).each(function () {
|
||||
var $textarea = $(this)
|
||||
if ($textarea.val().length) {
|
||||
textareaAutoResize($textarea)
|
||||
}
|
||||
})
|
||||
|
||||
$('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 = $('<span class="thumb"><span class="value"></span></span>')
|
||||
$(this).after(thumb)
|
||||
})
|
||||
|
||||
var range_wrapper = '.range-field'
|
||||
$(document).on('change', range_type, function (e) {
|
||||
var thumb = $(this).siblings('.thumb')
|
||||
thumb.find('.value').html($(this).val())
|
||||
})
|
||||
|
||||
$(document).on('input mousedown touchstart', range_type, function (e) {
|
||||
var thumb = $(this).siblings('.thumb')
|
||||
var width = $(this).outerWidth()
|
||||
|
||||
// If thumb indicator does not exist yet, create it
|
||||
if (thumb.length <= 0) {
|
||||
thumb = $('<span class="thumb"><span class="value"></span></span>')
|
||||
$(this).after(thumb)
|
||||
}
|
||||
|
||||
// Set indicator value
|
||||
thumb.find('.value').html($(this).val())
|
||||
|
||||
range_mousedown = true
|
||||
$(this).addClass('active')
|
||||
|
||||
if (!thumb.hasClass('active')) {
|
||||
thumb.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' })
|
||||
}
|
||||
|
||||
if (e.type !== 'input') {
|
||||
if (e.pageX === undefined || e.pageX === null) { // mobile
|
||||
left = e.originalEvent.touches[0].pageX - $(this).offset().left
|
||||
}else { // desktop
|
||||
left = e.pageX - $(this).offset().left
|
||||
}
|
||||
if (left < 0) {
|
||||
left = 0
|
||||
}
|
||||
else if (left > width) {
|
||||
left = width
|
||||
}
|
||||
thumb.addClass('active').css('left', left)
|
||||
}
|
||||
|
||||
thumb.find('.value').html($(this).val())
|
||||
})
|
||||
|
||||
$(document).on('mouseup touchend', range_wrapper, function () {
|
||||
range_mousedown = false
|
||||
$(this).removeClass('active')
|
||||
})
|
||||
|
||||
$(document).on('mousemove touchmove', range_wrapper, function (e) {
|
||||
var thumb = $(this).children('.thumb')
|
||||
var left
|
||||
if (range_mousedown) {
|
||||
if (!thumb.hasClass('active')) {
|
||||
thumb.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' })
|
||||
}
|
||||
if (e.pageX === undefined || e.pageX === null) { // mobile
|
||||
left = e.originalEvent.touches[0].pageX - $(this).offset().left
|
||||
}else { // desktop
|
||||
left = e.pageX - $(this).offset().left
|
||||
}
|
||||
var width = $(this).outerWidth()
|
||||
|
||||
if (left < 0) {
|
||||
left = 0
|
||||
}
|
||||
else if (left > width) {
|
||||
left = width
|
||||
}
|
||||
thumb.addClass('active').css('left', left)
|
||||
thumb.find('.value').html(thumb.siblings(range_type).val())
|
||||
}
|
||||
})
|
||||
|
||||
$(document).on('mouseout touchleave', range_wrapper, function () {
|
||||
if (!range_mousedown) {
|
||||
var thumb = $(this).children('.thumb')
|
||||
|
||||
if (thumb.hasClass('active')) {
|
||||
thumb.velocity({ height: '0', width: '0', top: '10px', marginLeft: '-6px'}, { duration: 100 })
|
||||
}
|
||||
thumb.removeClass('active')
|
||||
}
|
||||
})
|
||||
}); // 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.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.data('select-id', null).removeClass('initialized')
|
||||
return
|
||||
}
|
||||
|
||||
var uniqueID = Materialize.guid()
|
||||
$select.data('select-id', uniqueID)
|
||||
var wrapper = $('<div class="select-wrapper"></div>')
|
||||
wrapper.addClass($select.attr('class'))
|
||||
var options = $('<ul id="select-options-' + uniqueID + '" class="dropdown-content select-dropdown ' + (multiple ? 'multiple-select-dropdown' : '') + '"></ul>'),
|
||||
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 ' : ''
|
||||
|
||||
// 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.
|
||||
if (type === 'multiple') {
|
||||
options.append($('<li class="' + disabledClass + '"><img src="' + icon_url + '"' + classString + '><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'))
|
||||
} else {
|
||||
options.append($('<li class="' + disabledClass + '"><img src="' + icon_url + '"' + classString + '><span>' + option.html() + '</span></li>'))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Check for multiple type.
|
||||
if (type === 'multiple') {
|
||||
options.append($('<li class="' + disabledClass + '"><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'))
|
||||
} else {
|
||||
options.append($('<li class="' + disabledClass + '"><span>' + option.html() + '</span></li>'))
|
||||
}
|
||||
}
|
||||
|
||||
/* 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($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'))
|
||||
|
||||
selectOptions.each(function () {
|
||||
appendOptionWithIcon($select, $(this))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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, $(this).index(), $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 = $('<span class="caret">▼</span>')
|
||||
if ($select.is(':disabled'))
|
||||
dropdownIcon.addClass('disabled')
|
||||
|
||||
// escape double quotes
|
||||
var sanitizedLabelHtml = label.replace(/"/g, '"')
|
||||
|
||||
var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID + '" value="' + sanitizedLabelHtml + '"/>')
|
||||
$select.before($newSelect)
|
||||
$newSelect.before(dropdownIcon)
|
||||
|
||||
$newSelect.after(options)
|
||||
// Check if section element is disabled
|
||||
if (!$select.is(':disabled')) {
|
||||
$newSelect.dropdown({'hover': false, 'closeOnClick': 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')
|
||||
}
|
||||
if (!options.is(':visible')) {
|
||||
$(this).trigger('open', ['focus'])
|
||||
var label = $(this).val()
|
||||
var selectedOption = options.find('li').filter(function () {
|
||||
return $(this).text().toLowerCase() === label.toLowerCase()
|
||||
})[0]
|
||||
activateOption(options, selectedOption)
|
||||
}
|
||||
},
|
||||
'touchend click': function (e) {
|
||||
e.stopPropagation()
|
||||
}
|
||||
})
|
||||
|
||||
$newSelect.on('blur', function () {
|
||||
if (!multiple) {
|
||||
$(this).trigger('close')
|
||||
}
|
||||
options.find('li.selected').removeClass('selected')
|
||||
})
|
||||
|
||||
options.hover(function () {
|
||||
optionsHover = true
|
||||
}, function () {
|
||||
optionsHover = false
|
||||
})
|
||||
|
||||
$(window).on({
|
||||
'click': function () {
|
||||
multiple && (optionsHover || $newSelect.trigger('close'))
|
||||
}
|
||||
})
|
||||
|
||||
// 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').eq(index).find(':checkbox').prop('checked', true)
|
||||
})
|
||||
}
|
||||
|
||||
// Make option as selected and scroll to selected position
|
||||
activateOption = function (collection, newOption) {
|
||||
if (newOption) {
|
||||
collection.find('li.selected').removeClass('selected')
|
||||
var option = $(newOption)
|
||||
option.addClass('selected')
|
||||
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').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));
|
||||
|
||||
jQuery('select').siblings('input.select-dropdown').on('mousedown', function (e) {
|
||||
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
|
||||
if (e.clientX >= e.target.clientWidth || e.clientY >= e.target.clientHeight) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
});
|
||||
45
html/js/modules (optional)/global.js
Normal file
45
html/js/modules (optional)/global.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// Required for Meteor package, the use of window prevents export by Meteor
|
||||
(function(window){
|
||||
if(window.Package){
|
||||
Materialize = {};
|
||||
} else {
|
||||
window.Materialize = {};
|
||||
}
|
||||
})(window);
|
||||
|
||||
|
||||
// Unique ID
|
||||
Materialize.guid = (function() {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return function() {
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4();
|
||||
};
|
||||
})();
|
||||
|
||||
Materialize.elementOrParentIsFixed = function(element) {
|
||||
var $element = $(element);
|
||||
var $checkElements = $element.add($element.parents());
|
||||
var isFixed = false;
|
||||
$checkElements.each(function(){
|
||||
if ($(this).css("position") === "fixed") {
|
||||
isFixed = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return isFixed;
|
||||
};
|
||||
|
||||
// Velocity has conflicts when loaded with jQuery, this will check for it
|
||||
var Vel;
|
||||
if ($) {
|
||||
Vel = $.Velocity;
|
||||
} else if (jQuery) {
|
||||
Vel = jQuery.Velocity;
|
||||
} else {
|
||||
Vel = Velocity;
|
||||
}
|
||||
2643
html/js/modules (optional)/hammer.js
Executable file
2643
html/js/modules (optional)/hammer.js
Executable file
File diff suppressed because it is too large
Load Diff
799
html/js/modules (optional)/jarallax-video.js
Executable file
799
html/js/modules (optional)/jarallax-video.js
Executable file
@@ -0,0 +1,799 @@
|
||||
/*!
|
||||
* Name : Video Worker (wrapper for Youtube, Vimeo and Local videos)
|
||||
* Version : 1.2.1
|
||||
* Author : _nK https://nkdev.info
|
||||
* GitHub : https://github.com/nk-o/jarallax
|
||||
*/
|
||||
(function (window) {
|
||||
'use strict';
|
||||
|
||||
// Extend like jQuery.extend
|
||||
function extend (out) {
|
||||
out = out || {};
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
if (!arguments[i]) {
|
||||
continue;
|
||||
}
|
||||
for (var key in arguments[i]) {
|
||||
if (arguments[i].hasOwnProperty(key)) {
|
||||
out[key] = arguments[i][key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Deferred
|
||||
// thanks http://stackoverflow.com/questions/18096715/implement-deferred-object-without-using-jquery
|
||||
function Deferred () {
|
||||
this._done = [];
|
||||
this._fail = [];
|
||||
}
|
||||
Deferred.prototype = {
|
||||
execute: function (list, args) {
|
||||
var i = list.length;
|
||||
args = Array.prototype.slice.call(args);
|
||||
while(i--) {
|
||||
list[i].apply(null, args);
|
||||
}
|
||||
},
|
||||
resolve: function () {
|
||||
this.execute(this._done, arguments);
|
||||
},
|
||||
reject: function () {
|
||||
this.execute(this._fail, arguments);
|
||||
},
|
||||
done: function (callback) {
|
||||
this._done.push(callback);
|
||||
},
|
||||
fail: function (callback) {
|
||||
this._fail.push(callback);
|
||||
}
|
||||
};
|
||||
|
||||
// init events
|
||||
function addEventListener (el, eventName, handler) {
|
||||
if (el.addEventListener) {
|
||||
el.addEventListener(eventName, handler);
|
||||
} else {
|
||||
el.attachEvent('on' + eventName, function (){
|
||||
handler.call(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var VideoWorker = (function () {
|
||||
var ID = 0;
|
||||
|
||||
function VideoWorker_inner (url, options) {
|
||||
var _this = this;
|
||||
|
||||
_this.url = url;
|
||||
|
||||
_this.options_default = {
|
||||
autoplay: 1,
|
||||
loop: 1,
|
||||
mute: 1,
|
||||
controls: 0,
|
||||
|
||||
// start / end video time in ms
|
||||
startTime: 0,
|
||||
endTime: 0
|
||||
};
|
||||
|
||||
_this.options = extend({}, _this.options_default, options);
|
||||
|
||||
// check URL
|
||||
_this.videoID = _this.parseURL(url);
|
||||
|
||||
// init
|
||||
if(_this.videoID) {
|
||||
_this.ID = ID++;
|
||||
_this.loadAPI();
|
||||
_this.init();
|
||||
}
|
||||
}
|
||||
|
||||
return VideoWorker_inner;
|
||||
}());
|
||||
|
||||
VideoWorker.prototype.parseURL = function (url) {
|
||||
// parse youtube ID
|
||||
function getYoutubeID (ytUrl) {
|
||||
var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;
|
||||
var match = ytUrl.match(regExp);
|
||||
return match && match[1].length === 11 ? match[1] : false;
|
||||
}
|
||||
|
||||
// parse vimeo ID
|
||||
function getVimeoID (vmUrl) {
|
||||
var regExp = /https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/;
|
||||
var match = vmUrl.match(regExp);
|
||||
return match && match[3] ? match[3] : false;
|
||||
}
|
||||
|
||||
// parse local string
|
||||
function getLocalVideos (locUrl) {
|
||||
var videoFormats = locUrl.split(/,(?=mp4\:|webm\:|ogv\:|ogg\:)/);
|
||||
var result = {};
|
||||
var ready = 0;
|
||||
for(var k = 0; k < videoFormats.length; k++) {
|
||||
var match = videoFormats[k].match(/^(mp4|webm|ogv|ogg)\:(.*)/);
|
||||
if(match && match[1] && match[2]) {
|
||||
result[match[1] === 'ogv' ? 'ogg' : match[1]] = match[2];
|
||||
ready = 1;
|
||||
}
|
||||
}
|
||||
return ready ? result : false;
|
||||
}
|
||||
|
||||
var Youtube = getYoutubeID(url);
|
||||
var Vimeo = getVimeoID(url);
|
||||
var Local = getLocalVideos(url);
|
||||
|
||||
if(Youtube) {
|
||||
this.type = 'youtube';
|
||||
return Youtube;
|
||||
} else if (Vimeo) {
|
||||
this.type = 'vimeo';
|
||||
return Vimeo;
|
||||
} else if (Local) {
|
||||
this.type = 'local';
|
||||
return Local;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
VideoWorker.prototype.isValid = function () {
|
||||
return !!this.videoID;
|
||||
};
|
||||
|
||||
// events
|
||||
VideoWorker.prototype.on = function (name, callback) {
|
||||
this.userEventsList = this.userEventsList || [];
|
||||
|
||||
// add new callback in events list
|
||||
(this.userEventsList[name] || (this.userEventsList[name] = [])).push(callback);
|
||||
};
|
||||
VideoWorker.prototype.off = function (name, callback) {
|
||||
if(!this.userEventsList || !this.userEventsList[name]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!callback) {
|
||||
delete this.userEventsList[name];
|
||||
} else {
|
||||
for(var k = 0; k < this.userEventsList[name].length; k++) {
|
||||
if(this.userEventsList[name][k] === callback) {
|
||||
this.userEventsList[name][k] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
VideoWorker.prototype.fire = function (name) {
|
||||
var args = [].slice.call(arguments, 1);
|
||||
if(this.userEventsList && typeof this.userEventsList[name] !== 'undefined') {
|
||||
for(var k in this.userEventsList[name]) {
|
||||
// call with all arguments
|
||||
if(this.userEventsList[name][k]) {
|
||||
this.userEventsList[name][k].apply(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
VideoWorker.prototype.play = function (start) {
|
||||
var _this = this;
|
||||
if(!_this.player) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(_this.type === 'youtube' && _this.player.playVideo) {
|
||||
if(typeof start !== 'undefined') {
|
||||
_this.player.seekTo(start || 0);
|
||||
}
|
||||
_this.player.playVideo();
|
||||
}
|
||||
|
||||
if(_this.type === 'vimeo') {
|
||||
if (typeof start !== 'undefined') {
|
||||
_this.player.setCurrentTime(start);
|
||||
}
|
||||
_this.player.getPaused().then(function(paused) {
|
||||
if (paused) {
|
||||
_this.player.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(_this.type === 'local') {
|
||||
if(typeof start !== 'undefined') {
|
||||
_this.player.currentTime = start;
|
||||
}
|
||||
_this.player.play();
|
||||
}
|
||||
};
|
||||
|
||||
VideoWorker.prototype.pause = function () {
|
||||
if(!this.player) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.type === 'youtube' && this.player.pauseVideo) {
|
||||
this.player.pauseVideo();
|
||||
}
|
||||
|
||||
if(this.type === 'vimeo') {
|
||||
this.player.pause();
|
||||
}
|
||||
|
||||
if(this.type === 'local') {
|
||||
this.player.pause();
|
||||
}
|
||||
};
|
||||
|
||||
VideoWorker.prototype.getImageURL = function (callback) {
|
||||
var _this = this;
|
||||
|
||||
if(_this.videoImage) {
|
||||
callback(_this.videoImage);
|
||||
return;
|
||||
}
|
||||
|
||||
if(_this.type === 'youtube') {
|
||||
var availableSizes = [
|
||||
'maxresdefault',
|
||||
'sddefault',
|
||||
'hqdefault',
|
||||
'0'
|
||||
];
|
||||
var step = 0;
|
||||
|
||||
var tempImg = new Image();
|
||||
tempImg.onload = function () {
|
||||
// if no thumbnail, youtube add their own image with width = 120px
|
||||
if ((this.naturalWidth || this.width) !== 120 || step === availableSizes.length - 1) {
|
||||
// ok
|
||||
_this.videoImage = 'https://img.youtube.com/vi/' + _this.videoID + '/' + availableSizes[step] + '.jpg';
|
||||
callback(_this.videoImage);
|
||||
} else {
|
||||
// try another size
|
||||
step++;
|
||||
this.src = 'https://img.youtube.com/vi/' + _this.videoID + '/' + availableSizes[step] + '.jpg';
|
||||
}
|
||||
};
|
||||
tempImg.src = 'https://img.youtube.com/vi/' + _this.videoID + '/' + availableSizes[step] + '.jpg';
|
||||
}
|
||||
|
||||
if(_this.type === 'vimeo') {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', 'https://vimeo.com/api/v2/video/' + _this.videoID + '.json', true);
|
||||
request.onreadystatechange = function () {
|
||||
if (this.readyState === 4) {
|
||||
if (this.status >= 200 && this.status < 400) {
|
||||
// Success!
|
||||
var response = JSON.parse(this.responseText);
|
||||
_this.videoImage = response[0].thumbnail_large;
|
||||
callback(_this.videoImage);
|
||||
} else {
|
||||
// Error :(
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
request = null;
|
||||
}
|
||||
};
|
||||
|
||||
VideoWorker.prototype.getIframe = function (callback) {
|
||||
var _this = this;
|
||||
|
||||
// return generated iframe
|
||||
if(_this.$iframe) {
|
||||
callback(_this.$iframe);
|
||||
return;
|
||||
}
|
||||
|
||||
// generate new iframe
|
||||
_this.onAPIready(function () {
|
||||
var hiddenDiv;
|
||||
if(!_this.$iframe) {
|
||||
hiddenDiv = document.createElement('div');
|
||||
hiddenDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
// Youtube
|
||||
if(_this.type === 'youtube') {
|
||||
_this.playerOptions = {};
|
||||
_this.playerOptions.videoId = _this.videoID;
|
||||
_this.playerOptions.playerVars = {
|
||||
autohide: 1,
|
||||
rel: 0,
|
||||
autoplay: 0
|
||||
};
|
||||
|
||||
// hide controls
|
||||
if(!_this.options.controls) {
|
||||
_this.playerOptions.playerVars.iv_load_policy = 3;
|
||||
_this.playerOptions.playerVars.modestbranding = 1;
|
||||
_this.playerOptions.playerVars.controls = 0;
|
||||
_this.playerOptions.playerVars.showinfo = 0;
|
||||
_this.playerOptions.playerVars.disablekb = 1;
|
||||
}
|
||||
|
||||
// events
|
||||
var ytStarted;
|
||||
var ytProgressInterval;
|
||||
_this.playerOptions.events = {
|
||||
onReady: function (e) {
|
||||
// mute
|
||||
if(_this.options.mute) {
|
||||
e.target.mute();
|
||||
}
|
||||
// autoplay
|
||||
if(_this.options.autoplay) {
|
||||
_this.play(_this.options.startTime);
|
||||
}
|
||||
_this.fire('ready', e);
|
||||
},
|
||||
onStateChange: function (e) {
|
||||
// loop
|
||||
if(_this.options.loop && e.data === YT.PlayerState.ENDED) {
|
||||
_this.play(_this.options.startTime);
|
||||
}
|
||||
if(!ytStarted && e.data === YT.PlayerState.PLAYING) {
|
||||
ytStarted = 1;
|
||||
_this.fire('started', e);
|
||||
}
|
||||
if(e.data === YT.PlayerState.PLAYING) {
|
||||
_this.fire('play', e);
|
||||
}
|
||||
if(e.data === YT.PlayerState.PAUSED) {
|
||||
_this.fire('pause', e);
|
||||
}
|
||||
if(e.data === YT.PlayerState.ENDED) {
|
||||
_this.fire('end', e);
|
||||
}
|
||||
|
||||
// check for end of video and play again or stop
|
||||
if(_this.options.endTime) {
|
||||
if(e.data === YT.PlayerState.PLAYING) {
|
||||
ytProgressInterval = setInterval(function () {
|
||||
if(_this.options.endTime && _this.player.getCurrentTime() >= _this.options.endTime) {
|
||||
if(_this.options.loop) {
|
||||
_this.play(_this.options.startTime);
|
||||
} else {
|
||||
_this.pause();
|
||||
}
|
||||
}
|
||||
}, 150);
|
||||
} else {
|
||||
clearInterval(ytProgressInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var firstInit = !_this.$iframe;
|
||||
if(firstInit) {
|
||||
var div = document.createElement('div');
|
||||
div.setAttribute('id', _this.playerID);
|
||||
hiddenDiv.appendChild(div);
|
||||
document.body.appendChild(hiddenDiv);
|
||||
}
|
||||
_this.player = _this.player || new window.YT.Player(_this.playerID, _this.playerOptions);
|
||||
if(firstInit) {
|
||||
_this.$iframe = document.getElementById(_this.playerID);
|
||||
|
||||
// get video width and height
|
||||
_this.videoWidth = parseInt(_this.$iframe.getAttribute('width'), 10) || 1280;
|
||||
_this.videoHeight = parseInt(_this.$iframe.getAttribute('height'), 10) || 720;
|
||||
}
|
||||
}
|
||||
|
||||
// Vimeo
|
||||
if(_this.type === 'vimeo') {
|
||||
_this.playerOptions = '';
|
||||
|
||||
_this.playerOptions += 'player_id=' + _this.playerID;
|
||||
_this.playerOptions += '&autopause=0';
|
||||
|
||||
// hide controls
|
||||
if(!_this.options.controls) {
|
||||
_this.playerOptions += '&badge=0&byline=0&portrait=0&title=0';
|
||||
}
|
||||
|
||||
// autoplay
|
||||
_this.playerOptions += '&autoplay=' + (_this.options.autoplay ? '1' : '0');
|
||||
|
||||
// loop
|
||||
_this.playerOptions += '&loop=' + (_this.options.loop ? 1 : 0);
|
||||
|
||||
if(!_this.$iframe) {
|
||||
_this.$iframe = document.createElement('iframe');
|
||||
_this.$iframe.setAttribute('id', _this.playerID);
|
||||
_this.$iframe.setAttribute('src', 'https://player.vimeo.com/video/' + _this.videoID + '?' + _this.playerOptions);
|
||||
_this.$iframe.setAttribute('frameborder', '0');
|
||||
hiddenDiv.appendChild(_this.$iframe);
|
||||
document.body.appendChild(hiddenDiv);
|
||||
}
|
||||
|
||||
_this.player = _this.player || new Vimeo.Player(_this.$iframe);
|
||||
|
||||
// get video width and height
|
||||
_this.player.getVideoWidth().then(function (width) {
|
||||
_this.videoWidth = width || 1280;
|
||||
});
|
||||
_this.player.getVideoHeight().then(function (height) {
|
||||
_this.videoHeight = height || 720;
|
||||
});
|
||||
|
||||
// mute
|
||||
_this.player.setVolume(_this.options.mute ? 0 : 100);
|
||||
|
||||
var vmStarted;
|
||||
_this.player.on('timeupdate', function (e) {
|
||||
if(!vmStarted) {
|
||||
_this.fire('started', e);
|
||||
}
|
||||
vmStarted = 1;
|
||||
|
||||
// check for end of video and play again or stop
|
||||
if(_this.options.endTime) {
|
||||
if(_this.options.endTime && e.seconds >= _this.options.endTime) {
|
||||
if(_this.options.loop) {
|
||||
_this.play(_this.options.startTime);
|
||||
} else {
|
||||
_this.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
_this.player.on('play', function (e) {
|
||||
_this.fire('play', e);
|
||||
|
||||
// check for the start time and start with it
|
||||
if(_this.options.startTime && e.seconds === 0) {
|
||||
_this.play(_this.options.startTime);
|
||||
}
|
||||
});
|
||||
_this.player.on('pause', function (e) {
|
||||
_this.fire('pause', e);
|
||||
});
|
||||
_this.player.on('ended', function (e) {
|
||||
_this.fire('end', e);
|
||||
});
|
||||
_this.player.on('loaded', function (e) {
|
||||
_this.fire('ready', e);
|
||||
});
|
||||
}
|
||||
|
||||
// Local
|
||||
function addSourceToLocal (element, src, type) {
|
||||
var source = document.createElement('source');
|
||||
source.src = src;
|
||||
source.type = type;
|
||||
element.appendChild(source);
|
||||
}
|
||||
if(_this.type === 'local') {
|
||||
if(!_this.$iframe) {
|
||||
_this.$iframe = document.createElement('video');
|
||||
|
||||
// mute
|
||||
if(_this.options.mute) {
|
||||
_this.$iframe.muted = true;
|
||||
}
|
||||
|
||||
// loop
|
||||
if(_this.options.loop) {
|
||||
_this.$iframe.loop = true;
|
||||
}
|
||||
|
||||
_this.$iframe.setAttribute('id', _this.playerID);
|
||||
hiddenDiv.appendChild(_this.$iframe);
|
||||
document.body.appendChild(hiddenDiv);
|
||||
|
||||
for(var k in _this.videoID) {
|
||||
addSourceToLocal(_this.$iframe, _this.videoID[k], 'video/' + k);
|
||||
}
|
||||
}
|
||||
|
||||
_this.player = _this.player || _this.$iframe;
|
||||
|
||||
var locStarted;
|
||||
addEventListener(_this.player, 'playing', function (e) {
|
||||
if(!locStarted) {
|
||||
_this.fire('started', e);
|
||||
}
|
||||
locStarted = 1;
|
||||
});
|
||||
addEventListener(_this.player, 'timeupdate', function () {
|
||||
// check for end of video and play again or stop
|
||||
if(_this.options.endTime) {
|
||||
if(_this.options.endTime && this.currentTime >= _this.options.endTime) {
|
||||
if(_this.options.loop) {
|
||||
_this.play(_this.options.startTime);
|
||||
} else {
|
||||
_this.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
addEventListener(_this.player, 'play', function (e) {
|
||||
_this.fire('play', e);
|
||||
});
|
||||
addEventListener(_this.player, 'pause', function (e) {
|
||||
_this.fire('pause', e);
|
||||
});
|
||||
addEventListener(_this.player, 'ended', function (e) {
|
||||
_this.fire('end', e);
|
||||
});
|
||||
addEventListener(_this.player, 'loadedmetadata', function () {
|
||||
// get video width and height
|
||||
_this.videoWidth = this.videoWidth || 1280;
|
||||
_this.videoHeight = this.videoHeight || 720;
|
||||
|
||||
_this.fire('ready');
|
||||
|
||||
// autoplay
|
||||
if(_this.options.autoplay) {
|
||||
_this.play(_this.options.startTime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
callback(_this.$iframe);
|
||||
});
|
||||
};
|
||||
|
||||
VideoWorker.prototype.init = function () {
|
||||
var _this = this;
|
||||
|
||||
_this.playerID = 'VideoWorker-' + _this.ID;
|
||||
};
|
||||
|
||||
var YoutubeAPIadded = 0;
|
||||
var VimeoAPIadded = 0;
|
||||
VideoWorker.prototype.loadAPI = function () {
|
||||
var _this = this;
|
||||
|
||||
if(YoutubeAPIadded && VimeoAPIadded) {
|
||||
return;
|
||||
}
|
||||
|
||||
var src = '';
|
||||
|
||||
// load Youtube API
|
||||
if(_this.type === 'youtube' && !YoutubeAPIadded) {
|
||||
YoutubeAPIadded = 1;
|
||||
src = '//www.youtube.com/iframe_api';
|
||||
}
|
||||
|
||||
// load Vimeo API
|
||||
if(_this.type === 'vimeo' && !VimeoAPIadded) {
|
||||
VimeoAPIadded = 1;
|
||||
src = '//player.vimeo.com/api/player.js';
|
||||
}
|
||||
|
||||
if(!src) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.location.origin === 'file://') {
|
||||
src = 'http:' + src;
|
||||
}
|
||||
|
||||
// add script in head section
|
||||
var tag = document.createElement('script');
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
tag.src = src;
|
||||
|
||||
head.appendChild(tag);
|
||||
|
||||
head = null;
|
||||
tag = null;
|
||||
};
|
||||
|
||||
var loadingYoutubePlayer = 0;
|
||||
var loadingVimeoPlayer = 0;
|
||||
var loadingYoutubeDeffer = new Deferred();
|
||||
var loadingVimeoDeffer = new Deferred();
|
||||
VideoWorker.prototype.onAPIready = function (callback) {
|
||||
var _this = this;
|
||||
|
||||
// Youtube
|
||||
if(_this.type === 'youtube') {
|
||||
// Listen for global YT player callback
|
||||
if ((typeof YT === 'undefined' || YT.loaded === 0) && !loadingYoutubePlayer) {
|
||||
// Prevents Ready event from being called twice
|
||||
loadingYoutubePlayer = 1;
|
||||
|
||||
// Creates deferred so, other players know when to wait.
|
||||
window.onYouTubeIframeAPIReady = function () {
|
||||
window.onYouTubeIframeAPIReady = null;
|
||||
loadingYoutubeDeffer.resolve('done');
|
||||
callback();
|
||||
};
|
||||
} else if (typeof YT === 'object' && YT.loaded === 1) {
|
||||
callback();
|
||||
} else {
|
||||
loadingYoutubeDeffer.done(function () {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Vimeo
|
||||
if(_this.type === 'vimeo') {
|
||||
if(typeof Vimeo === 'undefined' && !loadingVimeoPlayer) {
|
||||
loadingVimeoPlayer = 1;
|
||||
var vimeo_interval = setInterval(function () {
|
||||
if(typeof Vimeo !== 'undefined') {
|
||||
clearInterval(vimeo_interval);
|
||||
loadingVimeoDeffer.resolve('done');
|
||||
callback();
|
||||
}
|
||||
}, 20);
|
||||
} else if (typeof Vimeo !== 'undefined') {
|
||||
callback();
|
||||
} else {
|
||||
loadingVimeoDeffer.done(function () {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Local
|
||||
if(_this.type === 'local') {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
window.VideoWorker = VideoWorker;
|
||||
}(window));
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Name : Video Background Extension for Jarallax
|
||||
* Version : 1.0.0
|
||||
* Author : _nK http://nkdev.info
|
||||
* GitHub : https://github.com/nk-o/jarallax
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if(typeof jarallax === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
var Jarallax = jarallax.constructor;
|
||||
|
||||
// append video after init Jarallax
|
||||
var def_init = Jarallax.prototype.init;
|
||||
Jarallax.prototype.init = function () {
|
||||
var _this = this;
|
||||
|
||||
def_init.apply(_this);
|
||||
|
||||
if(_this.video) {
|
||||
_this.video.getIframe(function (iframe) {
|
||||
var $parent = iframe.parentNode;
|
||||
_this.css(iframe, {
|
||||
position: _this.image.position,
|
||||
top: '0px', left: '0px', right: '0px', bottom: '0px',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
maxWidth: 'none',
|
||||
maxHeight: 'none',
|
||||
visibility: 'hidden',
|
||||
margin: 0,
|
||||
zIndex: -1
|
||||
});
|
||||
_this.$video = iframe;
|
||||
_this.image.$container.appendChild(iframe);
|
||||
|
||||
// remove parent iframe element (created by VideoWorker)
|
||||
$parent.parentNode.removeChild($parent);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// cover video
|
||||
var def_coverImage = Jarallax.prototype.coverImage;
|
||||
Jarallax.prototype.coverImage = function () {
|
||||
var _this = this;
|
||||
|
||||
def_coverImage.apply(_this);
|
||||
|
||||
// add video height over than need to hide controls
|
||||
if(_this.video && _this.image.$item.nodeName === 'IFRAME') {
|
||||
_this.css(_this.image.$item, {
|
||||
height: _this.image.$item.getBoundingClientRect().height + 400 + 'px',
|
||||
marginTop: (-200 + parseFloat(_this.css(_this.image.$item, 'margin-top'))) + 'px'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// init video
|
||||
var def_initImg = Jarallax.prototype.initImg;
|
||||
Jarallax.prototype.initImg = function () {
|
||||
var _this = this;
|
||||
var defaultResult = def_initImg.apply(_this);
|
||||
|
||||
if(!_this.options.videoSrc) {
|
||||
_this.options.videoSrc = _this.$item.getAttribute('data-jarallax-video') || false;
|
||||
}
|
||||
|
||||
if(_this.options.videoSrc) {
|
||||
var video = new VideoWorker(_this.options.videoSrc, {
|
||||
startTime: _this.options.videoStartTime || 0,
|
||||
endTime: _this.options.videoEndTime || 0
|
||||
});
|
||||
|
||||
if(video.isValid()) {
|
||||
_this.image.useImgTag = true;
|
||||
|
||||
video.on('ready', function () {
|
||||
var oldOnScroll = _this.onScroll;
|
||||
_this.onScroll = function () {
|
||||
oldOnScroll.apply(_this);
|
||||
if(_this.isVisible()) {
|
||||
video.play();
|
||||
} else {
|
||||
video.pause();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
video.on('started', function () {
|
||||
_this.image.$default_item = _this.image.$item;
|
||||
_this.image.$item = _this.$video;
|
||||
|
||||
// set video width and height
|
||||
_this.image.width = _this.options.imgWidth = _this.video.videoWidth || 1280;
|
||||
_this.image.height = _this.options.imgHeight = _this.video.videoHeight || 720;
|
||||
_this.coverImage();
|
||||
_this.clipContainer();
|
||||
_this.onScroll();
|
||||
|
||||
// hide image
|
||||
if(_this.image.$default_item) {
|
||||
_this.image.$default_item.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
_this.video = video;
|
||||
|
||||
if(video.type !== 'local') {
|
||||
video.getImageURL(function (url) {
|
||||
_this.image.src = url;
|
||||
_this.init();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// prevent default image loading when not local video
|
||||
if(video.type !== 'local') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// set empty image on local video if not defined
|
||||
else if (!defaultResult) {
|
||||
_this.image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultResult;
|
||||
};
|
||||
|
||||
// Destroy video parallax
|
||||
var def_destroy = Jarallax.prototype.destroy;
|
||||
Jarallax.prototype.destroy = function () {
|
||||
var _this = this;
|
||||
|
||||
def_destroy.apply(_this);
|
||||
};
|
||||
}());
|
||||
695
html/js/modules (optional)/jarallax.js
Executable file
695
html/js/modules (optional)/jarallax.js
Executable file
@@ -0,0 +1,695 @@
|
||||
/*!
|
||||
* Name : Just Another Parallax [Jarallax]
|
||||
* Version : 1.8.0
|
||||
* Author : _nK https://nkdev.info
|
||||
* GitHub : https://github.com/nk-o/jarallax
|
||||
*/
|
||||
(function (window) {
|
||||
'use strict';
|
||||
|
||||
// Adapted from https://gist.github.com/paulirish/1579671
|
||||
if(!Date.now) {
|
||||
Date.now = function () { return new Date().getTime(); };
|
||||
}
|
||||
if(!window.requestAnimationFrame) {
|
||||
(function () {
|
||||
|
||||
var vendors = ['webkit', 'moz'];
|
||||
for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
|
||||
var vp = vendors[i];
|
||||
window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame = window[vp+'CancelAnimationFrame']
|
||||
|| window[vp+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy
|
||||
|| !window.requestAnimationFrame || !window.cancelAnimationFrame) {
|
||||
var lastTime = 0;
|
||||
window.requestAnimationFrame = function (callback) {
|
||||
var now = Date.now();
|
||||
var nextTime = Math.max(lastTime + 16, now);
|
||||
return setTimeout(function () { callback(lastTime = nextTime); },
|
||||
nextTime - now);
|
||||
};
|
||||
window.cancelAnimationFrame = clearTimeout;
|
||||
}
|
||||
}());
|
||||
}
|
||||
|
||||
// test if css property supported by browser
|
||||
// like "transform"
|
||||
var tempDiv = document.createElement('div');
|
||||
function isPropertySupported (property) {
|
||||
var prefixes = ['O','Moz','ms','Ms','Webkit'];
|
||||
var i = prefixes.length;
|
||||
if (tempDiv.style[property] !== undefined) {
|
||||
return true;
|
||||
}
|
||||
property = property.charAt(0).toUpperCase() + property.substr(1);
|
||||
while (--i > -1 && tempDiv.style[prefixes[i] + property] === undefined) { }
|
||||
return i >= 0;
|
||||
}
|
||||
|
||||
var supportTransform = isPropertySupported('transform');
|
||||
var supportTransform3D = isPropertySupported('perspective');
|
||||
|
||||
var ua = navigator.userAgent;
|
||||
var isAndroid = ua.toLowerCase().indexOf('android') > -1;
|
||||
var isIOs = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
|
||||
var isFirefox = ua.toLowerCase().indexOf('firefox') > -1;
|
||||
var isIE = ua.indexOf('MSIE ') > -1 // IE 10 or older
|
||||
|| ua.indexOf('Trident/') > -1 // IE 11
|
||||
|| ua.indexOf('Edge/') > -1; // Edge
|
||||
var isIElt10 = document.all && !window.atob; // IE 9 or older
|
||||
|
||||
var wndW;
|
||||
var wndH;
|
||||
function updateWndVars () {
|
||||
wndW = window.innerWidth || document.documentElement.clientWidth;
|
||||
wndH = window.innerHeight || document.documentElement.clientHeight;
|
||||
}
|
||||
updateWndVars();
|
||||
|
||||
// list with all jarallax instances
|
||||
// need to render all in one scroll/resize event
|
||||
var jarallaxList = [];
|
||||
|
||||
// Jarallax instance
|
||||
var Jarallax = (function () {
|
||||
var instanceID = 0;
|
||||
|
||||
function Jarallax_inner (item, userOptions) {
|
||||
var _this = this,
|
||||
dataOptions;
|
||||
|
||||
_this.$item = item;
|
||||
|
||||
_this.defaults = {
|
||||
type : 'scroll', // type of parallax: scroll, scale, opacity, scale-opacity, scroll-opacity
|
||||
speed : 0.5, // supported value from -1 to 2
|
||||
imgSrc : null,
|
||||
imgWidth : null,
|
||||
imgHeight : null,
|
||||
elementInViewport : null,
|
||||
zIndex : -100,
|
||||
noAndroid : false,
|
||||
noIos : true,
|
||||
|
||||
// events
|
||||
onScroll : null, // function(calculations) {}
|
||||
onInit : null, // function() {}
|
||||
onDestroy : null, // function() {}
|
||||
onCoverImage : null // function() {}
|
||||
};
|
||||
dataOptions = JSON.parse(_this.$item.getAttribute('data-jarallax') || '{}');
|
||||
_this.options = _this.extend({}, _this.defaults, dataOptions, userOptions);
|
||||
|
||||
// stop init if android or ios
|
||||
if(!supportTransform || isAndroid && _this.options.noAndroid || isIOs && _this.options.noIos) {
|
||||
return;
|
||||
}
|
||||
|
||||
// fix speed option [-1.0, 2.0]
|
||||
_this.options.speed = Math.min(2, Math.max(-1, parseFloat(_this.options.speed)));
|
||||
|
||||
// custom element to check if parallax in viewport
|
||||
var elementInVP = _this.options.elementInViewport;
|
||||
// get first item from array
|
||||
if(elementInVP && typeof elementInVP === 'object' && typeof elementInVP.length !== 'undefined') {
|
||||
elementInVP = elementInVP[0];
|
||||
}
|
||||
// check if dom element
|
||||
if(!elementInVP instanceof Element) {
|
||||
elementInVP = null;
|
||||
}
|
||||
_this.options.elementInViewport = elementInVP;
|
||||
|
||||
_this.instanceID = instanceID++;
|
||||
|
||||
_this.image = {
|
||||
src : _this.options.imgSrc || null,
|
||||
$container : null,
|
||||
$item : null,
|
||||
width : _this.options.imgWidth || null,
|
||||
height : _this.options.imgHeight || null,
|
||||
// fix for some devices
|
||||
// use <img> instead of background image - more smoothly
|
||||
useImgTag : isIOs || isAndroid || isIE,
|
||||
|
||||
// position absolute is needed on IE9 and FireFox because fixed position have glitches
|
||||
position : !supportTransform3D || isFirefox ? 'absolute' : 'fixed'
|
||||
};
|
||||
|
||||
if(_this.initImg()) {
|
||||
_this.init();
|
||||
}
|
||||
}
|
||||
|
||||
return Jarallax_inner;
|
||||
}());
|
||||
|
||||
// add styles to element
|
||||
Jarallax.prototype.css = function (el, styles) {
|
||||
if(typeof styles === 'string') {
|
||||
if(window.getComputedStyle) {
|
||||
return window.getComputedStyle(el).getPropertyValue(styles);
|
||||
}
|
||||
return el.style[styles];
|
||||
}
|
||||
|
||||
// add transform property with vendor prefixes
|
||||
if(styles.transform) {
|
||||
if (supportTransform3D) {
|
||||
styles.transform += ' translateZ(0)';
|
||||
}
|
||||
styles.WebkitTransform = styles.MozTransform = styles.msTransform = styles.OTransform = styles.transform;
|
||||
}
|
||||
|
||||
for(var k in styles) {
|
||||
el.style[k] = styles[k];
|
||||
}
|
||||
return el;
|
||||
};
|
||||
// Extend like jQuery.extend
|
||||
Jarallax.prototype.extend = function (out) {
|
||||
out = out || {};
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
if (!arguments[i]) {
|
||||
continue;
|
||||
}
|
||||
for (var key in arguments[i]) {
|
||||
if (arguments[i].hasOwnProperty(key)) {
|
||||
out[key] = arguments[i][key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
// Jarallax functions
|
||||
Jarallax.prototype.initImg = function () {
|
||||
var _this = this;
|
||||
|
||||
// get image src
|
||||
if(_this.image.src === null) {
|
||||
_this.image.src = _this.css(_this.$item, 'background-image').replace(/^url\(['"]?/g,'').replace(/['"]?\)$/g,'');
|
||||
}
|
||||
return !(!_this.image.src || _this.image.src === 'none');
|
||||
};
|
||||
|
||||
Jarallax.prototype.init = function () {
|
||||
var _this = this,
|
||||
containerStyles = {
|
||||
position : 'absolute',
|
||||
top : 0,
|
||||
left : 0,
|
||||
width : '100%',
|
||||
height : '100%',
|
||||
overflow : 'hidden',
|
||||
pointerEvents : 'none'
|
||||
},
|
||||
imageStyles = {};
|
||||
|
||||
// save default user styles
|
||||
_this.$item.setAttribute('data-jarallax-original-styles', _this.$item.getAttribute('style'));
|
||||
|
||||
// set relative position and z-index to the parent
|
||||
if (_this.css(_this.$item, 'position') === 'static') {
|
||||
_this.css(_this.$item, {
|
||||
position: 'relative'
|
||||
});
|
||||
}
|
||||
if (_this.css(_this.$item, 'z-index') === 'auto') {
|
||||
_this.css(_this.$item, {
|
||||
zIndex: 0
|
||||
});
|
||||
}
|
||||
|
||||
// container for parallax image
|
||||
_this.image.$container = document.createElement('div');
|
||||
_this.css(_this.image.$container, containerStyles);
|
||||
_this.css(_this.image.$container, {
|
||||
visibility : 'hidden',
|
||||
'z-index' : _this.options.zIndex
|
||||
});
|
||||
_this.image.$container.setAttribute('id', 'jarallax-container-' + _this.instanceID);
|
||||
_this.$item.appendChild(_this.image.$container);
|
||||
|
||||
// use img tag
|
||||
if(_this.image.useImgTag) {
|
||||
_this.image.$item = document.createElement('img');
|
||||
_this.image.$item.setAttribute('src', _this.image.src);
|
||||
imageStyles = _this.extend({
|
||||
'max-width' : 'none'
|
||||
}, containerStyles, imageStyles);
|
||||
}
|
||||
|
||||
// use div with background image
|
||||
else {
|
||||
_this.image.$item = document.createElement('div');
|
||||
imageStyles = _this.extend({
|
||||
'background-position' : '50% 50%',
|
||||
'background-size' : '100% auto',
|
||||
'background-repeat' : 'no-repeat no-repeat',
|
||||
'background-image' : 'url("' + _this.image.src + '")'
|
||||
}, containerStyles, imageStyles);
|
||||
}
|
||||
|
||||
// check if one of parents have transform style (without this check, scroll transform will be inverted)
|
||||
// discussion - https://github.com/nk-o/jarallax/issues/9
|
||||
var parentWithTransform = 0;
|
||||
var $itemParents = _this.$item;
|
||||
while ($itemParents !== null && $itemParents !== document && parentWithTransform === 0) {
|
||||
var parent_transform = _this.css($itemParents, '-webkit-transform') || _this.css($itemParents, '-moz-transform') || _this.css($itemParents, 'transform');
|
||||
if(parent_transform && parent_transform !== 'none') {
|
||||
parentWithTransform = 1;
|
||||
|
||||
// add transform on parallax container if there is parent with transform
|
||||
_this.css(_this.image.$container, {
|
||||
transform: 'translateX(0) translateY(0)'
|
||||
});
|
||||
}
|
||||
$itemParents = $itemParents.parentNode;
|
||||
}
|
||||
|
||||
// absolute position if one of parents have transformations or parallax without scroll
|
||||
if (parentWithTransform || _this.options.type === 'opacity'|| _this.options.type === 'scale' || _this.options.type === 'scale-opacity') {
|
||||
_this.image.position = 'absolute';
|
||||
}
|
||||
|
||||
// add position to parallax block
|
||||
imageStyles.position = _this.image.position;
|
||||
|
||||
// parallax image
|
||||
_this.css(_this.image.$item, imageStyles);
|
||||
_this.image.$container.appendChild(_this.image.$item);
|
||||
|
||||
// cover image if width and height is ready
|
||||
function initAfterReady () {
|
||||
_this.coverImage();
|
||||
_this.clipContainer();
|
||||
_this.onScroll(true);
|
||||
|
||||
// call onInit event
|
||||
if(_this.options.onInit) {
|
||||
_this.options.onInit.call(_this);
|
||||
}
|
||||
|
||||
// timeout to fix IE blinking
|
||||
setTimeout(function () {
|
||||
if(_this.$item) {
|
||||
// remove default user background
|
||||
_this.css(_this.$item, {
|
||||
'background-image' : 'none',
|
||||
'background-attachment' : 'scroll',
|
||||
'background-size' : 'auto'
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
if(_this.image.width && _this.image.height) {
|
||||
// init if width and height already exists
|
||||
initAfterReady();
|
||||
} else {
|
||||
// load image and get width and height
|
||||
_this.getImageSize(_this.image.src, function (width, height) {
|
||||
_this.image.width = width;
|
||||
_this.image.height = height;
|
||||
initAfterReady();
|
||||
});
|
||||
}
|
||||
|
||||
jarallaxList.push(_this);
|
||||
};
|
||||
|
||||
Jarallax.prototype.destroy = function () {
|
||||
var _this = this;
|
||||
|
||||
// remove from instances list
|
||||
for(var k = 0, len = jarallaxList.length; k < len; k++) {
|
||||
if(jarallaxList[k].instanceID === _this.instanceID) {
|
||||
jarallaxList.splice(k, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// return styles on container as before jarallax init
|
||||
var originalStylesTag = _this.$item.getAttribute('data-jarallax-original-styles');
|
||||
_this.$item.removeAttribute('data-jarallax-original-styles');
|
||||
// null occurs if there is no style tag before jarallax init
|
||||
if(originalStylesTag === 'null') {
|
||||
_this.$item.removeAttribute('style');
|
||||
} else {
|
||||
_this.$item.setAttribute('style', originalStylesTag);
|
||||
}
|
||||
|
||||
// remove additional dom elements
|
||||
if(_this.$clipStyles) {
|
||||
_this.$clipStyles.parentNode.removeChild(_this.$clipStyles);
|
||||
}
|
||||
_this.image.$container.parentNode.removeChild(_this.image.$container);
|
||||
|
||||
// call onDestroy event
|
||||
if(_this.options.onDestroy) {
|
||||
_this.options.onDestroy.call(_this);
|
||||
}
|
||||
|
||||
// delete jarallax from item
|
||||
delete _this.$item.jarallax;
|
||||
|
||||
// delete all variables
|
||||
for(var n in _this) {
|
||||
delete _this[n];
|
||||
}
|
||||
};
|
||||
|
||||
Jarallax.prototype.getImageSize = function (src, callback) {
|
||||
if(!src || !callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tempImg = new Image();
|
||||
tempImg.onload = function () {
|
||||
callback(tempImg.width, tempImg.height);
|
||||
};
|
||||
tempImg.src = src;
|
||||
};
|
||||
|
||||
// it will remove some image overlapping
|
||||
// overlapping occur due to an image position fixed inside absolute position element (webkit based browsers works without any fix)
|
||||
Jarallax.prototype.clipContainer = function () {
|
||||
// clip is not working properly on real IE9 and less
|
||||
if(isIElt10) {
|
||||
return;
|
||||
}
|
||||
|
||||
var _this = this,
|
||||
rect = _this.image.$container.getBoundingClientRect(),
|
||||
width = rect.width,
|
||||
height = rect.height;
|
||||
|
||||
if(!_this.$clipStyles) {
|
||||
_this.$clipStyles = document.createElement('style');
|
||||
_this.$clipStyles.setAttribute('type', 'text/css');
|
||||
_this.$clipStyles.setAttribute('id', '#jarallax-clip-' + _this.instanceID);
|
||||
var head = document.head || document.getElementsByTagName('head')[0];
|
||||
head.appendChild(_this.$clipStyles);
|
||||
}
|
||||
|
||||
var styles = [
|
||||
'#jarallax-container-' + _this.instanceID + ' {',
|
||||
' clip: rect(0 ' + width + 'px ' + height + 'px 0);',
|
||||
' clip: rect(0, ' + width + 'px, ' + height + 'px, 0);',
|
||||
'}'
|
||||
].join('\n');
|
||||
|
||||
// add clip styles inline (this method need for support IE8 and less browsers)
|
||||
if (_this.$clipStyles.styleSheet){
|
||||
_this.$clipStyles.styleSheet.cssText = styles;
|
||||
} else {
|
||||
_this.$clipStyles.innerHTML = styles;
|
||||
}
|
||||
};
|
||||
|
||||
Jarallax.prototype.coverImage = function () {
|
||||
var _this = this;
|
||||
|
||||
if(!_this.image.width || !_this.image.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
var rect = _this.image.$container.getBoundingClientRect(),
|
||||
contW = rect.width,
|
||||
contH = rect.height,
|
||||
contL = rect.left,
|
||||
imgW = _this.image.width,
|
||||
imgH = _this.image.height,
|
||||
speed = _this.options.speed,
|
||||
isScroll = _this.options.type === 'scroll' || _this.options.type === 'scroll-opacity',
|
||||
scrollDist = 0,
|
||||
resultW = 0,
|
||||
resultH = contH,
|
||||
resultML = 0,
|
||||
resultMT = 0;
|
||||
|
||||
// scroll parallax
|
||||
if(isScroll) {
|
||||
// scroll distance and height for image
|
||||
if (speed < 0) {
|
||||
scrollDist = speed * Math.max(contH, wndH);
|
||||
} else {
|
||||
scrollDist = speed * (contH + wndH);
|
||||
}
|
||||
|
||||
// size for scroll parallax
|
||||
if (speed > 1) {
|
||||
resultH = Math.abs(scrollDist - wndH);
|
||||
} else if (speed < 0) {
|
||||
resultH = scrollDist / speed + Math.abs(scrollDist);
|
||||
} else {
|
||||
resultH += Math.abs(wndH - contH) * (1 - speed);
|
||||
}
|
||||
|
||||
scrollDist /= 2;
|
||||
}
|
||||
|
||||
// calculate width relative to height and image size
|
||||
resultW = resultH * imgW / imgH;
|
||||
if(resultW < contW) {
|
||||
resultW = contW;
|
||||
resultH = resultW * imgH / imgW;
|
||||
}
|
||||
|
||||
// center parallax image
|
||||
if(isScroll) {
|
||||
resultML = contL + (contW - resultW) / 2;
|
||||
resultMT = (wndH - resultH) / 2;
|
||||
} else {
|
||||
resultML = (contW - resultW) / 2;
|
||||
resultMT = (contH - resultH) / 2;
|
||||
}
|
||||
|
||||
// fix if parallax block in absolute position
|
||||
if(_this.image.position === 'absolute') {
|
||||
resultML -= contL;
|
||||
}
|
||||
|
||||
// store scroll distance
|
||||
_this.parallaxScrollDistance = scrollDist;
|
||||
|
||||
// apply result to item
|
||||
_this.css(_this.image.$item, {
|
||||
width: resultW + 'px',
|
||||
height: resultH + 'px',
|
||||
marginLeft: resultML + 'px',
|
||||
marginTop: resultMT + 'px'
|
||||
});
|
||||
|
||||
// call onCoverImage event
|
||||
if(_this.options.onCoverImage) {
|
||||
_this.options.onCoverImage.call(_this);
|
||||
}
|
||||
};
|
||||
|
||||
Jarallax.prototype.isVisible = function () {
|
||||
return this.isElementInViewport || false;
|
||||
};
|
||||
|
||||
Jarallax.prototype.onScroll = function (force) {
|
||||
var _this = this;
|
||||
|
||||
if(!_this.image.width || !_this.image.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
var rect = _this.$item.getBoundingClientRect(),
|
||||
contT = rect.top,
|
||||
contH = rect.height,
|
||||
styles = {
|
||||
visibility : 'visible',
|
||||
backgroundPosition : '50% 50%'
|
||||
};
|
||||
|
||||
// check if in viewport
|
||||
var viewportRect = rect;
|
||||
if(_this.options.elementInViewport) {
|
||||
viewportRect = _this.options.elementInViewport.getBoundingClientRect();
|
||||
}
|
||||
_this.isElementInViewport =
|
||||
viewportRect.bottom >= 0 &&
|
||||
viewportRect.right >= 0 &&
|
||||
viewportRect.top <= wndH &&
|
||||
viewportRect.left <= wndW;
|
||||
|
||||
// stop calculations if item is not in viewport
|
||||
if (force ? false : !_this.isElementInViewport) {
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate parallax helping variables
|
||||
var beforeTop = Math.max(0, contT),
|
||||
beforeTopEnd = Math.max(0, contH + contT),
|
||||
afterTop = Math.max(0, -contT),
|
||||
beforeBottom = Math.max(0, contT + contH - wndH),
|
||||
beforeBottomEnd = Math.max(0, contH - (contT + contH - wndH)),
|
||||
afterBottom = Math.max(0, -contT + wndH - contH),
|
||||
fromViewportCenter = 1 - 2 * (wndH - contT) / (wndH + contH);
|
||||
|
||||
// calculate on how percent of section is visible
|
||||
var visiblePercent = 1;
|
||||
if(contH < wndH) {
|
||||
visiblePercent = 1 - (afterTop || beforeBottom) / contH;
|
||||
} else {
|
||||
if(beforeTopEnd <= wndH) {
|
||||
visiblePercent = beforeTopEnd / wndH;
|
||||
} else if (beforeBottomEnd <= wndH) {
|
||||
visiblePercent = beforeBottomEnd / wndH;
|
||||
}
|
||||
}
|
||||
|
||||
// opacity
|
||||
if(_this.options.type === 'opacity' || _this.options.type === 'scale-opacity' || _this.options.type === 'scroll-opacity') {
|
||||
styles.transform = ''; // empty to add translateZ(0) where it is possible
|
||||
styles.opacity = visiblePercent;
|
||||
}
|
||||
|
||||
// scale
|
||||
if(_this.options.type === 'scale' || _this.options.type === 'scale-opacity') {
|
||||
var scale = 1;
|
||||
if(_this.options.speed < 0) {
|
||||
scale -= _this.options.speed * visiblePercent;
|
||||
} else {
|
||||
scale += _this.options.speed * (1 - visiblePercent);
|
||||
}
|
||||
styles.transform = 'scale(' + scale + ')';
|
||||
}
|
||||
|
||||
// scroll
|
||||
if(_this.options.type === 'scroll' || _this.options.type === 'scroll-opacity') {
|
||||
var positionY = _this.parallaxScrollDistance * fromViewportCenter;
|
||||
|
||||
// fix if parallax block in absolute position
|
||||
if(_this.image.position === 'absolute') {
|
||||
positionY -= contT;
|
||||
}
|
||||
|
||||
styles.transform = 'translateY(' + positionY + 'px)';
|
||||
}
|
||||
|
||||
_this.css(_this.image.$item, styles);
|
||||
|
||||
// call onScroll event
|
||||
if(_this.options.onScroll) {
|
||||
_this.options.onScroll.call(_this, {
|
||||
section: rect,
|
||||
|
||||
beforeTop: beforeTop,
|
||||
beforeTopEnd: beforeTopEnd,
|
||||
afterTop: afterTop,
|
||||
beforeBottom: beforeBottom,
|
||||
beforeBottomEnd: beforeBottomEnd,
|
||||
afterBottom: afterBottom,
|
||||
|
||||
visiblePercent: visiblePercent,
|
||||
fromViewportCenter: fromViewportCenter
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// init events
|
||||
function addEventListener (el, eventName, handler) {
|
||||
if (el.addEventListener) {
|
||||
el.addEventListener(eventName, handler);
|
||||
} else {
|
||||
el.attachEvent('on' + eventName, function (){
|
||||
handler.call(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function update (e) {
|
||||
window.requestAnimationFrame(function () {
|
||||
if(e.type !== 'scroll') {
|
||||
updateWndVars();
|
||||
}
|
||||
for(var k = 0, len = jarallaxList.length; k < len; k++) {
|
||||
// cover image and clip needed only when parallax container was changed
|
||||
if(e.type !== 'scroll') {
|
||||
jarallaxList[k].coverImage();
|
||||
jarallaxList[k].clipContainer();
|
||||
}
|
||||
jarallaxList[k].onScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
addEventListener(window, 'scroll', update);
|
||||
addEventListener(window, 'resize', update);
|
||||
addEventListener(window, 'orientationchange', update);
|
||||
addEventListener(window, 'load', update);
|
||||
|
||||
|
||||
// global definition
|
||||
var plugin = function (items) {
|
||||
// check for dom element
|
||||
// thanks: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
|
||||
if(typeof HTMLElement === "object" ? items instanceof HTMLElement : items && typeof items === "object" && items !== null && items.nodeType === 1 && typeof items.nodeName==="string") {
|
||||
items = [items];
|
||||
}
|
||||
|
||||
var options = arguments[1],
|
||||
args = Array.prototype.slice.call(arguments, 2),
|
||||
len = items.length,
|
||||
k = 0,
|
||||
ret;
|
||||
|
||||
for (k; k < len; k++) {
|
||||
if (typeof options === 'object' || typeof options === 'undefined') {
|
||||
if(!items[k].jarallax) {
|
||||
items[k].jarallax = new Jarallax(items[k], options);
|
||||
}
|
||||
}
|
||||
else if(items[k].jarallax) {
|
||||
ret = items[k].jarallax[options].apply(items[k].jarallax, args);
|
||||
}
|
||||
if (typeof ret !== 'undefined') {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
plugin.constructor = Jarallax;
|
||||
|
||||
// no conflict
|
||||
var oldPlugin = window.jarallax;
|
||||
window.jarallax = plugin;
|
||||
window.jarallax.noConflict = function () {
|
||||
window.jarallax = oldPlugin;
|
||||
return this;
|
||||
};
|
||||
|
||||
// jQuery support
|
||||
if(typeof jQuery !== 'undefined') {
|
||||
var jQueryPlugin = function () {
|
||||
var args = arguments || [];
|
||||
Array.prototype.unshift.call(args, this);
|
||||
var res = plugin.apply(window, args);
|
||||
return typeof res !== 'object' ? res : this;
|
||||
};
|
||||
jQueryPlugin.constructor = Jarallax;
|
||||
|
||||
// no conflict
|
||||
var oldJqPlugin = jQuery.fn.jarallax;
|
||||
jQuery.fn.jarallax = jQueryPlugin;
|
||||
jQuery.fn.jarallax.noConflict = function () {
|
||||
jQuery.fn.jarallax = oldJqPlugin;
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
// data-jarallax initialization
|
||||
addEventListener(window, 'DOMContentLoaded', function () {
|
||||
plugin(document.querySelectorAll('[data-jarallax], [data-jarallax-video]'));
|
||||
});
|
||||
}(window));
|
||||
205
html/js/modules (optional)/jquery-easing.js
vendored
Normal file
205
html/js/modules (optional)/jquery-easing.js
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
*
|
||||
* Uses the built in easing capabilities added In jQuery 1.1
|
||||
* to offer multiple easing options
|
||||
*
|
||||
* TERMS OF USE - jQuery Easing
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright © 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// t: current time, b: begInnIng value, c: change In value, d: duration
|
||||
jQuery.easing['jswing'] = jQuery.easing['swing'];
|
||||
|
||||
jQuery.extend( jQuery.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x, t, b, c, d) {
|
||||
//alert(jQuery.easing.default);
|
||||
return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
|
||||
},
|
||||
easeInQuad: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
easeOutQuad: function (x, t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
easeInOutQuad: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
easeInCubic: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
easeOutCubic: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t + 1) + b;
|
||||
},
|
||||
easeInOutCubic: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t + 2) + b;
|
||||
},
|
||||
easeInQuart: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t + b;
|
||||
},
|
||||
easeOutQuart: function (x, t, b, c, d) {
|
||||
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
||||
},
|
||||
easeInOutQuart: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
||||
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
||||
},
|
||||
easeInQuint: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t*t + b;
|
||||
},
|
||||
easeOutQuint: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
||||
},
|
||||
easeInOutQuint: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
||||
},
|
||||
easeInSine: function (x, t, b, c, d) {
|
||||
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
||||
},
|
||||
easeOutSine: function (x, t, b, c, d) {
|
||||
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
||||
},
|
||||
easeInOutSine: function (x, t, b, c, d) {
|
||||
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
||||
},
|
||||
easeInExpo: function (x, t, b, c, d) {
|
||||
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
||||
},
|
||||
easeOutExpo: function (x, t, b, c, d) {
|
||||
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
||||
},
|
||||
easeInOutExpo: function (x, t, b, c, d) {
|
||||
if (t==0) return b;
|
||||
if (t==d) return b+c;
|
||||
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||
},
|
||||
easeInCirc: function (x, t, b, c, d) {
|
||||
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
||||
},
|
||||
easeOutCirc: function (x, t, b, c, d) {
|
||||
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
||||
},
|
||||
easeInOutCirc: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
||||
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
||||
},
|
||||
easeInElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
},
|
||||
easeOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
},
|
||||
easeInOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
||||
},
|
||||
easeInBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*(t/=d)*t*((s+1)*t - s) + b;
|
||||
},
|
||||
easeOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
||||
},
|
||||
easeInOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
||||
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
||||
},
|
||||
easeInBounce: function (x, t, b, c, d) {
|
||||
return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
||||
},
|
||||
easeOutBounce: function (x, t, b, c, d) {
|
||||
if ((t/=d) < (1/2.75)) {
|
||||
return c*(7.5625*t*t) + b;
|
||||
} else if (t < (2/2.75)) {
|
||||
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
||||
} else if (t < (2.5/2.75)) {
|
||||
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
||||
} else {
|
||||
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function (x, t, b, c, d) {
|
||||
if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
||||
return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright © 2001 Robert Penner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
205
html/js/modules (optional)/jquery.easing.js
Executable file
205
html/js/modules (optional)/jquery.easing.js
Executable file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
*
|
||||
* Uses the built in easing capabilities added In jQuery 1.1
|
||||
* to offer multiple easing options
|
||||
*
|
||||
* TERMS OF USE - jQuery Easing
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright © 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// t: current time, b: begInnIng value, c: change In value, d: duration
|
||||
jQuery.easing['jswing'] = jQuery.easing['swing'];
|
||||
|
||||
jQuery.extend( jQuery.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x, t, b, c, d) {
|
||||
//alert(jQuery.easing.default);
|
||||
return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
|
||||
},
|
||||
easeInQuad: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
easeOutQuad: function (x, t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
easeInOutQuad: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
easeInCubic: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
easeOutCubic: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t + 1) + b;
|
||||
},
|
||||
easeInOutCubic: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t + 2) + b;
|
||||
},
|
||||
easeInQuart: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t + b;
|
||||
},
|
||||
easeOutQuart: function (x, t, b, c, d) {
|
||||
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
||||
},
|
||||
easeInOutQuart: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
||||
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
||||
},
|
||||
easeInQuint: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t*t + b;
|
||||
},
|
||||
easeOutQuint: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
||||
},
|
||||
easeInOutQuint: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
||||
},
|
||||
easeInSine: function (x, t, b, c, d) {
|
||||
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
||||
},
|
||||
easeOutSine: function (x, t, b, c, d) {
|
||||
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
||||
},
|
||||
easeInOutSine: function (x, t, b, c, d) {
|
||||
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
||||
},
|
||||
easeInExpo: function (x, t, b, c, d) {
|
||||
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
||||
},
|
||||
easeOutExpo: function (x, t, b, c, d) {
|
||||
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
||||
},
|
||||
easeInOutExpo: function (x, t, b, c, d) {
|
||||
if (t==0) return b;
|
||||
if (t==d) return b+c;
|
||||
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||
},
|
||||
easeInCirc: function (x, t, b, c, d) {
|
||||
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
||||
},
|
||||
easeOutCirc: function (x, t, b, c, d) {
|
||||
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
||||
},
|
||||
easeInOutCirc: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
||||
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
||||
},
|
||||
easeInElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
},
|
||||
easeOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
},
|
||||
easeInOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
||||
},
|
||||
easeInBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*(t/=d)*t*((s+1)*t - s) + b;
|
||||
},
|
||||
easeOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
||||
},
|
||||
easeInOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
||||
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
||||
},
|
||||
easeInBounce: function (x, t, b, c, d) {
|
||||
return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
||||
},
|
||||
easeOutBounce: function (x, t, b, c, d) {
|
||||
if ((t/=d) < (1/2.75)) {
|
||||
return c*(7.5625*t*t) + b;
|
||||
} else if (t < (2/2.75)) {
|
||||
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
||||
} else if (t < (2.5/2.75)) {
|
||||
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
||||
} else {
|
||||
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function (x, t, b, c, d) {
|
||||
if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
||||
return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright © 2001 Robert Penner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
364
html/js/modules (optional)/jquery.easypiechart.js
Executable file
364
html/js/modules (optional)/jquery.easypiechart.js
Executable file
@@ -0,0 +1,364 @@
|
||||
/**!
|
||||
* easy-pie-chart
|
||||
* Lightweight plugin to render simple, animated and retina optimized pie charts
|
||||
*
|
||||
* @license
|
||||
* @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
|
||||
* @version 2.1.7
|
||||
**/
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module unless amdModuleId is set
|
||||
define(["jquery"], function (a0) {
|
||||
return (factory(a0));
|
||||
});
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node. Does not work with strict CommonJS, but
|
||||
// only CommonJS-like environments that support module.exports,
|
||||
// like Node.
|
||||
module.exports = factory(require("jquery"));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(this, function ($) {
|
||||
|
||||
/**
|
||||
* Renderer to render the chart on a canvas object
|
||||
* @param {DOMElement} el DOM element to host the canvas (root of the plugin)
|
||||
* @param {object} options options object of the plugin
|
||||
*/
|
||||
var CanvasRenderer = function(el, options) {
|
||||
var cachedBackground;
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
el.appendChild(canvas);
|
||||
|
||||
if (typeof(G_vmlCanvasManager) === 'object') {
|
||||
G_vmlCanvasManager.initElement(canvas);
|
||||
}
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = canvas.height = options.size;
|
||||
|
||||
// canvas on retina devices
|
||||
var scaleBy = 1;
|
||||
if (window.devicePixelRatio > 1) {
|
||||
scaleBy = window.devicePixelRatio;
|
||||
canvas.style.width = canvas.style.height = [options.size, 'px'].join('');
|
||||
canvas.width = canvas.height = options.size * scaleBy;
|
||||
ctx.scale(scaleBy, scaleBy);
|
||||
}
|
||||
|
||||
// move 0,0 coordinates to the center
|
||||
ctx.translate(options.size / 2, options.size / 2);
|
||||
|
||||
// rotate canvas -90deg
|
||||
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);
|
||||
|
||||
var radius = (options.size - options.lineWidth) / 2;
|
||||
if (options.scaleColor && options.scaleLength) {
|
||||
radius -= options.scaleLength + 2; // 2 is the distance between scale and bar
|
||||
}
|
||||
|
||||
// IE polyfill for Date
|
||||
Date.now = Date.now || function() {
|
||||
return +(new Date());
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw a circle around the center of the canvas
|
||||
* @param {strong} color Valid CSS color string
|
||||
* @param {number} lineWidth Width of the line in px
|
||||
* @param {number} percent Percentage to draw (float between -1 and 1)
|
||||
*/
|
||||
var drawCircle = function(color, lineWidth, percent) {
|
||||
percent = Math.min(Math.max(-1, percent || 0), 1);
|
||||
var isNegative = percent <= 0 ? true : false;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);
|
||||
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the scale of the chart
|
||||
*/
|
||||
var drawScale = function() {
|
||||
var offset;
|
||||
var length;
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
ctx.fillStyle = options.scaleColor;
|
||||
|
||||
ctx.save();
|
||||
for (var i = 24; i > 0; --i) {
|
||||
if (i % 6 === 0) {
|
||||
length = options.scaleLength;
|
||||
offset = 0;
|
||||
} else {
|
||||
length = options.scaleLength * 0.6;
|
||||
offset = options.scaleLength - length;
|
||||
}
|
||||
ctx.fillRect(-options.size/2 + offset, 0, length, 1);
|
||||
ctx.rotate(Math.PI / 12);
|
||||
}
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
/**
|
||||
* Request animation frame wrapper with polyfill
|
||||
* @return {function} Request animation frame method or timeout fallback
|
||||
*/
|
||||
var reqAnimationFrame = (function() {
|
||||
return window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
function(callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* Draw the background of the plugin including the scale and the track
|
||||
*/
|
||||
var drawBackground = function() {
|
||||
if(options.scaleColor) drawScale();
|
||||
if(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Canvas accessor
|
||||
*/
|
||||
this.getCanvas = function() {
|
||||
return canvas;
|
||||
};
|
||||
|
||||
/**
|
||||
* Canvas 2D context 'ctx' accessor
|
||||
*/
|
||||
this.getCtx = function() {
|
||||
return ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the complete canvas
|
||||
*/
|
||||
this.clear = function() {
|
||||
ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the complete chart
|
||||
* @param {number} percent Percent shown by the chart between -100 and 100
|
||||
*/
|
||||
this.draw = function(percent) {
|
||||
// do we need to render a background
|
||||
if (!!options.scaleColor || !!options.trackColor) {
|
||||
// getImageData and putImageData are supported
|
||||
if (ctx.getImageData && ctx.putImageData) {
|
||||
if (!cachedBackground) {
|
||||
drawBackground();
|
||||
cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);
|
||||
} else {
|
||||
ctx.putImageData(cachedBackground, 0, 0);
|
||||
}
|
||||
} else {
|
||||
this.clear();
|
||||
drawBackground();
|
||||
}
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
ctx.lineCap = options.lineCap;
|
||||
|
||||
// if barcolor is a function execute it and pass the percent as a value
|
||||
var color;
|
||||
if (typeof(options.barColor) === 'function') {
|
||||
color = options.barColor(percent);
|
||||
} else {
|
||||
color = options.barColor;
|
||||
}
|
||||
|
||||
// draw bar
|
||||
drawCircle(color, options.lineWidth, percent / 100);
|
||||
}.bind(this);
|
||||
|
||||
/**
|
||||
* Animate from some percent to some other percentage
|
||||
* @param {number} from Starting percentage
|
||||
* @param {number} to Final percentage
|
||||
*/
|
||||
this.animate = function(from, to) {
|
||||
var startTime = Date.now();
|
||||
options.onStart(from, to);
|
||||
var animation = function() {
|
||||
var process = Math.min(Date.now() - startTime, options.animate.duration);
|
||||
var currentValue = options.easing(this, process, from, to - from, options.animate.duration);
|
||||
this.draw(currentValue);
|
||||
options.onStep(from, to, currentValue);
|
||||
if (process >= options.animate.duration) {
|
||||
options.onStop(from, to);
|
||||
} else {
|
||||
reqAnimationFrame(animation);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
reqAnimationFrame(animation);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
var EasyPieChart = function(el, opts) {
|
||||
var defaultOptions = {
|
||||
barColor: '#ef1e25',
|
||||
trackColor: '#f9f9f9',
|
||||
scaleColor: '#dfe0e0',
|
||||
scaleLength: 5,
|
||||
lineCap: 'round',
|
||||
lineWidth: 3,
|
||||
trackWidth: undefined,
|
||||
size: 110,
|
||||
rotate: 0,
|
||||
animate: {
|
||||
duration: 1000,
|
||||
enabled: true
|
||||
},
|
||||
easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
t = t / (d/2);
|
||||
if (t < 1) {
|
||||
return c / 2 * t * t + b;
|
||||
}
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
onStart: function(from, to) {
|
||||
return;
|
||||
},
|
||||
onStep: function(from, to, currentValue) {
|
||||
return;
|
||||
},
|
||||
onStop: function(from, to) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// detect present renderer
|
||||
if (typeof(CanvasRenderer) !== 'undefined') {
|
||||
defaultOptions.renderer = CanvasRenderer;
|
||||
} else if (typeof(SVGRenderer) !== 'undefined') {
|
||||
defaultOptions.renderer = SVGRenderer;
|
||||
} else {
|
||||
throw new Error('Please load either the SVG- or the CanvasRenderer');
|
||||
}
|
||||
|
||||
var options = {};
|
||||
var currentValue = 0;
|
||||
|
||||
/**
|
||||
* Initialize the plugin by creating the options object and initialize rendering
|
||||
*/
|
||||
var init = function() {
|
||||
this.el = el;
|
||||
this.options = options;
|
||||
|
||||
// merge user options into default options
|
||||
for (var i in defaultOptions) {
|
||||
if (defaultOptions.hasOwnProperty(i)) {
|
||||
options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];
|
||||
if (typeof(options[i]) === 'function') {
|
||||
options[i] = options[i].bind(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for jQuery easing
|
||||
if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {
|
||||
options.easing = jQuery.easing[options.easing];
|
||||
} else {
|
||||
options.easing = defaultOptions.easing;
|
||||
}
|
||||
|
||||
// process earlier animate option to avoid bc breaks
|
||||
if (typeof(options.animate) === 'number') {
|
||||
options.animate = {
|
||||
duration: options.animate,
|
||||
enabled: true
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof(options.animate) === 'boolean' && !options.animate) {
|
||||
options.animate = {
|
||||
duration: 1000,
|
||||
enabled: options.animate
|
||||
};
|
||||
}
|
||||
|
||||
// create renderer
|
||||
this.renderer = new options.renderer(el, options);
|
||||
|
||||
// initial draw
|
||||
this.renderer.draw(currentValue);
|
||||
|
||||
// initial update
|
||||
if (el.dataset && el.dataset.percent) {
|
||||
this.update(parseFloat(el.dataset.percent));
|
||||
} else if (el.getAttribute && el.getAttribute('data-percent')) {
|
||||
this.update(parseFloat(el.getAttribute('data-percent')));
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
/**
|
||||
* Update the value of the chart
|
||||
* @param {number} newValue Number between 0 and 100
|
||||
* @return {object} Instance of the plugin for method chaining
|
||||
*/
|
||||
this.update = function(newValue) {
|
||||
newValue = parseFloat(newValue);
|
||||
if (options.animate.enabled) {
|
||||
this.renderer.animate(currentValue, newValue);
|
||||
} else {
|
||||
this.renderer.draw(newValue);
|
||||
}
|
||||
currentValue = newValue;
|
||||
return this;
|
||||
}.bind(this);
|
||||
|
||||
/**
|
||||
* Disable animation
|
||||
* @return {object} Instance of the plugin for method chaining
|
||||
*/
|
||||
this.disableAnimation = function() {
|
||||
options.animate.enabled = false;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable animation
|
||||
* @return {object} Instance of the plugin for method chaining
|
||||
*/
|
||||
this.enableAnimation = function() {
|
||||
options.animate.enabled = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
$.fn.easyPieChart = function(options) {
|
||||
return this.each(function() {
|
||||
var instanceOptions;
|
||||
|
||||
if (!$.data(this, 'easyPieChart')) {
|
||||
instanceOptions = $.extend({}, options, $(this).data());
|
||||
$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
}));
|
||||
33
html/js/modules (optional)/jquery.hammer.js
Executable file
33
html/js/modules (optional)/jquery.hammer.js
Executable file
@@ -0,0 +1,33 @@
|
||||
(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery', 'hammerjs'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
factory(require('jquery'), require('hammerjs'));
|
||||
} else {
|
||||
factory(jQuery, Hammer);
|
||||
}
|
||||
}(function($, Hammer) {
|
||||
function hammerify(el, options) {
|
||||
var $el = $(el);
|
||||
if(!$el.data("hammer")) {
|
||||
$el.data("hammer", new Hammer($el[0], options));
|
||||
}
|
||||
}
|
||||
|
||||
$.fn.hammer = function(options) {
|
||||
return this.each(function() {
|
||||
hammerify(this, options);
|
||||
});
|
||||
};
|
||||
|
||||
// extend the emit method to also trigger jQuery events
|
||||
Hammer.Manager.prototype.emit = (function(originalEmit) {
|
||||
return function(type, data) {
|
||||
originalEmit.call(this, type, data);
|
||||
$(this.element).trigger({
|
||||
type: type,
|
||||
gesture: data
|
||||
});
|
||||
};
|
||||
})(Hammer.Manager.prototype.emit);
|
||||
}));
|
||||
98
html/js/modules (optional)/jquery.jsticky.js
Normal file
98
html/js/modules (optional)/jquery.jsticky.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/* jSticky Plugin
|
||||
* =============
|
||||
* Author: Andrew Henderson (@AndrewHenderson)
|
||||
* Date: 9/7/2012
|
||||
* Update: 02/14/2013
|
||||
* Website: http://github.com/andrewhenderson/jsticky/
|
||||
* Description: A jQuery plugin that keeps select DOM
|
||||
* element(s) in view while scrolling the page.
|
||||
*/
|
||||
|
||||
;(function($) {
|
||||
|
||||
$.fn.sticky = function(options) {
|
||||
|
||||
var defaults = {
|
||||
topSpacing: 0, // No spacing by default
|
||||
zIndex: '', // No default z-index
|
||||
stopper: '.sticky-stopper' // Default stopper class, also accepts number value
|
||||
},
|
||||
settings = $.extend({}, defaults, options); // Accepts custom stopper id or class
|
||||
|
||||
// Checks if custom z-index was defined
|
||||
function checkIndex() {
|
||||
|
||||
if (typeof settings.zIndex == 'number') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var hasIndex = checkIndex(); // True or false
|
||||
|
||||
// Checks if a stopper exists in the DOM or number defined
|
||||
function checkStopper() {
|
||||
|
||||
if ( 0 < $(settings.stopper).length || typeof settings.stopper === 'number' ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var hasStopper = checkStopper(); // True or false
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
var $this = $(this),
|
||||
thisHeight = $this.outerHeight(),
|
||||
thisWidth = $this.outerWidth(),
|
||||
topSpacing = settings.topSpacing,
|
||||
zIndex = settings.zIndex,
|
||||
pushPoint = $this.offset().top - topSpacing, // Point at which the sticky element starts pushing
|
||||
placeholder = $('<div></div>').width(thisWidth).height(thisHeight).addClass('sticky-placeholder'), // Cache a clone sticky element
|
||||
stopper = settings.stopper,
|
||||
$window = $(window);
|
||||
|
||||
function stickyScroll() {
|
||||
|
||||
var windowTop = $window.scrollTop(); // Check window's scroll position
|
||||
|
||||
if ( hasStopper && typeof stopper === 'string' ) {
|
||||
var stopperTop = $(stopper).offset().top,
|
||||
stopPoint = (stopperTop - thisHeight) - topSpacing;
|
||||
} else if (hasStopper && typeof stopper === 'number') {
|
||||
var stopPoint = stopper;
|
||||
}
|
||||
|
||||
if (pushPoint < windowTop) {
|
||||
// Create a placeholder for sticky element to occupy vertical real estate
|
||||
$this.after(placeholder).css({
|
||||
position: 'fixed',
|
||||
top: topSpacing
|
||||
});
|
||||
|
||||
if (hasIndex) {
|
||||
$this.css({ zIndex: zIndex });
|
||||
}
|
||||
|
||||
if (hasStopper) {
|
||||
if (stopPoint < windowTop) {
|
||||
var diff = (stopPoint - windowTop) + topSpacing;
|
||||
$this.css({ top: diff });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this.css({
|
||||
position: 'static',
|
||||
top: null,
|
||||
left: null
|
||||
});
|
||||
|
||||
placeholder.remove();
|
||||
}
|
||||
};
|
||||
|
||||
$window.bind("scroll", stickyScroll);
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
117
html/js/modules (optional)/jquery.sticky.js
Executable file
117
html/js/modules (optional)/jquery.sticky.js
Executable file
@@ -0,0 +1,117 @@
|
||||
/* jSticky Plugin
|
||||
* =============
|
||||
* Author: Andrew Henderson (@AndrewHenderson)
|
||||
* Contributor: Mike Street (@mikestreety)
|
||||
* Date: 9/7/2012
|
||||
* Update: 09/20/2016
|
||||
* Website: http://github.com/andrewhenderson/jsticky/
|
||||
* Description: A jQuery plugin that keeps select DOM
|
||||
* element(s) in view while scrolling the page.
|
||||
*/
|
||||
|
||||
;(function($) {
|
||||
|
||||
$.fn.sticky = function(options) {
|
||||
var defaults = {
|
||||
topSpacing: 0, // No spacing by default
|
||||
zIndex: '', // No default z-index
|
||||
stopper: '.sticky-stopper', // Default stopper class, also accepts number value
|
||||
stickyClass: false // Class applied to element when it's stuck
|
||||
};
|
||||
var settings = $.extend({}, defaults, options); // Accepts custom stopper id or class
|
||||
|
||||
// Checks if custom z-index was defined
|
||||
function checkIndex() {
|
||||
if (typeof settings.zIndex == 'number') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var hasIndex = checkIndex(); // True or false
|
||||
|
||||
// Checks if a stopper exists in the DOM or number defined
|
||||
function checkStopper() {
|
||||
if (0 < $(settings.stopper).length || typeof settings.stopper === 'number') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var hasStopper = checkStopper(); // True or false
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
var $this = $(this);
|
||||
var thisHeight = $this.outerHeight();
|
||||
var thisWidth = $this.outerWidth();
|
||||
var topSpacing = settings.topSpacing;
|
||||
var zIndex = settings.zIndex;
|
||||
var pushPoint = $this.offset().top - topSpacing; // Point at which the sticky element starts pushing
|
||||
var placeholder = $('<div></div>').width(thisWidth).height(thisHeight).addClass('sticky-placeholder'); // Cache a clone sticky element
|
||||
var stopper = settings.stopper;
|
||||
var $window = $(window);
|
||||
|
||||
function stickyScroll() {
|
||||
|
||||
var windowTop = $window.scrollTop(); // Check window's scroll position
|
||||
var stopPoint = stopper;
|
||||
var parentWidth = $this.parent().width();
|
||||
|
||||
placeholder.width(parentWidth)
|
||||
|
||||
if ( hasStopper && typeof stopper === 'string' ) {
|
||||
var stopperTop = $(stopper).offset().top;
|
||||
stopPoint = (stopperTop - thisHeight) - topSpacing;
|
||||
}
|
||||
|
||||
if (pushPoint < windowTop) {
|
||||
// Create a placeholder for sticky element to occupy vertical real estate
|
||||
if(settings.stickyClass)
|
||||
$this.addClass(settings.stickyClass);
|
||||
|
||||
$this.after(placeholder).css({
|
||||
position: 'fixed',
|
||||
top: topSpacing,
|
||||
width: parentWidth
|
||||
});
|
||||
|
||||
if (hasIndex) {
|
||||
$this.css({
|
||||
zIndex: zIndex
|
||||
});
|
||||
}
|
||||
|
||||
if (hasStopper) {
|
||||
if (stopPoint < windowTop) {
|
||||
var diff = (stopPoint - windowTop) + topSpacing;
|
||||
$this.css({
|
||||
top: diff
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(settings.stickyClass)
|
||||
$this.removeClass(settings.stickyClass);
|
||||
|
||||
$this.css({
|
||||
position: 'static',
|
||||
top: null,
|
||||
left: null,
|
||||
width: 'auto'
|
||||
});
|
||||
|
||||
placeholder.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if($window.innerHeight() > thisHeight) {
|
||||
|
||||
$window.bind('scroll', stickyScroll);
|
||||
$window.bind('load', stickyScroll);
|
||||
$window.bind('resize', stickyScroll);
|
||||
}
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
1608
html/js/modules (optional)/lightbox.js
Executable file
1608
html/js/modules (optional)/lightbox.js
Executable file
File diff suppressed because it is too large
Load Diff
401
html/js/modules (optional)/material-select.js
Executable file
401
html/js/modules (optional)/material-select.js
Executable file
@@ -0,0 +1,401 @@
|
||||
'use strict';
|
||||
|
||||
(function ($) {
|
||||
|
||||
$.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 = Boolean($select.attr('multiple')),
|
||||
lastID = $select.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.data('select-id', null).removeClass('initialized');
|
||||
return;
|
||||
}
|
||||
|
||||
var uniqueID = guid(); // Materialize.guid();
|
||||
$select.data('select-id', uniqueID);
|
||||
var wrapper = $('<div class="select-wrapper"></div>');
|
||||
wrapper.addClass($select.attr('class'));
|
||||
var options = $('<ul id="select-options-' + uniqueID + '" class="dropdown-content select-dropdown ' + (multiple ? 'multiple-select-dropdown' : '') + '"></ul>'),
|
||||
selectChildren = $select.children('option, optgroup'),
|
||||
valuesSelected = [],
|
||||
optionsHover = false;
|
||||
|
||||
var label = $select.find('option:selected').html() || $select.find('option:first').html() || '';
|
||||
|
||||
// Added to search
|
||||
var applySeachInList = function applySeachInList() {
|
||||
|
||||
var ul = $(this).closest('ul');
|
||||
var searchValue = $(this).val();
|
||||
var options = ul.find('li').find('span.filtrable');
|
||||
|
||||
options.each(function () {
|
||||
if (typeof this.outerText === 'string') {
|
||||
var liValue = this.outerText.toLowerCase();
|
||||
|
||||
if (liValue.indexOf(searchValue.toLowerCase()) === -1) {
|
||||
$(this).hide();
|
||||
$(this).parent().hide();
|
||||
} else {
|
||||
$(this).show();
|
||||
$(this).parent().show();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Added to search
|
||||
var setSearchableOption = function setSearchableOption() {
|
||||
var placeholder = $select.attr('searchable');
|
||||
var element = $('<span class="search-wrap"><input type="text" class="search" placeholder="' + placeholder + '"></span>');
|
||||
options.append(element);
|
||||
element.find('.search').keyup(applySeachInList);
|
||||
};
|
||||
|
||||
// Added to search
|
||||
var searchable = Boolean($select.attr('searchable'));
|
||||
|
||||
// Added to search
|
||||
if (searchable) {
|
||||
setSearchableOption();
|
||||
}
|
||||
|
||||
// Function that renders and appends the option taking into
|
||||
// account type and possible image icon.
|
||||
var appendOptionWithIcon = function appendOptionWithIcon(select, option, type) {
|
||||
// Add disabled attr if disabled
|
||||
var disabledClass = option.is(':disabled') ? 'disabled ' : '';
|
||||
var optgroupClass = type === 'optgroup-option' ? 'optgroup-option ' : '';
|
||||
|
||||
// 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.
|
||||
if (type === 'multiple') {
|
||||
options.append($('<li class="' + disabledClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span class="filtrable"><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
|
||||
} else {
|
||||
options.append($('<li class="' + disabledClass + optgroupClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span class="filtrable">' + option.html() + '</span></li>'));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for multiple type.
|
||||
if (type === 'multiple') {
|
||||
options.append($('<li class="' + disabledClass + '"><span class="filtrable"><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
|
||||
} else {
|
||||
options.append($('<li class="' + disabledClass + optgroupClass + '"><span class="filtrable">' + option.html() + '</span></li>'));
|
||||
}
|
||||
};
|
||||
|
||||
/* 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($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'));
|
||||
|
||||
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, $(this).index() - 1, $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 = $('<span class="caret">▼</span>');
|
||||
if ($select.is(':disabled')) {
|
||||
dropdownIcon.addClass('disabled');
|
||||
}
|
||||
|
||||
// escape double quotes
|
||||
var sanitizedLabelHtml = label.replace(/"/g, '"');
|
||||
|
||||
var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + ($select.is(':disabled') ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID + '" value="' + sanitizedLabelHtml + '"/>');
|
||||
$select.before($newSelect);
|
||||
$newSelect.before(dropdownIcon);
|
||||
|
||||
$newSelect.after(options);
|
||||
// Check if section element is disabled
|
||||
if (!$select.is(':disabled')) {
|
||||
$newSelect.dropdown({
|
||||
hover: false,
|
||||
closeOnClick: false
|
||||
});
|
||||
}
|
||||
|
||||
// Copy tabindex
|
||||
if ($select.attr('tabindex')) {
|
||||
$($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
|
||||
}
|
||||
|
||||
$select.addClass('initialized');
|
||||
|
||||
$newSelect.on({
|
||||
focus: function focus() {
|
||||
if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
|
||||
$('input.select-dropdown').trigger('close');
|
||||
}
|
||||
if (!options.is(':visible')) {
|
||||
$(this).trigger('open', ['focus']);
|
||||
var _label = $(this).val();
|
||||
var selectedOption = options.find('li').filter(function () {
|
||||
return $(this).text().toLowerCase() === _label.toLowerCase();
|
||||
})[0];
|
||||
activateOption(options, selectedOption);
|
||||
}
|
||||
},
|
||||
click: function click(e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// Changed to search to treat search
|
||||
$newSelect.on('blur', function () {
|
||||
|
||||
if (!multiple && !searchable) {
|
||||
$(this).trigger('close');
|
||||
}
|
||||
options.find('li.selected').removeClass('selected');
|
||||
});
|
||||
|
||||
// Added to search
|
||||
if (!multiple && searchable) {
|
||||
options.find('li').on('click', function () {
|
||||
$newSelect.trigger('close');
|
||||
});
|
||||
}
|
||||
|
||||
options.hover(function () {
|
||||
optionsHover = true;
|
||||
}, function () {
|
||||
optionsHover = false;
|
||||
});
|
||||
|
||||
// Changed to search to treat search
|
||||
$(window).on({
|
||||
click: function click() {
|
||||
(multiple || searchable) && (optionsHover || $newSelect.trigger('close'));
|
||||
}
|
||||
});
|
||||
|
||||
// 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').eq(index).find(':checkbox').prop('checked', true);
|
||||
});
|
||||
}
|
||||
|
||||
// Make option as selected and scroll to selected position
|
||||
var activateOption = function activateOption(collection, newOption) {
|
||||
if (newOption) {
|
||||
collection.find('li.selected').removeClass('selected');
|
||||
var option = $(newOption);
|
||||
option.addClass('selected');
|
||||
// commented because it causes problems in multiselect with many options
|
||||
// options.scrollTo(option)
|
||||
}
|
||||
};
|
||||
|
||||
// Allow user to search by typing
|
||||
// this array is cleared after 1 second
|
||||
var filterQuery = [],
|
||||
onKeyDown = function onKeyDown(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').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);
|
||||
}
|
||||
// };
|
||||
|
||||
function guid() {
|
||||
var d = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = (d + Math.random() * 16) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
jQuery('select').siblings('input.select-dropdown').on('mousedown', function (e) {
|
||||
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
|
||||
if (e.clientX >= e.target.clientWidth || e.clientY >= e.target.clientHeight) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
87
html/js/modules (optional)/mdb-autocomplete.js
Executable file
87
html/js/modules (optional)/mdb-autocomplete.js
Executable file
@@ -0,0 +1,87 @@
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* Material Design for Bootstrap
|
||||
* MDB Autocomplete Plugin
|
||||
*/
|
||||
|
||||
$.fn.mdb_autocomplete = function (options) {
|
||||
|
||||
// Default options
|
||||
var defaults = {
|
||||
data: {}
|
||||
};
|
||||
|
||||
var ENTER_CHAR_CODE = 13;
|
||||
|
||||
// Get options
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
// text input
|
||||
var $input = $(this);
|
||||
var $autocomplete = void 0;
|
||||
|
||||
// assign data from options
|
||||
var data = options.data;
|
||||
|
||||
if (Object.keys(data).length) {
|
||||
|
||||
$autocomplete = $('<ul class="mdb-autocomplete-wrap"></ul>');
|
||||
|
||||
$autocomplete.insertAfter($(this));
|
||||
};
|
||||
|
||||
// Listen if key was pressed
|
||||
$input.on('keyup', function (e) {
|
||||
|
||||
// get value from input
|
||||
var q = $input.val();
|
||||
|
||||
$autocomplete.empty();
|
||||
|
||||
// check if input isn't empty
|
||||
if (q.length) {
|
||||
|
||||
for (var item in data) {
|
||||
|
||||
// check if item contains value that we're looking for
|
||||
if (data[item].toLowerCase().indexOf(q.toLowerCase()) !== -1) {
|
||||
var option = $('<li>' + data[item] + '</li>');
|
||||
|
||||
$autocomplete.append(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e.which === ENTER_CHAR_CODE) {
|
||||
$autocomplete.children(":first").trigger('click');
|
||||
$autocomplete.empty();
|
||||
}
|
||||
|
||||
if (q.length === 0) {
|
||||
$('.mdb-autocomplete-clear').css('visibility', 'hidden');
|
||||
} else {
|
||||
$('.mdb-autocomplete-clear').css('visibility', 'visible');
|
||||
}
|
||||
});
|
||||
|
||||
$autocomplete.on('click', 'li', function () {
|
||||
|
||||
// Set input value after click
|
||||
$input.val($(this).text());
|
||||
|
||||
// Clear autocomplete
|
||||
$autocomplete.empty();
|
||||
});
|
||||
|
||||
$('.mdb-autocomplete-clear').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$input.val('');
|
||||
$(this).css('visibility', 'hidden');
|
||||
$autocomplete.empty();
|
||||
$(this).parent().find('label').removeClass('active');
|
||||
});
|
||||
});
|
||||
};
|
||||
5314
html/js/modules (optional)/mdb.js
Normal file
5314
html/js/modules (optional)/mdb.js
Normal file
File diff suppressed because one or more lines are too long
9
html/js/modules (optional)/panel-popuot.js
Normal file
9
html/js/modules (optional)/panel-popuot.js
Normal file
@@ -0,0 +1,9 @@
|
||||
//Collapse other tabs for popout
|
||||
$(function () {
|
||||
var active = true;
|
||||
|
||||
$('#accordion').on('show.bs.collapse', function () {
|
||||
if (active) $('#accordion .in').collapse('hide');
|
||||
});
|
||||
|
||||
});
|
||||
1380
html/js/modules (optional)/picker-date.js
Executable file
1380
html/js/modules (optional)/picker-date.js
Executable file
File diff suppressed because it is too large
Load Diff
699
html/js/modules (optional)/picker-time.js
Executable file
699
html/js/modules (optional)/picker-time.js
Executable file
@@ -0,0 +1,699 @@
|
||||
/*!
|
||||
* 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 $ = window.jQuery,
|
||||
$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 = '<svg/>';
|
||||
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 = 110,
|
||||
// innerRadius = 80 on 12 hour clock
|
||||
innerRadius = 80,
|
||||
tickRadius = 20,
|
||||
diameter = dialRadius * 2,
|
||||
duration = transitionSupported ? 350 : 1;
|
||||
|
||||
// Popover template
|
||||
var tpl = [
|
||||
'<div class="clockpicker picker">',
|
||||
'<div class="picker__holder">',
|
||||
'<div class="picker__frame">',
|
||||
'<div class="picker__wrap">',
|
||||
'<div class="picker__box">',
|
||||
'<div class="picker__date-display">',
|
||||
'<div class="clockpicker-display">',
|
||||
'<div class="clockpicker-display-column">',
|
||||
'<span class="clockpicker-span-hours text-primary"></span>',
|
||||
':',
|
||||
'<span class="clockpicker-span-minutes"></span>',
|
||||
'</div>',
|
||||
'<div class="clockpicker-display-column clockpicker-display-am-pm">',
|
||||
'<div class="clockpicker-span-am-pm"></div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="picker__calendar-container">',
|
||||
'<div class="clockpicker-plate">',
|
||||
'<div class="clockpicker-canvas"></div>',
|
||||
'<div class="clockpicker-dial clockpicker-hours"></div>',
|
||||
'<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>',
|
||||
'</div>',
|
||||
'<div class="clockpicker-am-pm-block">',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="picker__footer">',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('');
|
||||
|
||||
// ClockPicker
|
||||
function ClockPicker(element, options) {
|
||||
var popover = $(tpl),
|
||||
plate = popover.find('.clockpicker-plate'),
|
||||
holder = popover.find('.picker__holder'),
|
||||
hoursView = popover.find('.clockpicker-hours'),
|
||||
minutesView = popover.find('.clockpicker-minutes'),
|
||||
amPmBlock = popover.find('.clockpicker-am-pm-block'),
|
||||
isInput = element.prop('tagName') === 'INPUT',
|
||||
input = isInput ? element : element.find('input'),
|
||||
label = $("label[for=" + input.attr("id") + "]"),
|
||||
self = this,
|
||||
timer;
|
||||
|
||||
this.id = uniqueId('cp');
|
||||
this.element = element;
|
||||
this.holder = holder;
|
||||
this.options = options;
|
||||
this.isAppended = false;
|
||||
this.isShown = false;
|
||||
this.currentView = 'hours';
|
||||
this.isInput = isInput;
|
||||
this.input = input;
|
||||
this.label = label;
|
||||
this.popover = popover;
|
||||
this.plate = plate;
|
||||
this.hoursView = hoursView;
|
||||
this.minutesView = minutesView;
|
||||
this.amPmBlock = amPmBlock;
|
||||
this.spanHours = popover.find('.clockpicker-span-hours');
|
||||
this.spanMinutes = popover.find('.clockpicker-span-minutes');
|
||||
this.spanAmPm = popover.find('.clockpicker-span-am-pm');
|
||||
this.footer = popover.find('.picker__footer');
|
||||
this.amOrPm = "PM";
|
||||
|
||||
// Setup for for 12 hour clock if option is selected
|
||||
if (options.twelvehour) {
|
||||
var amPmButtonsTemplate = [
|
||||
'<div class="clockpicker-am-pm-block">',
|
||||
'<button type="button" class="btn-floating btn-flat clockpicker-button clockpicker-am-button">',
|
||||
'AM',
|
||||
'</button>',
|
||||
'<button type="button" class="btn-floating btn-flat clockpicker-button clockpicker-pm-button">',
|
||||
'PM',
|
||||
'</button>',
|
||||
'</div>'
|
||||
].join('');
|
||||
|
||||
var amPmButtons = $(amPmButtonsTemplate);
|
||||
|
||||
if(!options.ampmclickable) {
|
||||
$('<button type="button" class="btn-floating btn-flat clockpicker-button am-button" tabindex="1">' + "AM" + '</button>').on("click", function() {
|
||||
self.amOrPm = "AM";
|
||||
self.amPmBlock.children('.pm-button').removeClass('active');
|
||||
self.amPmBlock.children('.am-button').addClass('active');
|
||||
self.spanAmPm.empty().append('AM');
|
||||
}).appendTo(this.amPmBlock);
|
||||
$('<button type="button" class="btn-floating btn-flat clockpicker-button pm-button" tabindex="2">' + "PM" + '</button>').on("click", function() {
|
||||
self.amOrPm = 'PM';
|
||||
self.amPmBlock.children('.am-button').removeClass('active');
|
||||
self.amPmBlock.children('.pm-button').addClass('active');
|
||||
self.spanAmPm.empty().append('PM');
|
||||
}).appendTo(this.amPmBlock);
|
||||
}
|
||||
else {
|
||||
this.spanAmPm.empty();
|
||||
$('<div id="click-am">AM</div>').on("click", function() {
|
||||
self.spanAmPm.children('#click-am').addClass("text-primary");
|
||||
self.spanAmPm.children('#click-pm').removeClass("text-primary");
|
||||
self.amOrPm = "AM";
|
||||
}).appendTo(this.spanAmPm);
|
||||
$('<div id="click-pm">PM</div>').on("click", function() {
|
||||
self.spanAmPm.children('#click-pm').addClass("text-primary");
|
||||
self.spanAmPm.children('#click-am').removeClass("text-primary");
|
||||
self.amOrPm = 'PM';
|
||||
}).appendTo(this.spanAmPm);
|
||||
}
|
||||
}
|
||||
|
||||
if(options.darktheme)
|
||||
popover.addClass('darktheme');
|
||||
|
||||
// If autoclose is not setted, append a button
|
||||
$('<button type="button" class="btn-flat clockpicker-button" tabindex="' + (options.twelvehour? '3' : '1') + '">' + options.donetext + '</button>').click($.proxy(this.done, this)).appendTo(this.footer);
|
||||
|
||||
this.spanHours.click($.proxy(this.toggleView, this, 'hours'));
|
||||
this.spanMinutes.click($.proxy(this.toggleView, this, 'minutes'));
|
||||
|
||||
// Show or toggle
|
||||
input.on('focus.clockpicker click.clockpicker', $.proxy(this.show, this));
|
||||
|
||||
// Build ticks
|
||||
var tickTpl = $('<div class="clockpicker-tick"></div>'),
|
||||
i, tick, radian, radius;
|
||||
|
||||
// Hours view
|
||||
if (options.twelvehour) {
|
||||
for (i = 1; i < 13; i += 1) {
|
||||
tick = tickTpl.clone();
|
||||
radian = i / 6 * Math.PI;
|
||||
radius = outerRadius;
|
||||
tick.css('font-size', '140%');
|
||||
tick.css({
|
||||
left: dialRadius + Math.sin(radian) * radius - tickRadius,
|
||||
top: dialRadius - Math.cos(radian) * radius - tickRadius
|
||||
});
|
||||
tick.html(i === 0 ? '00' : i);
|
||||
hoursView.append(tick);
|
||||
tick.on(mousedownEvent, mousedown);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 24; i += 1) {
|
||||
tick = tickTpl.clone();
|
||||
radian = i / 6 * Math.PI;
|
||||
var inner = i > 0 && i < 13;
|
||||
radius = inner ? innerRadius : outerRadius;
|
||||
tick.css({
|
||||
left: dialRadius + Math.sin(radian) * radius - tickRadius,
|
||||
top: dialRadius - Math.cos(radian) * radius - tickRadius
|
||||
});
|
||||
if (inner)
|
||||
tick.css('font-size', '120%');
|
||||
tick.html(i === 0 ? '00' : i);
|
||||
hoursView.append(tick);
|
||||
tick.on(mousedownEvent, mousedown);
|
||||
}
|
||||
}
|
||||
|
||||
// Minutes view
|
||||
for (i = 0; i < 60; i += 5) {
|
||||
tick = tickTpl.clone();
|
||||
radian = i / 30 * Math.PI;
|
||||
tick.css({
|
||||
left: dialRadius + Math.sin(radian) * outerRadius - tickRadius,
|
||||
top: dialRadius - Math.cos(radian) * outerRadius - tickRadius
|
||||
});
|
||||
tick.css('font-size', '140%');
|
||||
tick.html(leadingZero(i));
|
||||
minutesView.append(tick);
|
||||
tick.on(mousedownEvent, mousedown);
|
||||
}
|
||||
|
||||
// Clicking on minutes view space
|
||||
plate.on(mousedownEvent, function(e) {
|
||||
if ($(e.target).closest('.clockpicker-tick').length === 0)
|
||||
mousedown(e, true);
|
||||
});
|
||||
|
||||
// Mousedown or touchstart
|
||||
function mousedown(e, space) {
|
||||
var offset = plate.offset(),
|
||||
isTouch = /^touch/.test(e.type),
|
||||
x0 = offset.left + dialRadius,
|
||||
y0 = offset.top + dialRadius,
|
||||
dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
|
||||
dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0,
|
||||
z = Math.sqrt(dx * dx + dy * dy),
|
||||
moved = false;
|
||||
|
||||
// When clicking on minutes view space, check the mouse position
|
||||
if (space && (z < outerRadius - tickRadius || z > outerRadius + tickRadius))
|
||||
return;
|
||||
e.preventDefault();
|
||||
|
||||
// Set cursor style of body after 200ms
|
||||
var movingTimer = setTimeout(function(){
|
||||
self.popover.addClass('clockpicker-moving');
|
||||
}, 200);
|
||||
|
||||
// Place the canvas to top
|
||||
if (svgSupported)
|
||||
plate.append(self.canvas);
|
||||
|
||||
// Clock
|
||||
self.setHand(dx, dy, !space, true);
|
||||
|
||||
// Mousemove on document
|
||||
$doc.off(mousemoveEvent).on(mousemoveEvent, function(e){
|
||||
e.preventDefault();
|
||||
var isTouch = /^touch/.test(e.type),
|
||||
x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0,
|
||||
y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0;
|
||||
if (! moved && x === dx && y === dy)
|
||||
// Clicking in chrome on windows will trigger a mousemove event
|
||||
return;
|
||||
moved = true;
|
||||
self.setHand(x, y, false, true);
|
||||
});
|
||||
|
||||
// Mouseup on document
|
||||
$doc.off(mouseupEvent).on(mouseupEvent, function(e) {
|
||||
$doc.off(mouseupEvent);
|
||||
e.preventDefault();
|
||||
var isTouch = /^touch/.test(e.type),
|
||||
x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0,
|
||||
y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0;
|
||||
if ((space || moved) && x === dx && y === dy)
|
||||
self.setHand(x, y);
|
||||
if (self.currentView === 'hours')
|
||||
self.toggleView('minutes', duration / 2);
|
||||
else
|
||||
if (options.autoclose) {
|
||||
self.minutesView.addClass('clockpicker-dial-out');
|
||||
setTimeout(function(){
|
||||
self.done();
|
||||
}, duration / 2);
|
||||
}
|
||||
plate.prepend(canvas);
|
||||
|
||||
// Reset cursor style of body
|
||||
clearTimeout(movingTimer);
|
||||
self.popover.removeClass('clockpicker-moving');
|
||||
|
||||
// Unbind mousemove event
|
||||
$doc.off(mousemoveEvent);
|
||||
});
|
||||
}
|
||||
|
||||
if (svgSupported) {
|
||||
// Draw clock hands and others
|
||||
var canvas = popover.find('.clockpicker-canvas'),
|
||||
svg = createSvgElement('svg');
|
||||
svg.setAttribute('class', 'clockpicker-svg');
|
||||
svg.setAttribute('width', diameter);
|
||||
svg.setAttribute('height', diameter);
|
||||
var g = createSvgElement('g');
|
||||
g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')');
|
||||
var bearing = createSvgElement('circle');
|
||||
bearing.setAttribute('class', 'clockpicker-canvas-bearing');
|
||||
bearing.setAttribute('cx', 0);
|
||||
bearing.setAttribute('cy', 0);
|
||||
bearing.setAttribute('r', 2);
|
||||
var hand = createSvgElement('line');
|
||||
hand.setAttribute('x1', 0);
|
||||
hand.setAttribute('y1', 0);
|
||||
var bg = createSvgElement('circle');
|
||||
bg.setAttribute('class', 'clockpicker-canvas-bg');
|
||||
bg.setAttribute('r', tickRadius);
|
||||
var fg = createSvgElement('circle');
|
||||
fg.setAttribute('class', 'clockpicker-canvas-fg');
|
||||
fg.setAttribute('r', 5);
|
||||
g.appendChild(hand);
|
||||
g.appendChild(bg);
|
||||
g.appendChild(fg);
|
||||
g.appendChild(bearing);
|
||||
svg.appendChild(g);
|
||||
canvas.append(svg);
|
||||
|
||||
this.hand = hand;
|
||||
this.bg = bg;
|
||||
this.fg = fg;
|
||||
this.bearing = bearing;
|
||||
this.g = g;
|
||||
this.canvas = canvas;
|
||||
}
|
||||
|
||||
raiseCallback(this.options.init);
|
||||
}
|
||||
|
||||
function raiseCallback(callbackFunction) {
|
||||
if(callbackFunction && typeof callbackFunction === "function")
|
||||
callbackFunction();
|
||||
}
|
||||
|
||||
// Default options
|
||||
ClockPicker.DEFAULTS = {
|
||||
'default': '', // default time, 'now' or '13:14' e.g.
|
||||
fromnow: 0, // set default time to * milliseconds from now (using with default = 'now')
|
||||
donetext: 'Done', // done button text
|
||||
autoclose: false, // auto close when minute is selected
|
||||
ampmclickable: false, // set am/pm button on itself
|
||||
darktheme: false, // set to dark theme
|
||||
twelvehour: true, // change to 12 hour AM/PM clock from 24 hour
|
||||
vibrate: true // vibrate the device when dragging clock hand
|
||||
};
|
||||
|
||||
// Show or hide popover
|
||||
ClockPicker.prototype.toggle = function() {
|
||||
this[this.isShown ? 'hide' : 'show']();
|
||||
};
|
||||
|
||||
// Set popover position
|
||||
ClockPicker.prototype.locate = function() {
|
||||
var element = this.element,
|
||||
popover = this.popover,
|
||||
offset = element.offset(),
|
||||
width = element.outerWidth(),
|
||||
height = element.outerHeight(),
|
||||
align = this.options.align,
|
||||
self = this;
|
||||
|
||||
popover.show();
|
||||
};
|
||||
|
||||
// Show popover
|
||||
ClockPicker.prototype.show = function(e){
|
||||
// Not show again
|
||||
if (this.isShown) {
|
||||
return;
|
||||
}
|
||||
raiseCallback(this.options.beforeShow);
|
||||
$(':input').each(function() {
|
||||
$(this).attr('tabindex', -1);
|
||||
})
|
||||
var self = this;
|
||||
// Initialize
|
||||
this.input.blur();
|
||||
this.popover.addClass('picker--opened');
|
||||
this.input.addClass('picker__input picker__input--active');
|
||||
$(document.body).css('overflow', 'hidden');
|
||||
if (!this.isAppended) {
|
||||
// Append popover to body
|
||||
this.popover.insertAfter(this.input);
|
||||
if(this.options.twelvehour) {
|
||||
this.amOrPm = 'PM';
|
||||
if(!this.options.ampmclickable) {
|
||||
this.amPmBlock.children('.am-button').removeClass('active');
|
||||
this.amPmBlock.children('.pm-button').addClass('active');
|
||||
this.spanAmPm.empty().append('PM');
|
||||
}
|
||||
else {
|
||||
this.spanAmPm.children('#click-pm').addClass("text-primary");
|
||||
this.spanAmPm.children('#click-am').removeClass("text-primary");
|
||||
}
|
||||
}
|
||||
// Reset position when resize
|
||||
$win.on('resize.clockpicker' + this.id, function() {
|
||||
if (self.isShown) {
|
||||
self.locate();
|
||||
}
|
||||
});
|
||||
this.isAppended = true;
|
||||
}
|
||||
// Get the time
|
||||
var value = ((this.input.prop('value') || this.options['default'] || '') + '').split(':');
|
||||
if(this.options.twelvehour && !(typeof value[1] === 'undefined')) {
|
||||
value[1] = value[1].replace("AM", "").replace("PM", "");
|
||||
}
|
||||
if (value[0] === 'now') {
|
||||
var now = new Date(+ new Date() + this.options.fromnow);
|
||||
value = [
|
||||
now.getHours(),
|
||||
now.getMinutes()
|
||||
];
|
||||
}
|
||||
this.hours = + value[0] || 0;
|
||||
this.minutes = + value[1] || 0;
|
||||
this.spanHours.html(leadingZero(this.hours));
|
||||
this.spanMinutes.html(leadingZero(this.minutes));
|
||||
// Toggle to hours view
|
||||
this.toggleView('hours');
|
||||
// Set position
|
||||
this.locate();
|
||||
this.isShown = true;
|
||||
// Hide when clicking or tabbing on any element except the clock and input
|
||||
$doc.on('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id, function(e) {
|
||||
var target = $(e.target);
|
||||
if (target.closest(self.popover.find('.picker__wrap')).length === 0 && target.closest(self.input).length === 0)
|
||||
self.hide();
|
||||
});
|
||||
// Hide when ESC is pressed
|
||||
$doc.on('keyup.clockpicker.' + this.id, function(e){
|
||||
if (e.keyCode === 27)
|
||||
self.hide();
|
||||
});
|
||||
raiseCallback(this.options.afterShow);
|
||||
};
|
||||
// Hide popover
|
||||
ClockPicker.prototype.hide = function() {
|
||||
raiseCallback(this.options.beforeHide);
|
||||
this.input.removeClass('picker__input picker__input--active');
|
||||
this.popover.removeClass('picker--opened');
|
||||
$(document.body).css('overflow', 'visible');
|
||||
this.isShown = false;
|
||||
$(':input').each(function(index) {
|
||||
$(this).attr('tabindex', index + 1);
|
||||
});
|
||||
// Unbinding events on document
|
||||
$doc.off('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id);
|
||||
$doc.off('keyup.clockpicker.' + this.id);
|
||||
this.popover.hide();
|
||||
raiseCallback(this.options.afterHide);
|
||||
};
|
||||
// Toggle to hours or minutes view
|
||||
ClockPicker.prototype.toggleView = function(view, delay) {
|
||||
var raiseAfterHourSelect = false;
|
||||
if (view === 'minutes' && $(this.hoursView).css("visibility") === "visible") {
|
||||
raiseCallback(this.options.beforeHourSelect);
|
||||
raiseAfterHourSelect = true;
|
||||
}
|
||||
var isHours = view === 'hours',
|
||||
nextView = isHours ? this.hoursView : this.minutesView,
|
||||
hideView = isHours ? this.minutesView : this.hoursView;
|
||||
this.currentView = view;
|
||||
|
||||
this.spanHours.toggleClass('text-primary', isHours);
|
||||
this.spanMinutes.toggleClass('text-primary', ! isHours);
|
||||
|
||||
// Let's make transitions
|
||||
hideView.addClass('clockpicker-dial-out');
|
||||
nextView.css('visibility', 'visible').removeClass('clockpicker-dial-out');
|
||||
|
||||
// Reset clock hand
|
||||
this.resetClock(delay);
|
||||
|
||||
// After transitions ended
|
||||
clearTimeout(this.toggleViewTimer);
|
||||
this.toggleViewTimer = setTimeout(function() {
|
||||
hideView.css('visibility', 'hidden');
|
||||
}, duration);
|
||||
|
||||
if (raiseAfterHourSelect)
|
||||
raiseCallback(this.options.afterHourSelect);
|
||||
};
|
||||
|
||||
// Reset clock hand
|
||||
ClockPicker.prototype.resetClock = function(delay) {
|
||||
var view = this.currentView,
|
||||
value = this[view],
|
||||
isHours = view === 'hours',
|
||||
unit = Math.PI / (isHours ? 6 : 30),
|
||||
radian = value * unit,
|
||||
radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius,
|
||||
x = Math.sin(radian) * radius,
|
||||
y = - Math.cos(radian) * radius,
|
||||
self = this;
|
||||
|
||||
if(svgSupported && delay) {
|
||||
self.canvas.addClass('clockpicker-canvas-out');
|
||||
setTimeout(function(){
|
||||
self.canvas.removeClass('clockpicker-canvas-out');
|
||||
self.setHand(x, y);
|
||||
}, delay);
|
||||
} else
|
||||
this.setHand(x, y);
|
||||
};
|
||||
|
||||
// Set clock hand to (x, y)
|
||||
ClockPicker.prototype.setHand = function(x, y, roundBy5, dragging) {
|
||||
var radian = Math.atan2(x, - y),
|
||||
isHours = this.currentView === 'hours',
|
||||
unit = Math.PI / (isHours || roundBy5? 6 : 30),
|
||||
z = Math.sqrt(x * x + y * y),
|
||||
options = this.options,
|
||||
inner = isHours && z < (outerRadius + innerRadius) / 2,
|
||||
radius = inner ? innerRadius : outerRadius,
|
||||
value;
|
||||
|
||||
if (options.twelvehour)
|
||||
radius = outerRadius;
|
||||
|
||||
// Radian should in range [0, 2PI]
|
||||
if (radian < 0)
|
||||
radian = Math.PI * 2 + radian;
|
||||
|
||||
// Get the round value
|
||||
value = Math.round(radian / unit);
|
||||
|
||||
// Get the round radian
|
||||
radian = value * unit;
|
||||
|
||||
// Correct the hours or minutes
|
||||
if(options.twelvehour) {
|
||||
if(isHours) {
|
||||
if(value === 0)
|
||||
value = 12;
|
||||
} else {
|
||||
if(roundBy5)
|
||||
value *= 5;
|
||||
if(value === 60)
|
||||
value = 0;
|
||||
}
|
||||
} else {
|
||||
if(isHours) {
|
||||
if(value === 12)
|
||||
value = 0;
|
||||
value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12;
|
||||
} else {
|
||||
if(roundBy5)
|
||||
value *= 5;
|
||||
if(value === 60)
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
if (isHours)
|
||||
this.fg.setAttribute('class', 'clockpicker-canvas-fg');
|
||||
else {
|
||||
if(value % 5 == 0)
|
||||
this.fg.setAttribute('class', 'clockpicker-canvas-fg');
|
||||
else
|
||||
this.fg.setAttribute('class', 'clockpicker-canvas-fg active');
|
||||
}
|
||||
|
||||
// Once hours or minutes changed, vibrate the device
|
||||
if (this[this.currentView] !== value)
|
||||
if (vibrate && this.options.vibrate)
|
||||
// Do not vibrate too frequently
|
||||
if (! this.vibrateTimer) {
|
||||
navigator[vibrate](10);
|
||||
this.vibrateTimer = setTimeout($.proxy(function(){
|
||||
this.vibrateTimer = null;
|
||||
}, this), 100);
|
||||
}
|
||||
|
||||
this[this.currentView] = value;
|
||||
this[isHours ? 'spanHours' : 'spanMinutes'].html(leadingZero(value));
|
||||
|
||||
// If svg is not supported, just add an active class to the tick
|
||||
if (! svgSupported) {
|
||||
this[isHours ? 'hoursView' : 'minutesView'].find('.clockpicker-tick').each(function(){
|
||||
var tick = $(this);
|
||||
tick.toggleClass('active', value === + tick.html());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Place clock hand at the top when dragging
|
||||
if (dragging || (! isHours && value % 5)) {
|
||||
this.g.insertBefore(this.hand, this.bearing);
|
||||
this.g.insertBefore(this.bg, this.fg);
|
||||
this.bg.setAttribute('class', 'clockpicker-canvas-bg clockpicker-canvas-bg-trans');
|
||||
} else {
|
||||
// Or place it at the bottom
|
||||
this.g.insertBefore(this.hand, this.bg);
|
||||
this.g.insertBefore(this.fg, this.bg);
|
||||
this.bg.setAttribute('class', 'clockpicker-canvas-bg');
|
||||
}
|
||||
|
||||
// Set clock hand and others' position
|
||||
var cx1 = Math.sin(radian) * (radius - tickRadius),
|
||||
cy1 = - Math.cos(radian) * (radius - tickRadius),
|
||||
cx2 = Math.sin(radian) * radius,
|
||||
cy2 = - Math.cos(radian) * radius;
|
||||
this.hand.setAttribute('x2', cx1);
|
||||
this.hand.setAttribute('y2', cy1);
|
||||
this.bg.setAttribute('cx', cx2);
|
||||
this.bg.setAttribute('cy', cy2);
|
||||
this.fg.setAttribute('cx', cx2);
|
||||
this.fg.setAttribute('cy', cy2);
|
||||
};
|
||||
|
||||
// Hours and minutes are selected
|
||||
ClockPicker.prototype.done = function() {
|
||||
raiseCallback(this.options.beforeDone);
|
||||
this.hide();
|
||||
this.label.addClass('active');
|
||||
|
||||
var last = this.input.prop('value'),
|
||||
value = leadingZero(this.hours) + ':' + leadingZero(this.minutes);
|
||||
if (this.options.twelvehour)
|
||||
value = value + this.amOrPm;
|
||||
|
||||
this.input.prop('value', value);
|
||||
if(value !== last) {
|
||||
this.input.triggerHandler('change');
|
||||
if(!this.isInput)
|
||||
this.element.trigger('change');
|
||||
}
|
||||
|
||||
if(this.options.autoclose)
|
||||
this.input.trigger('blur');
|
||||
|
||||
raiseCallback(this.options.afterDone);
|
||||
};
|
||||
|
||||
// Remove clockpicker from input
|
||||
ClockPicker.prototype.remove = function() {
|
||||
this.element.removeData('clockpicker');
|
||||
this.input.off('focus.clockpicker click.clockpicker');
|
||||
if (this.isShown)
|
||||
this.hide();
|
||||
if (this.isAppended) {
|
||||
$win.off('resize.clockpicker' + this.id);
|
||||
this.popover.remove();
|
||||
}
|
||||
};
|
||||
|
||||
// Extends $.fn.clockpicker
|
||||
$.fn.pickatime = function(option){
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return this.each(function(){
|
||||
var $this = $(this),
|
||||
data = $this.data('clockpicker');
|
||||
if (!data) {
|
||||
var options = $.extend({}, ClockPicker.DEFAULTS, $this.data(), typeof option == 'object' && option);
|
||||
$this.data('clockpicker', new ClockPicker($this, options));
|
||||
} else {
|
||||
// Manual operatsions. show, hide, remove, e.g.
|
||||
if (typeof data[option] === 'function')
|
||||
data[option].apply(data, args);
|
||||
}
|
||||
});
|
||||
};
|
||||
}());
|
||||
1163
html/js/modules (optional)/picker.js
Executable file
1163
html/js/modules (optional)/picker.js
Executable file
File diff suppressed because it is too large
Load Diff
11
html/js/modules (optional)/preloading.js
Executable file
11
html/js/modules (optional)/preloading.js
Executable file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
// Preloading script
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#preloader-markup').load('mdb-addons/preloader.html', function () {
|
||||
$(window).on('load', function () {
|
||||
$('#mdb-preloader').fadeOut('slow');
|
||||
});
|
||||
});
|
||||
});
|
||||
132
html/js/modules (optional)/range-input.js
Executable file
132
html/js/modules (optional)/range-input.js
Executable file
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
|
||||
/** **************
|
||||
* Range Input *
|
||||
****************/
|
||||
(function ($) {
|
||||
|
||||
var range_wrapper = '.range-field';
|
||||
var range_type = 'input[type=range]';
|
||||
var thumb_html = '<span class="thumb"><span class="value"></span></span>';
|
||||
var range_mousedown = false;
|
||||
var left = void 0;
|
||||
|
||||
var add_thumb = function add_thumb() {
|
||||
var $thumb = $(thumb_html);
|
||||
$(range_type).after($thumb);
|
||||
};
|
||||
|
||||
// Add thumbs;
|
||||
$(range_type).each(add_thumb);
|
||||
|
||||
$(document).on('change', range_type, function () {
|
||||
var $thumb = $(this);
|
||||
var $thumb_value = $thumb.siblings('.thumb').find('.value');
|
||||
$thumb_value.html($thumb.val());
|
||||
});
|
||||
|
||||
$(document).on('input mousedown touchstart', range_type, function (e) {
|
||||
var $this = $(this);
|
||||
var $thumb = $this.siblings('.thumb');
|
||||
var width = $this.outerWidth();
|
||||
var noThumb = !$thumb.length;
|
||||
// If thumb indicator does not exist yet, create it
|
||||
if (noThumb) {
|
||||
add_thumb();
|
||||
}
|
||||
|
||||
// Set indicator value
|
||||
$thumb.find('.value').html($this.val());
|
||||
|
||||
range_mousedown = true;
|
||||
$this.addClass('active');
|
||||
|
||||
if (!$thumb.hasClass('active')) {
|
||||
$thumb.velocity({
|
||||
height: '30px',
|
||||
width: '30px',
|
||||
top: '-20px',
|
||||
marginLeft: '-15px'
|
||||
}, {
|
||||
duration: 300,
|
||||
easing: 'easeOutExpo'
|
||||
});
|
||||
}
|
||||
|
||||
if (e.type !== 'input') {
|
||||
var isMobile = e.pageX === undefined || e.pageX === null;
|
||||
if (isMobile) {
|
||||
left = e.originalEvent.touches[0].pageX - $(this).offset().left;
|
||||
} else {
|
||||
left = e.pageX - $(this).offset().left;
|
||||
}
|
||||
|
||||
if (left < 0) {
|
||||
left = 0;
|
||||
} else if (left > width) {
|
||||
left = width;
|
||||
}
|
||||
$thumb.addClass('active').css('left', left);
|
||||
}
|
||||
|
||||
$thumb.find('.value').html($this.val());
|
||||
});
|
||||
|
||||
$(document).on('mouseup touchend', range_wrapper, function () {
|
||||
range_mousedown = false;
|
||||
$(this).removeClass('active');
|
||||
});
|
||||
|
||||
$(document).on('mousemove touchmove', range_wrapper, function (e) {
|
||||
var $thumb = $(this).children('.thumb');
|
||||
var left = void 0;
|
||||
|
||||
if (range_mousedown) {
|
||||
if (!$thumb.hasClass('active')) {
|
||||
$thumb.velocity({
|
||||
height: '30px',
|
||||
width: '30px',
|
||||
top: '-20px',
|
||||
marginLeft: '-15px'
|
||||
}, {
|
||||
duration: 300,
|
||||
easing: 'easeOutExpo'
|
||||
});
|
||||
}
|
||||
var isMobile = e.pageX === undefined || e.pageX === null;
|
||||
if (isMobile) {
|
||||
left = e.originalEvent.touches[0].pageX - $(this).offset().left;
|
||||
} else {
|
||||
left = e.pageX - $(this).offset().left;
|
||||
}
|
||||
|
||||
var width = $(this).outerWidth();
|
||||
if (left < 0) {
|
||||
left = 0;
|
||||
} else if (left > width) {
|
||||
left = width;
|
||||
}
|
||||
|
||||
$thumb.addClass('active').css('left', left);
|
||||
$thumb.find('.value').html($thumb.siblings(range_type).val());
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('mouseout touchleave', range_wrapper, function () {
|
||||
if (!range_mousedown) {
|
||||
var $thumb = $(this).children('.thumb');
|
||||
|
||||
if ($thumb.hasClass('active')) {
|
||||
$thumb.velocity({
|
||||
height: '0',
|
||||
width: '0',
|
||||
top: '10px',
|
||||
marginLeft: '-6px'
|
||||
}, {
|
||||
duration: 100
|
||||
});
|
||||
}
|
||||
$thumb.removeClass('active');
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
6
html/js/modules (optional)/rotating-cards.js
Normal file
6
html/js/modules (optional)/rotating-cards.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/* ROTATING CARDS */
|
||||
$('.rotate-btn').on('click', function () {
|
||||
var cardId = $(this).attr('data-card');
|
||||
$('#' + cardId).toggleClass('flipped');
|
||||
|
||||
});
|
||||
2
html/js/modules (optional)/scrollbar.js
Executable file
2
html/js/modules (optional)/scrollbar.js
Executable file
File diff suppressed because one or more lines are too long
23
html/js/modules (optional)/scrolling-nav.js
Normal file
23
html/js/modules (optional)/scrolling-nav.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/* SCROLLING NAVBAR */
|
||||
//jQuery to collapse the navbar on scroll
|
||||
$(window).scroll(function () {
|
||||
if ($(".navbar").offset()) {
|
||||
if ($(".navbar").offset().top > 50) {
|
||||
$(".scrolling-navbar").addClass("top-nav-collapse");
|
||||
} else {
|
||||
$(".scrolling-navbar").removeClass("top-nav-collapse");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//jQuery for page scrolling feature - requires jQuery Easing plugin
|
||||
$(function () {
|
||||
$('a.page-scroll').bind('click', function (event) {
|
||||
var $anchor = $(this);
|
||||
$('html, body').stop().animate({
|
||||
scrollTop: $($anchor.attr('href')).offset().top
|
||||
}, 1500, 'easeInOutExpo');
|
||||
event.preventDefault();
|
||||
});
|
||||
});
|
||||
14
html/js/modules (optional)/scrolling-navbar.js
Executable file
14
html/js/modules (optional)/scrolling-navbar.js
Executable file
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
/* SCROLLING NAVBAR */
|
||||
var OFFSET_TOP = 50;
|
||||
|
||||
$(window).scroll(function () {
|
||||
if ($('.navbar').length) {
|
||||
if ($('.navbar').offset().top > OFFSET_TOP) {
|
||||
$('.scrolling-navbar').addClass('top-nav-collapse');
|
||||
} else {
|
||||
$('.scrolling-navbar').removeClass('top-nav-collapse');
|
||||
}
|
||||
}
|
||||
});
|
||||
344
html/js/modules (optional)/sideNav.js
Normal file
344
html/js/modules (optional)/sideNav.js
Normal file
@@ -0,0 +1,344 @@
|
||||
(function ($) {
|
||||
|
||||
var methods = {
|
||||
init : function(options) {
|
||||
var defaults = {
|
||||
menuWidth: 240,
|
||||
edge: 'left',
|
||||
closeOnClick: false
|
||||
};
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
$(this).each(function(){
|
||||
var $this = $(this);
|
||||
var menu_id = $("#"+ $this.attr('data-activates'));
|
||||
|
||||
// Set to width
|
||||
if (options.menuWidth != 240) {
|
||||
menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
|
||||
// Add Touch Area
|
||||
var dragTarget = $('<div class="drag-target"></div>');
|
||||
$('body').append(dragTarget);
|
||||
|
||||
if (options.edge == 'left') {
|
||||
menu_id.css('transform', 'translateX(-100%)');
|
||||
dragTarget.css({'left': 0}); // Add Touch Area
|
||||
}
|
||||
else {
|
||||
menu_id.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_id.hasClass('fixed')) {
|
||||
if (window.innerWidth > 1440) {
|
||||
menu_id.css('transform', 'translateX(0)');
|
||||
}
|
||||
}
|
||||
|
||||
// Window resize to reset on large screens fixed
|
||||
if (menu_id.hasClass('fixed')) {
|
||||
$(window).resize( function() {
|
||||
if (window.innerWidth > 1440) {
|
||||
// Close menu if window is resized bigger than 992 and user has fixed sidenav
|
||||
if ($('#sidenav-overlay').length != 0 && menuOut) {
|
||||
removeMenu(true);
|
||||
}
|
||||
else {
|
||||
// menu_id.removeAttr('style');
|
||||
menu_id.css('transform', 'translateX(0%)');
|
||||
// menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
}
|
||||
else if (menuOut === false){
|
||||
if (options.edge === 'left') {
|
||||
menu_id.css('transform', 'translateX(-100%)');
|
||||
} else {
|
||||
menu_id.css('transform', 'translateX(100%)');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// if closeOnClick, then add close event for all a tags in side sideNav
|
||||
if (options.closeOnClick === true) {
|
||||
menu_id.on("click.itemclick", "a:not(.collapsible-header)", function(){
|
||||
removeMenu();
|
||||
});
|
||||
}
|
||||
|
||||
function removeMenu(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_id.velocity(
|
||||
{'translateX': '-100%'},
|
||||
{ duration: 200,
|
||||
queue: false,
|
||||
easing: 'easeOutCubic',
|
||||
complete: function() {
|
||||
if (restoreNav === true) {
|
||||
// Restore Fixed sidenav
|
||||
menu_id.removeAttr('style');
|
||||
menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Reset phantom div
|
||||
dragTarget.css({width: '', right: '0', left: ''});
|
||||
menu_id.velocity(
|
||||
{'translateX': '100%'},
|
||||
{ duration: 200,
|
||||
queue: false,
|
||||
easing: 'easeOutCubic',
|
||||
complete: function() {
|
||||
if (restoreNav === true) {
|
||||
// Restore Fixed sidenav
|
||||
menu_id.removeAttr('style');
|
||||
menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Touch Event
|
||||
var panning = false;
|
||||
var menuOut = false;
|
||||
|
||||
dragTarget.on('click', function(){
|
||||
removeMenu();
|
||||
});
|
||||
|
||||
dragTarget.hammer({
|
||||
prevent_default: false
|
||||
}).bind('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;
|
||||
|
||||
// Disable Scrolling
|
||||
var $body = $('body');
|
||||
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 ($('#sidenav-overlay').length === 0) {
|
||||
var overlay = $('<div id="sidenav-overlay"></div>');
|
||||
overlay.css('opacity', 0).click( function(){
|
||||
removeMenu();
|
||||
});
|
||||
$('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_id.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_id.css('transform', 'translateX(' + rightPos + 'px)');
|
||||
}
|
||||
|
||||
|
||||
// Percentage overlay
|
||||
var overlayPerc;
|
||||
if (options.edge === 'left') {
|
||||
overlayPerc = x / options.menuWidth;
|
||||
$('#sidenav-overlay').velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
else {
|
||||
overlayPerc = Math.abs((x - window.innerWidth) / options.menuWidth);
|
||||
$('#sidenav-overlay').velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
}
|
||||
|
||||
}).bind('panend', function(e) {
|
||||
|
||||
if (e.gesture.pointerType == "touch") {
|
||||
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) {
|
||||
if (leftPos != 0) {
|
||||
menu_id.velocity({'translateX': [0, leftPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
|
||||
// menu_id.css({'translateX': 0});
|
||||
$('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
|
||||
dragTarget.css({width: '50%', right: 0, left: ''});
|
||||
}
|
||||
else if (!menuOut || velocityX > 0.3) {
|
||||
// Enable Scrolling
|
||||
$('body').css({
|
||||
overflow: '',
|
||||
width: ''
|
||||
});
|
||||
// Slide menu closed
|
||||
menu_id.velocity({'translateX': [-1 * options.menuWidth - 10, leftPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});
|
||||
$('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
|
||||
complete: function () {
|
||||
$(this).remove();
|
||||
}});
|
||||
dragTarget.css({width: '10px', right: '', left: 0});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((menuOut && velocityX >= -0.3) || velocityX > 0.5) {
|
||||
menu_id.velocity({'translateX': [0, rightPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
$('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
|
||||
dragTarget.css({width: '50%', right: '', left: 0});
|
||||
}
|
||||
else if (!menuOut || velocityX < -0.3) {
|
||||
// Enable Scrolling
|
||||
$('body').css({
|
||||
overflow: '',
|
||||
width: ''
|
||||
});
|
||||
|
||||
// Slide menu closed
|
||||
menu_id.velocity({'translateX': [options.menuWidth + 10, rightPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});
|
||||
$('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
|
||||
complete: function () {
|
||||
$(this).remove();
|
||||
}});
|
||||
dragTarget.css({width: '10px', right: 0, left: ''});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$this.click(function() {
|
||||
if (menuOut === true) {
|
||||
menuOut = false;
|
||||
panning = false;
|
||||
removeMenu();
|
||||
}
|
||||
else {
|
||||
|
||||
// Disable Scrolling
|
||||
var $body = $('body');
|
||||
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_id.velocity({'translateX': [0, -1 * options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
else {
|
||||
dragTarget.css({width: '50%', right: '', left: 0});
|
||||
menu_id.velocity({'translateX': [0, options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
|
||||
var overlay = $('<div id="sidenav-overlay"></div>');
|
||||
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();
|
||||
} });
|
||||
|
||||
});
|
||||
$('body').append(overlay);
|
||||
overlay.velocity({opacity: 1}, {duration: 300, queue: false, easing: 'easeOutQuad',
|
||||
complete: function () {
|
||||
menuOut = true;
|
||||
panning = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
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 ));
|
||||
344
html/js/modules (optional)/sidenav.js
Normal file
344
html/js/modules (optional)/sidenav.js
Normal file
@@ -0,0 +1,344 @@
|
||||
(function ($) {
|
||||
|
||||
var methods = {
|
||||
init : function(options) {
|
||||
var defaults = {
|
||||
menuWidth: 240,
|
||||
edge: 'left',
|
||||
closeOnClick: false
|
||||
};
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
$(this).each(function(){
|
||||
var $this = $(this);
|
||||
var menu_id = $("#"+ $this.attr('data-activates'));
|
||||
|
||||
// Set to width
|
||||
if (options.menuWidth != 240) {
|
||||
menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
|
||||
// Add Touch Area
|
||||
var dragTarget = $('<div class="drag-target"></div>');
|
||||
$('body').append(dragTarget);
|
||||
|
||||
if (options.edge == 'left') {
|
||||
menu_id.css('transform', 'translateX(-100%)');
|
||||
dragTarget.css({'left': 0}); // Add Touch Area
|
||||
}
|
||||
else {
|
||||
menu_id.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_id.hasClass('fixed')) {
|
||||
if (window.innerWidth > 1440) {
|
||||
menu_id.css('transform', 'translateX(0)');
|
||||
}
|
||||
}
|
||||
|
||||
// Window resize to reset on large screens fixed
|
||||
if (menu_id.hasClass('fixed')) {
|
||||
$(window).resize( function() {
|
||||
if (window.innerWidth > 1440) {
|
||||
// Close menu if window is resized bigger than 992 and user has fixed sidenav
|
||||
if ($('#sidenav-overlay').length != 0 && menuOut) {
|
||||
removeMenu(true);
|
||||
}
|
||||
else {
|
||||
// menu_id.removeAttr('style');
|
||||
menu_id.css('transform', 'translateX(0%)');
|
||||
// menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
}
|
||||
else if (menuOut === false){
|
||||
if (options.edge === 'left') {
|
||||
menu_id.css('transform', 'translateX(-100%)');
|
||||
} else {
|
||||
menu_id.css('transform', 'translateX(100%)');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// if closeOnClick, then add close event for all a tags in side sideNav
|
||||
if (options.closeOnClick === true) {
|
||||
menu_id.on("click.itemclick", "a:not(.collapsible-header)", function(){
|
||||
removeMenu();
|
||||
});
|
||||
}
|
||||
|
||||
function removeMenu(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_id.velocity(
|
||||
{'translateX': '-100%'},
|
||||
{ duration: 200,
|
||||
queue: false,
|
||||
easing: 'easeOutCubic',
|
||||
complete: function() {
|
||||
if (restoreNav === true) {
|
||||
// Restore Fixed sidenav
|
||||
menu_id.removeAttr('style');
|
||||
menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Reset phantom div
|
||||
dragTarget.css({width: '', right: '0', left: ''});
|
||||
menu_id.velocity(
|
||||
{'translateX': '100%'},
|
||||
{ duration: 200,
|
||||
queue: false,
|
||||
easing: 'easeOutCubic',
|
||||
complete: function() {
|
||||
if (restoreNav === true) {
|
||||
// Restore Fixed sidenav
|
||||
menu_id.removeAttr('style');
|
||||
menu_id.css('width', options.menuWidth);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Touch Event
|
||||
var panning = false;
|
||||
var menuOut = false;
|
||||
|
||||
dragTarget.on('click', function(){
|
||||
removeMenu();
|
||||
});
|
||||
|
||||
dragTarget.hammer({
|
||||
prevent_default: false
|
||||
}).bind('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;
|
||||
|
||||
// Disable Scrolling
|
||||
var $body = $('body');
|
||||
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 ($('#sidenav-overlay').length === 0) {
|
||||
var overlay = $('<div id="sidenav-overlay"></div>');
|
||||
overlay.css('opacity', 0).click( function(){
|
||||
removeMenu();
|
||||
});
|
||||
$('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_id.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_id.css('transform', 'translateX(' + rightPos + 'px)');
|
||||
}
|
||||
|
||||
|
||||
// Percentage overlay
|
||||
var overlayPerc;
|
||||
if (options.edge === 'left') {
|
||||
overlayPerc = x / options.menuWidth;
|
||||
$('#sidenav-overlay').velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
else {
|
||||
overlayPerc = Math.abs((x - window.innerWidth) / options.menuWidth);
|
||||
$('#sidenav-overlay').velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
}
|
||||
|
||||
}).bind('panend', function(e) {
|
||||
|
||||
if (e.gesture.pointerType == "touch") {
|
||||
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) {
|
||||
if (leftPos != 0) {
|
||||
menu_id.velocity({'translateX': [0, leftPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
|
||||
// menu_id.css({'translateX': 0});
|
||||
$('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
|
||||
dragTarget.css({width: '50%', right: 0, left: ''});
|
||||
}
|
||||
else if (!menuOut || velocityX > 0.3) {
|
||||
// Enable Scrolling
|
||||
$('body').css({
|
||||
overflow: '',
|
||||
width: ''
|
||||
});
|
||||
// Slide menu closed
|
||||
menu_id.velocity({'translateX': [-1 * options.menuWidth - 10, leftPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});
|
||||
$('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
|
||||
complete: function () {
|
||||
$(this).remove();
|
||||
}});
|
||||
dragTarget.css({width: '10px', right: '', left: 0});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((menuOut && velocityX >= -0.3) || velocityX > 0.5) {
|
||||
menu_id.velocity({'translateX': [0, rightPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
$('#sidenav-overlay').velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'});
|
||||
dragTarget.css({width: '50%', right: '', left: 0});
|
||||
}
|
||||
else if (!menuOut || velocityX < -0.3) {
|
||||
// Enable Scrolling
|
||||
$('body').css({
|
||||
overflow: '',
|
||||
width: ''
|
||||
});
|
||||
|
||||
// Slide menu closed
|
||||
menu_id.velocity({'translateX': [options.menuWidth + 10, rightPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'});
|
||||
$('#sidenav-overlay').velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad',
|
||||
complete: function () {
|
||||
$(this).remove();
|
||||
}});
|
||||
dragTarget.css({width: '10px', right: 0, left: ''});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$this.click(function() {
|
||||
if (menuOut === true) {
|
||||
menuOut = false;
|
||||
panning = false;
|
||||
removeMenu();
|
||||
}
|
||||
else {
|
||||
|
||||
// Disable Scrolling
|
||||
var $body = $('body');
|
||||
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_id.velocity({'translateX': [0, -1 * options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
else {
|
||||
dragTarget.css({width: '50%', right: '', left: 0});
|
||||
menu_id.velocity({'translateX': [0, options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'});
|
||||
}
|
||||
|
||||
var overlay = $('<div id="sidenav-overlay"></div>');
|
||||
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();
|
||||
} });
|
||||
|
||||
});
|
||||
$('body').append(overlay);
|
||||
overlay.velocity({opacity: 1}, {duration: 300, queue: false, easing: 'easeOutQuad',
|
||||
complete: function () {
|
||||
menuOut = true;
|
||||
panning = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
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 ));
|
||||
19
html/js/modules (optional)/smooth-scroll.js
Executable file
19
html/js/modules (optional)/smooth-scroll.js
Executable file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
// SMOOTH SCROLL
|
||||
var SMOOTH_SCROLL_DURATION = 700;
|
||||
|
||||
$('.smooth-scroll').on('click', 'a', function (event) {
|
||||
event.preventDefault();
|
||||
var elAttr = $(this).attr('href');
|
||||
var offset = $(this).attr('data-offset') ? $(this).attr('data-offset') : 0;
|
||||
var setHash = $(this).closest('ul').attr('data-allow-hashes');
|
||||
$('body,html').animate({
|
||||
scrollTop: $(elAttr).offset().top - offset
|
||||
}, SMOOTH_SCROLL_DURATION);
|
||||
if ((typeof setHash === 'undefined' ? 'undefined' : _typeof(setHash)) !== (typeof undefined === 'undefined' ? 'undefined' : _typeof(undefined)) && setHash !== false) {
|
||||
history.replaceState(null, null, elAttr);
|
||||
}
|
||||
});
|
||||
416
html/js/modules (optional)/toastr.js
Executable file
416
html/js/modules (optional)/toastr.js
Executable file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Toastr
|
||||
* Copyright 2012-2015
|
||||
* Authors: John Papa, Hans Fjällemark, and Tim Ferrell.
|
||||
* All Rights Reserved.
|
||||
* Use, reproduction, distribution, and modification of this code is subject to the terms and
|
||||
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* ARIA Support: Greta Krafsig
|
||||
*
|
||||
* Project: https://github.com/CodeSeven/toastr
|
||||
*/
|
||||
/* global define */
|
||||
; (function (define) {
|
||||
define(['jquery'], function ($) {
|
||||
return (function () {
|
||||
var $container;
|
||||
var listener;
|
||||
var toastId = 0;
|
||||
var toastType = {
|
||||
error: 'error',
|
||||
info: 'info',
|
||||
success: 'success',
|
||||
warning: 'warning'
|
||||
};
|
||||
|
||||
var toastr = {
|
||||
clear: clear,
|
||||
remove: remove,
|
||||
error: error,
|
||||
getContainer: getContainer,
|
||||
info: info,
|
||||
options: {},
|
||||
subscribe: subscribe,
|
||||
success: success,
|
||||
version: '2.1.1',
|
||||
warning: warning
|
||||
};
|
||||
|
||||
var previousToast;
|
||||
|
||||
return toastr;
|
||||
|
||||
////////////////
|
||||
|
||||
function error(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.error,
|
||||
iconClass: getOptions().iconClasses.error,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function getContainer(options, create) {
|
||||
if (!options) { options = getOptions(); }
|
||||
$container = $('#' + options.containerId + '[position = ' + options.positionClass + ']');
|
||||
if ($container.length) {
|
||||
return $container;
|
||||
}
|
||||
if (create) {
|
||||
$container = createContainer(options);
|
||||
}
|
||||
return $container;
|
||||
}
|
||||
|
||||
function info(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.info,
|
||||
iconClass: getOptions().iconClasses.info,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function subscribe(callback) {
|
||||
listener = callback;
|
||||
}
|
||||
|
||||
function success(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.success,
|
||||
iconClass: getOptions().iconClasses.success,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function warning(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.warning,
|
||||
iconClass: getOptions().iconClasses.warning,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function clear($toastElement, clearOptions) {
|
||||
var options = getOptions();
|
||||
if (!$container) { getContainer(options); }
|
||||
if (!clearToast($toastElement, options, clearOptions)) {
|
||||
clearContainer(options);
|
||||
}
|
||||
}
|
||||
|
||||
function remove($toastElement) {
|
||||
var options = getOptions();
|
||||
if (!$container) { getContainer(options); }
|
||||
if ($toastElement && $(':focus', $toastElement).length === 0) {
|
||||
removeToast($toastElement);
|
||||
return;
|
||||
}
|
||||
if ($container.children().length) {
|
||||
$container.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// internal functions
|
||||
|
||||
function clearContainer (options) {
|
||||
var toastsToClear = $container.children();
|
||||
for (var i = toastsToClear.length - 1; i >= 0; i--) {
|
||||
clearToast($(toastsToClear[i]), options);
|
||||
}
|
||||
}
|
||||
|
||||
function clearToast ($toastElement, options, clearOptions) {
|
||||
var force = clearOptions && clearOptions.force ? clearOptions.force : false;
|
||||
if ($toastElement && (force || $(':focus', $toastElement).length === 0)) {
|
||||
$toastElement[options.hideMethod]({
|
||||
duration: options.hideDuration,
|
||||
easing: options.hideEasing,
|
||||
complete: function () { removeToast($toastElement); }
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function createContainer(options) {
|
||||
$container = $('<div/>')
|
||||
.attr('id', options.containerId)
|
||||
.attr('position', options.positionClass)
|
||||
.addClass(options.positionClass)
|
||||
.attr('aria-live', 'polite')
|
||||
.attr('role', 'alert');
|
||||
|
||||
$container.appendTo($(options.target));
|
||||
return $container;
|
||||
}
|
||||
|
||||
function getDefaults() {
|
||||
return {
|
||||
tapToDismiss: true,
|
||||
toastClass: 'toast',
|
||||
containerId: 'toast-container',
|
||||
debug: false,
|
||||
|
||||
showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
|
||||
showDuration: 300,
|
||||
showEasing: 'swing', //swing and linear are built into jQuery
|
||||
onShown: undefined,
|
||||
hideMethod: 'fadeOut',
|
||||
hideDuration: 1000,
|
||||
hideEasing: 'swing',
|
||||
onHidden: undefined,
|
||||
|
||||
extendedTimeOut: 1000,
|
||||
iconClasses: {
|
||||
error: 'toast-error',
|
||||
info: 'toast-info',
|
||||
success: 'toast-success',
|
||||
warning: 'toast-warning'
|
||||
},
|
||||
iconClass: 'toast-info',
|
||||
positionClass: 'toast-top-right',
|
||||
timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky
|
||||
titleClass: 'toast-title',
|
||||
messageClass: 'toast-message',
|
||||
target: 'body',
|
||||
closeHtml: '<button type="button">×</button>',
|
||||
newestOnTop: true,
|
||||
preventDuplicates: false,
|
||||
progressBar: false
|
||||
};
|
||||
}
|
||||
|
||||
function publish(args) {
|
||||
if (!listener) { return; }
|
||||
listener(args);
|
||||
}
|
||||
|
||||
function notify(map) {
|
||||
var options = getOptions();
|
||||
var iconClass = map.iconClass || options.iconClass;
|
||||
|
||||
if (typeof (map.optionsOverride) !== 'undefined') {
|
||||
options = $.extend(options, map.optionsOverride);
|
||||
iconClass = map.optionsOverride.iconClass || iconClass;
|
||||
}
|
||||
|
||||
if (shouldExit(options, map)) { return; }
|
||||
|
||||
toastId++;
|
||||
|
||||
$container = getContainer(options, true);
|
||||
|
||||
var intervalId = null;
|
||||
var $toastElement = $('<div/>');
|
||||
var $titleElement = $('<div/>');
|
||||
var $messageElement = $('<div/>');
|
||||
var $progressElement = $('<div/>');
|
||||
var $closeElement = $(options.closeHtml);
|
||||
var progressBar = {
|
||||
intervalId: null,
|
||||
hideEta: null,
|
||||
maxHideTime: null
|
||||
};
|
||||
var response = {
|
||||
toastId: toastId,
|
||||
state: 'visible',
|
||||
startTime: new Date(),
|
||||
options: options,
|
||||
map: map
|
||||
};
|
||||
|
||||
personalizeToast();
|
||||
|
||||
displayToast();
|
||||
|
||||
handleEvents();
|
||||
|
||||
publish(response);
|
||||
|
||||
if (options.debug && console) {
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
return $toastElement;
|
||||
|
||||
function personalizeToast() {
|
||||
setIcon();
|
||||
setTitle();
|
||||
setMessage();
|
||||
setCloseButton();
|
||||
setProgressBar();
|
||||
setSequence();
|
||||
}
|
||||
|
||||
function handleEvents() {
|
||||
$toastElement.hover(stickAround, delayedHideToast);
|
||||
if (!options.onclick && options.tapToDismiss) {
|
||||
$toastElement.click(hideToast);
|
||||
}
|
||||
|
||||
if (options.closeButton && $closeElement) {
|
||||
$closeElement.click(function (event) {
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else if (event.cancelBubble !== undefined && event.cancelBubble !== true) {
|
||||
event.cancelBubble = true;
|
||||
}
|
||||
hideToast(true);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.onclick) {
|
||||
$toastElement.click(function () {
|
||||
options.onclick();
|
||||
hideToast();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function displayToast() {
|
||||
$toastElement.hide();
|
||||
|
||||
$toastElement[options.showMethod](
|
||||
{duration: options.showDuration, easing: options.showEasing, complete: options.onShown}
|
||||
);
|
||||
|
||||
if (options.timeOut > 0) {
|
||||
intervalId = setTimeout(hideToast, options.timeOut);
|
||||
progressBar.maxHideTime = parseFloat(options.timeOut);
|
||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
|
||||
if (options.progressBar) {
|
||||
progressBar.intervalId = setInterval(updateProgress, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setIcon() {
|
||||
if (map.iconClass) {
|
||||
$toastElement.addClass(options.toastClass).addClass(iconClass);
|
||||
}
|
||||
}
|
||||
|
||||
function setSequence() {
|
||||
if (options.newestOnTop) {
|
||||
$container.prepend($toastElement);
|
||||
} else {
|
||||
$container.append($toastElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setTitle() {
|
||||
if (map.title) {
|
||||
$titleElement.append(map.title).addClass(options.titleClass);
|
||||
$toastElement.append($titleElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setMessage() {
|
||||
if (map.message) {
|
||||
$messageElement.append(map.message).addClass(options.messageClass);
|
||||
$toastElement.append($messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setCloseButton() {
|
||||
if (options.closeButton) {
|
||||
$closeElement.addClass('toast-close-button').attr('role', 'button');
|
||||
$toastElement.prepend($closeElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setProgressBar() {
|
||||
if (options.progressBar) {
|
||||
$progressElement.addClass('toast-progress');
|
||||
$toastElement.prepend($progressElement);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldExit(options, map) {
|
||||
if (options.preventDuplicates) {
|
||||
if (map.message === previousToast) {
|
||||
return true;
|
||||
} else {
|
||||
previousToast = map.message;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function hideToast(override) {
|
||||
if ($(':focus', $toastElement).length && !override) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(progressBar.intervalId);
|
||||
return $toastElement[options.hideMethod]({
|
||||
duration: options.hideDuration,
|
||||
easing: options.hideEasing,
|
||||
complete: function () {
|
||||
removeToast($toastElement);
|
||||
if (options.onHidden && response.state !== 'hidden') {
|
||||
options.onHidden();
|
||||
}
|
||||
response.state = 'hidden';
|
||||
response.endTime = new Date();
|
||||
publish(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delayedHideToast() {
|
||||
if (options.timeOut > 0 || options.extendedTimeOut > 0) {
|
||||
intervalId = setTimeout(hideToast, options.extendedTimeOut);
|
||||
progressBar.maxHideTime = parseFloat(options.extendedTimeOut);
|
||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
|
||||
}
|
||||
}
|
||||
|
||||
function stickAround() {
|
||||
clearTimeout(intervalId);
|
||||
progressBar.hideEta = 0;
|
||||
$toastElement.stop(true, true)[options.showMethod](
|
||||
{duration: options.showDuration, easing: options.showEasing}
|
||||
);
|
||||
}
|
||||
|
||||
function updateProgress() {
|
||||
var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100;
|
||||
$progressElement.width(percentage + '%');
|
||||
}
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
return $.extend({}, getDefaults(), toastr.options);
|
||||
}
|
||||
|
||||
function removeToast($toastElement) {
|
||||
if (!$container) { $container = getContainer(); }
|
||||
if ($toastElement.is(':visible')) {
|
||||
return;
|
||||
}
|
||||
$toastElement.remove();
|
||||
$toastElement = null;
|
||||
if ($container.children().length === 0) {
|
||||
$container.remove();
|
||||
previousToast = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
});
|
||||
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) { //Node
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
window['toastr'] = factory(window['jQuery']);
|
||||
}
|
||||
}));
|
||||
435
html/js/modules (optional)/toasts.js
Normal file
435
html/js/modules (optional)/toasts.js
Normal file
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
* Toastr
|
||||
* Copyright 2012-2015
|
||||
* Authors: John Papa, Hans Fjällemark, and Tim Ferrell.
|
||||
* All Rights Reserved.
|
||||
* Use, reproduction, distribution, and modification of this code is subject to the terms and
|
||||
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* ARIA Support: Greta Krafsig
|
||||
*
|
||||
* Project: https://github.com/CodeSeven/toastr
|
||||
*/
|
||||
/* global define */
|
||||
(function (define) {
|
||||
define(['jquery'], function ($) {
|
||||
return (function () {
|
||||
var $container;
|
||||
var listener;
|
||||
var toastId = 0;
|
||||
var toastType = {
|
||||
error: 'error',
|
||||
info: 'info',
|
||||
success: 'success',
|
||||
warning: 'warning'
|
||||
};
|
||||
|
||||
var toastr = {
|
||||
clear: clear,
|
||||
remove: remove,
|
||||
error: error,
|
||||
getContainer: getContainer,
|
||||
info: info,
|
||||
options: {},
|
||||
subscribe: subscribe,
|
||||
success: success,
|
||||
version: '2.1.2',
|
||||
warning: warning
|
||||
};
|
||||
|
||||
var previousToast;
|
||||
|
||||
return toastr;
|
||||
|
||||
////////////////
|
||||
|
||||
function error(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.error,
|
||||
iconClass: getOptions().iconClasses.error,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function getContainer(options, create) {
|
||||
if (!options) { options = getOptions(); }
|
||||
$container = $('#' + options.containerId);
|
||||
if ($container.length) {
|
||||
return $container;
|
||||
}
|
||||
if (create) {
|
||||
$container = createContainer(options);
|
||||
}
|
||||
return $container;
|
||||
}
|
||||
|
||||
function info(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.info,
|
||||
iconClass: getOptions().iconClasses.info,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function subscribe(callback) {
|
||||
listener = callback;
|
||||
}
|
||||
|
||||
function success(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.success,
|
||||
iconClass: getOptions().iconClasses.success,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function warning(message, title, optionsOverride) {
|
||||
return notify({
|
||||
type: toastType.warning,
|
||||
iconClass: getOptions().iconClasses.warning,
|
||||
message: message,
|
||||
optionsOverride: optionsOverride,
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
function clear($toastElement, clearOptions) {
|
||||
var options = getOptions();
|
||||
if (!$container) { getContainer(options); }
|
||||
if (!clearToast($toastElement, options, clearOptions)) {
|
||||
clearContainer(options);
|
||||
}
|
||||
}
|
||||
|
||||
function remove($toastElement) {
|
||||
var options = getOptions();
|
||||
if (!$container) { getContainer(options); }
|
||||
if ($toastElement && $(':focus', $toastElement).length === 0) {
|
||||
removeToast($toastElement);
|
||||
return;
|
||||
}
|
||||
if ($container.children().length) {
|
||||
$container.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// internal functions
|
||||
|
||||
function clearContainer (options) {
|
||||
var toastsToClear = $container.children();
|
||||
for (var i = toastsToClear.length - 1; i >= 0; i--) {
|
||||
clearToast($(toastsToClear[i]), options);
|
||||
}
|
||||
}
|
||||
|
||||
function clearToast ($toastElement, options, clearOptions) {
|
||||
var force = clearOptions && clearOptions.force ? clearOptions.force : false;
|
||||
if ($toastElement && (force || $(':focus', $toastElement).length === 0)) {
|
||||
$toastElement[options.hideMethod]({
|
||||
duration: options.hideDuration,
|
||||
easing: options.hideEasing,
|
||||
complete: function () { removeToast($toastElement); }
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function createContainer(options) {
|
||||
$container = $('<div/>')
|
||||
.attr('id', options.containerId)
|
||||
.addClass(options.positionClass)
|
||||
.attr('aria-live', 'polite')
|
||||
.attr('role', 'alert');
|
||||
|
||||
$container.appendTo($(options.target));
|
||||
return $container;
|
||||
}
|
||||
|
||||
function getDefaults() {
|
||||
return {
|
||||
tapToDismiss: true,
|
||||
toastClass: 'toast',
|
||||
containerId: 'toast-container',
|
||||
debug: false,
|
||||
|
||||
showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
|
||||
showDuration: 300,
|
||||
showEasing: 'swing', //swing and linear are built into jQuery
|
||||
onShown: undefined,
|
||||
hideMethod: 'fadeOut',
|
||||
hideDuration: 1000,
|
||||
hideEasing: 'swing',
|
||||
onHidden: undefined,
|
||||
closeMethod: false,
|
||||
closeDuration: false,
|
||||
closeEasing: false,
|
||||
|
||||
extendedTimeOut: 1000,
|
||||
iconClasses: {
|
||||
error: 'toast-error',
|
||||
info: 'toast-info',
|
||||
success: 'toast-success',
|
||||
warning: 'toast-warning'
|
||||
},
|
||||
iconClass: 'toast-info',
|
||||
positionClass: 'toast-top-right',
|
||||
timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky
|
||||
titleClass: 'toast-title',
|
||||
messageClass: 'toast-message',
|
||||
escapeHtml: false,
|
||||
target: 'body',
|
||||
closeHtml: '<button type="button">×</button>',
|
||||
newestOnTop: true,
|
||||
preventDuplicates: false,
|
||||
progressBar: false
|
||||
};
|
||||
}
|
||||
|
||||
function publish(args) {
|
||||
if (!listener) { return; }
|
||||
listener(args);
|
||||
}
|
||||
|
||||
function notify(map) {
|
||||
var options = getOptions();
|
||||
var iconClass = map.iconClass || options.iconClass;
|
||||
|
||||
if (typeof (map.optionsOverride) !== 'undefined') {
|
||||
options = $.extend(options, map.optionsOverride);
|
||||
iconClass = map.optionsOverride.iconClass || iconClass;
|
||||
}
|
||||
|
||||
if (shouldExit(options, map)) { return; }
|
||||
|
||||
toastId++;
|
||||
|
||||
$container = getContainer(options, true);
|
||||
|
||||
var intervalId = null;
|
||||
var $toastElement = $('<div/>');
|
||||
var $titleElement = $('<div/>');
|
||||
var $messageElement = $('<div/>');
|
||||
var $progressElement = $('<div/>');
|
||||
var $closeElement = $(options.closeHtml);
|
||||
var progressBar = {
|
||||
intervalId: null,
|
||||
hideEta: null,
|
||||
maxHideTime: null
|
||||
};
|
||||
var response = {
|
||||
toastId: toastId,
|
||||
state: 'visible',
|
||||
startTime: new Date(),
|
||||
options: options,
|
||||
map: map
|
||||
};
|
||||
|
||||
personalizeToast();
|
||||
|
||||
displayToast();
|
||||
|
||||
handleEvents();
|
||||
|
||||
publish(response);
|
||||
|
||||
if (options.debug && console) {
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
return $toastElement;
|
||||
|
||||
function escapeHtml(source) {
|
||||
if (source == null)
|
||||
source = "";
|
||||
|
||||
return new String(source)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function personalizeToast() {
|
||||
setIcon();
|
||||
setTitle();
|
||||
setMessage();
|
||||
setCloseButton();
|
||||
setProgressBar();
|
||||
setSequence();
|
||||
}
|
||||
|
||||
function handleEvents() {
|
||||
$toastElement.hover(stickAround, delayedHideToast);
|
||||
if (!options.onclick && options.tapToDismiss) {
|
||||
$toastElement.click(hideToast);
|
||||
}
|
||||
|
||||
if (options.closeButton && $closeElement) {
|
||||
$closeElement.click(function (event) {
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else if (event.cancelBubble !== undefined && event.cancelBubble !== true) {
|
||||
event.cancelBubble = true;
|
||||
}
|
||||
hideToast(true);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.onclick) {
|
||||
$toastElement.click(function (event) {
|
||||
options.onclick(event);
|
||||
hideToast();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function displayToast() {
|
||||
$toastElement.hide();
|
||||
|
||||
$toastElement[options.showMethod](
|
||||
{duration: options.showDuration, easing: options.showEasing, complete: options.onShown}
|
||||
);
|
||||
|
||||
if (options.timeOut > 0) {
|
||||
intervalId = setTimeout(hideToast, options.timeOut);
|
||||
progressBar.maxHideTime = parseFloat(options.timeOut);
|
||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
|
||||
if (options.progressBar) {
|
||||
progressBar.intervalId = setInterval(updateProgress, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setIcon() {
|
||||
if (map.iconClass) {
|
||||
$toastElement.addClass(options.toastClass).addClass(iconClass);
|
||||
}
|
||||
}
|
||||
|
||||
function setSequence() {
|
||||
if (options.newestOnTop) {
|
||||
$container.prepend($toastElement);
|
||||
} else {
|
||||
$container.append($toastElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setTitle() {
|
||||
if (map.title) {
|
||||
$titleElement.append(!options.escapeHtml ? map.title : escapeHtml(map.title)).addClass(options.titleClass);
|
||||
$toastElement.append($titleElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setMessage() {
|
||||
if (map.message) {
|
||||
$messageElement.append(!options.escapeHtml ? map.message : escapeHtml(map.message)).addClass(options.messageClass);
|
||||
$toastElement.append($messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setCloseButton() {
|
||||
if (options.closeButton) {
|
||||
$closeElement.addClass('toast-close-button').attr('role', 'button');
|
||||
$toastElement.prepend($closeElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setProgressBar() {
|
||||
if (options.progressBar) {
|
||||
$progressElement.addClass('toast-progress');
|
||||
$toastElement.prepend($progressElement);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldExit(options, map) {
|
||||
if (options.preventDuplicates) {
|
||||
if (map.message === previousToast) {
|
||||
return true;
|
||||
} else {
|
||||
previousToast = map.message;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function hideToast(override) {
|
||||
var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod;
|
||||
var duration = override && options.closeDuration !== false ?
|
||||
options.closeDuration : options.hideDuration;
|
||||
var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing;
|
||||
if ($(':focus', $toastElement).length && !override) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(progressBar.intervalId);
|
||||
return $toastElement[method]({
|
||||
duration: duration,
|
||||
easing: easing,
|
||||
complete: function () {
|
||||
removeToast($toastElement);
|
||||
if (options.onHidden && response.state !== 'hidden') {
|
||||
options.onHidden();
|
||||
}
|
||||
response.state = 'hidden';
|
||||
response.endTime = new Date();
|
||||
publish(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delayedHideToast() {
|
||||
if (options.timeOut > 0 || options.extendedTimeOut > 0) {
|
||||
intervalId = setTimeout(hideToast, options.extendedTimeOut);
|
||||
progressBar.maxHideTime = parseFloat(options.extendedTimeOut);
|
||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
|
||||
}
|
||||
}
|
||||
|
||||
function stickAround() {
|
||||
clearTimeout(intervalId);
|
||||
progressBar.hideEta = 0;
|
||||
$toastElement.stop(true, true)[options.showMethod](
|
||||
{duration: options.showDuration, easing: options.showEasing}
|
||||
);
|
||||
}
|
||||
|
||||
function updateProgress() {
|
||||
var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100;
|
||||
$progressElement.width(percentage + '%');
|
||||
}
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
return $.extend({}, getDefaults(), toastr.options);
|
||||
}
|
||||
|
||||
function removeToast($toastElement) {
|
||||
if (!$container) { $container = getContainer(); }
|
||||
if ($toastElement.is(':visible')) {
|
||||
return;
|
||||
}
|
||||
$toastElement.remove();
|
||||
$toastElement = null;
|
||||
if ($container.children().length === 0) {
|
||||
$container.remove();
|
||||
previousToast = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
});
|
||||
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) { //Node
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
window.toastr = factory(window.jQuery);
|
||||
}
|
||||
}));
|
||||
5
html/js/modules (optional)/velocity.min.js
vendored
Executable file
5
html/js/modules (optional)/velocity.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
64
html/js/modules (optional)/video-bg.js
Normal file
64
html/js/modules (optional)/video-bg.js
Normal file
@@ -0,0 +1,64 @@
|
||||
// VIDEO BACKGROUND
|
||||
|
||||
$( document ).ready(function() {
|
||||
|
||||
scaleVideoContainer();
|
||||
|
||||
initBannerVideoSize('.video-container .poster img');
|
||||
initBannerVideoSize('.video-container .filter');
|
||||
initBannerVideoSize('.video-container video');
|
||||
|
||||
$(window).on('resize', function() {
|
||||
scaleVideoContainer();
|
||||
scaleBannerVideoSize('.video-container .poster img');
|
||||
scaleBannerVideoSize('.video-container .filter');
|
||||
scaleBannerVideoSize('.video-container video');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function scaleVideoContainer() {
|
||||
|
||||
var height = $(window).height() + 5;
|
||||
var unitHeight = parseInt(height) + 'px';
|
||||
$('.homepage-hero-module').css('height',unitHeight);
|
||||
|
||||
}
|
||||
|
||||
function initBannerVideoSize(element){
|
||||
|
||||
$(element).each(function(){
|
||||
$(this).data('height', $(this).height());
|
||||
$(this).data('width', $(this).width());
|
||||
});
|
||||
|
||||
scaleBannerVideoSize(element);
|
||||
|
||||
}
|
||||
|
||||
function scaleBannerVideoSize(element){
|
||||
|
||||
var windowWidth = $(window).width(),
|
||||
windowHeight = $(window).height() + 5,
|
||||
videoWidth,
|
||||
videoHeight;
|
||||
|
||||
/* console.log(windowHeight); */
|
||||
|
||||
$(element).each(function(){
|
||||
var videoAspectRatio = $(this).data('height')/$(this).data('width');
|
||||
|
||||
$(this).width(windowWidth);
|
||||
|
||||
if(windowWidth < 1000){
|
||||
videoHeight = windowHeight;
|
||||
videoWidth = videoHeight / videoAspectRatio;
|
||||
$(this).css({'margin-top' : 0, 'margin-left' : -(videoWidth - windowWidth) / 2 + 'px'});
|
||||
|
||||
$(this).width(videoWidth).height(videoHeight);
|
||||
}
|
||||
|
||||
$('.homepage-hero-module .video-container video').addClass('fadeIn animated');
|
||||
|
||||
});
|
||||
}
|
||||
597
html/js/modules (optional)/waves.js
Executable file
597
html/js/modules (optional)/waves.js
Executable file
@@ -0,0 +1,597 @@
|
||||
/*!
|
||||
* Waves v0.7.5
|
||||
* http://fian.my.id/Waves
|
||||
*
|
||||
* Copyright 2014-2016 Alfiana E. Sibuea and other contributors
|
||||
* Released under the MIT license
|
||||
* https://github.com/fians/Waves/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
;
|
||||
(function (window, factory) {
|
||||
'use strict';
|
||||
|
||||
// AMD. Register as an anonymous module. Wrap in function so we have access
|
||||
// to root via `this`.
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], function () {
|
||||
return factory.apply(window);
|
||||
});
|
||||
}
|
||||
|
||||
// Node. Does not work with strict CommonJS, but only CommonJS-like
|
||||
// environments that support module.exports, like Node.
|
||||
else if (typeof exports === 'object') {
|
||||
module.exports = factory.call(window);
|
||||
}
|
||||
|
||||
// Browser globals.
|
||||
else {
|
||||
window.Waves = factory.call(window);
|
||||
}
|
||||
})(typeof global === 'object' ? global : this, function () {
|
||||
'use strict';
|
||||
|
||||
var Waves = Waves || {};
|
||||
var $$ = document.querySelectorAll.bind(document);
|
||||
var toString = Object.prototype.toString;
|
||||
var isTouchAvailable = 'ontouchstart' in window;
|
||||
|
||||
|
||||
// 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 isObject(value) {
|
||||
var type = typeof value;
|
||||
return type === 'function' || type === 'object' && !!value;
|
||||
}
|
||||
|
||||
function isDOMNode(obj) {
|
||||
return isObject(obj) && obj.nodeType > 0;
|
||||
}
|
||||
|
||||
function getWavesElements(nodes) {
|
||||
var stringRepr = toString.call(nodes);
|
||||
|
||||
if (stringRepr === '[object String]') {
|
||||
return $$(nodes);
|
||||
} else if (isObject(nodes) && /^\[object (Array|HTMLCollection|NodeList|Object)\]$/.test(stringRepr) && nodes.hasOwnProperty('length')) {
|
||||
return nodes;
|
||||
} else if (isDOMNode(nodes)) {
|
||||
return [nodes];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
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(styleObj) {
|
||||
var style = '';
|
||||
|
||||
for (var prop in styleObj) {
|
||||
if (styleObj.hasOwnProperty(prop)) {
|
||||
style += (prop + ':' + styleObj[prop] + ';');
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
var Effect = {
|
||||
|
||||
// Effect duration
|
||||
duration: 750,
|
||||
|
||||
// Effect delay (check for scroll before showing effect)
|
||||
delay: 200,
|
||||
|
||||
show: function (e, element, velocity) {
|
||||
|
||||
// Disable right click
|
||||
if (e.button === 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
element = element || this;
|
||||
|
||||
// Create ripple
|
||||
var ripple = document.createElement('div');
|
||||
ripple.className = 'waves-ripple waves-rippling';
|
||||
element.appendChild(ripple);
|
||||
|
||||
// Get click coordinate and element width
|
||||
var pos = offset(element);
|
||||
var relativeY = 0;
|
||||
var relativeX = 0;
|
||||
// Support for touch devices
|
||||
if ('touches' in e && e.touches.length) {
|
||||
relativeY = (e.touches[0].pageY - pos.top);
|
||||
relativeX = (e.touches[0].pageX - pos.left);
|
||||
}
|
||||
//Normal case
|
||||
else {
|
||||
relativeY = (e.pageY - pos.top);
|
||||
relativeX = (e.pageX - pos.left);
|
||||
}
|
||||
// Support for synthetic events
|
||||
relativeX = relativeX >= 0 ? relativeX : 0;
|
||||
relativeY = relativeY >= 0 ? relativeY : 0;
|
||||
|
||||
var scale = 'scale(' + ((element.clientWidth / 100) * 3) + ')';
|
||||
var translate = 'translate(0,0)';
|
||||
|
||||
if (velocity) {
|
||||
translate = 'translate(' + (velocity.x) + 'px, ' + (velocity.y) + 'px)';
|
||||
}
|
||||
|
||||
// Attach data to element
|
||||
ripple.setAttribute('data-hold', Date.now());
|
||||
ripple.setAttribute('data-x', relativeX);
|
||||
ripple.setAttribute('data-y', relativeY);
|
||||
ripple.setAttribute('data-scale', scale);
|
||||
ripple.setAttribute('data-translate', translate);
|
||||
|
||||
// Set ripple position
|
||||
var rippleStyle = {
|
||||
top: relativeY + 'px',
|
||||
left: relativeX + 'px'
|
||||
};
|
||||
|
||||
ripple.classList.add('waves-notransition');
|
||||
ripple.setAttribute('style', convertStyle(rippleStyle));
|
||||
ripple.classList.remove('waves-notransition');
|
||||
|
||||
// Scale the ripple
|
||||
rippleStyle['-webkit-transform'] = scale + ' ' + translate;
|
||||
rippleStyle['-moz-transform'] = scale + ' ' + translate;
|
||||
rippleStyle['-ms-transform'] = scale + ' ' + translate;
|
||||
rippleStyle['-o-transform'] = scale + ' ' + translate;
|
||||
rippleStyle.transform = scale + ' ' + translate;
|
||||
rippleStyle.opacity = '1';
|
||||
|
||||
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
||||
rippleStyle['-webkit-transition-duration'] = duration + 'ms';
|
||||
rippleStyle['-moz-transition-duration'] = duration + 'ms';
|
||||
rippleStyle['-o-transition-duration'] = duration + 'ms';
|
||||
rippleStyle['transition-duration'] = duration + 'ms';
|
||||
|
||||
ripple.setAttribute('style', convertStyle(rippleStyle));
|
||||
},
|
||||
|
||||
hide: function (e, element) {
|
||||
element = element || this;
|
||||
|
||||
var ripples = element.getElementsByClassName('waves-rippling');
|
||||
|
||||
for (var i = 0, len = ripples.length; i < len; i++) {
|
||||
removeRipple(e, element, ripples[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Collection of wrapper for HTML element that only have single tag
|
||||
* like <input> and <img>
|
||||
*/
|
||||
var TagWrapper = {
|
||||
|
||||
// Wrap <input> tag so it can perform the effect
|
||||
input: function (element) {
|
||||
|
||||
var parent = element.parentNode;
|
||||
|
||||
// If input already have parent just pass through
|
||||
if (parent.tagName.toLowerCase() === 'div' && parent.classList.contains('waves-effect')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Put element class and style to the specified parent
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.className = 'waves-input-wrapper';
|
||||
// element.className = element.className + ' waves-button-input';
|
||||
|
||||
// Put element as child
|
||||
parent.replaceChild(wrapper, element);
|
||||
wrapper.appendChild(element);
|
||||
|
||||
// Apply element color and background color to wrapper
|
||||
var elementStyle = window.getComputedStyle(element, null);
|
||||
var color = elementStyle.color;
|
||||
var backgroundColor = elementStyle.backgroundColor;
|
||||
|
||||
// wrapper.setAttribute('style', 'color:' + color + ';background:' + backgroundColor);
|
||||
// element.setAttribute('style', 'background-color:rgba(0,0,0,0);');
|
||||
|
||||
},
|
||||
|
||||
// Wrap <img> tag so it can perform the effect
|
||||
img: function (element) {
|
||||
|
||||
var parent = element.parentNode;
|
||||
|
||||
// If input already have parent just pass through
|
||||
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Put element as child
|
||||
var wrapper = document.createElement('i');
|
||||
parent.replaceChild(wrapper, element);
|
||||
wrapper.appendChild(element);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the effect and remove the ripple. Must be
|
||||
* a separate function to pass the JSLint...
|
||||
*/
|
||||
function removeRipple(e, el, ripple) {
|
||||
|
||||
// Check if the ripple still exist
|
||||
if (!ripple) {
|
||||
return;
|
||||
}
|
||||
|
||||
ripple.classList.remove('waves-rippling');
|
||||
|
||||
var relativeX = ripple.getAttribute('data-x');
|
||||
var relativeY = ripple.getAttribute('data-y');
|
||||
var scale = ripple.getAttribute('data-scale');
|
||||
var translate = ripple.getAttribute('data-translate');
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (e.type === 'mousemove') {
|
||||
delay = 150;
|
||||
}
|
||||
|
||||
// Fade out ripple after delay
|
||||
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
var style = {
|
||||
top: relativeY + 'px',
|
||||
left: relativeX + 'px',
|
||||
opacity: '0',
|
||||
|
||||
// Duration
|
||||
'-webkit-transition-duration': duration + 'ms',
|
||||
'-moz-transition-duration': duration + 'ms',
|
||||
'-o-transition-duration': duration + 'ms',
|
||||
'transition-duration': duration + 'ms',
|
||||
'-webkit-transform': scale + ' ' + translate,
|
||||
'-moz-transform': scale + ' ' + translate,
|
||||
'-ms-transform': scale + ' ' + translate,
|
||||
'-o-transform': scale + ' ' + translate,
|
||||
'transform': scale + ' ' + translate
|
||||
};
|
||||
|
||||
ripple.setAttribute('style', convertStyle(style));
|
||||
|
||||
setTimeout(function () {
|
||||
try {
|
||||
el.removeChild(ripple);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}, duration);
|
||||
|
||||
}, delay);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 (/^(mousedown|mousemove)$/.test(e.type) && TouchHandler.touches) {
|
||||
allow = false;
|
||||
}
|
||||
|
||||
return allow;
|
||||
},
|
||||
registerEvent: function (e) {
|
||||
var eType = e.type;
|
||||
|
||||
if (eType === 'touchstart') {
|
||||
|
||||
TouchHandler.touches += 1; // push
|
||||
|
||||
} else if (/^(touchend|touchcancel)$/.test(eType)) {
|
||||
|
||||
setTimeout(function () {
|
||||
if (TouchHandler.touches) {
|
||||
TouchHandler.touches -= 1; // pop after 500ms
|
||||
}
|
||||
}, 500);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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.parentElement !== null) {
|
||||
if (target.classList.contains('waves-effect') && (!(target instanceof SVGElement))) {
|
||||
element = target;
|
||||
break;
|
||||
}
|
||||
target = target.parentElement;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bubble the click and show effect if .waves-effect elem was found
|
||||
*/
|
||||
function showEffect(e) {
|
||||
|
||||
// Disable effect if element has "disabled" property on it
|
||||
// In some cases, the event is not triggered by the current element
|
||||
// if (e.target.getAttribute('disabled') !== null) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
var element = getWavesEffectElement(e);
|
||||
|
||||
if (element !== null) {
|
||||
|
||||
// Make it sure the element has either disabled property, disabled attribute or 'disabled' class
|
||||
if (element.disabled || element.getAttribute('disabled') || element.classList.contains('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
TouchHandler.registerEvent(e);
|
||||
|
||||
if (e.type === 'touchstart' && Effect.delay) {
|
||||
|
||||
var hidden = false;
|
||||
|
||||
var timer = setTimeout(function () {
|
||||
timer = null;
|
||||
Effect.show(e, element);
|
||||
}, Effect.delay);
|
||||
|
||||
var hideEffect = function (hideEvent) {
|
||||
|
||||
// if touch hasn't moved, and effect not yet started: start effect now
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
Effect.show(e, element);
|
||||
}
|
||||
if (!hidden) {
|
||||
hidden = true;
|
||||
Effect.hide(hideEvent, element);
|
||||
}
|
||||
};
|
||||
|
||||
var touchMove = function (moveEvent) {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
hideEffect(moveEvent);
|
||||
};
|
||||
|
||||
element.addEventListener('touchmove', touchMove, false);
|
||||
element.addEventListener('touchend', hideEffect, false);
|
||||
element.addEventListener('touchcancel', hideEffect, false);
|
||||
|
||||
} else {
|
||||
|
||||
Effect.show(e, element);
|
||||
|
||||
if (isTouchAvailable) {
|
||||
element.addEventListener('touchend', Effect.hide, false);
|
||||
element.addEventListener('touchcancel', Effect.hide, false);
|
||||
}
|
||||
|
||||
element.addEventListener('mouseup', Effect.hide, false);
|
||||
element.addEventListener('mouseleave', Effect.hide, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Waves.init = function (options) {
|
||||
var body = document.body;
|
||||
|
||||
options = options || {};
|
||||
|
||||
if ('duration' in options) {
|
||||
Effect.duration = options.duration;
|
||||
}
|
||||
|
||||
if ('delay' in options) {
|
||||
Effect.delay = options.delay;
|
||||
}
|
||||
|
||||
if (isTouchAvailable) {
|
||||
body.addEventListener('touchstart', showEffect, false);
|
||||
body.addEventListener('touchcancel', TouchHandler.registerEvent, false);
|
||||
body.addEventListener('touchend', TouchHandler.registerEvent, false);
|
||||
}
|
||||
|
||||
body.addEventListener('mousedown', showEffect, false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attach Waves to dynamically loaded inputs, or add .waves-effect and other
|
||||
* waves classes to a set of elements. Set drag to true if the ripple mouseover
|
||||
* or skimming effect should be applied to the elements.
|
||||
*/
|
||||
Waves.attach = function (elements, classes) {
|
||||
|
||||
elements = getWavesElements(elements);
|
||||
|
||||
if (toString.call(classes) === '[object Array]') {
|
||||
classes = classes.join(' ');
|
||||
}
|
||||
|
||||
classes = classes ? ' ' + classes : '';
|
||||
|
||||
var element, tagName;
|
||||
|
||||
for (var i = 0, len = elements.length; i < len; i++) {
|
||||
|
||||
element = elements[i];
|
||||
tagName = element.tagName.toLowerCase();
|
||||
|
||||
if (['input', 'img'].indexOf(tagName) !== -1) {
|
||||
TagWrapper[tagName](element);
|
||||
element = element.parentElement;
|
||||
}
|
||||
|
||||
if (element.className.indexOf('waves-effect') === -1) {
|
||||
element.className += ' waves-effect' + classes;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cause a ripple to appear in an element via code.
|
||||
*/
|
||||
Waves.ripple = function (elements, options) {
|
||||
elements = getWavesElements(elements);
|
||||
var elementsLen = elements.length;
|
||||
|
||||
options = options || {};
|
||||
options.wait = options.wait || 0;
|
||||
options.position = options.position || null; // default = centre of element
|
||||
|
||||
|
||||
if (elementsLen) {
|
||||
var element, pos, off, centre = {},
|
||||
i = 0;
|
||||
var mousedown = {
|
||||
type: 'mousedown',
|
||||
button: 1
|
||||
};
|
||||
var hideRipple = function (mouseup, element) {
|
||||
return function () {
|
||||
Effect.hide(mouseup, element);
|
||||
};
|
||||
};
|
||||
|
||||
for (; i < elementsLen; i++) {
|
||||
element = elements[i];
|
||||
pos = options.position || {
|
||||
x: element.clientWidth / 2,
|
||||
y: element.clientHeight / 2
|
||||
};
|
||||
|
||||
off = offset(element);
|
||||
centre.x = off.left + pos.x;
|
||||
centre.y = off.top + pos.y;
|
||||
|
||||
mousedown.pageX = centre.x;
|
||||
mousedown.pageY = centre.y;
|
||||
|
||||
Effect.show(mousedown, element);
|
||||
|
||||
if (options.wait >= 0 && options.wait !== null) {
|
||||
var mouseup = {
|
||||
type: 'mouseup',
|
||||
button: 1
|
||||
};
|
||||
|
||||
setTimeout(hideRipple(mouseup, element), options.wait);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all ripples from an element.
|
||||
*/
|
||||
Waves.calm = function (elements) {
|
||||
elements = getWavesElements(elements);
|
||||
var mouseup = {
|
||||
type: 'mouseup',
|
||||
button: 1
|
||||
};
|
||||
|
||||
for (var i = 0, len = elements.length; i < len; i++) {
|
||||
Effect.hide(mouseup, elements[i]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deprecated API fallback
|
||||
*/
|
||||
Waves.displayEffect = function (options) {
|
||||
console.error('Waves.displayEffect() has been deprecated and will be removed in future version. Please use Waves.init() to initialize Waves effect');
|
||||
Waves.init(options);
|
||||
};
|
||||
|
||||
return Waves;
|
||||
});
|
||||
|
||||
//Initialization
|
||||
Waves.attach('.btn:not(.btn-flat), .btn-floating', ['waves-light']);
|
||||
Waves.attach('.btn-flat', ['waves-effect']);
|
||||
Waves.attach('.view .mask', ['waves-light']);
|
||||
Waves.attach('.waves-light', ['waves-light']);
|
||||
Waves.attach('.navbar-nav a:not(.navbar-brand), .nav-icons li a, .navbar form, .nav-tabs .nav-item', ['waves-light']);
|
||||
Waves.attach('.pager li a', ['waves-light']);
|
||||
Waves.attach('.pagination .page-item .page-link', ['waves-effect']);
|
||||
Waves.init();
|
||||
180
html/js/modules (optional)/wow.js
Executable file
180
html/js/modules (optional)/wow.js
Executable file
@@ -0,0 +1,180 @@
|
||||
'use strict';
|
||||
|
||||
var WOW;
|
||||
|
||||
(function($) {
|
||||
|
||||
WOW = function WOW() {
|
||||
|
||||
return {
|
||||
|
||||
init: function init() {
|
||||
|
||||
var animationName = [];
|
||||
|
||||
var once = 1;
|
||||
|
||||
function mdbWow() {
|
||||
|
||||
var windowHeight = window.innerHeight;
|
||||
var scroll = window.scrollY;
|
||||
|
||||
$('.wow').each(function() {
|
||||
|
||||
if ($(this).css('visibility') == 'visible') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (windowHeight + scroll - 100 > getOffset(this) && scroll < getOffset(this) || windowHeight + scroll - 100 > getOffset(this) + $(this).height() && scroll < getOffset(this) + $(this).height() || windowHeight + scroll == $(document).height() && getOffset(this) + 100 > $(document).height()) {
|
||||
|
||||
var index = $(this).index('.wow');
|
||||
|
||||
var delay = $(this).attr('data-wow-delay');
|
||||
|
||||
if (delay) {
|
||||
|
||||
delay = $(this).attr('data-wow-delay').slice(0, -1
|
||||
|
||||
);
|
||||
var self = this;
|
||||
|
||||
var timeout = parseFloat(delay) * 1000;
|
||||
|
||||
$(self).addClass('animated');
|
||||
$(self).css({ 'visibility': 'visible' });
|
||||
$(self).css({ 'animation-delay': delay });
|
||||
$(self).css({ 'animation-name': animationName[index] });
|
||||
|
||||
var removeTime = $(this).css('animation-duration').slice(0, -1) * 1000;
|
||||
|
||||
if ($(this).attr('data-wow-delay')) {
|
||||
|
||||
removeTime += $(this).attr('data-wow-delay').slice(0, -1) * 1000;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
$(self).removeClass('animated');
|
||||
}, removeTime);
|
||||
} else {
|
||||
|
||||
$(this).addClass('animated');
|
||||
$(this).css({ 'visibility': 'visible' });
|
||||
$(this).css({ 'animation-name': animationName[index] });
|
||||
|
||||
var removeTime = $(this).css('animation-duration').slice(0, -1) * 1000;
|
||||
|
||||
var self = this;
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
$(self).removeClass('animated');
|
||||
}, removeTime);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function appear() {
|
||||
|
||||
$('.wow').each(function() {
|
||||
|
||||
var index = $(this).index('.wow');
|
||||
|
||||
var delay = $(this).attr('data-wow-delay');
|
||||
|
||||
if (delay) {
|
||||
|
||||
delay = $(this).attr('data-wow-delay').slice(0, -1);
|
||||
|
||||
var timeout = parseFloat(delay) * 1000;
|
||||
|
||||
$(this).addClass('animated');
|
||||
$(this).css({ 'visibility': 'visible' });
|
||||
$(this).css({ 'animation-delay': delay + 's' });
|
||||
$(this).css({ 'animation-name': animationName[index] });
|
||||
} else {
|
||||
|
||||
$(this).addClass('animated');
|
||||
$(this).css({ 'visibility': 'visible' });
|
||||
$(this).css({ 'animation-name': animationName[index] });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function hide() {
|
||||
|
||||
var windowHeight = window.innerHeight;
|
||||
var scroll = window.scrollY;
|
||||
|
||||
$('.wow.animated').each(function() {
|
||||
|
||||
if (windowHeight + scroll - 100 > getOffset(this) && scroll > getOffset(this) + 100 || windowHeight + scroll - 100 < getOffset(this) && scroll < getOffset(this) + 100 || getOffset(this) + $(this).height > $(document).height() - 100) {
|
||||
|
||||
$(this).removeClass('animated');
|
||||
$(this).css({ 'animation-name': 'none' });
|
||||
$(this).css({ 'visibility': 'hidden' });
|
||||
} else {
|
||||
|
||||
var removeTime = $(this).css('animation-duration').slice(0, -1) * 1000;
|
||||
|
||||
if ($(this).attr('data-wow-delay')) {
|
||||
|
||||
removeTime += $(this).attr('data-wow-delay').slice(0, -1) * 1000;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
$(self).removeClass('animated');
|
||||
}, removeTime);
|
||||
}
|
||||
});
|
||||
|
||||
mdbWow();
|
||||
|
||||
once--;
|
||||
}
|
||||
|
||||
function getOffset(elem) {
|
||||
|
||||
var box = elem.getBoundingClientRect();
|
||||
|
||||
var body = document.body;
|
||||
var docEl = document.documentElement;
|
||||
|
||||
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
||||
|
||||
var clientTop = docEl.clientTop || body.clientTop || 0;
|
||||
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
|
||||
return Math.round(top);
|
||||
}
|
||||
|
||||
$('.wow').each(function() {
|
||||
|
||||
$(this).css({ 'visibility': 'hidden' });
|
||||
animationName[$(this).index('.wow')] = $(this).css('animation-name');
|
||||
$(this).css({ 'animation-name': 'none' });
|
||||
});
|
||||
|
||||
$(window).scroll(function() {
|
||||
|
||||
if (once) {
|
||||
|
||||
hide();
|
||||
} else {
|
||||
|
||||
mdbWow();
|
||||
}
|
||||
});
|
||||
|
||||
appear();
|
||||
}
|
||||
};
|
||||
};
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user