/* Copyright (c) 2011, Geert Bergman (geert@scrivo.nl) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of "Scrivo" nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $Id: OKCancelDialog.js 749 2013-07-23 01:47:39Z geert $ */ "use strict"; SUI.dialog.OKCancelDialog = SUI.defineClass( /** @lends SUI.dialog.OKCancelDialog.prototype */{ /** @ignore */ baseClass: SUI.Window, /** * @class * SUI.dialog.OKCancelDialog is an empty dialog box with an OK and cancel * button. It can serve as a base for most of your standard dialogs. There * is an optional third button that can be activated. * * @augments SUI.Window * * @description * Create an OK/Cancel dialog. * * @constructs * @param see base class * @param {int} arg.clientWidth Client width of the dialog window * @param {int} arg.clientHeight Client height of the dialog window * @param {Function} arg.onOK Event handler for the ok button * @param {Function} arg.onCancel Event handler for the cancel button */ initializer: function(arg) { // set the size to requested values else set it to the default values arg.height = arg.height || this.HEIGHT; arg.width = arg.width || this.WIDTH; // dialog windows are not resizable by default arg.resizable = arg.resizable || false; SUI.dialog.OKCancelDialog.initializeBase(this, arg); // create split layout to split the panel in a client section and // a button bar on the south side this.splitLayout = new SUI.SplitLayout({ south: { height: this.BUTTON_BAR_HEIGHT } }); // create the client panel for the dialog contents. this.clientPanel = new SUI.Panel({ minHeight: 20, minWidth: 100, // give it some extra padding to make the dialog border look // biggger padding: new SUI.Padding(this.EXTRA_WINDOW_BORDER), innerBorder: new SUI.Border(this.PANEL_BORDER) }); // create a container for the buttons this.buttonPanel = new SUI.AnchorLayout({}); // create a cancel button in the bottom right corner this.cancelButton = new SUI.form.Button({ top: this.EXTRA_WINDOW_BORDER, right: this.EXTRA_WINDOW_BORDER, width: 100, anchor: { right: true }, title: SUI.i18n.cancel }); // create an ok button left next to the cancel button this.okButton = new SUI.form.Button({ top: this.EXTRA_WINDOW_BORDER, right: 112, width: 100, anchor: { right: true }, title: SUI.i18n.ok }); // create an extra button left next to the ok button this.extraButton = new SUI.form.Button({ top: this.EXTRA_WINDOW_BORDER, right: 220, width: 100, anchor: { right: true }, title: "" }); // and hide it for now this.extraButton.el().style.display = "none"; // add the split layout to the cient area this.add(this.splitLayout); // add the clientPanel and button panel to the split layout this.splitLayout.add(this.clientPanel, "center"); this.splitLayout.add(this.buttonPanel, "south"); // add the butts to the button panel this.buttonPanel.add(this.extraButton); this.buttonPanel.add(this.okButton); this.buttonPanel.add(this.cancelButton); // if the client width or height was given in the arguments, set it if (arg.clientWidth) { this.setClientWidth(arg.clientWidth); } if (arg.clientHeight) { this.setClientHeight(arg.clientHeight); } var that = this; // if the ok or cancel listeners were given in the arguments, set them if (arg.onOK) { this.addListener("onOK", arg.onOK); } if (arg.onCancel) { this.addListener("onCancel", arg.onCancel); } if (arg.onDataSaved) { this.addListener("onDataSaved", arg.onDataSaved); } // execute _handleOK on Enter key this.onEnter = function() { that._handleOK(); }; // attach _handleOK to the onclick even of the ok button SUI.browser.addEventListener(this.okButton.el(), "click", function(e) { if (!that._handleOK()) { SUI.browser.noPropagation(e); } } ); // execute _handleCancel on Esc key this.onEsc = function() { that._handleCancel(); }; // attach _handleCancel to the onclick even of the cancel button SUI.browser.addEventListener(this.cancelButton.el(), "click", function(e) { if (!that._handleCancel()) { SUI.browser.noPropagation(e); } } ); // execute the dialog's onCancel routine when the user clicks on // the close button this.addListener("onClose", function() { this.callListener("onCancel"); } ); }, /** * Add some extra space to the border */ EXTRA_WINDOW_BORDER: 4, /** * Thin line of the panel border */ PANEL_BORDER: 1, /** * The height of the button bar */ BUTTON_BAR_HEIGHT: 34, /** * Default dialog height */ HEIGHT: 117, /** * Default dialog width */ WIDTH: 340, /** * Show an extra button on the button bar. * @param {String} title The text on the button * @param {Function} handler The function to execute on the onclick event * of the button */ addExtraButton: function(title, handler) { // set the title and show the button this.extraButton.el().innerHTML = title; this.extraButton.el().style.display = "block"; // add the function the to onclick event SUI.browser.addEventListener(this.extraButton.el(), "click", function(e) { if (!handler(new SUI.Event(this, e))) { SUI.browser.noPropagation(e); } } ); }, /** * Function that is called by the dialog when the data needs to be * harvested. Override this function with your own and the object * that will be return is the argument for the onOK event listener. * @return {Object} An object with form data. */ formToData: function() { this.close(); return null; }, /** * onOK event handler: is executed when the user clicks on the OK button * @param {Object} data The from data represented as an object */ onOK: function(data) { }, /** * onCancel event handler: is executed when the user clicks on the Cancel * button */ onCancel: function() { }, /** * Set the client area width of the dialog window to the specified * width. Normally you're not really interested in the outer size * if the dialog window, but in the space where your are adding your * boxes. This way you can conveniently size the dialog window to fit * your contents. * @param {int} w New client width of the dialog */ setClientWidth: function(w) { // get the widths of the area outside of the client area ... var wb = this.clientAreaPosition(); // ... add these, the extra padding and border to the requested width this.width(w + wb.left + wb.right + 2 * (this.EXTRA_WINDOW_BORDER + this.PANEL_BORDER)); this.center(); }, /** * Set the client area height of the dialog window to the specified * height. Normally you're not really interested in the outer size * if the dialog window, but in the space where your are adding your * boxes. This way you can conveniently size the dialog window to fit * your contents. * @param {int} h New client height of the dialog */ setClientHeight: function(h) { // get the height of the area outside of the client area ... var wb = this.clientAreaPosition(); // ... add these, the extra padding and border to the requested height this.height(h + wb.top + wb.bottom + 2 * (this.EXTRA_WINDOW_BORDER + this.PANEL_BORDER) + this.BUTTON_BAR_HEIGHT); this.center(); }, /** * Close the dialog and notfiy the interface that data was saved. */ dataSaved: function() { this.callListener("onDataSaved"); this.close(); }, /** * Flag to prevent double actions on double clicking of the ok button * @private */ _okClicked: false, /* Cancel was pressed: close the dialog and call the listener */ _handleCancel: function() { this.callListener("onCancel"); this.close(); }, /* OK was pressed: save the data, close the dialog and call the listener */ _handleOK: function() { if (!this._okClicked && !this.okButton.el().disabled) { this._okClicked = true; var that = this; setTimeout(function() { that._okClicked = false; }, 2000); var val = this.formToData(); this.callListener("onOK", val); } } });