455 lines
14 KiB
JavaScript
455 lines
14 KiB
JavaScript
|
(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));
|
||
|
});
|
||
|
|
||
|
|
||
|
// File Input Path
|
||
|
$('.file-field').each(function() {
|
||
|
var path_input = $(this).find('input.file-path');
|
||
|
$(this).find('input[type="file"]').change(function () {
|
||
|
path_input.val($(this)[0].files[0].name);
|
||
|
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('mousedown touchstart', range_type, function(e) {
|
||
|
var thumb = $(this).siblings('.thumb');
|
||
|
|
||
|
// If thumb indicator does not exist yet, create it
|
||
|
if (thumb.length <= 0) {
|
||
|
thumb = $('<span class="thumb"><span class="value"></span></span>');
|
||
|
$(this).append(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.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($(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);
|
||
|
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
$(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(){
|
||
|
$select = $(this);
|
||
|
|
||
|
if ( $select.hasClass('browser-default')) {
|
||
|
return; // Continue to next (return false breaks out of entire loop)
|
||
|
}
|
||
|
|
||
|
// Tear down structure if Select needs to be rebuilt
|
||
|
var lastID = $select.data('select-id');
|
||
|
if (lastID) {
|
||
|
$select.parent().find('i').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"></ul>');
|
||
|
var selectOptions = $select.children('option');
|
||
|
|
||
|
var label;
|
||
|
if ($select.find('option:selected') !== undefined) {
|
||
|
label = $select.find('option:selected');
|
||
|
}
|
||
|
else {
|
||
|
label = options.first();
|
||
|
}
|
||
|
|
||
|
|
||
|
// Create Dropdown structure
|
||
|
selectOptions.each(function () {
|
||
|
// Add disabled attr if disabled
|
||
|
options.append($('<li class="' + (($(this).is(':disabled')) ? 'disabled' : '') + '"><span>' + $(this).html() + '</span></li>'));
|
||
|
});
|
||
|
|
||
|
|
||
|
options.find('li').each(function (i) {
|
||
|
var $curr_select = $select;
|
||
|
$(this).click(function () {
|
||
|
// Check if option element is disabled
|
||
|
if (!$(this).hasClass('disabled')) {
|
||
|
$curr_select.find('option').eq(i).prop('selected', true);
|
||
|
// Trigger onchange() event
|
||
|
$curr_select.trigger('change');
|
||
|
$curr_select.siblings('input.select-dropdown').val($(this).text());
|
||
|
if (typeof callback !== 'undefined') callback();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
});
|
||
|
|
||
|
// Wrap Elements
|
||
|
$select.wrap(wrapper);
|
||
|
// Add Select Display Element
|
||
|
var dropdownIcon = $('<span class="caret">▼</span>');
|
||
|
if ( $select.is(':disabled') )
|
||
|
dropdownIcon.addClass('disabled');
|
||
|
|
||
|
var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ label.html() +'"/>');
|
||
|
$select.before($newSelect);
|
||
|
$newSelect.before(dropdownIcon);
|
||
|
|
||
|
$('body').append(options);
|
||
|
// Check if section element is disabled
|
||
|
if (!$select.is(':disabled')) {
|
||
|
$newSelect.dropdown({"hover": false});
|
||
|
}
|
||
|
|
||
|
// Copy tabindex
|
||
|
if ($select.attr('tabindex')) {
|
||
|
$($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
|
||
|
}
|
||
|
|
||
|
$select.addClass('initialized');
|
||
|
|
||
|
$newSelect.on('focus', function(){
|
||
|
$(this).trigger('open');
|
||
|
label = $(this).val();
|
||
|
selectedOption = options.find('li').filter(function() {
|
||
|
return $(this).text().toLowerCase() === label.toLowerCase();
|
||
|
})[0];
|
||
|
activateOption(options, selectedOption);
|
||
|
});
|
||
|
|
||
|
$newSelect.on('blur', function(){
|
||
|
$(this).trigger('close');
|
||
|
});
|
||
|
|
||
|
// Make option as selected and scroll to selected position
|
||
|
activateOption = function(collection, newOption) {
|
||
|
collection.find('li.active').removeClass('active');
|
||
|
$(newOption).addClass('active');
|
||
|
collection.scrollTo(newOption);
|
||
|
};
|
||
|
|
||
|
// Allow user to search by typing
|
||
|
// this array is cleared after 1 second
|
||
|
filterQuery = [];
|
||
|
|
||
|
onKeyDown = function(event){
|
||
|
// TAB - switch to another input
|
||
|
if(event.which == 9){
|
||
|
$newSelect.trigger('close');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// ARROW DOWN WHEN SELECT IS CLOSED - open select options
|
||
|
if(event.which == 40 && !options.is(":visible")){
|
||
|
$newSelect.trigger('open');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// ENTER WHEN SELECT IS CLOSED - submit form
|
||
|
if(event.which == 13 && !options.is(":visible")){
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
event.preventDefault();
|
||
|
|
||
|
// CASE WHEN USER TYPE LETTERS
|
||
|
letter = String.fromCharCode(event.which).toLowerCase();
|
||
|
var nonLetters = [9,13,27,38,40];
|
||
|
if (letter && (nonLetters.indexOf(event.which) === -1)){
|
||
|
filterQuery.push(letter);
|
||
|
|
||
|
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(event.which == 13){
|
||
|
activeOption = options.find('li.active:not(.disabled)')[0];
|
||
|
if(activeOption){
|
||
|
$(activeOption).trigger('click');
|
||
|
$newSelect.trigger('close');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ARROW DOWN - move to next not disabled option
|
||
|
if(event.which == 40){
|
||
|
newOption = options.find('li.active').next('li:not(.disabled)')[0];
|
||
|
if(newOption){
|
||
|
activateOption(options, newOption);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ESC - close options
|
||
|
if(event.which == 27){
|
||
|
$newSelect.trigger('close');
|
||
|
}
|
||
|
|
||
|
// ARROW UP - move to previous not disabled option
|
||
|
if(event.which == 38){
|
||
|
newOption = options.find('li.active').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);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
}( jQuery ));
|