Wednesday, April 21, 2010

Building a Twitter style TextArea using GWT



When using twitter the client can only place a 140 characters in the box. There is a nice big GREY label above the box that shows the user how many characters are left. I have been playing with GWT for awhile now and decided that building that control wouldn't be too hard. Turns out it isn't but I hit a few bumps along the way.

The main gist of it is that you have to be careful how you calculate it. I was trying to keep a running count of how many times a key was pressed. The only problem is there are a lot of key codes to recongnize and the character codes can differ, it seems, across browsers. Just when I was in despair about the struggles creating this control it hit me that there is a much easier way. The only thing that needs to be taken into consideration is when the event on the control gets fired.

The solution is to take the length of the text in the TextArea and subtract it from the desired limit.

counter =140 - length

For this to work though the event needs to occur after the TextArea is updated. So keep track and update the counter using the KeyUpEvent in GWT.




int counter = 240

TextArea post = new TextArea();

post.addKeyUpHandler(new KeyUpHandler() {

public void onKeyUp(KeyUpEvent event) {
int postLength = post.getText().length();
counter = 140 - postLength;

submit.setEnabled( (counter<140) );

if( submit.isEnabled() ){
submit.removeStyleDependentName("disabled");
}else{
submit.addStyleDependentName("disabled");
}


count.setText( counter + "" );
}

});




One additional problem is how to keep the counter from going negative by allowing the user to type in too many characters. The solution is to create a KeyDownEvent handler that will check the current counter and make sure it is not less then 1 before allowing the Key event to propagate. Once the text content length reaches 140 then the event will need to be prevented.


post.addKeyDownHandler(new KeyDownHandler() {

public void onKeyDown(KeyDownEvent event) {
if( counter<1 ){
event.preventDefault();
event.stopPropagation();
}
}
});

No comments: