Hello,
I have a form with a TextField called “Name” and a Button for submitting the form. I’d like to set the Submit Button disabled at first. When user starts writing text to the Name TextField the Submit Button should get enabled. And if user clears the Name TextField, the Submit Button should get disabled.
How can I achieve this or is there other good workaround for this case?
ValueChangeListener of the TextField seems to be fired after the TextField has lost its focus and for me that is too late.
Currently we don’t really have any solution for this, other than creating/extending your own component. The client-side implementation of our TextField does not send any events to the server on keyboard events.
A very extreme workaround is to attach ActionHandlers for a containing Panel/Window for every possible key, which is rather cumbersome in itself, not to mention the huge amount of HTTP-request it will generate.
We realize that this is a valid use case, but sending events to the server from every keystroke is not feasible for any Ajax framework. At least in your case, it would be enough to send events only when the textfield changes from empty to non-empty and vice-versa. That would dramatically reduce the amount of request made to the server, but we are hesitant in adding these kinds of very specific events to the framework.
I kind of hate to say this, but I think your best bet is to implement this behaviour yourself with a custom widgetset. That’s not saying we won’t help you with it, on the contrary, we’ll be more than willing to help you succeed in it.
I hope this helps you atleast somehow.
Cheers, Jouni
Original post was not mine, but I face similar problem in my project and would need help implementing custom component which sends key presses to server.
There was ticket in track
http://dev.itmill.com/ticket/2387 , which might relate to this issue, I wonder what is its status (thinking it might be solution for my problem)?
Just to be clear, I describe my problem:
I need to receive key presses from client side TextField component, to check if SSID (social security ID) is correct and then do some stuff with it. To reduce huge amount of ajax calls, it would be ok to only send one when value in field is some specific length.
I would be happy to see code example for both server and client side.
In the past we have brainstormed the idea of declaring simple validators using javascript that would be run both in server and clients side. Some implementation ideas:
Create ClientSideJavaScriptValidator interface (on serverside) that could contain getValidationJS() and getValidationError()
AbstractField should pass the client-side validation JS and error in UIDL if the validators implement ClientSideJavaScript validator
Client side components (at least TextField) should support those directly
We could implement server-side JavaScriptValidator class that would implement both ClientSideJavaScriptValidator and Validator interfaces using server-side JavaScript interpreter.
It might be possible to pass references to other fields that should be taken into account in the validation
As a result
Implementing simple validators that are run both on server and client would be fairly easy.
No compile-time checking for the validation code
Toolkit would become dependant on a JavaScript interpreter. It might be possible to go around this if the JavaScriptValidator implementation is not included in Toolkit - the interface and JavaScript passing mechanism would be useful for implementing many validators even without JavaScript interpreter
I remember that we have these JS validators (for both client and server) used in some client projects. But I don’t see the point to use them in version 5 onwards.
The issue with JavaScript validators is that they are written in JavaScript. Java developers most likely want to write their validators in Java as they do with other code. With GWT around it is possible and we definitely should make use of it. Helpers in Toolkit itself would make this easier, but we’ll never make this into version 5.
Of course it is a shame that it requires having GWT developing environment set up too, but don’t most big projects need their custom components anyway.
Implementing multifield validation that works in both GWT code and server code, shouldn’t be a problem in GWT approach if the idea is developed a bit further.
I would say that the only notable (but a huge) drawback for client-side Java-validators (instead of JavaScript) validators is complexity. One must write a lot of code and recompile widgetset. With javascript validators the use could be as simple as
tf.addValidator(new JSValidator(“return (‘’ + value).length() > 0”, “value should not be empty”)) . If the complexity can be somehow resolved with tooling, it would be more robust alternative.
Also, the above idea for javascript validators was not meant to be “the only way to go”. Instead it could provide foundation for introducing a set of “ready made” validators that internally use javascript and complementary method for writing validators - if you happen to know javascript.
This is such a popular feature request right now, I’ll provide
working code for the onkeypress-textfield right here - it’s actually client-side only (extends the regular textfield), and will trigger the serverside value-change when the user types, after a 300ms delay, and provided the textfield is in immediate-mode.
Some improvements you might like to do:
make it a separate component (inherit TextField serverside and change tag)
make 300ms delay configurable
make a separate on/off switch for the direct/superimmediate/keypress -feature
package com.virtuallypreinstalled.marc.examples.gwt.client.ui;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ui.ITextField;
public class IDirectTextField extends ITextField {
Timer timer = null;
public IDirectTextField() {
addKeyboardListener(new KeyboardListenerAdapter() {
public void onKeyPress(Widget sender, char keyCode, int modifiers) {
if (timer != null) {
timer.cancel();
}
timer = new ChangeTimer();
}
});
}
private class ChangeTimer extends Timer {
ChangeTimer() {
schedule(300);
}
public void run() {
IDirectTextField.this.timer = null;
onChange(IDirectTextField.this);
}
}
}
As always, feel free to ask if something is unclear.