| /** |
| * bootbox.js v3.3.0 |
| * |
| * http://bootboxjs.com/license.txt |
| */ |
| var bootbox = window.bootbox || (function(document, $) { |
| /*jshint scripturl:true sub:true */ |
| |
| var _locale = 'en', |
| _defaultLocale = 'en', |
| _animate = true, |
| _backdrop = 'static', |
| _defaultHref = 'javascript:;', |
| _classes = '', |
| _btnClasses = {}, |
| _icons = {}, |
| /* last var should always be the public object we'll return */ |
| that = {}; |
| |
| |
| /** |
| * public API |
| */ |
| that.setLocale = function(locale) { |
| for (var i in _locales) { |
| if (i == locale) { |
| _locale = locale; |
| return; |
| } |
| } |
| throw new Error('Invalid locale: '+locale); |
| }; |
| |
| that.addLocale = function(locale, translations) { |
| if (typeof _locales[locale] === 'undefined') { |
| _locales[locale] = {}; |
| } |
| for (var str in translations) { |
| _locales[locale][str] = translations[str]; |
| } |
| }; |
| |
| that.setIcons = function(icons) { |
| _icons = icons; |
| if (typeof _icons !== 'object' || _icons === null) { |
| _icons = {}; |
| } |
| }; |
| |
| that.setBtnClasses = function(btnClasses) { |
| _btnClasses = btnClasses; |
| if (typeof _btnClasses !== 'object' || _btnClasses === null) { |
| _btnClasses = {}; |
| } |
| }; |
| |
| that.alert = function(/*str, label, cb*/) { |
| var str = "", |
| label = _translate('OK'), |
| cb = null; |
| |
| switch (arguments.length) { |
| case 1: |
| // no callback, default button label |
| str = arguments[0]; |
| break; |
| case 2: |
| // callback *or* custom button label dependent on type |
| str = arguments[0]; |
| if (typeof arguments[1] == 'function') { |
| cb = arguments[1]; |
| } else { |
| label = arguments[1]; |
| } |
| break; |
| case 3: |
| // callback and custom button label |
| str = arguments[0]; |
| label = arguments[1]; |
| cb = arguments[2]; |
| break; |
| default: |
| throw new Error("Incorrect number of arguments: expected 1-3"); |
| } |
| |
| return that.dialog(str, { |
| // only button (ok) |
| "label" : label, |
| "icon" : _icons.OK, |
| "class" : _btnClasses.OK, |
| "callback": cb |
| }, { |
| // ensure that the escape key works; either invoking the user's |
| // callback or true to just close the dialog |
| "onEscape": cb || true |
| }); |
| }; |
| |
| that.confirm = function(/*str, labelCancel, labelOk, cb*/) { |
| var str = "", |
| labelCancel = _translate('CANCEL'), |
| labelOk = _translate('CONFIRM'), |
| cb = null; |
| |
| switch (arguments.length) { |
| case 1: |
| str = arguments[0]; |
| break; |
| case 2: |
| str = arguments[0]; |
| if (typeof arguments[1] == 'function') { |
| cb = arguments[1]; |
| } else { |
| labelCancel = arguments[1]; |
| } |
| break; |
| case 3: |
| str = arguments[0]; |
| labelCancel = arguments[1]; |
| if (typeof arguments[2] == 'function') { |
| cb = arguments[2]; |
| } else { |
| labelOk = arguments[2]; |
| } |
| break; |
| case 4: |
| str = arguments[0]; |
| labelCancel = arguments[1]; |
| labelOk = arguments[2]; |
| cb = arguments[3]; |
| break; |
| default: |
| throw new Error("Incorrect number of arguments: expected 1-4"); |
| } |
| |
| var cancelCallback = function() { |
| if (typeof cb === 'function') { |
| return cb(false); |
| } |
| }; |
| |
| var confirmCallback = function() { |
| if (typeof cb === 'function') { |
| return cb(true); |
| } |
| }; |
| |
| return that.dialog(str, [{ |
| // first button (cancel) |
| "label" : labelCancel, |
| "icon" : _icons.CANCEL, |
| "class" : _btnClasses.CANCEL, |
| "callback": cancelCallback |
| }, { |
| // second button (confirm) |
| "label" : labelOk, |
| "icon" : _icons.CONFIRM, |
| "class" : _btnClasses.CONFIRM, |
| "callback": confirmCallback |
| }], { |
| // escape key bindings |
| "onEscape": cancelCallback |
| }); |
| }; |
| |
| that.prompt = function(/*str, labelCancel, labelOk, cb, defaultVal*/) { |
| var str = "", |
| labelCancel = _translate('CANCEL'), |
| labelOk = _translate('CONFIRM'), |
| cb = null, |
| defaultVal = ""; |
| |
| switch (arguments.length) { |
| case 1: |
| str = arguments[0]; |
| break; |
| case 2: |
| str = arguments[0]; |
| if (typeof arguments[1] == 'function') { |
| cb = arguments[1]; |
| } else { |
| labelCancel = arguments[1]; |
| } |
| break; |
| case 3: |
| str = arguments[0]; |
| labelCancel = arguments[1]; |
| if (typeof arguments[2] == 'function') { |
| cb = arguments[2]; |
| } else { |
| labelOk = arguments[2]; |
| } |
| break; |
| case 4: |
| str = arguments[0]; |
| labelCancel = arguments[1]; |
| labelOk = arguments[2]; |
| cb = arguments[3]; |
| break; |
| case 5: |
| str = arguments[0]; |
| labelCancel = arguments[1]; |
| labelOk = arguments[2]; |
| cb = arguments[3]; |
| defaultVal = arguments[4]; |
| break; |
| default: |
| throw new Error("Incorrect number of arguments: expected 1-5"); |
| } |
| |
| var header = str; |
| |
| // let's keep a reference to the form object for later |
| var form = $("<form></form>"); |
| form.append("<input class='input-block-level' autocomplete=off type=text value='" + defaultVal + "' />"); |
| |
| var cancelCallback = function() { |
| if (typeof cb === 'function') { |
| // yep, native prompts dismiss with null, whereas native |
| // confirms dismiss with false... |
| return cb(null); |
| } |
| }; |
| |
| var confirmCallback = function() { |
| if (typeof cb === 'function') { |
| return cb(form.find("input[type=text]").val()); |
| } |
| }; |
| |
| var div = that.dialog(form, [{ |
| // first button (cancel) |
| "label" : labelCancel, |
| "icon" : _icons.CANCEL, |
| "class" : _btnClasses.CANCEL, |
| "callback": cancelCallback |
| }, { |
| // second button (confirm) |
| "label" : labelOk, |
| "icon" : _icons.CONFIRM, |
| "class" : _btnClasses.CONFIRM, |
| "callback": confirmCallback |
| }], { |
| // prompts need a few extra options |
| "header" : header, |
| // explicitly tell dialog NOT to show the dialog... |
| "show" : false, |
| "onEscape": cancelCallback |
| }); |
| |
| // ... the reason the prompt needs to be hidden is because we need |
| // to bind our own "shown" handler, after creating the modal but |
| // before any show(n) events are triggered |
| // @see https://github.com/makeusabrew/bootbox/issues/69 |
| |
| div.on("shown", function() { |
| form.find("input[type=text]").focus(); |
| |
| // ensure that submitting the form (e.g. with the enter key) |
| // replicates the behaviour of a normal prompt() |
| form.on("submit", function(e) { |
| e.preventDefault(); |
| div.find(".btn-primary").click(); |
| }); |
| }); |
| |
| div.modal("show"); |
| |
| return div; |
| }; |
| |
| that.dialog = function(str, handlers, options) { |
| var buttons = "", |
| callbacks = []; |
| |
| if (!options) { |
| options = {}; |
| } |
| |
| // check for single object and convert to array if necessary |
| if (typeof handlers === 'undefined') { |
| handlers = []; |
| } else if (typeof handlers.length == 'undefined') { |
| handlers = [handlers]; |
| } |
| |
| var i = handlers.length; |
| while (i--) { |
| var label = null, |
| href = null, |
| _class = null, |
| icon = '', |
| callback = null; |
| |
| if (typeof handlers[i]['label'] == 'undefined' && |
| typeof handlers[i]['class'] == 'undefined' && |
| typeof handlers[i]['callback'] == 'undefined') { |
| // if we've got nothing we expect, check for condensed format |
| |
| var propCount = 0, // condensed will only match if this == 1 |
| property = null; // save the last property we found |
| |
| // be nicer to count the properties without this, but don't think it's possible... |
| for (var j in handlers[i]) { |
| property = j; |
| if (++propCount > 1) { |
| // forget it, too many properties |
| break; |
| } |
| } |
| |
| if (propCount == 1 && typeof handlers[i][j] == 'function') { |
| // matches condensed format of label -> function |
| handlers[i]['label'] = property; |
| handlers[i]['callback'] = handlers[i][j]; |
| } |
| } |
| |
| if (typeof handlers[i]['callback']== 'function') { |
| callback = handlers[i]['callback']; |
| } |
| |
| if (handlers[i]['class']) { |
| _class = handlers[i]['class']; |
| } else if (i == handlers.length -1 && handlers.length <= 2) { |
| // always add a primary to the main option in a two-button dialog |
| _class = 'btn-primary'; |
| } |
| |
| if (handlers[i]['link'] !== true) { |
| _class = 'btn ' + _class; |
| } |
| |
| if (handlers[i]['label']) { |
| label = handlers[i]['label']; |
| } else { |
| label = "Option "+(i+1); |
| } |
| |
| if (handlers[i]['icon']) { |
| icon = "<i class='"+handlers[i]['icon']+"'></i> "; |
| } |
| |
| if (handlers[i]['href']) { |
| href = handlers[i]['href']; |
| } |
| else { |
| href = _defaultHref; |
| } |
| |
| buttons = "<a data-handler='"+i+"' class='"+_class+"' href='" + href + "'>"+icon+""+label+"</a>" + buttons; |
| |
| callbacks[i] = callback; |
| } |
| |
| // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302 |
| // and https://github.com/twitter/bootstrap/issues/4474 |
| // for an explanation of the inline overflow: hidden |
| // @see https://github.com/twitter/bootstrap/issues/4854 |
| // for an explanation of tabIndex=-1 |
| |
| var parts = ["<div class='bootbox modal' tabindex='-1' style='overflow:hidden;'>"]; |
| |
| if (options['header']) { |
| var closeButton = ''; |
| if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) { |
| closeButton = "<a href='"+_defaultHref+"' class='close'>×</a>"; |
| } |
| |
| parts.push("<div class='modal-header'>"+closeButton+"<h3>"+options['header']+"</h3></div>"); |
| } |
| |
| // push an empty body into which we'll inject the proper content later |
| parts.push("<div class='modal-body'></div>"); |
| |
| if (buttons) { |
| parts.push("<div class='modal-footer'>"+buttons+"</div>"); |
| } |
| |
| parts.push("</div>"); |
| |
| var div = $(parts.join("\n")); |
| |
| // check whether we should fade in/out |
| var shouldFade = (typeof options.animate === 'undefined') ? _animate : options.animate; |
| |
| if (shouldFade) { |
| div.addClass("fade"); |
| } |
| |
| var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes; |
| if (optionalClasses) { |
| div.addClass(optionalClasses); |
| } |
| |
| // now we've built up the div properly we can inject the content whether it was a string or a jQuery object |
| div.find(".modal-body").html(str); |
| |
| function onCancel(source) { |
| // for now source is unused, but it will be in future |
| var hideModal = null; |
| if (typeof options.onEscape === 'function') { |
| // @see https://github.com/makeusabrew/bootbox/issues/91 |
| hideModal = options.onEscape(); |
| } |
| |
| if (hideModal !== false) { |
| div.modal('hide'); |
| } |
| } |
| |
| // hook into the modal's keyup trigger to check for the escape key |
| div.on('keyup.dismiss.modal', function(e) { |
| // any truthy value passed to onEscape will dismiss the dialog |
| // as long as the onEscape function (if defined) doesn't prevent it |
| if (e.which === 27 && options.onEscape) { |
| onCancel('escape'); |
| } |
| }); |
| |
| // handle close buttons too |
| div.on('click', 'a.close', function(e) { |
| e.preventDefault(); |
| onCancel('close'); |
| }); |
| |
| // well, *if* we have a primary - give the first dom element focus |
| div.on('shown', function() { |
| div.find("a.btn-primary:first").focus(); |
| }); |
| |
| div.on('hidden', function(e) { |
| // @see https://github.com/makeusabrew/bootbox/issues/115 |
| // allow for the fact hidden events can propagate up from |
| // child elements like tooltips |
| if (e.target === this) { |
| div.remove(); |
| } |
| }); |
| |
| // wire up button handlers |
| div.on('click', '.modal-footer a', function(e) { |
| |
| var handler = $(this).data("handler"), |
| cb = callbacks[handler], |
| hideModal = null; |
| |
| // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted |
| // if we've got a custom href attribute, all bets are off |
| if (typeof handler !== 'undefined' && |
| typeof handlers[handler]['href'] !== 'undefined') { |
| |
| return; |
| } |
| |
| e.preventDefault(); |
| |
| if (typeof cb === 'function') { |
| hideModal = cb(e); |
| } |
| |
| // the only way hideModal *will* be false is if a callback exists and |
| // returns it as a value. in those situations, don't hide the dialog |
| // @see https://github.com/makeusabrew/bootbox/pull/25 |
| if (hideModal !== false) { |
| div.modal("hide"); |
| } |
| }); |
| |
| // stick the modal right at the bottom of the main body out of the way |
| $("body").append(div); |
| |
| div.modal({ |
| // unless explicitly overridden take whatever our default backdrop value is |
| backdrop : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop, |
| // ignore bootstrap's keyboard options; we'll handle this ourselves (more fine-grained control) |
| keyboard : false, |
| // @ see https://github.com/makeusabrew/bootbox/issues/69 |
| // we *never* want the modal to be shown before we can bind stuff to it |
| // this method can also take a 'show' option, but we'll only use that |
| // later if we need to |
| show : false |
| }); |
| |
| // @see https://github.com/makeusabrew/bootbox/issues/64 |
| // @see https://github.com/makeusabrew/bootbox/issues/60 |
| // ...caused by... |
| // @see https://github.com/twitter/bootstrap/issues/4781 |
| div.on("show", function(e) { |
| $(document).off("focusin.modal"); |
| }); |
| |
| if (typeof options.show === 'undefined' || options.show === true) { |
| div.modal("show"); |
| } |
| |
| return div; |
| }; |
| |
| /** |
| * #modal is deprecated in v3; it can still be used but no guarantees are |
| * made - have never been truly convinced of its merit but perhaps just |
| * needs a tidyup and some TLC |
| */ |
| that.modal = function(/*str, label, options*/) { |
| var str; |
| var label; |
| var options; |
| |
| var defaultOptions = { |
| "onEscape": null, |
| "keyboard": true, |
| "backdrop": _backdrop |
| }; |
| |
| switch (arguments.length) { |
| case 1: |
| str = arguments[0]; |
| break; |
| case 2: |
| str = arguments[0]; |
| if (typeof arguments[1] == 'object') { |
| options = arguments[1]; |
| } else { |
| label = arguments[1]; |
| } |
| break; |
| case 3: |
| str = arguments[0]; |
| label = arguments[1]; |
| options = arguments[2]; |
| break; |
| default: |
| throw new Error("Incorrect number of arguments: expected 1-3"); |
| } |
| |
| defaultOptions['header'] = label; |
| |
| if (typeof options == 'object') { |
| options = $.extend(defaultOptions, options); |
| } else { |
| options = defaultOptions; |
| } |
| |
| return that.dialog(str, [], options); |
| }; |
| |
| |
| that.hideAll = function() { |
| $(".bootbox").modal("hide"); |
| }; |
| |
| that.animate = function(animate) { |
| _animate = animate; |
| }; |
| |
| that.backdrop = function(backdrop) { |
| _backdrop = backdrop; |
| }; |
| |
| that.classes = function(classes) { |
| _classes = classes; |
| }; |
| |
| /** |
| * private API |
| */ |
| |
| /** |
| * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are |
| * unlikely to be required. If this gets too large it can be split out into separate JS files. |
| */ |
| var _locales = { |
| 'br' : { |
| OK : 'OK', |
| CANCEL : 'Cancelar', |
| CONFIRM : 'Sim' |
| }, |
| 'da' : { |
| OK : 'OK', |
| CANCEL : 'Annuller', |
| CONFIRM : 'Accepter' |
| }, |
| 'de' : { |
| OK : 'OK', |
| CANCEL : 'Abbrechen', |
| CONFIRM : 'Akzeptieren' |
| }, |
| 'en' : { |
| OK : 'OK', |
| CANCEL : 'Cancel', |
| CONFIRM : 'OK' |
| }, |
| 'es' : { |
| OK : 'OK', |
| CANCEL : 'Cancelar', |
| CONFIRM : 'Aceptar' |
| }, |
| 'fr' : { |
| OK : 'OK', |
| CANCEL : 'Annuler', |
| CONFIRM : 'D\'accord' |
| }, |
| 'it' : { |
| OK : 'OK', |
| CANCEL : 'Annulla', |
| CONFIRM : 'Conferma' |
| }, |
| 'nl' : { |
| OK : 'OK', |
| CANCEL : 'Annuleren', |
| CONFIRM : 'Accepteren' |
| }, |
| 'pl' : { |
| OK : 'OK', |
| CANCEL : 'Anuluj', |
| CONFIRM : 'Potwierdź' |
| }, |
| 'ru' : { |
| OK : 'OK', |
| CANCEL : 'Отмена', |
| CONFIRM : 'Применить' |
| }, |
| 'zh_CN' : { |
| OK : 'OK', |
| CANCEL : '取消', |
| CONFIRM : '确认' |
| }, |
| 'zh_TW' : { |
| OK : 'OK', |
| CANCEL : '取消', |
| CONFIRM : '確認' |
| } |
| }; |
| |
| function _translate(str, locale) { |
| // we assume if no target locale is probided then we should take it from current setting |
| if (typeof locale === 'undefined') { |
| locale = _locale; |
| } |
| if (typeof _locales[locale][str] === 'string') { |
| return _locales[locale][str]; |
| } |
| |
| // if we couldn't find a lookup then try and fallback to a default translation |
| |
| if (locale != _defaultLocale) { |
| return _translate(str, _defaultLocale); |
| } |
| |
| // if we can't do anything then bail out with whatever string was passed in - last resort |
| return str; |
| } |
| |
| return that; |
| |
| }(document, window.jQuery)); |
| |
| // @see https://github.com/makeusabrew/bootbox/issues/71 |
| window.bootbox = bootbox; |