UNPKG

viur-ignite-js

Version:

Javascript Libary | Extension of viur-ignite-css

398 lines (323 loc) 10 kB
/** * VIUR JS FRAMEWORK v1.0.4 * * http://ignite.viur.is * https://github.com/viur-ignite/viur-ignite-js * * Copyleft Mausbrand Infosys * Released under the GLP-3.0 license */ /** * PURE JS FUNCTIONS */ var root = function (base, decimals) { return Math.pow(base, 1 / decimals); }; Math.root = Math.root || root; function formatBytes (bytes, decimals) { if (bytes == 0) return '0 Byte'; var k = 1000; var dm = decimals || 3; var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } /** * jQuery extensions */ $(function() { // scroll to an element $.fn.scrollTo = function (options) { options = $.extend({ speed: 1000, easing: 'swing', onScrollStart: $.noop, onScrollEnd: $.noop }, options); // scroll only to the first element $this = $(this[0]); var thisTop = $this.offset().top; var bodyTop = $('body').offset().top; var place = thisTop - bodyTop; // need to avoid trigger callback twice, caused by the double animation of body,html var triggeredStartCallback = triggeredEndCallback = false; $('html,body').animate({ scrollTop: place }, { duration: options.speed, easing: options.easing, start: function() { if (!triggeredStartCallback) options.onScrollStart.call(null, $this, null); triggeredStartCallback = true; }, complete: function() { if (!triggeredEndCallback) options.onScrollEnd.call(null, $this, null); triggeredEndCallback = true; } }); return this; }; // enable scroll anchor for an element $.fn.scrollAnchor = function (options) { this.on('click', function(event) { event.preventDefault(); var $this = $(this); if (!!$this.data('target')) var target = $this.data('target'); else if (!!$this.attr('href')) var target = $this.attr('href'); else return console.error('No Scroll Target'); return $(target).scrollTo(options); }); }; // toggle class $('[data-scroll-target]').on('click', function (event) { event.preventDefault(); var target = $(this).data('scroll-target'); var speed = $(this).data('scroll-speed'); var easing = $(this).data('scroll-easing'); var $target = $(target); var options = {}; if (typeof speed != 'undefined') options.speed = speed; if (typeof easing != 'undefined') options.easing = easing; $target.scrollTo(options); }); // popup $.fn.popup = function (options) { options = $.extend({ toggleClass: 'is-active', overlayClass: 'popup-overlay', onOpen: $.noop, onClose: $.noop }, options); if (! $(this).elementExist() ) { return false; } // use only the first element $this = $(this[0]); // open popup __open(); // close on X-click $this.find('.popup-close').on('click', __close); function __open () { $('.' + options.overlayClass).addClass(options.toggleClass); // overlay show $this.addClass(options.toggleClass); // popup show options.onOpen.call(null, $this, null); } function __close () { $('.' + options.overlayClass).removeClass(options.toggleClass); // overlay hide $this.removeClass(options.toggleClass); // popup hide options.onClose.call(null, $this, null); } return this; }; // create new popup $.createPopup = function (options) { options = $.extend({ title: 'VIUR Popup', html: 'This is a VIUR popup', footer: '', button: [ {title:'Close', class: 'popup-close'} ], onopen: $.noop, onClose: $.noop }, options); // create overlay if doesnt exist if (! $('.popup-overlay').elementExist() ) $('body').append('<div class="popup-overlay" style="display:none"></div>').show(); // remove other popups $('.popup').remove(); var button = ''; if (Array.isArray( options.button )) { options.button.forEach(function (val, index) { if (typeof options.button[index].onClick === 'undefined') options.button[index].onClick = $.noop; if(!!val.html) { button += val.html; } else { button += __getButtonPrototype() .replace('{{class}}', !!val.class ? val.class : '') .replace('{{style}}', !!val.style ? val.style : '') .replace('{{index}}', index) .replace('{{title}}', !!val.title ? val.title : ''); } }); } var popup = __getPopupPrototype() .replace('{{header}}', options.title) .replace('{{content}}', options.html) .replace('{{button}}', button) .replace('{{footer}}', options.footer); var $popup = $(popup) .popup({onOpen: options.onOpen, onClose: options.onClose}) .appendTo('body') .show(); // action by buttons with data-index $popup.find('.formActions > button[data-index]').on('click', function () { var index = $(this).data('index'); var callback = options.button[index].onClick; callback($popup); }); function __getPopupPrototype() { return '<div class="popup" style="display:none">\ <div class="popup-box">\ <header class="popup-header">{{header}}</header>\ <div class="popup-content">\ {{content}}\ <div class="formActions">{{button}}</div>\ </div>\ <footer class="popup-footer">{{footer}}</footer>\ <button class="popup-close has-icon i-cross"></button>\ </div>\ </div>'; } function __getButtonPrototype() { return '<button class="btn {{class}}" style="{{style}}" data-index="{{index}}">{{title}}</button>'; } }; // check if an element exist $.fn.elementExist = function() { return ($(this).length > 0) === true; }; // toggle class $('[data-toggler]').on('click', function (event) { event.preventDefault(); var dataToggle = $(this).data('toggler'); var $toggleObj = $(dataToggle); var toggleClass = $toggleObj.data('toggle'); $toggleObj.toggleClass(toggleClass); }); // suggestions for an input field $.fn.suggestions = function (options) { options = $.extend({ data: [], searchType: 'contains', // contains or startWith url: '', getAttribute: 'q', type: 'data', // type: url or data caseSensitive: false, onSelect: $.noop, // after select onType: $.noop // ^= keydown }, options); var $elements = $(this); if ($elements.elementExist()) { $elements.each(function (index) { var $element = $(this); var offset = $element.offset(); var width = $element.innerWidth(); // use here innerWidth because of the border var height = $element.outerHeight(); var moveIndex = 0; // index for key up down var $suggestionBox = $( __getSuggestionBoxPrototype() ) .appendTo('body') .width(width) .css('left', offset.left) .css('top', offset.top + height) .hide(); $element.on('keydown', function(e) { var key = e.key; switch (key) { case 'ArrowUp': moveIndex--; if (moveIndex === 0) { moveIndex = $suggestionBox.find('.suggestion-box-item').length; } $suggestionBox.find('.suggestion-box-item').removeClass('is-active'); $( $suggestionBox.find('.suggestion-box-item')[moveIndex - 1] ).addClass('is-active'); break; case 'ArrowDown': moveIndex++; if (moveIndex > $suggestionBox.find('.suggestion-box-item').length) { moveIndex = 1; } $suggestionBox.find('.suggestion-box-item').removeClass('is-active'); $( $suggestionBox.find('.suggestion-box-item')[moveIndex - 1] ).addClass('is-active'); break; case 'Enter': var text = $suggestionBox.find('.suggestion-box-item.is-active').text(); $element.val(text); $suggestionBox.hide(); options.onSelect.call(null, this, null); break; default: var input = $element.val(); __loadSuggestions(input, $suggestionBox, $element); moveIndex = 0; // reset moveIndex for new suggestions break; } options.onType.call(null, this, null); }); }); } function __loadSuggestions(input, $suggestionBox, $element) { var arr = __searchSuggestions(input); var items = ''; arr.forEach(function (value, index) { items += __getSuggestionItemPrototype() .replace('{{value}}', value); }) $suggestionBox.html( __getSuggestionBoxContentPrototype() .replace('{{items}}', items) ).show(); $suggestionBox.find('.suggestion-box-item').on('click', function(e) { var text = $(this).text(); $element.val(text); $suggestionBox.hide(); }) } function __searchSuggestions(q) { if (options.caseSensitive == false) { q = q.toLowerCase(); } switch (options.type) { case 'url': var arr; $.ajax({ url: options.url, data: {q: q}, async: false, // Its deprecated, but async ajax sucks dataType: 'json', success: function (response) { arr = response; } }); return arr; break; case 'data': if (typeof options.data != 'undefined' && Array.isArray(options.data)) { var data = options.data; var arr = []; data.forEach(function (value, index) { var searchvalue = value; // use an extra variable that the value isnt lowercase if (options.caseSensitive == false) { searchvalue = value.toLowerCase(); } if ((options.searchType == 'contains' && searchvalue.indexOf(q) !== -1) || (options.searchType == 'startWith' && searchvalue.indexOf(q) === 0) ) { arr.push(value) } }) return arr; } break; default: // function ends here // because suggesions are missing return this; break; } } function __getSuggestionBoxPrototype() { return '<div class="suggestion-box"><div>'; } function __getSuggestionBoxContentPrototype() { return '<ul class="suggestion-box-items">{{items}}</ul>'; } function __getSuggestionItemPrototype() { return '<li class="suggestion-box-item">{{value}}</li>'; } return this; }; })