229 lines
8.1 KiB
JavaScript
229 lines
8.1 KiB
JavaScript
/**
|
||
* nlform.js v1.0.0
|
||
* https://www.codrops.com
|
||
*
|
||
* Licensed under the MIT license.
|
||
* https://www.opensource.org/licenses/mit-license.php
|
||
*
|
||
* Copyright 2013, Codrops
|
||
* https://www.codrops.com
|
||
*/
|
||
;( function( window ) {
|
||
|
||
'use strict';
|
||
|
||
var document = window.document;
|
||
|
||
if (!String.prototype.trim) {
|
||
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');};
|
||
}
|
||
|
||
function NLForm( el, elClass ) {
|
||
this.el = el;
|
||
this.overlay = this.el.querySelector( '.nl-overlay' );
|
||
this.elClass = (elClass !== undefined) ? '.' + elClass : '';
|
||
this.fields = [];
|
||
this.fldOpen = -1;
|
||
this._init();
|
||
}
|
||
|
||
NLForm.prototype = {
|
||
_init : function() {
|
||
var self = this;
|
||
Array.prototype.slice.call( this.el.querySelectorAll( 'select' + self.elClass ) ).forEach( function( el, i ) {
|
||
self.fldOpen++;
|
||
self.fields.push( new NLField( self, el, 'dropdown', self.fldOpen ) );
|
||
} );
|
||
Array.prototype.slice.call( this.el.querySelectorAll( 'input' + self.elClass + ':not([type="hidden"]):not([type="submit"])' ) ).forEach( function( el, i ) {
|
||
self.fldOpen++;
|
||
self.fields.push( new NLField( self, el, 'input', self.fldOpen ) );
|
||
} );
|
||
Array.prototype.slice.call( this.el.querySelectorAll( 'a' + self.elClass ) ).forEach( function( el, i ) {
|
||
self.fldOpen++;
|
||
//self.fields.push( new NLField( self, el, 'dropdown', self.fldOpen ) );
|
||
|
||
} );
|
||
this.overlay.addEventListener( 'click', function(ev) { self._closeFlds(); } );
|
||
this.overlay.addEventListener( 'touchstart', function(ev) { self._closeFlds(); } );
|
||
},
|
||
_closeFlds : function() {
|
||
if( this.fldOpen !== -1 ) {
|
||
this.fields[ this.fldOpen ].close();
|
||
}
|
||
}
|
||
};
|
||
|
||
function NLField( form, el, type, idx ) {
|
||
var parsed = el.getAttribute('data-parsed');
|
||
if (parsed != 1) {
|
||
el.setAttribute('data-parsed', 1);
|
||
this.form = form;
|
||
this.elOriginal = el;
|
||
this.pos = idx;
|
||
this.type = type;
|
||
this._create();
|
||
this._initEvents();
|
||
}
|
||
}
|
||
|
||
NLField.prototype = {
|
||
_create : function() {
|
||
if( this.type === 'dropdown' ) {
|
||
this._createDropDown();
|
||
}
|
||
else if( this.type === 'input' ) {
|
||
this._createInput();
|
||
}
|
||
else if( this.type === 'widget' ) {
|
||
//this._createInput();
|
||
}
|
||
},
|
||
_createDropDown : function() {
|
||
var self = this;
|
||
this.fld = document.createElement( 'div' );
|
||
this.fld.className = 'nl-field nl-dd';
|
||
this.toggle = document.createElement( 'a' );
|
||
this.toggle.innerHTML = this.elOriginal.options[ this.elOriginal.selectedIndex ].innerHTML;
|
||
this.toggle.className = 'nl-field-toggle';
|
||
this.optionsList = document.createElement( 'ul' );
|
||
var ihtml = '';
|
||
Array.prototype.slice.call( this.elOriginal.querySelectorAll( 'option' ) ).forEach( function( el, i ) {
|
||
ihtml += self.elOriginal.selectedIndex === i ? '<li class="nl-dd-checked">' + el.innerHTML + '</li>' : '<li>' + el.innerHTML + '</li>';
|
||
// selected index value
|
||
if( self.elOriginal.selectedIndex === i ) {
|
||
self.selectedIdx = i;
|
||
}
|
||
} );
|
||
this.optionsList.innerHTML = ihtml;
|
||
this.fld.appendChild( this.toggle );
|
||
this.fld.appendChild( this.optionsList );
|
||
this.elOriginal.parentNode.insertBefore( this.fld, this.elOriginal );
|
||
this.elOriginal.style.display = 'none';
|
||
},
|
||
_createInput : function() {
|
||
var self = this;
|
||
this.fld = document.createElement( 'div' );
|
||
this.fld.className = 'nl-field nl-ti-text';
|
||
this.toggle = document.createElement( 'a' );
|
||
this.toggle.innerHTML = this.elOriginal.getAttribute('value')? this.elOriginal.getAttribute('value'): this.elOriginal.getAttribute('placeholder');
|
||
this.toggle.className = 'nl-field-toggle';
|
||
this.optionsList = document.createElement( 'ul' );
|
||
this.getinput = document.createElement( 'input' );
|
||
this.getinput.setAttribute( 'type', this.elOriginal.getAttribute('type')? this.elOriginal.getAttribute('type'): '');
|
||
this.getinput.setAttribute( 'placeholder', this.elOriginal.getAttribute( 'placeholder' ) );
|
||
this.getinput.setAttribute( 'value', this.elOriginal.getAttribute('value')? this.elOriginal.getAttribute('value'): '');
|
||
this.getinputWrapper = document.createElement( 'li' );
|
||
this.getinputWrapper.className = 'nl-ti-input';
|
||
this.inputsubmit = document.createElement( 'button' );
|
||
this.inputsubmit.className = 'nl-field-go';
|
||
this.inputsubmit.innerHTML = 'Go';
|
||
this.getinputWrapper.appendChild( this.getinput );
|
||
this.getinputWrapper.appendChild( this.inputsubmit );
|
||
this.example = document.createElement( 'li' );
|
||
this.example.className = 'nl-ti-example';
|
||
this.example.innerHTML = this.elOriginal.getAttribute( 'data-subline' );
|
||
this.optionsList.appendChild( this.getinputWrapper );
|
||
this.optionsList.appendChild( this.example );
|
||
this.fld.appendChild( this.toggle );
|
||
this.fld.appendChild( this.optionsList );
|
||
this.elOriginal.parentNode.insertBefore( this.fld, this.elOriginal );
|
||
this.elOriginal.style.display = 'none';
|
||
},
|
||
_initEvents : function() {
|
||
var self = this;
|
||
this.toggle.addEventListener( 'click', function( ev ) { ev.preventDefault(); ev.stopPropagation(); self._open(); } );
|
||
this.toggle.addEventListener( 'touchstart', function( ev ) { ev.preventDefault(); ev.stopPropagation(); self._open(); } );
|
||
|
||
if( this.type === 'dropdown' ) {
|
||
var opts = Array.prototype.slice.call( this.optionsList.querySelectorAll( 'li' ) );
|
||
opts.forEach( function( el, i ) {
|
||
el.addEventListener( 'click', function( ev ) { ev.preventDefault(); self.close( el, opts.indexOf( el ) ); } );
|
||
el.addEventListener( 'hover', function( ev ) { ev.preventDefault(); self.close( el, opts.indexOf( el ), true ); } );
|
||
el.addEventListener( 'touchstart', function( ev ) { ev.preventDefault(); self.close( el, opts.indexOf( el ) ); } );
|
||
} );
|
||
}
|
||
else if( this.type === 'input' ) {
|
||
this.getinput.addEventListener( 'keydown', function( ev ) {
|
||
if ( ev.keyCode == 13 ) {
|
||
self.close();
|
||
}
|
||
} );
|
||
this.inputsubmit.addEventListener( 'click', function( ev ) { ev.preventDefault(); self.close(); } );
|
||
this.inputsubmit.addEventListener( 'touchstart', function( ev ) { ev.preventDefault(); self.close(); } );
|
||
}
|
||
|
||
},
|
||
_open : function() {
|
||
if( this.open ) {
|
||
return false;
|
||
}
|
||
this.open = true;
|
||
this.form.fldOpen = this.pos;
|
||
var self = this;
|
||
this.fld.className += ' nl-field-open';
|
||
this._checkPosition()
|
||
},
|
||
_checkPosition: function() {
|
||
var ul = this.fld.querySelector('ul');
|
||
var left = this._getOffset(ul).left;
|
||
|
||
var windowWidth = document.documentElement.clientWidth
|
||
|| document.body.clientWidth;
|
||
|
||
if (windowWidth < left + ul.scrollWidth) {
|
||
var diff = windowWidth - (left + ul.scrollWidth);
|
||
ul.style.left = diff+'px';
|
||
}
|
||
},
|
||
_getOffset: function(el) {
|
||
var _x = 0;
|
||
var _y = 0;
|
||
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
|
||
_x += el.offsetLeft - el.scrollLeft;
|
||
_y += el.offsetTop - el.scrollTop;
|
||
el = el.offsetParent;
|
||
}
|
||
return { top: _y, left: _x };
|
||
},
|
||
close : function( opt, idx, flag ) {
|
||
if( !this.open ) {
|
||
return false;
|
||
}
|
||
if (!flag) {
|
||
this.open = false;
|
||
this.form.fldOpen = -1;
|
||
this.fld.className = this.fld.className.replace(/\b nl-field-open\b/,'');
|
||
}
|
||
|
||
if( this.type === 'dropdown' ) {
|
||
if( opt ) {
|
||
// remove class nl-dd-checked from previous option
|
||
var selectedopt = this.optionsList.children[ this.selectedIdx ];
|
||
selectedopt.className = '';
|
||
opt.className = 'nl-dd-checked';
|
||
this.toggle.innerHTML = opt.innerHTML;
|
||
// update selected index value
|
||
this.selectedIdx = idx;
|
||
// update original select element´s value
|
||
this.elOriginal.value = this.elOriginal.children[ this.selectedIdx ].value;
|
||
if ("createEvent" in document) {
|
||
var evt = document.createEvent("HTMLEvents");
|
||
evt.initEvent("change", false, true);
|
||
this.elOriginal.dispatchEvent(evt);
|
||
}
|
||
else
|
||
this.elOriginal.fireEvent("change");
|
||
}
|
||
}
|
||
else if( this.type === 'input' ) {
|
||
this.getinput.blur();
|
||
this.toggle.innerHTML = this.getinput.value.trim() !== '' ? this.getinput.value : this.getinput.getAttribute( 'placeholder' );
|
||
this.elOriginal.value = this.getinput.value;
|
||
}
|
||
}
|
||
};
|
||
|
||
// add to global namespace
|
||
window.NLForm = NLForm;
|
||
} )( window );
|