// @define Ext.MessageBox, Ext.Msg /** * Utility class for generating different styles of message boxes. The singleton instance, Ext.MessageBox * alias `Ext.Msg` can also be used. * * Note that a MessageBox is asynchronous. Unlike a regular JavaScript `alert` (which will halt * browser execution), showing a MessageBox will not cause the code to stop. For this reason, if you have code * that should only run *after* some user feedback from the MessageBox, you must use a callback function * (see the `function` parameter for {@link #method-show} for more details). * * Basic alert * * @example * Ext.Msg.alert('Status', 'Changes saved successfully.'); * * Prompt for user data and process the result using a callback * * @example * Ext.Msg.prompt('Name', 'Please enter your name:', function(btn, text){ * if (btn == 'ok'){ * // process text value and close... * } * }); * * Show a dialog using config options * * @example * Ext.Msg.show({ * title:'Save Changes?', * message: 'You are closing a tab that has unsaved changes. Would you like to save your changes?', * buttons: Ext.Msg.YESNOCANCEL, * icon: Ext.Msg.QUESTION, * fn: function(btn) { * if (btn === 'yes') { * console.log('Yes pressed'); * } else if (btn === 'no') { * console.log('No pressed'); * } else { * console.log('Cancel pressed'); * } * } * }); * * Showing Ext.Msg while it's already shown will cause the visible instance to be * overwritten with the newly passed config. While this may be the desired outcome, you * can also create a new MessageBox that can exist alongside the Ext.Msg * singleton instance. * * @example * var myMsg = Ext.create('Ext.window.MessageBox', { * // set closeAction to 'destroy' if this instance is not * // intended to be reused by the application * closeAction: 'destroy' * }).show({ * title: 'Custom MessageBox Instance', * message: 'I can exist along with Ext.Msg' * }); * * Ext.Msg.alert('Overlapping', 'Ext.Msg instance'); * * ## Static Values * * The following values can be utilized by Ext.window.MessageBox and Ext.Msg: * * OK : {text: 'OK', itemId: 'ok'} * YES : {text: 'Yes', itemId: 'yes'} * NO : {text: 'No', itemId: 'no'} * CANCEL: {text: 'Cancel', itemId: 'cancel'} * * INFO : Ext.baseCSSPrefix + 'msgbox-info' * WARNING : Ext.baseCSSPrefix + 'msgbox-warning' * QUESTION: Ext.baseCSSPrefix + 'msgbox-question' * ERROR : Ext.baseCSSPrefix + 'msgbox-error' * * OKCANCEL: [ * {text: 'Cancel', itemId: 'cancel'}, * {text: 'OK', itemId: 'ok'} * ] * * YESNOCANCEL: [ * {text: 'Cancel', itemId: 'cancel'}, * {text: 'No', itemId: 'no'}, * {text: 'Yes', itemId: 'yes'} * ] * * YESNO: [ * {text: 'No', itemId: 'no'}, * {text: 'Yes', itemId: 'yes'} * ] * */Ext.define('Ext.window.MessageBox', { extend: 'Ext.window.Window', requires: [ 'Ext.toolbar.Toolbar', 'Ext.form.field.Text', 'Ext.form.field.TextArea', 'Ext.button.Button', 'Ext.layout.container.Anchor', 'Ext.layout.container.HBox', 'Ext.ProgressBar' ], alias: 'widget.messagebox', /** * @property * Button config that displays a single OK button */ OK : 1, /** * @property * Button config that displays a single Yes button */ YES : 2, /** * @property * Button config that displays a single No button */ NO : 4, /** * @property * Button config that displays a single Cancel button */ CANCEL : 8, /** * @property * Button config that displays OK and Cancel buttons */ OKCANCEL : 9, /** * @property * Button config that displays Yes and No buttons */ YESNO : 6, /** * @property * Button config that displays Yes, No and Cancel buttons */ YESNOCANCEL : 14, /** * @property * The CSS class that provides the INFO icon image */ INFO : Ext.baseCSSPrefix + 'message-box-info', /** * @property * The CSS class that provides the WARNING icon image */ WARNING : Ext.baseCSSPrefix + 'message-box-warning', /** * @property * The CSS class that provides the QUESTION icon image */ QUESTION : Ext.baseCSSPrefix + 'message-box-question', /** * @property * The CSS class that provides the ERROR icon image */ ERROR : Ext.baseCSSPrefix + 'message-box-error', // hide it by offsets. Windows are hidden on render by default. hideMode: 'offsets', closeAction: 'hide', resizable: false, scrollable: true, title: ' ', defaultMinWidth: 250, defaultMaxWidth: 600, defaultMinHeight: 110, defaultMaxHeight: 500, // Forcibly set these to null on the prototype to override anything set higher in // the hierarchy minWidth: null, maxWidth: null, minHeight: null, maxHeight: null, constrain: true, cls: [Ext.baseCSSPrefix + 'message-box', Ext.baseCSSPrefix + 'hidden-offsets'], layout: { type: 'vbox', align: 'stretch' }, // We want to shrinkWrap around all docked items shrinkWrapDock: true, /** * @property * The default height in pixels of the message box's multiline textarea if displayed. */ defaultTextHeight : 75, /** * @property * The minimum width in pixels of the message box if it is a progress-style dialog. This is useful * for setting a different minimum width than text-only dialogs may need. */ minProgressWidth : 250, /** * @property * The minimum width in pixels of the message box if it is a prompt dialog. This is useful * for setting a different minimum width than text-only dialogs may need. */ minPromptWidth: 250, /** * @property * An object containing the default button text strings that can be overriden for localized language support. * Supported properties are: ok, cancel, yes and no. Generally you should include a locale-specific * resource file for handling language support across the framework. * Customize the default text like so: * * Ext.window.MessageBox.buttonText.yes = "oui"; //french * @locale */ buttonText: { ok: 'OK', yes: 'Yes', no: 'No', cancel: 'Cancel' }, buttonIds: [ 'ok', 'yes', 'no', 'cancel' ], baseIconCls: Ext.baseCSSPrefix + 'message-box-icon', ariaRole: 'alertdialog', makeButton: function(btnIdx) { var btnId = this.buttonIds[btnIdx]; return new Ext.button.Button({ handler: this.btnCallback, itemId: btnId, scope: this, text: this.buttonText[btnId], minWidth: 75 }); }, btnCallback: function(btn, event) { var me = this, value, field; // If this is caused by a keydown event (eg: SPACE on a Button), then the // hide will throw focus back to the previously focused element which will // then recieve an unexpected keyup event. // So defer callback handling until the upcoming keyup event. if (event && event.type === 'keydown' && !event.isSpecialKey()) { event.getTarget(null, null, true).on({ keyup: function(e) { me.btnCallback(btn, e); }, single: true }); return; } if (me.cfg.prompt || me.cfg.multiline) { if (me.cfg.multiline) { field = me.textArea; } else { field = me.textField; } value = field.getValue(); field.reset(); } // Component.onHide blurs the active element if the Component contains the active element me.hide(); me.userCallback(btn.itemId, value, me.cfg); }, hide: function() { var me = this, cls = me.cfg ? me.cfg.cls : ''; me.progressBar.reset(); if (cls) { me.removeCls(cls); } me.callParent(arguments); }, /** * @private */ constructor: function(cfg) { var me = this; me.callParent(arguments); // set the default min/max/Width/Height to the initially configured min/max/Width/Height // so that it will be used as the default when reconfiguring. me.minWidth = me.defaultMinWidth = (me.minWidth || me.defaultMinWidth); me.maxWidth = me.defaultMaxWidth = (me.maxWidth || me.defaultMaxWidth); me.minHeight = me.defaultMinHeight = (me.minHeight || me.defaultMinHeight); me.maxHeight = me.defaultMaxHeight = (me.maxHeight || me.defaultMaxHeight); }, initComponent: function(cfg) { var me = this, baseId = me.id, i, button; // A title or iconCls could have been passed in the config to the constructor. me.title = me.title || ' '; me.iconCls = me.iconCls || ''; me.topContainer = new Ext.container.Container({ layout: 'hbox', padding: 10, style: { overflow: 'hidden' }, items: [ me.iconComponent = new Ext.Component({ cls: me.baseIconCls }), me.promptContainer = new Ext.container.Container({ flex: 1, layout: { type: 'vbox', align: 'stretch' }, items: [ me.msg = new Ext.Component({ id: baseId + '-msg', cls: me.baseCls + '-text' }), me.textField = new Ext.form.field.Text({ id: baseId + '-textfield', enableKeyEvents: true, ariaAttributes: { 'aria-labelledby': me.msg.id }, listeners: { keydown: me.onPromptKey, scope: me } }), me.textArea = new Ext.form.field.TextArea({ id: baseId + '-textarea', height: 75, ariaAttributes: { 'aria-labelledby': me.msg.id } }) ] }) ] }); me.progressBar = new Ext.ProgressBar({ id: baseId + '-progressbar', margin: '0 10 10 10' }); me.items = [me.topContainer, me.progressBar]; // Create the buttons based upon passed bitwise config me.msgButtons = []; for (i = 0; i < 4; i++) { button = me.makeButton(i); me.msgButtons[button.itemId] = button; me.msgButtons.push(button); } me.bottomTb = new Ext.toolbar.Toolbar({ id: baseId + '-toolbar', ui: 'footer', dock: 'bottom', focusableContainer: false, ariaRole: null, layout: { pack: 'center' }, items: [ me.msgButtons[0], me.msgButtons[1], me.msgButtons[2], me.msgButtons[3] ] }); me.dockedItems = [me.bottomTb]; me.on('close', me.onClose, me); me.callParent(); }, afterRender: function() { var me = this; me.callParent(arguments); // These fields do not have a visible label, we're using message component instead. // Input elements have aria-labelledby pointing to the message component's id; // "for" attributes on the labelEl are redundant and get in the way. me.textField.labelEl.dom.removeAttribute('for'); me.textArea.labelEl.dom.removeAttribute('for'); }, onClose: function() { var btn = this.msgButtons[3]; if (btn) { this.btnCallback(btn); } }, onPromptKey: function(textField, e) { var me = this; if (e.keyCode === e.RETURN || e.keyCode === 10) { if (me.msgButtons.ok.isVisible()) { me.msgButtons.ok.handler.call(me, me.msgButtons.ok); } else if (me.msgButtons.yes.isVisible()) { me.msgButtons.yes.handler.call(me, me.msgButtons.yes); } } }, reconfigure: function(cfg) { var me = this, buttons = 0, hideToolbar = true, oldButtonText = me.buttonText, resizer = me.resizer, header = me.header, headerCfg = header && !header.isHeader, message = cfg && (cfg.message || cfg.msg), buttonTips = cfg.buttonTips, title, iconCls, resizeTracker, width, height, i, textArea, textField, msg, progressBar, msgButtons, wait, tool; // Restore default buttonText before reconfiguring. me.updateButtonText(); me.cfg = cfg = cfg || {}; wait = cfg.wait; if (cfg.width) { width = cfg.width; } if (cfg.height) { height = cfg.height; } me.minWidth = cfg.minWidth || me.defaultMinWidth; me.maxWidth = cfg.maxWidth || me.defaultMaxWidth; me.minHeight = cfg.minHeight || me.defaultMinHeight; me.maxHeight = cfg.maxHeight || me.defaultMaxHeight; if ('maskClickAction' in cfg) { me.maskClickAction = cfg.maskClickAction; } else { delete me.maskClickAction; } if (resizer) { resizeTracker = resizer.resizeTracker; resizer.minWidth = resizeTracker.minWidth = me.minWidth; resizer.maxWidth = resizeTracker.maxWidth = me.maxWidth; resizer.minHeight = resizeTracker.minHeight = me.minHeight; resizer.maxHeight = resizeTracker.maxHeight = me.maxHeight; } // Previous default is rarely going to be valid delete me.defaultFocus; if (cfg.defaultFocus) { me.defaultFocus = cfg.defaultFocus; } // clear any old animateTarget me.animateTarget = cfg.animateTarget || undefined; // Defaults to modal me.modal = cfg.modal !== false; // Show the title/icon if a title/iconCls config was passed in the config // to either the constructor or the show() method. Note that anything // passed in the config should win. // // Note that if there is no title/iconCls in the config, check the headerCfg // and default to the instance properties. This works because there are default // values defined in initComponent. if (cfg.title != null) { title = cfg.title; } else if (headerCfg && header.title != null) { title = header.title; } else { title = me.title; } if (cfg.iconCls != null) { iconCls = cfg.iconCls; } else if (headerCfg && header.iconCls != null) { iconCls = header.iconCls; } else { iconCls = me.iconCls; } me.setTitle(title); me.setIconCls(iconCls); // Extract button configs if (Ext.isObject(cfg.buttons)) { me.buttonText = cfg.buttons; buttons = 0; } else { me.buttonText = cfg.buttonText || me.buttonText; buttons = Ext.isNumber(cfg.buttons) ? cfg.buttons : 0; } Ext.each(me.buttonIds, function (buttonId) { me.msgButtons[buttonId].setTooltip((buttonTips && buttonTips[buttonId]) || null); }); // Apply custom-configured buttonText // Infer additional buttons from the specified property names in the buttonText object buttons = buttons | me.updateButtonText(); // Restore buttonText. Next run of reconfigure will restore to prototype's buttonText me.buttonText = oldButtonText; // During the on render, or size resetting layouts, and in subsequent hiding and showing, we need to // suspend layouts, and flush at the end when the Window's children are at their final visibility. Ext.suspendLayouts(); me.width = me.height = null; if (width || height) { if (width) { me.setWidth(width); } if (height) { me.setHeight(height); } } if (!me.rendered) { me.render(Ext.getBody()); } // Hide or show the close tool me.closable = cfg.closable !== false && !wait; // We need to redefine `header` because me.setIconCls() could create a Header instance. header = me.header; if (header) { tool = header.child('[type=close]'); if (tool) { tool.setVisible(me.closable); } // Hide or show the header if (!cfg.title && !me.closable && !cfg.iconCls) { header.hide(); } else { header.show(); } } // Default to dynamic drag: drag the window, not a ghost me.liveDrag = !cfg.proxyDrag; // wrap the user callback me.userCallback = Ext.Function.bindCallback(cfg.callback ||cfg.fn || Ext.emptyFn, cfg.scope || Ext.global); // Hide or show the icon Component me.setIcon(cfg.icon); // Hide or show the message area msg = me.msg; if (message) { msg.setHtml(message); msg.show(); // As per WAI-ARIA spec, the alertdialog element should point to message element // via aria-describedby attribute. me.ariaEl.dom.setAttribute('aria-describedby', msg.id); } else { msg.hide(); me.ariaEl.dom.removeAttribute('aria-describedby'); } // Hide or show the input field textArea = me.textArea; textField = me.textField; if (cfg.prompt || cfg.multiline) { me.multiline = cfg.multiline; if (cfg.multiline) { textArea.setValue(cfg.value); textArea.setHeight(cfg.defaultTextHeight || me.defaultTextHeight); textArea.show(); textField.hide(); me.defaultFocus = textArea; } else { textField.setValue(cfg.value); textArea.hide(); textField.show(); me.defaultFocus = textField; } // When either input field is displayed, it will reference the message component's // element via aria-labelledby. In such cases we need to remove aria-describedby // from the window ariaEl to avoid the message being announced twice. me.ariaEl.dom.removeAttribute('aria-describedby'); } else { textArea.hide(); textField.hide(); } // Hide or show the progress bar progressBar = me.progressBar; if (cfg.progress || wait) { progressBar.show(); me.updateProgress(0, cfg.progressText); me.defaultFocus = progressBar; if (wait) { progressBar.wait(wait === true ? cfg.waitConfig : wait); } } else { progressBar.hide(); } // Hide or show buttons depending on flag value sent. msgButtons = me.msgButtons; for (i = 0; i < 4; i++) { if (buttons & Math.pow(2, i)) { // Default to focus on the first visible button if focus not already set if (!me.defaultFocus) { me.defaultFocus = msgButtons[i]; } msgButtons[i].show(); hideToolbar = false; } else { msgButtons[i].hide(); } } // Hide toolbar if no buttons to show if (hideToolbar) { me.bottomTb.hide(); } else { me.bottomTb.show(); } Ext.resumeLayouts(true); }, /** * @private * Set button text according to current buttonText property object * @return {Number} The buttons bitwise flag based upon the button IDs specified in the buttonText property. */ updateButtonText: function() { var me = this, buttonText = me.buttonText, buttons = 0, btnId, btn; for (btnId in buttonText) { if (buttonText.hasOwnProperty(btnId)) { btn = me.msgButtons[btnId]; if (btn) { if (me.cfg && me.cfg.buttonText) { buttons = buttons | Math.pow(2, Ext.Array.indexOf(me.buttonIds, btnId)); } if (btn.text !== buttonText[btnId]) { btn.setText(buttonText[btnId]); } } } } return buttons; }, /** * Displays a new message box, or re-initializes an existing message box, based on the config options passed in. All * display functions (e.g. prompt, alert, etc.) on MessageBox call this function internally, although those calls * are basic shortcuts and do not support all of the config options allowed here. * * Example usage: * * Ext.Msg.show({ * title: 'Address', * message: 'Please enter your address:', * width: 300, * buttons: Ext.Msg.OKCANCEL, * multiline: true, * fn: saveAddress, * animateTarget: 'addAddressBtn', * icon: Ext.window.MessageBox.INFO * }); * * @param {Object} cfg The following config options are supported: * * @param {String/Ext.dom.Element} [cfg.animateTarget] * An id or Element from which the message box should animate as it opens and closes. * * @param {Number} [cfg.buttons=false] * A bitwise button specifier consisting of the sum of any of the following constants: * * - Ext.MessageBox.OK * - Ext.MessageBox.YES * - Ext.MessageBox.NO * - Ext.MessageBox.CANCEL * * Some common combinations have already been predefined: * * - Ext.MessageBox.OKCANCEL * - Ext.MessageBox.YESNO * - Ext.MessageBox.YESNOCANCEL * * Or false to not show any buttons. * * This may also be specified as an object hash containing custom button text in the same format as the * {@link #buttonText} config. Button IDs present as property names will be made visible. * * @param {Boolean} [cfg.closable] * False to hide the top-right close button (defaults to true). Note that progress and wait dialogs will ignore this * property and always hide the close button as they can only be closed programmatically. * * @param {String} [cfg.cls] * A custom CSS class to apply to the message box's container element * * @param {Number} [cfg.defaultTextHeight=75] * The default height in pixels of the message box's multiline textarea if displayed. * * @param {Function} [cfg.fn] * A callback function which is called when the dialog is dismissed either by clicking on the configured buttons, or * on the dialog close button, or by pressing the return button to enter input. * * Progress and wait dialogs will ignore this option since they do not respond to user actions and can only be * closed programmatically, so any required function should be called by the same code after it closes the dialog. * Parameters passed: * * @param {String} cfg.fn.buttonId The ID of the button pressed, one of: * * - ok * - yes * - no * - cancel * * @param {String} cfg.fn.text Value of the input field if either `prompt` or `multiline` is true * @param {Object} cfg.fn.opt The config object passed to show. * * @param {Object} [cfg.buttonText] * An object containing string properties which override the system-supplied button text values just for this * invocation. The property names are: * * - ok * - yes * - no * - cancel * * @param {Object} [cfg.buttonTips] An object keyed by the button ids containing * {@link Ext.button.Button#tooltip tooltip} configurations for each button. eg: * * { * ok: 'Commit the record', * cancel: 'Discard the record' * } * * @param {Object} [cfg.scope] * The scope (`this` reference) in which the function will be executed. * * @param {String} [cfg.icon] * A CSS class that provides a background image to be used as the body icon for the dialog. * One can use a predefined icon class: * * - Ext.MessageBox.INFO * - Ext.MessageBox.WARNING * - Ext.MessageBox.QUESTION * - Ext.MessageBox.ERROR * * or use just any `'custom-class'`. Defaults to empty string. * * @param {String} [cfg.iconCls] * The standard {@link Ext.window.Window#iconCls} to add an optional header icon (defaults to '') * * @param {String} [cfg.defaultFocus] * The button to focus when showing the dialog. If not specified, defaults to * the first visible button. * * @param {Number} [cfg.maxWidth] * The maximum width in pixels of the message box (defaults to 600) * * @param {Number} [cfg.minWidth] * The minimum width in pixels of the message box (defaults to 100) * * @param {Boolean} [cfg.modal] * False to allow user interaction with the page while the message box is displayed (defaults to true) * * @param {String} [cfg.message] * A string that will replace the existing message box body text (defaults to the XHTML-compliant non-breaking space * character ' ') * * @param {Boolean} [cfg.multiline] * True to prompt the user to enter multi-line text (defaults to false) * * @param {Boolean} [cfg.progress] * True to display a progress bar (defaults to false) * * @param {String} [cfg.progressText] * The text to display inside the progress bar if progress = true (defaults to '') * * @param {Boolean} [cfg.prompt] * True to prompt the user to enter single-line text (defaults to false) * * @param {Boolean} [cfg.proxyDrag] * True to display a lightweight proxy while dragging (defaults to false) * * @param {String} cfg.title * The title text * * @param {String} [cfg.value] * The string value to set into the active textbox element if displayed * * @param {Object/Boolean} [cfg.wait=false] * `true` to display a progress bar, or a configuration for {@link Ext.ProgressBar#wait}. * * @param {Object} [cfg.waitConfig] * A {@link Ext.ProgressBar#wait} config object (applies only if wait = true) * * @param {Number} [cfg.width] * The width of the dialog in pixels * * @cfg {String} [cfg.maskClickAction=focus] * The method to call when the window's modal mask is clicked or tapped: * * - **`'{@link #method-focus}'`** : * * The default. Focus the window, which will then pass focus into its {@link #cfg-defaultFocus} delegate. * * - **`'{@link #method-hide}'`** : * * {@link #method-hide} the window by setting visibility to hidden and applying negative offsets. * @since 6.2.0 * * @return {Ext.window.MessageBox} this */ show: function(cfg) { var me = this, visibleFocusables; cfg = cfg || {}; // If called during global layout suspension, make the call after layout resumption if (Ext.Component.layoutSuspendCount) { Ext.on({ resumelayouts: function() { me.show(cfg); }, single: true }); return me; } me.reconfigure(cfg); if (cfg.cls) { me.addCls(cfg.cls); } // Do not steal focus from anything that may be focused if the MessageBox has no visible focusable // items. For example, a "wait" message box should not get focus. visibleFocusables = me.query('textfield:not([hidden]),textarea:not([hidden]),button:not([hidden])'); me.preventFocusOnActivate = !visibleFocusables.length; me.callParent(); return me; }, onShow: function() { this.callParent(arguments); this.center(); }, updateText: function(text) { this.msg.setHtml(text); }, /** * Adds the specified icon to the dialog. By default, the class 'x-messagebox-icon' is applied for default * styling, and the class passed in is expected to supply the background image url. Pass in empty string ('') * to clear any existing icon. This method must be called before the MessageBox is shown. * The following built-in icon classes are supported, but you can also pass in a custom class name: * * Ext.window.MessageBox.INFO * Ext.window.MessageBox.WARNING * Ext.window.MessageBox.QUESTION * Ext.window.MessageBox.ERROR * * @param {String} icon A CSS classname specifying the icon's background image url, or empty string to clear the icon * @param {Number} [width] The width of the icon. If not specified, the default is used * @param {Number} [height] The height of the icon. If not specified, the default is used * @return {Ext.window.MessageBox} this */ setIcon : function(icon, width, height) { var me = this, iconCmp = me.iconComponent, cls = me.messageIconCls; if (cls) { iconCmp.removeCls(cls); } if (icon) { iconCmp.show(); if (width || height) { iconCmp.setSize(width || iconCmp.getWidth(), height || iconCmp.getHeight()); } iconCmp.addCls(Ext.baseCSSPrefix + 'dlg-icon'); iconCmp.addCls(me.messageIconCls = icon); } else { iconCmp.removeCls(Ext.baseCSSPrefix + 'dlg-icon'); iconCmp.hide(); } return me; }, /** * Updates a progress-style message box's text and progress bar. Only relevant on message boxes * initiated via {@link Ext.window.MessageBox#progress} or {@link Ext.window.MessageBox#wait}, * or by calling {@link Ext.window.MessageBox#method-show} with progress: true. * * @param {Number} [value=0] Any number between 0 and 1 (e.g., .5) * @param {String} [progressText=''] The progress text to display inside the progress bar. * @param {String} [message] The message box's body text is replaced with the specified string (defaults to undefined * so that any existing body text will not get overwritten by default unless a new value is passed in) * @return {Ext.window.MessageBox} this */ updateProgress : function(value, progressText, message){ this.progressBar.updateProgress(value, progressText); if (message){ this.updateText(message); } return this; }, onEsc: function() { if (this.closable !== false) { this.callParent(arguments); } }, /** * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's confirm). * If a callback function is passed it will be called after the user clicks either button, * and the id of the button that was clicked will be passed as the only parameter to the callback * (could also be the top-right close button, which will always report as "cancel"). * * @param {String} title The title bar text * @param {String} message The message box body text * @param {Function} [fn] The callback function invoked after the message box is closed. * See {@link #method-show} method for details. * @param {Object} [scope=window] The scope (`this` reference) in which the callback is executed. * @return {Ext.window.MessageBox} this */ confirm: function(cfg, message, fn, scope) { if (Ext.isString(cfg)) { cfg = { title: cfg, icon: this.QUESTION, message: message, buttons: this.YESNO, callback: fn, scope: scope }; } return this.show(cfg); }, /** * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to JavaScript's prompt). * The prompt can be a single-line or multi-line textbox. If a callback function is passed it will be called after the user * clicks either button, and the id of the button that was clicked (could also be the top-right * close button, which will always report as "cancel") and the text that was entered will be passed as the two parameters to the callback. * * @param {String} title The title bar text * @param {String} message The message box body text * @param {Function} [fn] The callback function invoked after the message box is closed. * See {@link #method-show} method for details. * @param {Object} [scope=window] The scope (`this` reference) in which the callback is executed. * @param {Boolean/Number} [multiline=false] True to create a multiline textbox using the defaultTextHeight * property, or the height in pixels to create the textbox/ * @param {String} [value=''] Default value of the text input element * @return {Ext.window.MessageBox} this */ prompt: function(title, message, fn, scope, multiline, value) { if (Ext.isString(title)) { title = { prompt: true, title: title, minWidth: this.minPromptWidth, message: message, buttons: this.OKCANCEL, callback: fn, scope: scope, multiline: multiline, value: value }; } return this.show(title); }, /** * Displays a message box with an infinitely auto-updating progress bar. This can be used to block user * interaction while waiting for a long-running process to complete that does not have defined intervals. * You are responsible for closing the message box when the process is complete. * * @param {String} message The message box body text * @param {String} [title] The title bar text * @param {Object} [config] A {@link Ext.ProgressBar#wait} config object * @return {Ext.window.MessageBox} this */ wait: function(message, title, config) { if (Ext.isString(message)) { message = { title : title, message : message, closable: false, wait: true, modal: true, minWidth: this.minProgressWidth, waitConfig: config }; } return this.show(message); }, /** * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript alert prompt). * If a callback function is passed it will be called after the user clicks the button, and the * id of the button that was clicked will be passed as the only parameter to the callback * (could also be the top-right close button, which will always report as "cancel"). * * @param {String} title The title bar text * @param {String} message The message box body text * @param {Function} [fn] The callback function invoked after the message box is closed. * See {@link #method-show} method for details. * @param {Object} [scope=window] The scope (<code>this</code> reference) in which the callback is executed. * @return {Ext.window.MessageBox} this */ alert: function(title, message, fn, scope) { if (Ext.isString(title)) { title = { title: title, message: message, buttons: this.OK, fn: fn, scope: scope, minWidth: this.minWidth }; } return this.show(title); }, /** * Displays a message box with a progress bar. * * You are responsible for updating the progress bar as needed via {@link Ext.window.MessageBox#updateProgress} * and closing the message box when the process is complete. * * @param {String} title The title bar text * @param {String} message The message box body text * @param {String} [progressText=''] The text to display inside the progress bar * @return {Ext.window.MessageBox} this */ progress: function(title, message, progressText) { if (Ext.isString(title)) { title = { title: title, message: message, progress: true, progressText: progressText }; } return this.show(title); }}, function(MessageBox) { /** * @class Ext.MessageBox * @alternateClassName Ext.Msg * @extends Ext.window.MessageBox * @singleton * @inheritdoc Ext.window.MessageBox */ // We want to defer creating Ext.MessageBox and Ext.Msg instances // until overrides have been applied. Ext.onInternalReady(function() { Ext.MessageBox = Ext.Msg = new MessageBox(); });});