Author: pyaschenko
Date: 2010-07-29 11:18:41 -0400 (Thu, 29 Jul 2010)
New Revision: 18281
Modified:
root/ui-sandbox/inputs/trunk/combobox/src/main/java/org/richfaces/renderkit/ComboBoxRendererBase.java
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoComplete.js
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoCompleteBase.js
root/ui-sandbox/inputs/trunk/combobox/src/main/templates/comboBox.template.xml
Log:
https://jira.jboss.org/browse/RF-8875
tokens was added
some fixes
Modified:
root/ui-sandbox/inputs/trunk/combobox/src/main/java/org/richfaces/renderkit/ComboBoxRendererBase.java
===================================================================
---
root/ui-sandbox/inputs/trunk/combobox/src/main/java/org/richfaces/renderkit/ComboBoxRendererBase.java 2010-07-29
12:56:25 UTC (rev 18280)
+++
root/ui-sandbox/inputs/trunk/combobox/src/main/java/org/richfaces/renderkit/ComboBoxRendererBase.java 2010-07-29
15:18:41 UTC (rev 18281)
@@ -71,7 +71,9 @@
MethodExpression autocompleteMethod = component.getAutocompleteMethod();
if (autocompleteMethod != null) {
try {
- String value = getInputValue(facesContext, component);
+ //String value = getInputValue(facesContext, component);
+ Map<String, String> requestParameters =
facesContext.getExternalContext().getRequestParameterMap();
+ String value = requestParameters.get(component.getClientId(facesContext)
+ "Value");
itemsObject = autocompleteMethod.invoke(facesContext.getELContext(),
new Object[] {facesContext, component, value});
} catch (ELException e) {
Modified:
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoComplete.js
===================================================================
---
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoComplete.js 2010-07-29
12:56:25 UTC (rev 18280)
+++
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoComplete.js 2010-07-29
15:18:41 UTC (rev 18281)
@@ -73,9 +73,10 @@
$super.constructor.call(this, componentId, componentId+ID.SELECT, fieldId, options);
this.attachToDom(componentId);
this.options = $.extend(this.options, defaultOptions, options);
- this.inputValue = this.getInputValue();
+ this.value = this.__getSubValue();
this.index = -1;
this.isFirstAjax = true;
+ updateTokenOptions.call(this);
bindEventHandlers.call(this);
updateItemsList.call(this, "");
};
@@ -88,20 +89,23 @@
var defaultOptions = {
selectedItemClass:'cb_select',
- autoFill:true,
+ autoFill:false,
minChars:1,
selectFirst:true,
ajaxMode:true,
- attachToBody:true,
- tokens: ", "
+ tokens: ",",
+ attachToBody:true
};
var ID = {
SELECT:'List',
- ITEMS:'Items'
+ ITEMS:'Items',
+ VALUE:'Value'
};
var REGEXP_TRIM = /^[\n\s]*(.*)[\n\s]*$/;
+ var REGEXP_TOKEN_LEFT;
+ var REGEXP_TOKEN_RIGHT;
var getData = function (nodeList) {
var data = [];
@@ -110,6 +114,15 @@
});
return data;
}
+
+ var updateTokenOptions = function () {
+ this.useTokens = (typeof this.options.tokens == "string" &&
this.options.tokens.length>0);
+ if (this.useTokens) {
+ var escapedTokens = this.options.tokens.split('').join("\\");
+ REGEXP_TOKEN_LEFT = new RegExp('[^'+escapedTokens+']+$','i');
+ REGEXP_TOKEN_RIGHT = new RegExp('['+escapedTokens+']','i');
+ };
+ };
var bindEventHandlers = function () {
rf.Event.bind(rf.getDomElement(this.id+ID.ITEMS).parentNode,
"click"+this.namespace+" mouseover"+this.namespace, onMouseAction,
this);
@@ -165,13 +178,14 @@
}
};
- var callAjax = function(event) {
+ var callAjax = function(event, value) {
$(rf.getDomElement(this.id+ID.ITEMS)).removeData().empty();
+ rf.getDomElement(this.id+ID.VALUE).value = value;
var _this = this;
var ajaxSuccess = function (event) {
- updateItemsList.call(_this, _this.inputValue, event.componentData &&
event.componentData[_this.id]);
+ updateItemsList.call(_this, _this.value, event.componentData &&
event.componentData[_this.id]);
if (_this.isVisible && _this.options.selectFirst) {
selectItem.call(_this, 0);
}
@@ -223,36 +237,35 @@
var item = this.items.eq(this.index);
item.addClass(this.options.selectedItemClass);
scrollToSelectedItem.call(this);
- !noAutoFill && autoFill.call(this, this.inputValue,
getSelectedItemValue.call(this));
+ !noAutoFill && autoFill.call(this, this.value,
getSelectedItemValue.call(this));
};
var changeValue = function (event, value) {
selectItem.call(this);
- if (typeof value == "undefined") {
- // called from show method, not actually value changed
- if (this.items.length==0 && this.inputValue.length>=this.options.minChars
&& this.isFirstAjax) {
- this.options.ajaxMode && callAjax.call(this, event);
- }
- return;
- }
+ // value is undefined if called from AutoCompleteBase onChange
+ var subValue = (typeof value == "undefined") ? this.__getSubValue() : value;
// TODO: ajax call here if needed
- if ((!this.cache || value.toLowerCase().indexOf(this.cache.key.toLowerCase())!=0 ||
this.inputValue.length==0) &&
- value.length>=this.options.minChars) {
- this.inputValue = value;
- this.options.ajaxMode && callAjax.call(this, event);
+ if ((!this.cache || subValue.length==0 ||
subValue.toLowerCase().indexOf(this.cache.key.toLowerCase())!=0) &&
+ subValue.length>=this.options.minChars) {
+ this.value = subValue;
+ this.options.ajaxMode && callAjax.call(this, event, subValue);
return;
}
- var newItems = this.cache.getItems(value);
+ var newItems = this.cache.getItems(subValue);
this.items = $(newItems);
//TODO: works only with simple markup, not with <tr>
$(rf.getDomElement(this.id+ID.ITEMS)).empty().append(newItems);
this.index = -1;
- this.inputValue = value;
+ this.value = subValue;
if (this.options.selectFirst) {
- selectItem.call(this, 0, false, event.which == rf.KEYS.BACKSPACE);
+ if (event.which == rf.KEYS.RETURN || event.type == "click") {
+ this.setInputValue(subValue);
+ } else {
+ selectItem.call(this, 0, false, event.which == rf.KEYS.BACKSPACE);
+ }
}
};
@@ -263,6 +276,45 @@
}
return undefined;
};
+
+ var getSubValue = function () {
+ if (this.useTokens) {
+ var field = rf.getDomElement(this.fieldId);
+ var value = field.value;
+ var cursorPosition = rf.Selection.getStart(field);
+ var beforeCursorStr = value.substring(0, cursorPosition);
+ var afterCursorStr = value.substring(cursorPosition);
+ var r = REGEXP_TOKEN_LEFT.exec(beforeCursorStr);
+ var result = "";
+ if (r) {
+ result = r[0];
+ }
+ r = afterCursorStr.search(REGEXP_TOKEN_RIGHT);
+ if (r==-1) r = afterCursorStr.length;
+ result += afterCursorStr.substring(0, r);
+
+ return result;
+ } else {
+ return this.getInputValue();
+ }
+ };
+
+ var updateInputValue = function (value) {
+ var field = rf.getDomElement(this.fieldId);
+ var inputValue = field.value;
+ var cursorPosition = rf.Selection.getStart(field);
+ var beforeCursorStr = inputValue.substring(0, cursorPosition);
+ var afterCursorStr = inputValue.substring(cursorPosition);
+ var pos = beforeCursorStr.search(REGEXP_TOKEN_LEFT);
+ var startPos = pos!=-1 ? pos : 0;
+ pos = afterCursorStr.search(REGEXP_TOKEN_RIGHT);
+ var endPos = pos!=-1 ? pos : inputValue.length;
+ field.focus();
+ field.value = inputValue.substring(0, startPos) + value +
afterCursorStr.substring(endPos);
+ rf.Selection.setCaretTo(field, cursorPosition+endPos);
+ return field.value;
+ };
+
/*
* Prototype definition
*/
@@ -276,6 +328,22 @@
* Protected methods
*/
__changeValue: changeValue,
+ __updateState: function () {
+ var subValue = this.__getSubValue();
+ // called from onShow method, not actually value changed
+ if (this.items.length==0 && subValue.length>=this.options.minChars
&& this.isFirstAjax) {
+ this.options.ajaxMode && callAjax.call(this, event, subValue);
+ }
+ return;
+ },
+ __getSubValue: getSubValue,
+ __updateInputValue: function (value) {
+ if (this.useTokens) {
+ return updateInputValue.call(this, value);
+ } else {
+ return $super.__updateInputValue.call(this, value);
+ }
+ },
/*
* Override abstract protected methods
*/
@@ -300,8 +368,7 @@
rf.getDomElement(this.fieldId).focus();
},
__onShow: function (event) {
- if (this.items && this.items.length>0) {
- //??TODO it's nessesary only if not changed value
+ if (event.which != rf.KEYS.BACKSPACE && this.items &&
this.items.length>0) {
if (this.index!=0 && this.options.selectFirst) {
selectItem.call(this, 0);
}
Modified:
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoCompleteBase.js
===================================================================
---
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoCompleteBase.js 2010-07-29
12:56:25 UTC (rev 18280)
+++
root/ui-sandbox/inputs/trunk/combobox/src/main/resources/META-INF/resources/org.richfaces/AutoCompleteBase.js 2010-07-29
15:18:41 UTC (rev 18281)
@@ -107,7 +107,6 @@
this.hide(event);
} else {
onShow.call(this, event);
- //rf.getDomElement(this.fieldId).focus();
}
};
@@ -136,14 +135,14 @@
//TODO: is it needed to chesk keys?
if (event.which == rf.KEYS.LEFT || event.which == rf.KEYS.RIGHT || flag) {
if (flag) {
- this.__changeValue(event, value);
- onShow.call(this, event, true);
+ this.__changeValue(event);
+ onShow.call(this, event);
}
}
};
- var onShow = function (event, noChangeValue) {
- !noChangeValue && this.__changeValue(event);
+ var onShow = function (event) {
+ this.__updateState(event);
this.show(event);
};
@@ -249,7 +248,7 @@
return this.namespace;
},
getInputValue: function () {
- return this.fieldId ? rf.getDomElement(this.fieldId).value : undefined;
+ return this.fieldId ? rf.getDomElement(this.fieldId).value : "";
},
setInputValue: function (value) {
this.currentValue = this.__updateInputValue(value);
Modified: root/ui-sandbox/inputs/trunk/combobox/src/main/templates/comboBox.template.xml
===================================================================
---
root/ui-sandbox/inputs/trunk/combobox/src/main/templates/comboBox.template.xml 2010-07-29
12:56:25 UTC (rev 18280)
+++
root/ui-sandbox/inputs/trunk/combobox/src/main/templates/comboBox.template.xml 2010-07-29
15:18:41 UTC (rev 18281)
@@ -15,6 +15,7 @@
<cc:implementation>
<div id="#{clientId}" class="cb_field_width cb_field">
+ <input id="#{clientId}Value" name="#{clientId}Value"
type="hidden" class="cb_font cb_input" />
<div style="position : relative; overflow : hidden; text-align :
left; padding-right : 21px;">
<input id="#{clientId}Input" name="#{clientId}"
type="text" class="cb_font cb_input" />
<div id="#{clientId}Button" class="cb_button">