Selecting TextInputCell

519 views
Skip to first unread message

tjmcc18

unread,
May 25, 2011, 10:23:15 AM5/25/11
to Google Web Toolkit
I have a CellTable which makes use of TextInputCells to allow the user
to edit data. I would like this to behave in a spreadsheet like
manner such that the user can select the various textboxes and make
changes as they see fit. However, the default behavior for selecting
the textboxes is not desirable. When a user first selects a textbox,
it receives focus and the user can edit the data. When the user then
tries to select another textbox, the previous textbox loses focus but
the newly selected textbox does not receive focus. Clicking on the
box again gives it focus. In essence it takes two click to select the
textbox. This is very annoying. I believe the first click possibly
selects the cell, but I'm not sure. Does anyone know how to get
around this?

-TJ

tjmcc18

unread,
May 25, 2011, 12:41:24 PM5/25/11
to Google Web Toolkit
Try clicking though and editing the TextInputCells in the showcase.
It takes multiple clicks... how can I get around that?

http://gwt.google.com/samples/Showcase/Showcase.html#!CwCellSampler

-TJ

tjmcc18

unread,
May 26, 2011, 9:12:57 AM5/26/11
to Google Web Toolkit
Best I could come up with is to use a modified version of EditTextCell
instead, which at least highlights the text in the box on click. This
still seems like a bug or at least an area that needs improvement.

-TJ

On May 25, 10:23 am, tjmcc18 <tjmc...@gmail.com> wrote:

Andrei

unread,
Aug 2, 2012, 9:51:58 AM8/2/12
to google-we...@googlegroups.com
This is what I do. First, I modified the input cell:

public class SpiralTextInputCell extends TextInputCell {

// Default value
private int startIndex = 1000;

public SpiralTextInputCell() {
}

/* When we have more than one DataGrid on a page, their tab indexes will collide.
* To prevent this, we should use a different start index for each grid after the first one.
*/
public SpiralTextInputCell(int startIndex) {
this.startIndex = startIndex;
}

@Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
ViewData viewData = getViewData(context.getKey());
if (viewData != null && viewData.getCurrentValue().equals(value)) {
clearViewData(context.getKey());
viewData = null;
}
String s = (viewData != null) ? viewData.getCurrentValue() : value;
if (s != null) {
int tabIndex = startIndex + context.getIndex();
sb.appendHtmlConstant("<input type=\"text\" value=\"" + s + "\" tabindex=\"" + tabIndex + "\"></input>");
}
}
}

Now users can use their TAB key to move from one cell to another within their tables. Not that this may not be the desired behavior if you mix different cell types in the same table.

Second, set keyboardSelectionPolicy to DISABLED for your DataGrid/CellTable.

Finally, I modified my standard DataGrid with the following:

    addCellPreviewHandler(new Handler<T>() {

        @Override
        public void onCellPreview(CellPreviewEvent<T> event) {
            if ("keydown".equals(event.getNativeEvent().getType())) {

                /* We only support up and down arrows, because left and right arrows
                 * are used to navigate inside the input elements.
                 */

                int col = event.getContext().getColumn();
                int row = event.getContext().getIndex();
                if (event.getNativeEvent().getKeyCode() == 13 || event.getNativeEvent().getKeyCode() == 40) {
                    row++;
                    if (row == getRowCount()) {
                        row = 0;
                    }
                } else if (event.getNativeEvent().getKeyCode() == 38) {
                    row--;
                    if (row == -1) {
                        row = getRowCount() - 1;
                    }
                }
                getRowElement(row).getCells().getItem(col).getFirstChildElement().getFirstChildElement().focus();
         }
    }
});

Now users can hit the enter button to move to the next cell below. You can modify it so that focus moves to the next cell on the right, if any, and if not - to the first cell in the next row.
Users can also use up and down arrows to move from cell to cell in the same column.

By the way, I see no reason to use a CellTable anymore. Use DataGrid.

I hope this helps.

Andrei

unread,
Aug 2, 2012, 12:36:50 PM8/2/12
to google-we...@googlegroups.com
Sorry, I rushed a little bit. The new cell should be able to handle null values properly. Here is an updated version:

public class SpiralTextInputCell extends TextInputCell {

// Default value
private int startIndex = 1000;

public SpiralTextInputCell() {
}

/* When we have more than one DataGrid on a page, their tab indexes will collide.
 * To prevent this, we should use a different start index for each grid after the first one.
 */
public SpiralTextInputCell(int startIndex) {
this.startIndex = startIndex;
}

@Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
ViewData viewData = getViewData(context.getKey());
if (viewData != null && viewData.getCurrentValue().equals(value)) {
clearViewData(context.getKey());
viewData = null;
}
String s = (viewData != null) ? viewData.getCurrentValue() : value;
if (s == null) s = "";
Reply all
Reply to author
Forward
0 new messages