/* * * jAlert v.3 Made with love by Versatility Werks (http://flwebsites.biz) MIT Licensed * * */ ;(function($) { var $jAlertSelectedOpts = {}; if(!Date.now) Date.now = function(){ return +new Date(); }; $.fn.jAlert = function(options) { var themes = ['default', 'green', 'red', 'black', 'blue','yellow'], sizes = ['xsm', 'sm', 'md', 'lg', 'xlg', 'full'], backgroundColors = ['white', 'black'], styles = [], //array of styles that gets joined together with a space between in a style tag on the jalert div classes = ['animated'], //array of classes that get joined together with a space between on the jalert div backgroundClasses = []; //array of classes that get joined together with a space between on the jalert background div /* Block Multiple Instances by running jAlert for each one */ if (this.length > 1){ this.each(function() { $(this).jAlert(options); }); return this; } /* Combine user options with default */ options = $.extend({}, $.fn.jAlert.defaults, options); /* If they didn't set an id, just create a random one */ if( !options.id ) { var unique = Date.now().toString() + Math.floor(Math.random() * 100000); var alert_id = 'ja_' + unique; } else { var alert_id = options.id; } $jAlertSelectedOpts[alert_id] = {}; thisAlert = $jAlertSelectedOpts[alert_id]; thisAlert.options = options; thisAlert.options.id = alert_id; thisAlert.instance = false; if( thisAlert.options.type == 'confirm' ) { if( !thisAlert.options.content ) { thisAlert.options.content = thisAlert.options.confirmQuestion; } thisAlert.options.btns = [ { 'text': thisAlert.options.confirmBtnText, 'theme': 'green', 'class': 'confirmBtn', 'closeAlert': true, 'onClick': thisAlert.options.onConfirm }, { 'text': thisAlert.options.denyBtnText, 'theme': 'red', 'class': 'denyBtn', 'closeAlert': true, 'onClick': thisAlert.options.onDeny } ]; thisAlert.options.autofocus = thisAlert.options.confirmAutofocus; } /* Add theme class */ if( $.inArray(thisAlert.options.theme, themes) == -1 ) { console.log('jAlert Config Error: Invalid theme selection.'); return false; } classes.push('ja_'+thisAlert.options.theme); /* If they set custom classes */ if( thisAlert.options['class'] ) { classes.push(thisAlert.options['class']); } if( thisAlert.options.classes ) { classes.push(thisAlert.options.classes); } /* If no title, add class */ if( !thisAlert.options.title ) { classes.push( 'ja_noTitle' ); } /* if it's set and it's not in the array of sizes OR it's an object and it's missing width/height */ if( thisAlert.options.size && ((typeof thisAlert.options.size == 'string' && $.inArray(thisAlert.options.size, sizes) == -1) || (typeof thisAlert.options.size == 'object' && (typeof thisAlert.options.size.width == 'undefined' || typeof thisAlert.options.size.height == 'undefined'))) ) { console.log('jAlert Config Error: Invalid size selection (try a preset or make sure you\'re including height and width in your size object).'); return false; } /* If it's not set, set to md */ else if( !thisAlert.options.size ) { classes.push('ja_sm'); } /* If it's set and it's an object */ else if( typeof thisAlert.options.size == 'object' ) { styles.push('width: '+thisAlert.options.size.width+';'); styles.push('height: '+thisAlert.options.size.height+';'); } /* If it's set and it's not an object */ else { classes.push('ja_'+thisAlert.options.size); } /* Add background color class */ if( $.inArray(thisAlert.options.backgroundColor, backgroundColors) == -1 ) { console.log('jAlert Config Error: Invalid background color selection.'); return false; } backgroundClasses.push('ja_wrap_'+thisAlert.options.backgroundColor); /* If there are button(s), then you obviously don't want to hide the div when you alert anywhere or they'll be useless...SAME with autofocus */ if( (typeof thisAlert.options.btns == 'object' || typeof thisAlert.options.btns == 'array') || thisAlert.options.autofocus ){ thisAlert.options.closeOnClick = false; } thisAlert.options.onOpen = [ thisAlert.options.onOpen ]; var onload = "onload='$.fn.jAlert.mediaLoaded($(this))'", loader = "
Loading...
"; /* Creates content */ if( thisAlert.options.image ) { thisAlert.options.content = "
"+ loader+ ""; } else if( thisAlert.options.video ) { thisAlert.options.content = "
"+ loader+ "
"+ "
"+ "
"; /* Add to the onOpen callbacks array to append the iframe and attach the onload callback in a crossbrowser compatible way (IE is a bizitch). */ thisAlert.options.onOpen.unshift( function(alert){ var iframe = document.createElement("iframe"); iframe.src = thisAlert.options.video; if(iframe.addEventListener) { iframe.addEventListener('load', function(){ $.fn.jAlert.mediaLoaded($(this)); }, true) } else if (iframe.attachEvent){ iframe.attachEvent("onload", function(){ $.fn.jAlert.mediaLoaded($(this)); }); } else { iframe.onload = function(){ $.fn.jAlert.mediaLoaded($(this)); }; } alert.find('.ja_video').append(iframe); }); } else if( thisAlert.options.iframe ) { if( !thisAlert.options.iframeHeight ) { thisAlert.options.iframeHeight = $(window).height() * 0.9+'px'; } thisAlert.options.content = "
"+ loader+ "
"; /* Add to the onOpen callbacks array to append the iframe and attach the onload callback in a crossbrowser compatible way (IE is a bizitch). */ thisAlert.options.onOpen.unshift( function(alert){ var iframe = document.createElement("iframe"); iframe.src = thisAlert.options.iframe; iframe.height = thisAlert.options.iframeHeight; iframe.className = 'ja_iframe'; if(iframe.addEventListener) { iframe.addEventListener('load', function(){ $.fn.jAlert.mediaLoaded($(this)); }, true) } else if (iframe.attachEvent){ iframe.attachEvent("onload", function(){ $.fn.jAlert.mediaLoaded($(this)); }); } else { iframe.onload = function(){ $.fn.jAlert.mediaLoaded($(this)); }; } alert.find('.ja_media_wrap').append(iframe); }); } else if( thisAlert.options.ajax ) { thisAlert.options.content = "
"+ loader+ "
"; /* Store as another var */ onAjaxCallbacks = thisAlert.options.onOpen; /* Overwrite the onOpen to be the ajax call */ thisAlert.options.onOpen = [function(alert){ $.ajax(thisAlert.options.ajax, { async: true, complete: function(jqXHR, textStatus) { alert.find('.ja_media_wrap').replaceWith(jqXHR.responseText); /* Run onOpen callbacks here */ $.each(onAjaxCallbacks, function(index, onAjax){ onAjax(alert); }); }, error: function(jqXHR, textStatus, errorThrown) { thisAlert.options.onAjaxFail(alert, 'Error getting content: Code: '+jqXHR.status+ ' : Msg: '+jqXHR.statusText); } }); }]; } this.centerAlert = function() { var viewportHeight = $(window).height(), alertHeight = thisAlert.instance.height(), diff = viewportHeight - alertHeight; var top = diff / 2; if( top > 200 ) { top = top - 100; } if( top <= 0 ) { top = 0; } thisAlert.instance.css('margin-top', top+'px'); $('body').css('overflow', 'hidden'); if( diff > 5 ) { thisAlert.instance.parents('.ja_wrap').css('position', 'fixed'); } else { thisAlert.instance.parents('.ja_wrap').css('position', 'absolute'); /* Scroll to alert */ $('html, body').animate({ scrollTop: top - 50 }, 200); } } var animateAlert = function(which, thisAlert){ if( which == 'hide' ) { thisAlert.removeClass($jAlertSelectedOpts[thisAlert.attr('id')].options.showAnimation).addClass($jAlertSelectedOpts[thisAlert.attr('id')].options.hideAnimation); } else { thisAlert.centerAlert(); thisAlert.addClass($jAlertSelectedOpts[thisAlert.attr('id')].options.showAnimation).removeClass($jAlertSelectedOpts[thisAlert.attr('id')].options.hideAnimation).show(); } } var getBtnHTML = function(btn){ if(typeof btn.href == 'undefined'){ btn.href = ''; } if(typeof btn['class'] == 'undefined'){ btn['class'] = ''; } if(typeof btn.theme == 'undefined'){ btn['class'] += ' ja_btn_default'; }else{ btn['class'] += ' ja_btn_'+btn.theme; } if(typeof btn.text == 'undefined'){ btn.text = ''; } if(typeof btn.id == 'undefined'){ var unique = Date.now().toString() + Math.floor(Math.random() * 100000); btn.id = 'ja_btn_' + unique; } if(typeof btn.target == 'undefined'){ btn.target = '_self'; } if(typeof btn.closeAlert == 'undefined'){ btn.closeAlert = true; } /* Attach on click handler */ $('body').on('click', '#'+btn.id, function(e){ var button = $(this); if( btn.closeAlert ) { button.parents('.jAlert').closeAlert(); } var callbackResponse = true; if( typeof btn.onClick == 'function' ) { callbackResponse = btn.onClick(e, button); } if( !callbackResponse || btn.closeAlert ) { e.preventDefault(); return false; } return callbackResponse; }); return ""+btn.text+" "; } /* Hides an alert and optionally removes it */ this.closeAlert = function(remove, onClose){ var alertInstance = $(this); if( remove != false ) { remove = true; } if(alertInstance.length) { alertInstance.unbind('DOMSubtreeModified'); animateAlert('hide', alertInstance); window.setTimeout(function() { var alertWrap = alertInstance.parents('.ja_wrap'); if( remove ) { alertWrap.remove(); } else { alertWrap.hide(); } if(typeof onClose == 'function') { onClose(alertInstance); } else if(typeof $jAlertSelectedOpts[alertInstance.attr('id')].options.onClose == 'function') { $jAlertSelectedOpts[alertInstance.attr('id')].options.onClose(alertInstance); } if( $('.jAlert').length > 0 ) { $('.jAlert:last').centerAlert(); } else { $('body').css('overflow', 'auto'); } }, $jAlertSelectedOpts[alertInstance.attr('id')].options.animationTimeout); } return this; } /* Shows an alert that already exists */ this.showAlert = function(replaceOthers, removeOthers, onOpen, onClose){ var alertInstance = $(this); if( replaceOthers != false ) { replaceOthers = true; } if( removeOthers !== false ) { removeOthers = true; } if( replaceOthers ) { $('.jAlert:visible').closeAlert(removeOthers); } /* Put this one above the last one by moving to end of dom */ var wrap = alertInstance.parents('.ja_wrap'); $('body').append(wrap); animateAlert('show', alertInstance); if( typeof onClose == 'function' ) { $jAlertSelectedOpts[alertInstance.attr('id')].options.onClose = onClose; } window.setTimeout(function(){ if(typeof onOpen == 'function') { onOpen(alertInstance); } }, $jAlertSelectedOpts[alertInstance.attr('id')].options.animationTimeout); } /* Adds a new alert to the dom */ var addAlert = function(content){ var html = ''; html += '
'+ '
'+ '
'; if( thisAlert.options.closeBtn ) { html += "
"; } html += '
'+content; if( thisAlert.options.btns ) { html += '
'; } if( typeof thisAlert.options.btns[0] == 'object' ) { $.each(thisAlert.options.btns, function(index, btn){ if( typeof btn == 'object' ) { html += getBtnHTML(btn); } }); } else if( typeof thisAlert.options.btns == 'object' ) { html += getBtnHTML(thisAlert.options.btns); } else if( thisAlert.options.btns ) { console.log('jAlert Config Error: Incorrect value for btns (must be object or array of objects): '+thisAlert.options.btns); } if( thisAlert.options.btns ) { html += '
'; } html += '
'+ '
'+ '
'+ '
'; var alertHTML = $(html); if( thisAlert.options.replaceOtherAlerts ) { $('.jAlert:visible').closeAlert(); } $('body').append(alertHTML); thisAlert.instance = $('#'+thisAlert.options.id); animateAlert('show', thisAlert.instance); if( thisAlert.options.closeBtn ){ thisAlert.instance.on('click', '.closejAlert', function(e){ e.preventDefault(); $(this).parents('.jAlert').closeAlert(); return false; }); } /* Bind mouseup handler to document if this alert has closeOnClick enabled */ if( thisAlert.options.closeOnClick ){ /* Unbind if already exists */ $(document).off('mouseup', $.fn.jAlert.onMouseUp); /* Bind mouseup */ $(document).on('mouseup', $.fn.jAlert.onMouseUp); } /* Bind on keydown handler to document and if esc was pressed, find all visible jAlerts with that close option enabled and close them */ if( thisAlert.options.closeOnEsc ){ /* Unbind if already exists */ $(document).off('keydown', $.fn.jAlert.onEscKeyDown); /* Bind keydown */ $(document).on('keydown', $.fn.jAlert.onEscKeyDown); } /* If there are onOpen callbacks, run them. */ if( thisAlert.options.onOpen ) { $.each(thisAlert.options.onOpen, function(index, onOpen){ onOpen(thisAlert.instance); }); } /* If the alert has an element that should be focused by default */ if( thisAlert.options.autofocus ) { thisAlert.instance.find(thisAlert.options.autofocus).focus(); } else { thisAlert.instance.focus(); } thisAlert.instance.bind("DOMSubtreeModified", function(){ thisAlert.instance.centerAlert(); }); return thisAlert.instance; }; /* Shows an alert based on content type */ this.initialize = function(){ if( !thisAlert.options.content && !thisAlert.options.image && !thisAlert.options.video && !thisAlert.options.iframe && !thisAlert.options.ajax ) { console.log('jAlert potential error: No content defined'); return addAlert(''); } else { if( !thisAlert.options.content ) { thisAlert.options.content = ''; } return addAlert(thisAlert.options.content); } } this.initialize(); return this; /* END OF PLUGIN */ }; /* Default thisAlert.options */ $.fn.jAlert.defaults = { 'title': false, //title for the popup (false = don't show) 'content': false, //html for the popup (replaced if you use image, ajax, or iframe) 'image': false, //adds a centered img tag 'imageWidth': 'auto', //defaults to max-width: 100%; width: auto; 'video': false, //adds a responsive iframe video - value is the "src" of the iframe 'ajax': false, //uses ajax call to get contents 'onAjaxFail': function(alert, errorThrown){ //callback for when ajax fails thisAlert.closeAlert(); errorAlert(errorThrown); }, 'iframe': false, //uses iframe as content 'iframeHeight': false, //string. height of the iframe within the popup (false = 90% of viewport height) 'class': '', //adds a class to the jAlert (add as many as you want space delimited) 'classes': '', //add classes to the jAlert (space delimited) 'id': false, //adds an ID to the jAlert 'showAnimation': 'fadeInUp', 'hideAnimation': 'fadeOutDown', 'animationTimeout': 600, //approx duration of animation to wait until onClose 'theme': 'default', // red, green, blue, black, default 'backgroundColor': 'black', //white, black 'size': false, //false = css default, xsm, sm, md, lg, xlg, full, { height: 200, width: 200 } 'replaceOtherAlerts': false, //if there's already an open jAlert, remove it first 'closeOnClick': false, //close the alert when you click anywhere 'closeOnEsc': true, //close the alert when you click the escape key 'closeBtn': true, //adds a button to the top right of the alert that allows you to close it 'closeBtnAlt': false, //alternative close button 'btns': false, //adds buttons to the popup at the bottom. Pass an object for a single button, or an object of objects for many /* Variety of buttons you could create (also, an example of how to pass the object 'btns': [ {'text':'Open in new window', 'closeAlert':false, 'href': 'http://google.com', 'target':'_new'}, {'text':'Cool, close this alert', 'theme': 'blue', 'closeAlert':true}, {'text':'Buy Now', 'closeAlert':true, 'theme': 'green', 'onClick': function(){ console.log('You bought it!'); } }, {'text':'I do not want it', 'closeAlert': true, 'theme': 'red', 'onClick': function(){ console.log('Did not want it'); } }, {'text':'DOA', 'closeAlert': true, 'theme': 'black', 'onClick': function(){ console.log('Dead on arrival'); } } ] */ 'btnBackground': true, //adds optional background to btns 'autofocus': false, //pass a selector to autofocus on it 'onOpen': function(alert){ //on open call back. Fires just after the alert has finished rendering return false; }, 'onClose': function(alert){ //fires when you close the alert return false; }, 'type': 'modal', //modal, confirm, tooltip /* The following only applies when type == 'confirm' */ 'confirmQuestion': 'Esta seguro?', 'confirmBtnText': 'Si', 'denyBtnText': 'No', 'confirmAutofocus': '.confirmBtn', //confirmBtn or denyBtn 'onConfirm': function(e, btn){ e.preventDefault(); console.log('confirmed'); return false; }, 'onDeny': function(e, btn){ e.preventDefault(); //console.log('denied'); return false; } } /* Mouseup on document */ $.fn.jAlert.onMouseUp = function(e){ /* Find top visible jAlert and see if it has closeOnClick enabled */ var lastVisibleAlert = $('.jAlert:visible:last'); if( $jAlertSelectedOpts[lastVisibleAlert.attr('id')].options.closeOnClick ) { lastVisibleAlert.closeAlert(); } }; /* Keydown on document (escape key) */ $.fn.jAlert.onEscKeyDown = function(e){ /* Escape = 27 */ if(e.keyCode === 27){ /* Find top visible jAlert and see if it has closeOnClick enabled */ var lastVisibleAlert = $('.jAlert:visible:last'); if( $jAlertSelectedOpts[lastVisibleAlert.attr('id')].options.closeOnEsc ) { lastVisibleAlert.closeAlert(); } } }; /* If you're not using the DOM (aka, you're not hiding or showing a specific alert, you can just use $.jAlert */ $.jAlert = function(options){ return $.fn.jAlert(options); } /* Alert on click function - attach to existing dom */ $.fn.alertOnClick = function(options) { $(this).on('click', function(e){ e.preventDefault(); $.jAlert(options); return false; }); } /* Alert on click function - global, works for changing dom */ $.alertOnClick = function(selector, options) { $('body').on('click', selector, function(e){ e.preventDefault(); $.jAlert(options); return false; }); } /* Slowed window resize function */ var $jAlertResizeTimeout; $(window).resize(function () { window.clearTimeout($jAlertResizeTimeout); $jAlertResizeTimeout = window.setTimeout(function(){ $('.jAlert:visible').each(function(){ $(this).centerAlert(); }); }, 200); }); /* Onload callback for iframe, img, etc */ $.fn.jAlert.mediaLoaded = function(elem){ var wrap = elem.parents('.ja_media_wrap'), vid_wrap = wrap.find('.ja_video'); wrap.find('.ja_loader').remove(); if( vid_wrap.length > 0 ) { vid_wrap.fadeIn('fast'); } else { elem.fadeIn('fast'); } elem.parents('.jAlert').centerAlert(); } /* END OF ON JQUERY LOAD */ })(jQuery);