"Grid" TextField

Hello,

Is there a way to obtain a TextField like this ?

I want the focus to go from one cell to the other when a letter is typed in a cell. But without sending any event to the server.
I don’t know how to implement it in my widget client side.

Any idea :slight_smile:

Thanks,
Kevin.
11616.png

You could do it with a KeyUpHandler or KeyDownHandler. Here’s
an example
of using it

Then change the focus to the next field with nextfield.setFocus(true). You’ll have to dig up the reference to it from the component hierarchy.

I was also thinking if you could fake the multiple text fields somehow. For example, you could use a fixed-width font and then have a background that consists of boxes… Oh well, that could be difficult as you’d need to know the font width in pixels, which is not possible.

Actually, that’s exactly what I don’t know to do.
How the client code of one TextField can “know” the others TextFields ?

I think you have several alternatives for that.

If you have the PID (Paintable ID) of the other VTextField, you can get it from ApplicationConnection with getPaintable(). That’s easy, the problem is how to get the PID. You could dig them up on the server-side and then send to the client-side components, but that’s a bit complex again. Perhaps the easiest way is to set the PIDs for the TextFields explicitly with setDebugId(). For example, setDebugId(“myfield1”) sets the PID to: “PID_Smyfield1”.

You could also dig up the field’s HTML DOM element using the DOM API, and then use the other getPaintable() to get the VTextField by the DOM element.

To me it sounds you would rather want to use the GWT TextBox widget rather than the Vaadin VTextField.

Getting the next text box (if you append then all side-by-side in the dom) could be as easy as

currentTextBox.getElement().getNextSibling()

Thank you both for your answers. I have nearly solved my issue. Everything works fine in my widget. But now I don’t know how to get the content text of my “GridTextField” from the server side. Do you have any idea ?

Here is the server code of the GridTextField :


import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.AbstractComponent;

@SuppressWarnings("serial")
@com.vaadin.ui.ClientWidget(client.ui.VGridTextField.class)
public class GridTextField extends AbstractComponent
{
        /** The number of characters composing the GridTextField. */
	private int nbCar;
	
		public GridTextField(int nbCar)
		{
			if (nbCar < 1) throw new IllegalArgumentException();
			else this.nbCar = nbCar;
		}
		
		@Override
		public void paintContent(PaintTarget target) throws PaintException
		{
			super.paintContent(target);
		
			target.addAttribute("nbCar", nbCar);
		}
		
		public String getText()
		{
			??
		}
	
}

You need to receive the value in changeVariables(). But extending AbstractField would be more natural, as the component has a value which the user can input.

Well, you probably have the following basic alternatives:

[list]

[]
On server-side, extend AbstractField. On client-side, extend GWT Composite or something like that, that contains all the individual text fields, which are GWT text boxes (as Jouni suggested). You need to handle the communication of the field value to the server-side.
[
]
On server-side, extend TextField. On client-side, extend VTextField. Also, on the server-side, extend CustomComponent to group the multiple TextFields together. Do the communication between textfields as I suggested above. The advantage is that the TextField-VTextField already handles the communication of the value to the server-side.

[/list]Jouni’s approach is more proper, although probably needs a bit more client-side code.

If you’re a Pro Account subscriber, a related article:
#257
.

Sorry I haven’t been clear enough.
My VGridTextField contains several VCellGridTextField (the TextFields). I am able to get the content text of all the TextFields in my VGridTextField.
But know I just want to get this value in GridTextField (server) by calling VGridTextField’s getText() method client).

Mmm, you can’t just call a client-side widget’s method from a server-side component. You need to serialize the data in the widget using updateVariable() and deserialize it in the server-side component in changeVariables(). See sections
Integrating a GWT Widget
and
Server-Side Components
.

Thank you.
Here is my server and client code for who is interested in.
I am sorry for the french comments.

A CellGridTextField is equivalent to one cell in the GridTextField.
VCellGridTextField and VGridTextField are the client-side code.
11618.zip (3.37 KB)

You should probably package this as an add-on and upload it to the
Directory
. That’s the proper way of sharing your components. It’s really easy if you use Eclipse and the Vaadin Eclipse plugin.

I didn’t want to do it but if you ask me… Because I think it is not the best way to do it.