/* 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);
}
}
});