Author: vmolotkov
Date: 2007-11-21 12:13:18 -0500 (Wed, 21 Nov 2007)
New Revision: 4150
Added:
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/ListBase.js
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/extend.js
Modified:
branches/3.1.x/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx
Log:
refactoring of .js files
Added:
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/ListBase.js
===================================================================
---
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/ListBase.js
(rev 0)
+++
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/ListBase.js 2007-11-21
17:13:18 UTC (rev 4150)
@@ -0,0 +1,352 @@
+if(!window.Richfaces) window.Richfaces = {};
+
+Richfaces.ListBase = Class.create();
+
+Richfaces.ListBase.compare = function(obj1, obj2) {
+ return ((obj1 == obj2) ? 0 : ((obj1 < obj2) ? -1 : 1));
+}
+
+Richfaces.ListBase.ORDERING_LIST_CLASSES = {
+ normal : "ol_internal_tab rich-ordering-list-items",
+ disabled : "ol_internal_tab rich-ordering-list-disabled",
+ active : "ol_internal_tab rich-ordering-list-active"
+}
+
+Richfaces.ListBase.ASC = "acs";
+Richfaces.ListBase.DESC = "desc";
+
+Richfaces.ListBase.CONTROL_SET = ["A", "INPUT", "TEXTAREA",
"SELECT", "BUTTON"];
+
+Richfaces.ListBase.prototype = {
+ initialize : function(containerId, contentTableId, headerTableId, focusKeeperId,
valueKeeperId,
+ onclickControlId) {
+ this.selectedItems = new Array();
+
+ this.container = $(containerId);
+ this.shuttleTable = $(contentTableId);
+ this.valueKeeper = $(valueKeeperId);
+ this.focusKeeper = $(focusKeeperId);
+ this.focusKeeper.focused = false;
+ this.setFocus();
+ this.focusKeeper.observe("keydown", (function(e)
{this.onkeydownHandler(window.event || e)}).bindAsEventListener(this));
+ this.focusKeeper.observe("blur", function (e)
{this.focusListener(e);}.bindAsEventListener(this));
+
+ this.shuttleTbody = this.shuttleTable.tBodies[0];
+
+ this.items = null;
+ this.retrieveShuttleItems(containerId);
+
+ this.shuttle = null;
+ this.sortOrder = Richfaces.ListBase.ASC;
+
+ this.activeItem = null;
+
+ this.shuttleTop = LayoutManager.getElemXY(this.shuttleTable).top;
+
+ $(contentTableId).observe("click", function(e)
{this.onclickHandler(window.event || e)}.bindAsEventListener(this));
+ },
+
+ retrieveShuttleItems : function(containerId) {
+ var rows = this.shuttleTbody.rows;
+ this.shuttleItems = new Array();
+ var id;
+
+ for (var i = 0; i < rows.length; i++) {
+ var row = rows[i];
+ id = row.id.split(containerId + ":")[1];
+ this.shuttleItems[i]
+ = new Richfaces.SelectItem(null, (id || i),
+ ((Richfaces.SelectItems.isSelected(row)) ? true : false), row);
+ if (Richfaces.SelectItems.isSelected(row)) {
+ this.selectedItems.push(row);
+ }
+ if (Richfaces.SelectItems.isActive(row)) {
+ this.activeItem = row;
+ }
+ }
+ },
+
+ getExtremeItem : function(position) { //FIXME
+ var extremeItem = this.selectedItems[0];
+ var currentItem;
+
+ for (var i = 1; i < this.selectedItems.length; i++) {
+ currentItem = this.selectedItems[i];
+ if (position == "first") {
+ if (currentItem.rowIndex < extremeItem.rowIndex) {
+ extremeItem = currentItem;
+ }
+ } else {
+ if (currentItem.rowIndex > extremeItem.rowIndex) {
+ extremeItem = currentItem;
+ }
+ }
+ }
+ return extremeItem;
+ },
+
+ getEventTargetRow : function(event) {
+ var activeElem;
+ if (event.rangeParent) {
+ //activeElem = event.rangeParent.parentNode;
+ activeElem = event.target;
+ } else {
+ activeElem = event.srcElement;
+ }
+
+ if (activeElem == null) {
+ return;
+ }
+
+ if (activeElem.tagName &&
Richfaces.ListBase.CONTROL_SET.indexOf(activeElem.tagName) != -1) {
+ return;
+ }
+
+ while (activeElem.tagName.toLowerCase() != "tr") {
+ activeElem = activeElem.parentNode;
+ if (!activeElem.tagName) {
+ return; //for IE
+ }
+ }
+
+ return activeElem;
+ },
+
+ onclickHandler : function(event) {
+ var activeElem = this.getEventTargetRow(event);
+ if (activeElem != null) {
+
+ if (event.ctrlKey) {
+ this.addSelectedItem(activeElem);
+ this.activeItem = activeElem;
+ } else if (event.shiftKey) {
+ this.selectItemGroup(activeElem);
+ } else {
+ this.selectionItem(activeElem);
+ this.activeItem = activeElem;
+ }
+
+
+ Richfaces.SelectItems.doActive(this.activeItem);
+ this.saveState();
+ //this.controlListManager();
+ this.setFocus();
+ }
+ },
+
+ onkeydownHandler : function(event) {
+ var action = null;
+ switch (event.keyCode) {
+ case 34 : action = 'last'; this.moveSelectedItems(action ,event); break;
//page down
+ case 33 : action = 'first'; this.moveSelectedItems(action, event); break;
//page up
+ case 38 : //up arrow
+ action = 'up';
+ this.moveActiveItem(action, event);
+ break;
+ case 40 : //down arrow
+ action = 'down';
+ this.moveActiveItem(action, event);
+ break;
+ case 65 : // Ctrl + A
+ if (event.ctrlKey) {
+ this.selectAll();
+ Event.stop(event);
+ }
+ Richfaces.SelectItems.doActive(this.activeItem);
+ this.saveState();
+ break;
+ case 32 : this.invertSelection(event); this.saveState(); break; //blank
+ }
+ },
+
+ invertSelection : function(event) {
+ var eventItem = this.activeItem;
+ var eventShuttleItem = this.getSelectItemByNode(eventItem);
+ if (eventShuttleItem._selected) {
+ eventShuttleItem._selected = false;
+ this.selectedItems.remove(eventShuttleItem);
+ } else {
+ eventShuttleItem._selected = true;
+ this.selectedItems.push(eventShuttleItem);
+ }
+ },
+
+ moveActiveItem : function(action, event) {
+ var item = this.activeItem;
+ var rows = this.shuttleTbody.rows;
+ if ((action == 'up') && (item.rowIndex > 0)) {
+ this.changeActiveItems(rows[item.rowIndex - 1], item);
+ } else if ((action == 'down') && (item.rowIndex <
this.shuttleItems.length - 1)) {
+ this.changeActiveItems(rows[item.rowIndex + 1], item);
+ }
+
+ this.saveState();
+ this.autoScrolling(action, event);
+ //this.controlListManager();
+ },
+
+ changeActiveItems : function(newItem, item) {
+ var shuttleItem = this.getSelectItemByNode(item);
+ var newShuttleItem = this.getSelectItemByNode(newItem);
+
+ this.resetMarked();
+
+ Richfaces.SelectItems.doActive(newItem);
+ newItem._selected = true;
+ this.activeItem = newItem;
+ this.selectedItems.push(newItem);
+ },
+
+ selectAll : function() {
+ var startIndex = 0;
+ var endIndex = this.shuttleItems.length - 1;
+ this.selectItemRange(startIndex, endIndex);
+ },
+
+ /**
+ * Click handler
+ */
+ selectionItem : function(activeItem) {
+ var markedItem = this.getSelectItemByNode(activeItem);
+ var markedShuttleItem = activeItem;
+
+ if (markedItem != null) {
+ this.resetMarked();
+ if (markedItem._selected) {
+ markedItem._selected = false;
+ } else {
+ markedItem._selected = true;
+ this.selectedItems[0] = markedShuttleItem;
+ }
+ }
+ },
+
+ /**
+ * CTRL+Click handler
+ */
+ addSelectedItem : function(activeItem) {
+ var markedItem = this.getSelectItemByNode(activeItem);
+ var markedShuttleItem = activeItem;
+
+ if (markedItem._selected) {
+ this.selectedItems.remove(markedShuttleItem);
+ markedItem._selected = false;
+ } else {
+ markedItem._selected = true;
+ this.selectedItems.push(markedShuttleItem);
+ }
+
+ Richfaces.SelectItems.doSelect(this.activeItem);
+
+ if (this.activeItem && !this.getSelectItemByNode(this.activeItem)._selected) {
+ Richfaces.SelectItems.doNormal(this.activeItem);
+ }
+ },
+
+ /**
+ * Shift+Click handler
+ */
+ selectItemGroup : function(currentItem) {
+ //FIXME
+ var activeItemIndex = this.activeItem.rowIndex;
+ var startIndex;
+ var endIndex;
+
+ if (currentItem.rowIndex > activeItemIndex) {
+ startIndex = activeItemIndex;
+ endIndex = currentItem.rowIndex;
+ } else {
+ startIndex = currentItem.rowIndex;
+ endIndex = activeItemIndex;
+ }
+
+ this.resetMarked();
+
+ this.selectItemRange(startIndex, endIndex);
+ },
+
+ selectItemRange : function(startIndex, endIndex) {
+ var rows = this.shuttleTbody.rows;
+ for (var i = startIndex; i <= endIndex; i++) {
+ Richfaces.SelectItems.doSelect(rows[i]);
+ this.selectedItems.push(rows[i]);
+ this.getSelectItemByNode(rows[i])._selected = true;
+ }
+ },
+
+ resetMarked : function() {
+ var rows = this.shuttleTbody.rows;
+ for (var i = 0; i < rows.length; i++) {
+ var shuttleItem = rows[i];
+ Richfaces.SelectItems.doNormal(shuttleItem);
+ this.getSelectItemByNode(shuttleItem)._selected = false; //FIXME
+ }
+ this.selectedItems.length = 0;
+ },
+
+ getSelectItemByNode : function(selectItemNode) {
+ for (var i = 0; i < this.shuttleItems.length; i++) {
+ var item = this.shuttleItems[i];
+ if (selectItemNode.rowIndex == item._node.rowIndex) {
+ return item;
+ }
+ }
+ return null;
+ },
+
+ autoScrolling : function(action, event) {
+ this.selectedItems.sort(this.compareByRowIndex);
+ var increment;
+ var scrollTop = this.shuttleTable.parentNode.scrollTop;
+ if (action == 'up' || action == 'first') {
+ var targetItemTop = LayoutManager.getElemXY(this.selectedItems[0]).top;
+ increment = (targetItemTop - scrollTop) - this.shuttleTop;
+ if (increment < 0) {
+ this.shuttleTable.parentNode.scrollTop += increment;
+ }
+ } else if (action == 'down' || action == 'last') {
+ var item = this.selectedItems[this.selectedItems.length - 1];
+ targetItemBottom =
LayoutManager.getElemXY(this.selectedItems[this.selectedItems.length - 1]).top +
item.offsetHeight;
+ var increment = (targetItemBottom - scrollTop) - (this.shuttleTop +
this.shuttleTable.parentNode.offsetHeight - LayoutManager.SCROLL_WIDTH);
+ if (increment > 0) {
+ this.shuttleTable.parentNode.scrollTop += increment;
+ }
+ }
+ Event.stop(event);
+ },
+
+ setFocus : function() {
+ this.focusKeeper.focus();
+ this.focusKeeper.focused = true;
+ if (this.isListActive()) {
+ this.shuttleTable.className = Richfaces.ListBase.ORDERING_LIST_CLASSES.active;
+ }
+ },
+
+ focusListener : function(e) {
+ e = e || window.event;
+ this.focusKeeper.focusused = false;
+ this.shuttleTable.className = Richfaces.ListBase.ORDERING_LIST_CLASSES.normal;
+ },
+
+ compareByLabel : function(obj1, obj2) {
+ obj1 = obj1._label;
+ obj2 = obj2._label;
+ return Richfaces.ListBase.compare(obj1, obj2);
+ },
+
+ compareByRowIndex : function(obj1, obj2) {
+ obj1 = obj1.rowIndex;
+ obj2 = obj2.rowIndex;
+ return Richfaces.ListBase.compare(obj1, obj2);
+ },
+
+ isListActive : function() {
+ if ((this.activeItem != null || this.selectedItems.length != 0) &&
this.focusKeeper.focused) {
+ return true;
+ }
+ return false;
+ }
+}
+
+
Added:
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/extend.js
===================================================================
---
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/extend.js
(rev 0)
+++
branches/3.1.x/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/extend.js 2007-11-21
17:13:18 UTC (rev 4150)
@@ -0,0 +1,189 @@
+// vim: tw=80 ts=4 sw=4 noet
+// ----------------------------------------------------------------------------
+// Project : Extend - Prototype OOP extension
+// URL : <
http://www.ivy.fr/js/extend>
+// ----------------------------------------------------------------------------
+// Author : Sebastien Pierre <sebastien(a)ivy.fr>
+// License : Revised BSD License
+// ----------------------------------------------------------------------------
+// Creation : 08-Sep-2006
+// Last mod : 17-Nov-2006
+// ----------------------------------------------------------------------------
+
+// The Extend object holds all the information required to implement the
+// inheritance and other OO-goodness.
+if(!window.Extend) {
+
+Extend = {
+ VERSION: 1.1,
+ CLASSDEF: "CLASSDEF",
+ DELETE: "DELETE",
+ // These are a list of methods of class instances that are reserved by the
+ // OO layer (see the reparent method for more info)
+ INSTANCE_RESERVED: {
+ CLASSDEF: true,
+ getClass: true,
+ parentClass: true
+ },
+
+ // Sets up a class
+ setupClass: function( _class, declaration )
+ {
+ // We create an empty prototype if the user did not provide one
+ declaration = declaration || {}
+ _class.prototype = declaration
+ // We clone the given method definition, because they will be augmented
+ // with the ones defined in the parent class
+ _class.methods = {}
+ for ( var key in declaration ) { _class.methods[key] = declaration[key] }
+ _class.inherited = {}
+ _class.parentClass = undefined
+ if ( declaration[Extend.CLASSDEF] )
+ { _class.className = declaration[Extend.CLASSDEF].name }
+ else
+ { _class.className = undefined }
+ _class.subclasses = _class.subclasses || []
+ _class.constructor = Extend.Operations.constructor
+ _class.reparent = Extend.Operations.reparent
+ _class.method = Extend.Operations.method
+ _class.update = Extend.Operations.update
+ if ( declaration[Extend.CLASSDEF] )
+ { _class.reparent(declaration[Extend.CLASSDEF].parent) }
+ // We update the class methods with an `ofClass` method that returns the
+ // class, so that instances will have a proper
+ declaration.getClass = function() {return _class}
+ declaration.parentClass = function() {return this.getClass().parentClass}
+ declaration.parentCall = function() {
+ var new_args = []
+ for ( var i=1;i<arguments.length;i++ ) {new_args.push(arguments[i])}
+ return this.parentClass().method(arguments[0]).apply(this, new_args)
+ }
+ declaration.setClass = function(newClass) {
+ return this.getClass().parentClass
+ }
+ // We reparent the subclasses if any
+ for ( var i=0 ; i<_class.subclasses ; i++ ) {
+ _class.subclasses[i].reparent(_class)
+ }
+ return _class
+ },
+ // These are operations that will be "mixed-in" with the new classes
+ Operations: {
+ constructor: function() {
+ return this.prototype.initialize || function() {}
+ },
+ // Reparents this class
+ reparent: function( newParentClass )
+ {
+ if ( this.parentClass )
+ {
+ var this_index = this.subclasses.indexOf(this)
+ this.parentClass.subclasses.splice(this_index, 1)
+ for ( var method_name in this.inherited ) {
+ this.method(method_name, null, this.parentClass)
+ }
+ }
+ this.parentClass = newParentClass
+ if ( !newParentClass ) return
+ var parent_methods = newParentClass.prototype
+ // We iterate on all the parent methods
+ for ( parent_method_name in parent_methods ) {
+ // If the method is a reserved one, we skip it
+ if ( Extend.INSTANCE_RESERVED[parent_method_name] == true ) { continue }
+ // If the method is not directly defined in the current class, we add it
+ if ( this.methods[parent_method_name] == undefined )
+ {
+ this.method( parent_method_name,
+ parent_methods[parent_method_name],
+ newParentClass.inherited[parent_method_name] || newParentClass
+ )
+ }
+ }
+ newParentClass.subclasses.push(this)
+ },
+ update: function(newPrototype) {
+ Extend.setupClass(this, newPrototype||this.prototype)
+ },
+ // Returns, sets or deletes a method in this class
+ method: function( name, body, declaredIn ) {
+ if ( body == undefined )
+ {
+ var method = this.prototype[name]
+ if ( name == undefined ) throw new Error("Method not found: "+name)
+ return method
+ }
+ else
+ {
+ declaredIn = declaredIn || this
+ // If the method is declared in this class
+ if ( declaredIn == this )
+ {
+ if ( body == Extend.DELETE ) {
+ delete this.methods[name]
+ delete this.inherited[name]
+ delete this.prototype[name]
+ // If the method is defined in the parent we set it
+ if ( this.parentClass ) {
+ var parent_method = this.parentClass.method(name)
+ if ( parent_method ) {
+ this.method(name, parent_method, this.parentClass.inherited[name] ||
this.parentClass)
+ }
+ }
+ } else {
+ this.methods[name] = body
+ this.prototype[name] = body
+ delete this.inherited[name]
+ }
+ }
+ // Or if its declared in another class
+ else
+ {
+ if ( body == Extend.DELETE ) {
+ delete this.inherited[name]
+ delete this.methods[name]
+ delete this.prototype[name]
+ // If the method is defined in the parent we set it
+ if ( this.parentClass ) {
+ var parent_method = this.parentClass.method(name)
+ if ( parent_method ) {
+ this.method(name, parent_method, this.parentClass.inherited[name] ||
this.parentClass)
+ }
+ }
+ }
+ else {
+ if ( this.methods[name] == undefined ) {
+ this.inherited[name] = declaredIn
+ this.prototype[name] = body
+ }
+ }
+ }
+ for ( var i=0 ; i<this.subclasses.length ; i++ )
+ {
+ this.subclasses[i].method(name,body,declaredIn)
+ }
+ }
+ }
+ }
+}
+
+// In case prototype is not available, we use this instead
+try {
+ Class = Class
+} catch ( Error ) {
+ Class = {create:function() {return function() {this.initialize.apply(this,
arguments)}}}
+}
+Class._create = Class.create
+Class.create = function( declaration ) {
+ var new_class = Extend.setupClass(Class._create(declaration), declaration)
+ // The following only works on FireFox
+ /*
+ new_class.watch("prototype", function(id,oldval,newval) {
+ new_class.prototype = newval
+ Extend.setupClass(new_class, newval)
+ return newval
+ })*/
+ return new_class
+};
+
+};
+// EOF
Modified:
branches/3.1.x/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx
===================================================================
---
branches/3.1.x/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx 2007-11-21
17:04:30 UTC (rev 4149)
+++
branches/3.1.x/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx 2007-11-21
17:13:18 UTC (rev 4150)
@@ -13,11 +13,13 @@
<h:scripts>
new org.ajax4jsf.javascript.PrototypeScript(),
+ scripts/extend.js,
scripts/ShuttleUtils.js,
scripts/SelectItem.js,
scripts/LayoutManager.js
- scripts/Control.js,
- scripts/OrderingList.js,
+ scripts/Control.js,
+ scripts/ListBase.js,
+ scripts/OrderingList.js
</h:scripts>
<f:clientId var="clientId"/>
@@ -72,7 +74,7 @@
function init() {
try {
var cotrolsIdPrefix = [['up', 'disup'], ['down',
'disdown'], ['last', 'dislast'],
['first','disfirst']];
- var shuttle = new Shuttle('#{cId}', '#{cId}internal_tab',
'#{cId}internal_header_tab', '#{cId}focusKeeper',
'#{cId}valueKeeper', cotrolsIdPrefix, '#{cId}sortLabel', function()
{#{component.attributes['onorderchanged']}});
+ var shuttle = new Richfaces.OrderingList('#{cId}',
'#{cId}internal_tab', '#{cId}internal_header_tab',
'#{cId}focusKeeper', '#{cId}valueKeeper', cotrolsIdPrefix,
'#{cId}sortLabel', function()
{#{component.attributes['onorderchanged']}});
var layoutManager = new LayoutManager('#{clientId}internal_header_tab',
'#{clientId}internal_tab');
layoutManager.widthSynchronization();
} catch (e) {