Author: vmolotkov
Date: 2007-12-27 16:10:45 -0500 (Thu, 27 Dec 2007)
New Revision: 5053
Modified:
trunk/sandbox/ui/combobox/src/main/java/org/richfaces/renderkit/ComboBoxBaseRenderer.java
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/css/combobox.xcss
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/scripts/combobox.js
trunk/sandbox/ui/combobox/src/main/templates/combobox.jspx
Log:
client-side functionality
Modified:
trunk/sandbox/ui/combobox/src/main/java/org/richfaces/renderkit/ComboBoxBaseRenderer.java
===================================================================
---
trunk/sandbox/ui/combobox/src/main/java/org/richfaces/renderkit/ComboBoxBaseRenderer.java 2007-12-27
20:54:32 UTC (rev 5052)
+++
trunk/sandbox/ui/combobox/src/main/java/org/richfaces/renderkit/ComboBoxBaseRenderer.java 2007-12-27
21:10:45 UTC (rev 5053)
@@ -31,12 +31,12 @@
return UIComboBox.class;
}
- protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent
component) throws IOException {
+ /*protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent
component) throws IOException {
UIComboBox comboBox = (UIComboBox)component;
String popupId = comboBox.getClientId(context) + POPUP;
- writer.startElement(HTML.DIV_ELEM, comboBox);
- writer.writeAttribute(HTML.id_ATTRIBUTE, popupId, null);
- writer.writeAttribute(HTML.style_ATTRIBUTE, "display: none", null);
+ //writer.startElement(HTML.DIV_ELEM, comboBox);
+ //writer.writeAttribute(HTML.id_ATTRIBUTE, popupId, null);
+ //writer.writeAttribute(HTML.style_ATTRIBUTE, "display: none", null);
List <String> suggestionValues = comboBox.getSuggestionValues();
if (suggestionValues != null) {
@@ -46,11 +46,24 @@
}
}
- writer.endElement(HTML.DIV_ELEM);
- writer.startElement(HTML.SCRIPT_ELEM, component);
- writer.writeText(encodeScript(context, component,popupId), "script");
- writer.endElement(HTML.SCRIPT_ELEM);
+ //writer.endElement(HTML.DIV_ELEM);
+ //writer.startElement(HTML.SCRIPT_ELEM, component);
+ //writer.writeText(encodeScript(context, component,popupId),
"script");
+ //writer.endElement(HTML.SCRIPT_ELEM);
+ }*/
+
+ public void encodeItems( FacesContext context, UIComponent component) throws IOException
{
+ UIComboBox comboBox = (UIComboBox)component;
+ List <String> suggestionValues = comboBox.getSuggestionValues();
+ ResponseWriter writer = context.getResponseWriter();
+
+ if (suggestionValues != null) {
+ for (Iterator <String> iterator = suggestionValues.iterator();
iterator.hasNext();) {
+ String suggestion = iterator .next();
+ encodeSuggestion(writer, comboBox, suggestion);
+ }
+ }
}
protected void encodeSuggestion(ResponseWriter writer, UIComboBox comboBox, String
value) throws IOException{
Modified:
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/css/combobox.xcss
===================================================================
---
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/css/combobox.xcss 2007-12-27
20:54:32 UTC (rev 5052)
+++
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/css/combobox.xcss 2007-12-27
21:10:45 UTC (rev 5053)
@@ -1 +1,42 @@
-<?xml version="1.0" encoding="UTF-8"?>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<f:template
xmlns:f='http:/jsf.exadel.com/template'
+
xmlns:u='http:/jsf.exadel.com/template/util'
+
xmlns="http://www.w3.org/1999/xhtml" >
+
+<f:verbatim>
+<![CDATA[
+
+.rich-combobox-list {
+ z-index: 1000;
+ overflow: auto;
+ white-space:nowrap;
+}
+
+.rich-combobox-item {
+ border:1px solid #FFFFFF;
+ font-family:tahoma,arial,helvetica,sans-serif;
+ font-size:12px;
+ font-size-adjust:none;
+ font-stretch:normal;
+ font-style:normal;
+ font-variant:normal;
+ font-weight:normal;
+ line-height:normal;
+ overflow:hidden;
+ padding:2px;
+ white-space:nowrap;
+}
+
+.rich-combobox-item-normal {
+
+}
+
+.rich-combobox-item-selected {
+ background:#DFE8F6 none repeat scroll 0%;
+ border:1px dotted #A3BAE9 !important;
+ cursor:pointer;
+}
+
+]]>
+</f:verbatim>
+</f:template>
\ No newline at end of file
Modified:
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/scripts/combobox.js
===================================================================
---
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/scripts/combobox.js 2007-12-27
20:54:32 UTC (rev 5052)
+++
trunk/sandbox/ui/combobox/src/main/resources/org/richfaces/renderkit/html/scripts/combobox.js 2007-12-27
21:10:45 UTC (rev 5053)
@@ -2,8 +2,208 @@
Richfaces.ComboBox = Class.create();
Richfaces.ComboBox.prototype = {
- initialize: function(combobox, options) {
+ initialize: function(combobox, listId, fieldId, buttonId, classes, listWidth,
listHeight) {
this.combobox = $(combobox);
+ this.comboList = new Richfaces.ComboBoxList(listId, classes, listWidth, listHeight);
+ this.field = $(fieldId);
+ this.button = $(buttonId);
+
+ this.initCombobox();
+ },
+
+ initCombobox : function() {
+ this.button.observe("click",
function(e){this.clickHandler(e);}.bindAsEventListener(this));
+ this.field.observe("keydown",
function(e){this.keyboardManager(e);}.bindAsEventListener(this));
+ //this.field.observe("blur",
function(e){this.focusHandler(e);}.bindAsEventListener(this));
+ this.field.observe("change",
function(e){this.dataUpdating(e);}.bindAsEventListener(this));
+
+ this.comboList.list.observe("mousemove",
function(e){this.listListener(e)}.bindAsEventListener(this));
+ this.comboList.list.observe("click",
function(e){this.valueHandler(e);}.bindAsEventListener(this));
+ },
+
+ clickHandler : function(event) {
+ if (this.comboList.visible()) {
+ this.comboList.hide();
+ } else {
+ this.comboList.show();
+ }
+ this.field.focus();
+ },
+
+ listListener : function(event) {
+ //changes item's decoration
+ var item = this.comboList.getEventItem(event);
+ if (item) {
+ this.comboList.selectItem(this.comboList.getEventItem(event));
+ }
+ },
+
+ valueHandler : function(event) {
+ this.field.value = this.comboList.selectedItem.innerHTML;
+
+ this.comboList.hide();
+ },
+
+ keyboardManager : function(event) {
+ if ((event.keyCode == Event.KEY_UP) || (event.keyCode == Event.KEY_DOWN)) {
+ this.comboList.moveSelectedItem(event);
+ }
+ },
+
+ focusHandler : function(event) {
+ this.comboList.hide();
+ },
+
+ dataUpdating : function() {
+ this.comboList.setItems(this.comboList.dataFilter(this.field.value));
+ this.comboList.show();
}
+};
-};
+Richfaces.ComboBoxList = Class.create();
+Richfaces.ComboBoxList.prototype = {
+
+ initialize: function(listId, classes, width, height) {
+ this.list = $(listId);
+ this.items = this.getItems();
+
+ this.currentItems = this.items;
+
+ this.classes = classes;
+ this.selectedItem = null;
+
+ this.setSize(width, height);
+ },
+
+ getItems : function() {
+ return this.list.childNodes;
+ },
+
+ show : function() {
+ if (this.currentItems.length != 0) {
+ this.selectItem(this.currentItems[0]);
+ }
+ this.list.show();
+ },
+
+ hide : function() {
+ this.resetState();
+ this.list.hide();
+ },
+
+ visible : function() {
+ return this.list.visible();
+ },
+
+ setSize : function(width, height) {
+ this.list.style.width = width + "px";
+ this.list.style.height = height + "px";
+ },
+
+ scrolling : function(event) {
+ var increment;
+ var listTop = Richfaces.ComboBoxList.getElemXY(this.list).top;
+ var scrollTop = this.list.scrollTop;
+ var itemTop = Richfaces.ComboBoxList.getElemXY(this.selectedItem).top;
+
+ if ((event.keyCode == Event.KEY_UP) || (event.keyCode == 33)) {
+ increment = (itemTop - scrollTop) - listTop;
+ if (increment < 0) {
+ this.list.scrollTop += increment;
+ }
+ } else if ((event.keyCode == Event.KEY_DOWN) || (event.keyCode == 34)) {
+ var itemBottom = itemTop + this.selectedItem.offsetHeight;
+ var increment = (itemBottom - scrollTop) - (listTop + this.list.clientHeight);
+ if (increment > 0) {
+ this.list.scrollTop += increment;
+ }
+ }
+ Event.stop(event);
+ },
+
+ /* items library*/
+ selectItem : function(item) {
+ if (this.selectedItem) {
+ this.normalizeItem(this.selectedItem);
+ }
+
+ this.selectedItem = item;
+ this.changeItem(item, this.classes.ITEM.SELECTED);
+ },
+
+ normalizeItem : function(item) {
+ this.selectedItem = null;
+ this.changeItem(item, this.classes.ITEM.NORMAL);
+ },
+
+ changeItem : function(item, className) {
+ item.className = className;
+ },
+
+ getEventItem : function(event) {
+ var item = Event.findElement(event, "div");
+ if ((item == null) || (item.id == this.list.id)) {
+ return;
+ }
+ return item;
+ },
+
+ moveSelectedItem : function(event) {
+ var item = this.selectedItem;
+ if (event.keyCode == Event.KEY_UP) {
+ var prevItem = item.previousSibling;
+ if (prevItem) {
+ this.itemsRearrangement(item, prevItem);
+ }
+ } else if (event.keyCode == Event.KEY_DOWN) {
+ var nextItem = item.nextSibling;
+ if (nextItem) {
+ this.itemsRearrangement(item, nextItem);
+ }
+ }
+ this.scrolling(event);
+ },
+
+ itemsRearrangement : function(item, newItem) {
+ this.normalizeItem(item);
+ this.selectItem(newItem);
+ },
+
+ resetState : function() {
+ this.normalizeItem(this.selectedItem);
+ this.selectedItem = null;
+ },
+
+ setItems : function(newItems) {
+ this.currentItems = newItems;
+
+ this.list.innerHTML = newItems.join(""); //FIXME: to optimaize
+ },
+
+ dataFilter : function(text) {
+ var filteredData = new Array();
+ for (var i = 0; i < this.items.length; i++) {
+ var item = this.items[i];
+ if (item.innerHTML.substr(0, text.length).toLowerCase() == text.toLowerCase()) {
//FIXME: to optimaize
+ filteredData.push(item);
+ }
+ }
+ return filteredData;
+ },
+}
+
+Richfaces.ComboBoxList.getElemXY = function(elem) {
+ var x = elem.offsetLeft;
+ var y = elem.offsetTop;
+
+ for (var parent = elem.offsetParent; parent; parent = parent.offsetParent) {
+ x += parent.offsetLeft;
+ y += parent.offsetTop;
+ }
+ return {left: x, top: y};
+}
+
+Richfaces.ComboBoxList.CLASSES = {
+ ITEM : {NORMAL : "rich-combobox-item rich-combobox-item-normal", SELECTED :
"rich-combobox-item rich-combobox-item-selected"},
+ LIST : {}
+}
\ No newline at end of file
Modified: trunk/sandbox/ui/combobox/src/main/templates/combobox.jspx
===================================================================
--- trunk/sandbox/ui/combobox/src/main/templates/combobox.jspx 2007-12-27 20:54:32 UTC
(rev 5052)
+++ trunk/sandbox/ui/combobox/src/main/templates/combobox.jspx 2007-12-27 21:10:45 UTC
(rev 5053)
@@ -1,32 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
-<f:root
xmlns="http://www.w3.org/1999/xhtml"
-
xmlns:f="http://ajax4jsf.org/cdk/template"
- xmlns:c="
http://java.sun.com/jsf/core"
+<f:root
+
xmlns:f="http://ajax4jsf.org/cdk/template"
+ xmlns:c="
http://java.sun.com/jsf/core"
xmlns:ui="
http://ajax4jsf.org/cdk/ui"
- xmlns:vcp="
http://ajax4jsf.org/cdk/vcp"
+ xmlns:u="
http://ajax4jsf.org/cdk/u"
+ xmlns:jsp="
http://ajax4jsf.org/cdk/jsp"
+ xmlns:x="
http://ajax4jsf.org/cdk/x"
baseclass="org.richfaces.renderkit.ComboBoxBaseRenderer"
class="org.richfaces.renderkit.html.ComboBoxRenderer"
component="org.richfaces.component.UIComboBox">
+ <h:styles>css/combobox.xcss</h:styles>
<h:scripts>
- new
org.ajax4jsf.javascript.PrototypeScript(),/org/richfaces/renderkit/html/scripts/combobox.js
+ new org.ajax4jsf.javascript.PrototypeScript(),
+ scripts/combobox.js
</h:scripts>
- <f:resource name="org.richfaces.renderkit.html.images.SpinnerButtonDown"
var="down_arrow" />
-
+ <f:resource name="org.richfaces.renderkit.html.images.SpinnerButtonDown"
var="down_arrow" />
+
<f:clientid var="clientId" />
-
- <table cellpadding="0" cellspacing="0"
id="#{clientId}">
- <tbody>
- <tr>
- <td>
- <input type="text" id="#{clientId}_input"/>
- </td>
- <td style="padding: 0px 4px 0px 4px">
- <input type="image" src="#{down_arrow}"
id="#{clientId}_button" onclick="return false;"/>
- </td>
- </tr>
- </tbody>
- </table>
- <vcp:body/>
+ <div id="#{clientId}">
+ <div id="comboboxControl#{clientId}" class=""
style="position:relative;">
+ <input id="comboboxField#{clientId}" class=""
type="text" size="20" autocomplete="off"/>
+ <img id="comboboxButton#{clientId}" class=""
style="position:absolute; top:0pt; border:1px solid black;
height:22px;width:22px;" src="#{down_arrow}"/>
+ </div>
+ <div id="list#{clientId}" style="display:none"
class="rich-combobox-list">
+ <f:call name="encodeItems"/>
+ </div>
+ </div>
+ <script type="text/javascript">
+ var combobox = new Richfaces.ComboBox("#{clientId}",
+ "list#{clientId}",
+ "comboboxField#{clientId}",
+ "comboboxButton#{clientId}", Richfaces.ComboBoxList.CLASSES, 100,
150);
+ </script>
</f:root>
\ No newline at end of file