@qooxdoo/framework
Version:
The JS Framework for Coders
459 lines (387 loc) • 13.4 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2004-2009 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Martin Wittemann (martinwittemann)
************************************************************************ */
/**
* The form object is responsible for managing form items. For that, it takes
* advantage of two existing qooxdoo classes.
* The {@link qx.ui.form.Resetter} is used for resetting and the
* {@link qx.ui.form.validation.Manager} is used for all validation purposes.
*
* The view code can be found in the used renderer ({@link qx.ui.form.renderer}).
*/
qx.Class.define("qx.ui.form.Form",
{
extend : qx.core.Object,
construct : function()
{
this.base(arguments);
this.__groups = [];
this._buttons = [];
this._buttonOptions = [];
this._validationManager = this._createValidationManager();
this._resetter = this._createResetter();
},
events : {
/** Fired as soon as something changes in the form.*/
"change" : "qx.event.type.Event"
},
members :
{
__groups : null,
_validationManager : null,
_groupCounter : 0,
_buttons : null,
_buttonOptions : null,
_resetter : null,
/*
---------------------------------------------------------------------------
ADD
---------------------------------------------------------------------------
*/
/**
* Adds a form item to the form including its internal
* {@link qx.ui.form.validation.Manager} and {@link qx.ui.form.Resetter}.
*
* *Hint:* The order of all add calls represent the order in the layout.
*
* @param item {qx.ui.form.IForm} A supported form item.
* @param label {String} The string, which should be used as label.
* @param validator {Function | qx.ui.form.validation.AsyncValidator ? null}
* The validator which is used by the validation
* {@link qx.ui.form.validation.Manager}.
* @param name {String?null} The name which is used by the data binding
* controller {@link qx.data.controller.Form}.
* @param validatorContext {var?null} The context of the validator.
* @param options {Map?null} An additional map containing custom data which
* will be available in your form renderer specific to the added item.
*/
add : function(item, label, validator, name, validatorContext, options) {
if (this.__isFirstAdd()) {
this.__groups.push({
title: null, items: [], labels: [], names: [],
options: [], headerOptions: {}
});
}
// save the given arguments
this.__groups[this._groupCounter].items.push(item);
this.__groups[this._groupCounter].labels.push(label);
this.__groups[this._groupCounter].options.push(options);
// if no name is given, use the label without not working character
if (name == null) {
name = label.replace(
/\s+|&|-|\+|\*|\/|\||!|\.|,|:|\?|;|~|%|\{|\}|\(|\)|\[|\]|<|>|=|\^|@|\\/g, ""
);
}
this.__groups[this._groupCounter].names.push(name);
// add the item to the validation manager
this._validationManager.add(item, validator, validatorContext);
// add the item to the reset manager
this._resetter.add(item);
// fire the change event
this.fireEvent("change");
},
/**
* Adds a group header to the form.
*
* *Hint:* The order of all add calls represent the order in the layout.
*
* @param title {String} The title of the group header.
* @param options {Map?null} A special set of custom data which will be
* given to the renderer.
*/
addGroupHeader : function(title, options) {
if (!this.__isFirstAdd()) {
this._groupCounter++;
}
this.__groups.push({
title: title, items: [], labels: [], names: [],
options: [], headerOptions: options
});
// fire the change event
this.fireEvent("change");
},
/**
* Adds a button to the form.
*
* *Hint:* The order of all add calls represent the order in the layout.
*
* @param button {qx.ui.form.Button} The button to add.
* @param options {Map?null} An additional map containing custom data which
* will be available in your form renderer specific to the added button.
*/
addButton : function(button, options) {
this._buttons.push(button);
this._buttonOptions.push(options || null);
// fire the change event
this.fireEvent("change");
},
/**
* Returns whether something has already been added.
*
* @return {Boolean} true, if nothing has been added jet.
*/
__isFirstAdd : function() {
return this.__groups.length === 0;
},
/*
---------------------------------------------------------------------------
REMOVE
---------------------------------------------------------------------------
*/
/**
* Removes the given item from the form.
*
* @param item {qx.ui.form.IForm} A supported form item.
* @return {Boolean} <code>true</code>, if the item could be removed.
*/
remove : function(item) {
for (var i = 0; i < this.__groups.length; i++) {
var group = this.__groups[i];
for (var j = 0; j < group.items.length; j++) {
var storedItem = group.items[j];
if (storedItem === item) {
// remove all stored data
group.items.splice(j, 1);
group.labels.splice(j, 1);
group.names.splice(j, 1);
group.options.splice(j, 1);
// remove the item to the validation manager
this._validationManager.remove(item);
// remove the item to the reset manager
this._resetter.remove(item);
// fire the change event
this.fireEvent("change");
return true;
}
}
}
return false;
},
/**
* Removes the given group header from the form. All items in the group will be moved to
* another group (usually the previous group). If there is more than one group with
* the same title, only the first group will be removed.
*
* @param title {String} The title.
* @return {Boolean} <code>true</code>, if the header could be removed.
*/
removeGroupHeader : function(title) {
for (var i = 0; i < this.__groups.length; i++) {
var group = this.__groups[i];
if (group.title === title) {
var targetGroup;
// if it's the first group
if (i == 0) {
// if it's the only group
if (this.__groups.length == 1) {
// remove the title and the header options
group.title = null;
group.headerOptions = {};
// fire the change event
this.fireEvent("change");
return true;
} else {
// add to the next
targetGroup = this.__groups[i+1];
}
} else {
// add to the previous group
targetGroup = this.__groups[i-1];
}
// copy the data over
targetGroup.items = targetGroup.items.concat(group.items);
targetGroup.labels = targetGroup.labels.concat(group.labels);
targetGroup.names = targetGroup.names.concat(group.names);
targetGroup.options = targetGroup.options.concat(group.options);
// delete the group
this.__groups.splice(i, 1);
this._groupCounter--;
// fire the change event
this.fireEvent("change");
return true;
}
}
return false;
},
/**
* Removes the given button from the form.
*
* @param button {qx.ui.form.Button} The button to remove.
* @return {Boolean} <code>true</code>, if the button could be removed.
*/
removeButton : function(button) {
for (var i = 0; i < this._buttons.length; i++) {
var storedButton = this._buttons[i];
if (storedButton === button) {
this._buttons.splice(i, 1);
this._buttonOptions.splice(i, 1);
// fire the change event
this.fireEvent("change");
return true;
}
}
return false;
},
/**
* Returns all added items as a map.
*
* @return {Map} A map containing for every item an entry with its name.
*/
getItems : function() {
var items = {};
// go threw all groups
for (var i = 0; i < this.__groups.length; i++) {
var group = this.__groups[i];
// get all items
for (var j = 0; j < group.names.length; j++) {
var name = group.names[j];
items[name] = group.items[j];
}
}
return items;
},
/**
* Return an item by name.
*
* @param name {string} Item name.
* @return {qx.ui.form.IForm|null} The form item or null.
*/
getItem : function(name) {
for (var i = 0; i < this.__groups.length; i++) {
var group = this.__groups[i];
for (var j = 0; j < group.names.length; j++) {
if (group.names[j] === name) {
return group.items[j];
}
}
}
return null;
},
/*
---------------------------------------------------------------------------
RESET SUPPORT
---------------------------------------------------------------------------
*/
/**
* Resets the form. This means reseting all form items and the validation.
*/
reset : function() {
this._resetter.reset();
this._validationManager.reset();
},
/**
* Redefines the values used for resetting. It calls
* {@link qx.ui.form.Resetter#redefine} to get that.
*/
redefineResetter : function() {
this._resetter.redefine();
},
/**
* Redefines the value used for resetting of the given item. It calls
* {@link qx.ui.form.Resetter#redefineItem} to get that.
*
* @param item {qx.ui.core.Widget} The item to redefine.
*/
redefineResetterItem : function(item) {
this._resetter.redefineItem(item);
},
/*
---------------------------------------------------------------------------
VALIDATION
---------------------------------------------------------------------------
*/
/**
* Validates the form using the
* {@link qx.ui.form.validation.Manager#validate} method.
*
* @return {Boolean | null} The validation result.
*/
validate : function() {
return this._validationManager.validate();
},
/**
* Returns the internally used validation manager. If you want to do some
* enhanced validation tasks, you need to use the validation manager.
*
* @return {qx.ui.form.validation.Manager} The used manager.
*/
getValidationManager : function() {
return this._validationManager;
},
/*
---------------------------------------------------------------------------
RENDERER SUPPORT
---------------------------------------------------------------------------
*/
/**
* Accessor method for the renderer which returns all added items in a
* array containing a map of all items:
* {title: title, items: [], labels: [], names: []}
*
* @return {Array} An array containing all necessary data for the renderer.
* @internal
*/
getGroups : function() {
return this.__groups;
},
/**
* Accessor method for the renderer which returns all added buttons in an
* array.
* @return {Array} An array containing all added buttons.
* @internal
*/
getButtons : function() {
return this._buttons;
},
/**
* Accessor method for the renderer which returns all added options for
* the buttons in an array.
* @return {Array} An array containing all added options for the buttons.
* @internal
*/
getButtonOptions : function() {
return this._buttonOptions;
},
/*
---------------------------------------------------------------------------
INTERNAL
---------------------------------------------------------------------------
*/
/**
* Creates and returns the used validation manager.
*
* @return {qx.ui.form.validation.Manager} The validation manager.
*/
_createValidationManager : function() {
return new qx.ui.form.validation.Manager();
},
/**
* Creates and returns the used resetter.
*
* @return {qx.ui.form.Resetter} the resetter class.
*/
_createResetter : function() {
return new qx.ui.form.Resetter();
}
},
/*
*****************************************************************************
DESTRUCTOR
*****************************************************************************
*/
destruct : function()
{
// holding references to widgets --> must set to null
this.__groups = this._buttons = this._buttonOptions = null;
this._validationManager.dispose();
this._resetter.dispose();
}
});