Author: vmolotkov
Date: 2008-02-11 09:18:39 -0500 (Mon, 11 Feb 2008)
New Revision: 6007
Modified:
trunk/sandbox/ui/inplaceInput/src/main/config/component/inplaceinput.xml
trunk/sandbox/ui/inplaceInput/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/css/inplaceinput.xcss
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/scripts/inplaceinput.js
trunk/sandbox/ui/inplaceInput/src/main/templates/inplaceinput.jspx
Log:
inplaceInput functionality
Modified: trunk/sandbox/ui/inplaceInput/src/main/config/component/inplaceinput.xml
===================================================================
--- trunk/sandbox/ui/inplaceInput/src/main/config/component/inplaceinput.xml 2008-02-11
14:05:40 UTC (rev 6006)
+++ trunk/sandbox/ui/inplaceInput/src/main/config/component/inplaceinput.xml 2008-02-11
14:18:39 UTC (rev 6007)
@@ -63,11 +63,6 @@
<defaultvalue>false</defaultvalue>
</property>
<property>
- <name>apllyFromControlsOnly</name>
- <classname>boolean</classname>
- <defaultvalue>false</defaultvalue>
- </property>
- <property>
<name>editEvent</name>
<classname>java.lang.String</classname>
<defaultvalue><![CDATA["click"]]></defaultvalue>
@@ -89,6 +84,11 @@
<name>onviewactivated</name>
<classname>java.lang.String</classname>
</property>
+ <property>
+ <name>selectOnEdit</name>
+ <classname>boolean</classname>
+ <defaultvalue>false</defaultvalue>
+ </property>
</properties>
</component>
</components>
Modified:
trunk/sandbox/ui/inplaceInput/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java
===================================================================
---
trunk/sandbox/ui/inplaceInput/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java 2008-02-11
14:05:40 UTC (rev 6006)
+++
trunk/sandbox/ui/inplaceInput/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java 2008-02-11
14:18:39 UTC (rev 6007)
@@ -1,5 +1,13 @@
package org.richfaces.renderkit;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.javascript.ScriptString;
+import org.ajax4jsf.javascript.ScriptUtils;
import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -19,4 +27,44 @@
protected Class<UIInplaceInput> getComponentClass() {
return UIInplaceInput.class;
}
+
+ public String getAsEventHandler(FacesContext context, UIComponent component, String
attributeName) {
+ String event = (String) component.getAttributes().get(attributeName);
+ ScriptString result = JSReference.NULL;
+
+ if (event != null) {
+ event = event.trim();
+
+ if (event.length() != 0) {
+ JSFunctionDefinition function = new JSFunctionDefinition();
+ function.addParameter("event");
+ function.addToBody(event);
+
+ result = function;
+ }
+ }
+ return ScriptUtils.toScript(result);
+ }
+
+ protected String getConvertedStringValue(FacesContext context, UIInplaceInput
component, Object value) {
+ Converter converter = component.getConverter();
+
+ if (converter == null) {
+ if (value == null) {
+ return "";
+ } else if (value instanceof String) {
+ return (String) value;
+ }
+
+ Class converterType = value.getClass();
+ if (converterType != null ) {
+ converter = context.getApplication().createConverter(converterType);
+ }
+
+ if (converter == null) {
+ return value.toString();
+ }
+ }
+ return converter.getAsString(context, component, value);
}
+}
Modified:
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/css/inplaceinput.xcss
===================================================================
---
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/css/inplaceinput.xcss 2008-02-11
14:05:40 UTC (rev 6006)
+++
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/css/inplaceinput.xcss 2008-02-11
14:18:39 UTC (rev 6007)
@@ -5,9 +5,47 @@
<f:verbatim>
<![CDATA[
+.rich-inplace {
+}
+.rich-inplace-changed {
+ background-color:#F1F1F1;
+ border-bottom:1px dashed #000000;
+ padding-left:3px;
+ padding-right:3px;
+ white-space:nowrap;
+
+ background-image:url(/inplaceInput-sample/images/mark_open.gif);
+ background-position:left top;
+ background-repeat:no-repeat;
+}
+
+.rich-inplace-view {
+ background-color:#F1F1F1;
+ border-bottom:1px dashed #000000;
+ padding-left:3px;
+ padding-right:3px;
+ white-space:nowrap;
+}
+
+.rich-inplace-edit {
+ /*position:relative;*/
+ width:100px;
+}
+
+.rich-inplace-field {
+ background:#FFF281 none repeat scroll 0%;
+ border:0px none;
+ /*left:0px;
+ top:0px;
+ position:absolute;*/
+ margin:0px;
+ padding:0px 0px 0px 3px;
+ width:100px;
+}
]]>
</f:verbatim>
+
</f:template>
Modified:
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/scripts/inplaceinput.js
===================================================================
---
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/scripts/inplaceinput.js 2008-02-11
14:05:40 UTC (rev 6006)
+++
trunk/sandbox/ui/inplaceInput/src/main/resources/org/richfaces/renderkit/html/scripts/inplaceinput.js 2008-02-11
14:18:39 UTC (rev 6007)
@@ -4,33 +4,165 @@
Richfaces.InplaceInput.prototype = {
- initialize: function(clientId, temValueKeepId, valueKeepId, attributes, events) {
+ initialize: function(clientId, temValueKeepId, valueKeepId, attributes, events, classes)
{
this.inplaceInput = $(clientId);
this.tempValueKeeper = $(temValueKeepId);
this.valueKeeper = $(valueKeepId);
this.attributes = attributes;
+ this.events = events;
+ this.classes = classes;
+
+ this.currentText = this.getCurrentText();
+
this.currentState = Richfaces.InplaceInput.STATES[0];
this.initHandlers();
+ this.initEvents();
},
initHandlers : function() {
this.inplaceInput.observe(this.attributes.editEvent,
function(e){this.switchingStatesHandler(e);}.bindAsEventListener(this));
+ this.tempValueKeeper.observe("blur",
function(e){this.tmpValueBlurHandler(e);}.bindAsEventListener(this));
},
- switchingStatesHandler : function() {
+ initEvents : function() {
+ for (var e in this.events) {
+ if (e) {
+ this.inplaceInput.observe("rich:" + e, this.events[e]);
+ }
+ }
+ },
+
+ /*
+ * HANDLERS
+ */
+ switchingStatesHandler : function(e) {
+ var target;
+ if (e.target) {
+ target = e.target;
+ } else if (target = e.srcElement) {
+ target = e.srcElement;
+ } else {
+ //TO DO: to catch this exception
+ }
+ if (target.tagName.toLowerCase() == "input") {
+ return;
+ }
+
+ if (this.events.oneditactivation) {
+ this.inplaceInput.fire("rich:oneditactivation", {});
+ }
this.endViewState();
+ this.startEditableState();
+ if (this.events.oneditactivated) {
+ this.inplaceInput.fire("rich:oneditactivated", {});
+ }
+ },
+
+ tmpValueBlurHandler : function() {
+ var userValue = this.tempValueKeeper.value;
+ if (this.events.onviewactivation) {
+ this.inplaceInput.fire("rich:onviewactivation", {});
+ }
+ this.endEditableState();
+ this.applyUserValue();
+ if (this.valueKeeper.value != userValue) {
+ this.startChangedState();
+ } else {
+ this.startViewState();
+ }
+ if (this.events.onviewactivated) {
+ this.inplaceInput.fire("rich:onviewactivated", {});
+ }
+ },
+
+ /**
+ * STATE'S API
+ */
+ endViewState : function() {
+ this.deleteViewArtifacts();
+ },
+
+ endEditableState : function() {
+ this.tempValueKeeper.hide();
+ },
+
+ endChangedState : function() {
+ this.deleteViewArtifacts();
+ },
+
+ startEditableState : function() {
+ this.currentState = Richfaces.InplaceInput.STATES[1];
+ this.inplaceInput.className = this.classes.COMPONENT.EDITABLE;
this.tempValueKeeper.show();
-
- this.currentState = Richfaces.InplaceInput.STATES[1];
+ this.tempValueKeeper.focus();
+ if (this.attributes.selectOnEdit) {
+ Richfaces.InplaceInput.textboxSelect(this.tempValueKeeper, 0,
this.tempValueKeeper.value.length);
+ }
},
- endViewState : function() {
- var viewValue = (this.inplaceInput.textContent) ? this.inplaceInput.textContent :
this.inplaceInput.textNode;
- this.inplaceInput.removeNode(viewValue);
+ startViewState : function() {
+ this.currentState = Richfaces.InplaceInput.STATES[0];
+ this.createNewText(this.currentText);
+ this.inplaceInput.className = this.classes.COMPONENT.VIEW;
+ },
+
+ startChangedState : function () {
+ this.currentState = Richfaces.InplaceInput.STATES[2];
+ this.createNewText(this.valueKeeper.value);
+ this.inplaceInput.className = this.classes.COMPONENT.CHANGED;
+ },
+
+ /**
+ * UTILITIES
+ */
+ applyUserValue : function() {
+ var newValue = this.tempValueKeeper.value;
+ if (newValue == "") {
+ this.setDefaultText();
+ this.valueKeeper.value = "";
+ } else if (newValue != this.valueKeeper.value) {
+ this.currentText = newValue;
+ this.valueKeeper.value = newValue;
+ }
+ },
+
+ setDefaultText : function() {
+ this.currentText = this.attributes.defaultLabel;
+ },
+
+ deleteViewArtifacts : function () {
+ this.inplaceInput.removeChild(this.inplaceInput.childNodes[2]);
+ },
+
+ getCurrentText : function() {
+ return this.inplaceInput.childNodes[2];
+ },
+
+ createNewText : function(text) {
+ this.inplaceInput.appendChild(document.createTextNode(text));
}
};
-Richfaces.InplaceInput.STATES = [0, 1, 2];// 0 - view, 1- editable, 2 - changed
\ No newline at end of file
+Richfaces.InplaceInput.STATES = [0, 1, 2];// 0 - view, 1- editable, 2 - changed
+Richfaces.InplaceInput.CLASSES = {
+ COMPONENT : {CHANGED : "rich-inplace rich-inplace-changed",
+ VIEW : "rich-inplace rich-inplace-view",
+ EDITABLE : "rich-inplace rich-inplace-edit"}
+}
+
+Richfaces.InplaceInput.textboxSelect = function(oTextbox, iStart, iEnd) {
+ if (Prototype.Browser.IE) {
+ var oRange = oTextbox.createTextRange();
+ oRange.moveStart("character", iStart);
+ oRange.moveEnd("character", -oTextbox.value.length + iEnd);
+ oRange.select();
+ } else if (Prototype.Browser.Gecko) {
+ oTextbox.setSelectionRange(iStart, iEnd);
+ } else {
+ //FIXME
+ oTextbox.setSelectionRange(iStart, iEnd);
+ }
+}
\ No newline at end of file
Modified: trunk/sandbox/ui/inplaceInput/src/main/templates/inplaceinput.jspx
===================================================================
--- trunk/sandbox/ui/inplaceInput/src/main/templates/inplaceinput.jspx 2008-02-11 14:05:40
UTC (rev 6006)
+++ trunk/sandbox/ui/inplaceInput/src/main/templates/inplaceinput.jspx 2008-02-11 14:18:39
UTC (rev 6007)
@@ -18,29 +18,46 @@
</h:scripts>
<f:clientid var="clientId" />
- <span id="#{clientId}" class="rich-inplace">
- #{component.attributes["value"]}
- <input id='#{clientId}tempValue"'
- class='rich-inplace-input'
+ <jsp:scriptlet>
+ <![CDATA[
+ Object value = component.getAttributes().get("value");
+ Object fieldValue = component.getAttributes().get("value");
+ value = getConvertedStringValue(context, component,value);
+ if (value == null) {
+ fieldValue = "";
+ value = component.getAttributes().get("defaultLabel");
+ }
+ if (value.equals("")) {
+ value = component.getAttributes().get("defaultLabel");
+ }
+ variables.setVariable("value", value);
+ variables.setVariable("fieldValue", fieldValue);
+ ]]>
+ </jsp:scriptlet>
+ <span id="#{clientId}" class="rich-inplace
rich-inplace-view">
+ <input id='#{clientId}tempValue'
+ class='rich-inplace-field'
style='display:none;'
type='text'
size='#{component.attributes["inputSize"]}'
maxlength='#{component.attributes["inputMaxLength"]}'
minlength='#{component.attributes["inputMinLength"]}'
- value='#{component.attributes["value"]}'/>
- <input id='#{clientId}value' type='hidden'
value='#{component.attributes["value"]}'/>
+ value='#{fieldValue}'/>
+ <input id='#{clientId}value' type='hidden'
value='#{fieldValue}'/>
+ #{value}
</span>
<script type="text/javascript">
var attributes = {defaultLabel :
'#{component.attributes["defaultLabel"]}',
showControls : '#{component.attributes["showControls"]}',
apllyFromControlsOnly :
'#{component.attributes["apllyFromControlsOnly"]}',
- editEvent : '#{component.attributes["editEvent"]}'};
+ editEvent : '#{component.attributes["editEvent"]}',
+ selectOnEdit : '#{component.attributes["selectOnEdit"]}'};
- var events = {oneditactivation :
'#{component.attributes["oneditactivation"]}',
- onviewactivation :
'#{component.attributes["onviewactivation"]}',
- oneditactivated : '#{component.attributes["onviewactivation"]}',
- onviewactivated :
'#{component.attributes["onviewactivated"]}'};
+ var events = {oneditactivation : #{this:getAsEventHandler(context, component,
"oneditactivation")},
+ onviewactivation : #{this:getAsEventHandler(context, component,
"onviewactivation")},
+ oneditactivated : #{this:getAsEventHandler(context, component,
"oneditactivated")},
+ onviewactivated : #{this:getAsEventHandler(context, component,
"onviewactivated")}};
- var inplaceInput = new Richfaces.InplaceInput('#{clientId}',
'#{clientId}tempValue', '#{clientId}value', attributes, events);
+ var inplaceInput = new Richfaces.InplaceInput('#{clientId}',
'#{clientId}tempValue', '#{clientId}value', attributes, events,
Richfaces.InplaceInput.CLASSES);
</script>
</f:root>
\ No newline at end of file