AutoTab to next field when field is full [message #1772647] |
Wed, 13 September 2017 14:36 |
|
We would like to support an auto-tab feature for fields so that a field defined as auto-tab will jump the focus to the next field in the tab sequence when it is 'full' i.e. reached its' text limit (Text#setTextLimit method).
We currently do this with a thin SWT.Modify listener on the field, which in principle works OK... but... because of the network latency lag, it takes a moment for the event to be triggered, and the user may have started typing in more input which is then lost because setTextLimit is limiting any more characters from being entered... but I'd like them to go to the next field.
What I'm looking for (I think) is a client-side feature that does the tabbing, so it is immediate.
Is this possible?
Thanks, John
---
Just because you can doesn't mean you should
|
|
|
Re: AutoTab to next field when field is full [message #1772667 is a reply to message #1772647] |
Wed, 13 September 2017 16:48 |
|
The Client Scripting API should be what you're looking for. You can write javascript that will run on the client to interact with widgets:
http://www.eclipse.org/rap/developers-guide/devguide.php?topic=scripting.html&version=3.2
Hope that helps,
Cole Markham
CCM Computing
|
|
|
Re: AutoTab to next field when field is full [message #1772727 is a reply to message #1772667] |
Thu, 14 September 2017 12:11 |
|
Thanks Cole, seems like a good place to start. I've implemented part of this and it is detecting the limit being reached OK, but how (in JS) do I trigger the TAB to move to the next field?
For info, here's what I've done so far:
In Java, server-side:
public static void addAutoTabBehavior(Text text, int limitLen) {
ClientListener listener = MyRWTScriptListenerAutoTab.getInstance();
text.addListener(SWT.Modify, listener);
WidgetUtil.registerDataKeys("myFieldLengthLimit");
text.setData("myFieldLengthLimit", limitLen);
}
My ScriptListener is pretty simple:
import org.eclipse.rap.rwt.SingletonUtil;
import org.eclipse.rap.rwt.scripting.ClientListener;
@SuppressWarnings("serial")
public class MyRWTScriptListenerAutoTab extends ClientListener {
public static MyRWTScriptListenerAutoTab getInstance() {
return SingletonUtil.getSessionInstance(MyRWTScriptListenerAutoTab.class);
}
private MyRWTScriptListenerAutoTab() {
super(getText());
}
private static String getText() {
String scriptCode = ResourceLoaderUtil.readTextContent(CustomBehaviors.RESOURCES_PREFIX + "AutoTab.js");
return(scriptCode);
}
}
On the JS client-side:
var handleEvent = function(event) {
switch(event.type) {
case SWT.Modify:
var limitLen = event.widget.getData("myFieldLengthLimit");
handleModifyEvent(event, limitLen);
break;
}
};
var handleModifyEvent = function(event, limitLen) {
var text = event.widget.getText();
var lenNow = text.length;
if (limitLen == lenNow) {
console.log("text limitLen=" + limitLen + " vs lenNow=" + lenNow + " - needs to trigger AUTOTAB");
}
};
This works in as far as I get the message on the console saying that the AUTOTAB needs to be done, but how?
Is there some way to send a TAB keypress to the browser, or is there a better way to do this with the RAP JS?
Thanks, John
---
Just because you can doesn't mean you should
|
|
|
|
Re: AutoTab to next field when field is full [message #1772740 is a reply to message #1772730] |
Thu, 14 September 2017 14:11 |
|
Well, this sort of works, but still need some help...
When I configure my tab sequence in Java, I ensure that any field with AutoTab required has the clientscripting listener as shown above, and I set another attribute to the RAP Id of the next widget in sequence:
WidgetUtil.registerDataKeys("myNextFocusControl");
...
String rapId = WidgetUtil.getId(nextControl);
text.setData("myNextFocusControl", rapId);
Then on the JS side:
...
var nextControl = event.widget.getData("myNextFocusControl");
if (nextControl != null) {
var ctl = rap.getObject(nextControl);
if (ctl != null) {
ctl.forceFocus();
}
}
...
Fine, and this works for a simple application.
However, we have constant changes to which controls are enabled/disabled through the life of the UI, so this technique would require me to recalculate the tab sequence and send appropriate nextControl data to the client each time enabling changes.
Yes, this is possible, but seems highly inefficient and potentially client-server slow!
It would be better to have JS logic that validated that the nextControl for focus was not read-only (disabled input) and if so, find that control's nextControl instead (repeating until it finds a control that is not disabled).
This would then all be client-side, so fast.
I'm just not sure how to do this, as I'm no JS expert. I would guess I'd want something like this below, but it doesn't return anything whether the control is disabled or not:
if (ctl.$input.disabled) ...
Hopefully that all makes sense - just trying to avoid unnecessary c/s comms and UI changes when there really is no need, and performance is important here.
Thanks in advance for useful ideas...
John
---
Just because you can doesn't mean you should
|
|
|
|
Re: AutoTab to next field when field is full [message #1772785 is a reply to message #1772763] |
Fri, 15 September 2017 08:36 |
|
Hi Chris,
Looks interesting, but I'd rather not use unsupported/undocumented features as it could break in the future, and I won't remember what or why we did it!
I've found a different approach instead, since the forceFocus method returns whether it was successful or not (seems reliable), I can traverse my way through the controls using the same technique until I reach one that will take the forceFocus successfully... this approach seems to work well:
var nextControl = event.widget.getData("myNextFocusControl");
while (nextControl != null) {
var ctl = rap.getObject(nextControl);
if (ctl != null) {
var suc = ctl.forceFocus();
if (suc) {
return;
}
// move onto the next control in the list
// to see if we can focus that one instead
// (prev might be disabled)
nextControl = ctl.getData("myNextFocusControl");
}
}
John
---
Just because you can doesn't mean you should
|
|
|
Powered by
FUDForum. Page generated in 0.07066 seconds