Author: vmolotkov
Date: 2007-11-01 16:38:48 -0400 (Thu, 01 Nov 2007)
New Revision: 3697
Modified:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/SelectItem.js
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx
Log:
functionality "saveState" on the client side,
data synchronization on the server side,
cosmetic changes in a template,corrected behaviour SHIFT+CLICK
Modified:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java 2007-11-01
18:39:02 UTC (rev 3696)
+++
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/component/UIOrderingList.java 2007-11-01
20:38:48 UTC (rev 3697)
@@ -1,6 +1,7 @@
package org.richfaces.component;
import java.util.Iterator;
+import java.util.List;
import org.ajax4jsf.component.UIDataAdaptor;
import org.ajax4jsf.model.DataComponentState;
@@ -11,6 +12,12 @@
public abstract class UIOrderingList extends UIDataAdaptor {
+ private List synchronizedList;
+
+ private List selectedItems;
+
+ private Object activeItem;
+
@Override
protected DataComponentState createComponentState() {
return new RepeatState();
@@ -39,4 +46,27 @@
}
}
+ public List getSynchronizedList() {
+ return synchronizedList;
+ }
+
+ public void setSynchronizedList(List synchronizedList) {
+ this.synchronizedList = synchronizedList;
+ }
+
+ public List getSelectedItems() {
+ return selectedItems;
+ }
+
+ public void setSelectedItems(List selectedItems) {
+ this.selectedItems = selectedItems;
+ }
+
+ public Object getActiveItem() {
+ return activeItem;
+ }
+
+ public void setActiveItem(Object activeItem) {
+ this.activeItem = activeItem;
+ }
}
Modified:
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java 2007-11-01
18:39:02 UTC (rev 3696)
+++
trunk/sandbox/ui/orderingList/src/main/java/org/richfaces/renderkit/OrderingListRendererBase.java 2007-11-01
20:38:48 UTC (rev 3697)
@@ -1,7 +1,11 @@
package org.richfaces.renderkit;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
@@ -14,6 +18,14 @@
public abstract class OrderingListRendererBase extends AbstractRowsRenderer {
+ private final static String VALUE_ORDER_ID_PREFIX = "valueKeeper";
+
+ private final static Character ACTIVITY_MARKER = 'a';
+
+ private final static Character SELECTION_MARKER = 's';
+
+ private final static String ITEM_SEPARATOR = ",";
+
protected Class getComponentClass() {
return UIOrderingList.class;
}
@@ -30,7 +42,6 @@
UIDataAdaptor table = holder.getTable();
writer.startElement(HTML.TR_ELEMENT, table);
- writer.writeAttribute(HTML.id_ATTRIBUTE, table.getClientId(context), null);
List<UIComponent> children = table.getChildren();
for (UIComponent component : children) {
@@ -51,15 +62,54 @@
public void encodeChildren(FacesContext context, UIComponent component) throws
IOException {
encodeRows(context, component);
}
-
- public String initJSShuttleObject(FacesContext context, UIOrderingList component) {
- StringBuffer script = new StringBuffer();
- script.append("var shuttleItems = new Array();");
- script.append("for (var i = 9; i > 0; i--) {");
- script.append("shuttleItems[9-i] = new SelectItem('Item ' + i, i,
'description' + i, null, false);");
- script.append("}");
- script.append("var shuttle = new
Shuttle('").append(component.getClientId(context)).append("',
shuttleItems);");
- //script.append(" shuttle.init();");
- return script.toString();
+
+ public void doDecode(FacesContext context, UIComponent component) {
+ UIOrderingList orderingList = (UIOrderingList) component;
+
+ String clientId = component.getClientId(context);
+ Map requestParameterMap = context.getExternalContext()
+ .getRequestParameterMap();
+
+ String valueOrder = (String)
requestParameterMap.get(clientId.concat(VALUE_ORDER_ID_PREFIX));
+
+ if (valueOrder != null) {
+ String[] valueOrderAr = valueOrder.split(ITEM_SEPARATOR);
+ List oldValues = (List) orderingList.getValue();
+ valuesSynchronization(valueOrderAr, oldValues);
+ }
}
+
+
+ private void valuesSynchronization(String[] valueOrder, List oldValues) {
+ List synchronizedList = new ArrayList();
+ List selectedItems = new ArrayList();
+ Object activeItem = null;
+ Integer itemIndex = null;
+ String[] currentOrder;
+
+ for (int i = 0; i < valueOrder.length; i++) {
+ currentOrder = valueOrder[i].split("d+");
+
+ try {
+ itemIndex = new Integer(currentOrder[0]);
+ } catch (NumberFormatException e) {
+ // TODO: handle exception
+ }
+
+ Object currentItem = oldValues.get(itemIndex.intValue());
+ synchronizedList.add(currentItem);
+
+ if (currentOrder.length > 1) {
+ Iterator it = Arrays.asList(currentOrder[1].toCharArray()).iterator();
+ while (it.hasNext()) {
+ Character marker = (Character) it.next();
+ if (ACTIVITY_MARKER.equals(marker)) {
+ activeItem = currentItem;
+ } else if (SELECTION_MARKER.equals(marker)) {
+ selectedItems.add(currentItem);
+ }
+ }
+ }
+ }
+ }
}
Modified:
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js 2007-11-01
18:39:02 UTC (rev 3696)
+++
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/OrderingList.js 2007-11-01
20:38:48 UTC (rev 3697)
@@ -8,21 +8,27 @@
}
}
-Shuttle = function(containerId, shuttleItems) {
+Shuttle = function(containerId, tableId, focusKeeperId, valueKeeperId) {
this.container = document.getElementById(containerId);
+ this.shuttleTable = document.getElementById(tableId);
+ this.shuttleTbody = this.shuttleTable.tBodies[0];
+
this.items = null;
this.selectedItems = new Array();
- this.shuttleItems = shuttleItems;
+ this.retrieveShuttleItems();
this.shuttle = null;
this.sortOrder = Shuttle.ASC;
- this.shuttleTable = null;
- this.shuttleTbody = null;
-
this.activeItem = null;
- this.focusKeeper = document.getElementById("focusKeeper");
+ this.focusKeeper = document.getElementById(focusKeeperId);
+ this.valueKeeper = document.getElementById(valueKeeperId);
+
+ var obj = this;
+ this.focusKeeper.onkeydown = function(e) {
+ obj.onkeydownHandler(window.event || e);
+ }
}
Shuttle.ASC = "acs";
@@ -30,7 +36,20 @@
Shuttle.SELECTED_ITEM_CLASS = "selectedItem";
Shuttle.NORMAL_ITEM_CLASS = "normalItem";
Shuttle.ACTIVE_ITEM_CLASS = "activeItem";
+Shuttle.ACTIVITY_MARKER = "a";
+Shuttle.SELECTION_MARKER = "s";
+Shuttle.ITEM_SEPARATOR = ",";
+Shuttle.prototype.retrieveShuttleItems = function() {
+ var rows = this.shuttleTbody.rows;
+ this.shuttleItems = new Array();
+ var obj = this;
+ for (var i = 0; i < rows.length; i++) {
+ var row = rows[i];
+ this.shuttleItems[i] = new SelectItem(null, i, false, row);
+ }
+}
+
Shuttle.prototype.add = function(selectItem) {
this.createShuttleItem(selectItem, this.shuttle);
}
@@ -93,7 +112,9 @@
item.parentNode.insertBefore(item, rows[item.rowIndex + incr]);
}
}
- }
+ }
+
+ this.saveState();
}
}
@@ -117,25 +138,37 @@
}
Shuttle.prototype.onclickHandler = function(event) {
- var activeElem = event.target || event.srcElement;
+ //var activeElem = event.target || event.srcElement;
+ var activeElem;
+ if (event.rangeParent) {
+ activeElem = event.rangeParent.parentNode;
+ } else {
+ activeElem = event.srcElement;
+ }
+
if (activeElem == null) {
return;
}
while (activeElem.tagName.toLowerCase() != "tr") {
activeElem = activeElem.parentNode;
+ if (!activeElem.tagName) {
+ return; //for IE
+ }
}
if (event.ctrlKey) {
this.addSelectedItem(activeElem);
- //FIX
+ this.activeItem = activeElem;
} else if (event.shiftKey) {
- this.selectItemGroup(activeElem);
+ this.selectionItemGroup(activeElem);
} else {
- this.selectItem(activeElem);
+ this.selectionItem(activeElem);
+ this.activeItem = activeElem;
}
- activeElem.className = Shuttle.ACTIVE_ITEM_CLASS;
- this.activeItem = activeElem;
+ this.activeItem.className = Shuttle.ACTIVE_ITEM_CLASS;
+
+ this.saveState();
}
Shuttle.prototype.onkeydownHandler = function(event) {
@@ -149,17 +182,15 @@
/**
* Click handler
*/
-Shuttle.prototype.selectItem = function(activeItem) {
- var markedItem = this.getSelectItemById(activeItem.id);
+Shuttle.prototype.selectionItem = function(activeItem) {
+ var markedItem = this.getSelectItemByNode(activeItem);
var markedShuttleItem = activeItem;
if (markedItem != null) {
+ this.resetMarked();
if (markedItem._selected) {
- this.resetMarked();
markedItem._selected = false;
} else {
- this.resetMarked();
-
markedItem._selected = true;
this.selectedItems[0] = markedShuttleItem;
}
@@ -170,7 +201,7 @@
* CTRL+Click handler
*/
Shuttle.prototype.addSelectedItem = function(activeItem) {
- var markedItem = this.getSelectItemById(activeItem.id);
+ var markedItem = this.getSelectItemByNode(activeItem);
var markedShuttleItem = activeItem;
if (markedItem._selected) {
@@ -182,7 +213,7 @@
}
this.activeItem.className = Shuttle.SELECTED_ITEM_CLASS;
- if (this.activeItem && !this.getSelectItemById(this.activeItem.id)._selected) {
+ if (this.activeItem && !this.getSelectItemByNode(this.activeItem)._selected) {
this.activeItem.className = Shuttle.NORMAL_ITEM_CLASS;
}
}
@@ -190,23 +221,27 @@
/**
* Shift+Click handler
*/
-Shuttle.prototype.selectItemGroup = function(activeItem) {
- var lastItemIndex = this.activeItem.rowIndex;
+Shuttle.prototype.selectionItemGroup = function(currentItem) {
+ //FIXME
+ var activeItemIndex = this.activeItem.rowIndex;
var startIndex;
var endIndex;
- this.resetMarked();
- if (activeItem.rowIndex > lastItemIndex) {
- startIndex = lastItemIndex;
- endIndex = activeItem.rowIndex;
+
+ if (currentItem.rowIndex > activeItemIndex) {
+ startIndex = activeItemIndex;
+ endIndex = currentItem.rowIndex;
} else {
- startIndex = activeItem.rowIndex;
- endIndex = lastItemIndex;
+ startIndex = currentItem.rowIndex;
+ endIndex = activeItemIndex;
}
+
+ this.resetMarked();
+
var rows = this.shuttleTbody.rows;
for (var i = startIndex; i <= endIndex; i++) {
rows[i].className = Shuttle.SELECTED_ITEM_CLASS;
this.selectedItems.push(rows[i]);
- this.getSelectItemById(rows[i].id)._selected = true;
+ this.getSelectItemByNode(rows[i])._selected = true;
}
}
@@ -215,33 +250,26 @@
for (var i = 0; i < rows.length; i++) {
var shuttleItem = rows[i];
shuttleItem.className = Shuttle.NORMAL_ITEM_CLASS;
- this.getSelectItemById(shuttleItem.id)._selected = false; //FIXME
+ this.getSelectItemByNode(shuttleItem)._selected = false; //FIXME
}
this.selectedItems.length = 0;
}
-Shuttle.prototype.getSelectItemById = function(selectItemId) {
+Shuttle.prototype.getSelectItemByNode = function(selectItemNode) {
for (var i = 0; i < this.shuttleItems.length; i++) {
var item = this.shuttleItems[i];
- if (selectItemId == item._id) {
+ if (selectItemNode.rowIndex == item._node.rowIndex) {
return item;
}
}
- return null
+ return null;
}
-Shuttle.prototype.init = function() {
- this.shuttleTable = document.createElement("table");
- this.shuttleTbody = document.createElement("tbody");
+/*Shuttle.prototype.init = function() {
this.shuttle = this.shuttleTbody;
this.addList(this.shuttleItems);
this.shuttleTable.appendChild(this.shuttle)
this.container.appendChild(this.shuttleTable);
-
- var obj = this;
- this.focusKeeper.onkeydown = function(e) {
- obj.onkeydownHandler(window.event || e);
- }
}
Shuttle.prototype.rebuild = function() {
@@ -282,8 +310,30 @@
td.textContent = selectItem._label;
}
selectItem._node = tr;
+}*/
+
+Shuttle.prototype.toString = function() {
+ var result = new Array();
+ for (var i = 0; i < this.shuttleItems.length; i++) {
+ var item = this.shuttleItems[i];
+ result.push(item._id);
+ if (item._selected) {
+ result.push(Shuttle.SELECTION_MARKER);
+ }
+ if (this.activeItem.rowIndex == item._node.rowIndex) {
+ result.push(Shuttle.ACTIVITY_MARKER);
+ }
+ if (i != (this.shuttleItems.length - 1)) {
+ result.push(Shuttle.ITEM_SEPARATOR);
+ }
+ }
+ return result.join("");
}
+Shuttle.prototype.saveState = function() {
+ this.valueKeeper.value = this.toString();
+}
+
Shuttle.prototype.compareByLabel = function(obj1, obj2) {
obj1 = obj1._label;
obj2 = obj2._label;
Modified:
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/SelectItem.js
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/SelectItem.js 2007-11-01
18:39:02 UTC (rev 3696)
+++
trunk/sandbox/ui/orderingList/src/main/resources/org/richfaces/renderkit/html/scripts/SelectItem.js 2007-11-01
20:38:48 UTC (rev 3697)
@@ -1,20 +1,6 @@
-SelectItem = function(label, value, description, id, selected, node) {
+SelectItem = function(label, id, selected, node) {
this._label = label;
- this._value = value;
this._node = node;
- this._description = description;
- if (id == null) {
- this._id = this.generateId();
- } else {
- this._id = id;
- }
+ this._id = id;
this._selected = selected;
-}
-
-SelectItem.ITEM_ID_PREFIX = "row_";
-SelectItem.PREV_ID = 0;
-
-SelectItem.prototype.generateId = function() {
- SelectItem.PREV_ID++;
- return SelectItem.ITEM_ID_PREFIX.concat(SelectItem.PREV_ID);
}
\ No newline at end of file
Modified:
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx
===================================================================
---
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx 2007-11-01
18:39:02 UTC (rev 3696)
+++
trunk/sandbox/ui/orderingList/src/main/templates/org/richfaces/htmlOrderingList.jspx 2007-11-01
20:38:48 UTC (rev 3697)
@@ -16,22 +16,47 @@
</h:scripts>
<f:clientid var="clientId"/>
- <div id="#{clientId}"
onclick="Shuttle.setFocus('focusKeeper')">
- <input id="focusKeeper" type="button" value=""
style="position: absolute; top: -100; left: -100;"
name="focusKeeper"/>
- <vcp:body>
- <f:call name="renderChildren" />
- </vcp:body>
+ <script type="text/javascript">
+ function init() {
+ var shuttle = new Shuttle('#{clientId}', '#{clientId}internal_tab',
'#{clientId}focusKeeper', '#{clientId}valueKeeper');
+ Shuttle.setFocus('#{clientId}focusKeeper');
+ document.getElementById('up').onclick = function()
{shuttle.moveSelectedItems('up');};
+ document.getElementById('down').onclick = function()
{shuttle.moveSelectedItems('down');};
+ document.getElementById('first').onclick = function()
{shuttle.moveSelectedItems('first');};
+ document.getElementById('last').onclick = function()
{shuttle.moveSelectedItems('last');};
+ document.getElementById('#{clientId}table').onclick = function(e)
{shuttle.onclickHandler(window.event || e);}
+ }
+ </script>
+
+ <div id="#{clientId}"
onclick="Shuttle.setFocus('#{clientId}focusKeeper')">
+ <input id="#{clientId}focusKeeper" type="button"
value="" style="position: absolute; left: -32767;"
name="focusKeeper"/>
+ <input id="#{clientId}valueKeeper" type="hidden"
name="valueKeeper" value=""/>
- <a href="#"
onclick="shuttle.sort();">Header</a><br/>
- <a href="#"
onclick="shuttle.moveSelectedItems('up');">up</a><br/>
- <a href="#"
onclick="shuttle.moveSelectedItems('down');">down</a><br/>
- <a href="#"
onclick="shuttle.moveSelectedItems('first');">first</a><br/>
- <a href="#"
onclick="shuttle.moveSelectedItems('last');">last</a>
+ <table id="#{clientId}table" cellpadding="0"
cellspacing="0" class="">
+ <tbody id="#{clientId}tbody">
+ <tr>
+ <td>
+ <div class="">
+ <table id="#{clientId}internal_tab" cellpadding="0"
cellspacing="0" class="">
+ <vcp:body>
+ <f:call name="renderChildren" />
+ </vcp:body>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <a id="sortLabel" href="#">Header</a><br/>
+ <a id="up" href="#" >up</a><br/>
+ <a id="down" href="#" >down</a><br/>
+ <a id="first" href="#" >first</a><br/>
+ <a id="last" href="#" >last</a>
</div>
<script type="text/javascript">
- #{this:initJSShuttleObject(context, component)}
document.body.onselectstart = function() {return false;};
document.body.className = "body";
- document.body.onload = Shuttle.setFocus('focusKeeper');
+ document.body.onload = init();
</script>
</f:root>
\ No newline at end of file