Implement HasValue<String>
in your widget.You can addValueChangeHandler too.
GWT custom composite widget that behaves as a single editor
Question
I have a composite widget composed by 3 TextBoxes that acts as a "date mask" field, like: [dd]/[mm]/[yyy] (dont ask why I am doing this :), I dont like DateBox and I have to force the user to keep a type of format, so I wrote my own widget). Here is the java code:
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;`enter code here`
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
public class DateMaskWidget extends Composite {
private static DateMaskWidgetUiBinder uiBinder = GWT
.create(DateMaskWidgetUiBinder.class);
interface DateMaskWidgetUiBinder extends UiBinder<Widget, DateMaskWidget> {
}
@UiField
TextBox daysTextbox;
@UiField
TextBox monthsTextbox;
@UiField
TextBox yearsTextbox;
public DateMaskWidget() {
initWidget(uiBinder.createAndBindUi(this));
daysTextbox.setMaxLength(2);
monthsTextbox.setMaxLength(2);
yearsTextbox.setMaxLength(4);
}
@UiHandler("daysTextbox")
void onKeyUp(KeyUpEvent event)
{
//if 2 chars were entered focus the next box
if(daysTextbox.getText().length()==daysTextbox.getMaxLength())
monthsTextbox.setFocus(true);
}
@UiHandler("monthsTextbox")
void onKeyUp2(KeyUpEvent event)
{
//if 2 chars were entered focus the next box
if(monthsTextbox.getText().length()==monthsTextbox.getMaxLength())
yearsTextbox.setFocus(true);
}
}
Now I'd like this widget to behave as a single Editor (like a single TextBox), so i can set a value to it by passing a string like xx/xx/xxxx .
The Question is: which interface do I need to implement and which methods do I need to override to achive this?? Which methods are used in the editor framework to set/get the value of an editor??
I will need to take the given string (probably passed in a method like setValue() ), split it in 3 parts, and assign each part to the right text box. And same thing for a getValue() method.
Thanks for your help
[Update]
Ok, I implemented both HasValue and IsEditor interfaces as follows:
public class DateMaskWidget extends Composite implements HasValue<String>,
IsEditor<ValueBoxEditor<String>> {
private static DateMaskWidgetUiBinder uiBinder = GWT
.create(DateMaskWidgetUiBinder.class);
interface DateMaskWidgetUiBinder extends UiBinder<Widget, DateMaskWidget> {
}
public DateMaskWidget() {
initWidget(uiBinder.createAndBindUi(this));
}
//...............other code ...................
@Override
public HandlerRegistration addValueChangeHandler(
ValueChangeHandler<String> handler) {
//TODO add code here
}
@Override
public ValueBoxEditor<String> asEditor() {
//TODO add code here
return null;
}
@Override
public String getValue() {
String value="";
value+=this.daysTextbox.getValue()+"/"+
this.monthsTextbox.getValue()+"/"+this.yearsTextbox.getValue();
return value;
}
@Override
public void setValue(String value) {
String[] values = value.split("/");
this.daysTextbox.setValue(values[0]);
this.monthsTextbox.setValue(values[1]);
this.yearsTextbox.setValue(values[2]);
System.out.println("Set Value:"+value);
}
@Override
public void setValue(String value, boolean fireEvents) {
//TODO add code here
}
}
Now the question is what should I add to asEditor() and addValueChangeHandler() here?
asEditor() needs to return an ValueBoxEditor but not sure how to implement this.
thanks again
No correct solution
OTHER TIPS
Try to implement the same interface as original TextBox:
IsEditor<ValueBoxEditor<java.lang.String>>
Editor framework will use ValueBoxEditor.getValue()
and ValueBoxEditor.setValue(...)
methods.
Ok, after looking around into the GWT source code of TextBox and some other classes it extends/implements, here is what I came up with:
public class DateMaskWidget extends Composite implements HasValue<String>,
IsEditor<TakesValueEditor<String>> {
private static DateMaskWidgetUiBinder uiBinder = GWT
.create(DateMaskWidgetUiBinder.class);
interface DateMaskWidgetUiBinder extends UiBinder<Widget, DateMaskWidget> {
}
@UiField
TextBox daysTextbox;
@UiField
TextBox monthsTextbox;
@UiField
TextBox yearsTextbox;
private TakesValueEditor<String> editor;
private boolean valueChangeHandlerInitialized;
public DateMaskWidget() {
initWidget(uiBinder.createAndBindUi(this));
daysTextbox.setMaxLength(2);
monthsTextbox.setMaxLength(2);
yearsTextbox.setMaxLength(4);
}
@UiHandler("daysTextbox")
void onKeyUp(KeyUpEvent event)
{
//if 2 chars were entered focus the next box
if(daysTextbox.getText().length()==daysTextbox.getMaxLength())
monthsTextbox.setFocus(true);
}
@UiHandler("monthsTextbox")
void onKeyUp2(KeyUpEvent event)
{
//if 2 chars were entered focus the next box
if(monthsTextbox.getText().length()==monthsTextbox.getMaxLength())
yearsTextbox.setFocus(true);
}
public HandlerRegistration addChangeHandler(ChangeHandler handler) {
return addDomHandler(handler, ChangeEvent.getType());
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String>
handler) {
// Initialization code
if (!valueChangeHandlerInitialized) {
valueChangeHandlerInitialized = true;
addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
ValueChangeEvent.fire(DateMaskWidget.this, getValue());
}
});
}
return addHandler(handler, ValueChangeEvent.getType());
}
@Override
public String getValue() {
String value="";
value+=this.daysTextbox.getValue()+"/"+
this.monthsTextbox.getValue()+"/"+this.yearsTextbox.getValue();
return value;
}
@Override
public void setValue(String value) {
String[] values = value.split("/");
if(values.length==3)
{
this.daysTextbox.setValue(values[0]);
this.monthsTextbox.setValue(values[1]);
this.yearsTextbox.setValue(values[2]);
}
else
{
this.daysTextbox.setValue("");
this.monthsTextbox.setValue("");
this.yearsTextbox.setValue("");
}
System.out.println("Set Value:"+value);
}
@Override
public void setValue(String value, boolean fireEvents) {
setValue(value);
if(fireEvents)
ValueChangeEvent.fire(this, value);
}
@Override
public TakesValueEditor<String> asEditor() {
if (editor == null) {
editor = ValueBoxEditor.of(this);
}
return editor;
}
}