How to add Widget as a Cell in Cell Table GWT - gwt

Now I'm stuck in issue of pagination the widgets in GWT.
I'm using Cell table to display a list of instances of an UI Binder class of mine (Ex: LocationView).
http://gwt.google.com/samples/Showcase/Showcase.html#!CwCellTable
This is the showcase of the CellTable.
Now I want to add my widget (UI Binder class) to each cell of the table . It will look somehow like this
In this Cell Table, each cell is this widget (LocationView - an UI Binder Class):
So How can I create this table using cell table (I do not use grid view because it's not supported pagination)
or If I can not use Cell table to create this table, what I can use to it that supports pagnigation (if the number of LocationView (The icon you see) is over 6, it will jump to page 2).
Thank you for your help!.

Creating custom cells tutorial explains how to do that.

To add a widget to a cell I use custom CellTableBuilder and I set unique id for the cell that should contain a widget.
Then I attach the widget to DOM and move it to the cell.
void addWidgetToCell(final String cellId, final Widget widget) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
Element cellElem = DOM.getElementById(cellId);
if (!widget.isAttached()) {
// attach the detail to DOM (cannot attach it directly to the cell, because it has existing parent widget)
RootPanel.get().add(widget);
}
// move detail element under the cell element
cellElem.appendChild(widget.getElement());
}
});
}

Related

How can I get the row, column clicked in gwt table?

I have a flextable that gets populated with data from a database.
I want to get the ROW number of the clicked row.
So far I figured out only how to get the value of a particular cell in a particular row. You have to know the position and hard code it which isn't practical.
String test =flexTable.getFlexCellFormatter().getElement(2, 2).getInnerHTML();
System.out.println(test);
How can I create a ClickHandler to get the selected row?
//flexTable is a FlexTable object. Add a ClickHandler to it.
flexTable.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
//gets the index of the cell you clicked on
int cellIndex = flexTable.getCellForEvent(event).getCellIndex();
//gets the index of the row you clicked on
int rowIndex = flexTable.getCellForEvent(event).getRowIndex();
//print statements below will verify
System.out.println("cellIndex "+cellIndex);
System.out.println("rowIndex "+rowIndex);
//gets the value of the selected cell
String test =flexTable.getFlexCellFormatter().getElement(rowIndex,cellIndex ).getInnerHTML();
System.out.println(test);
}
});
The FlexTable supports row spans and column spans, allowing you to layout data in a variety of ways. I think you should use CellTable or a DataGrid or for that matter even a CellList if only single column data is being displayed. To these widgets you can add a selectionhandler to which you can achieve your goal. Refer this it has some pre coded examples.

GWT adding widget to Column Header

I want to customize my cell table's column header. I have to include support for sorting and filtering. I want to have images for both actions. When the user clicks on the sort image, it will toggle (based on ascending / descending order sort ) and the table sorts based on the icon clicked. I am currenty doing this with some messy HTML manipulation , in the onBrowserEvent of my custom header cell. Could someone tell me how I could use GWT's ToggleButton here?
Thanks.
You can't use GWT Widget in Cell Table.
But, you can use a custom Cell for the header.
public class ButtonHeader extends Header<String> {
private String text;
/**
* Construct a new TextHeader.
*
* #param text the header text as a String
*/
public ButtonHeader(String text) {
super(new ButtonCell());
this.text = text;
setUpdater(new ValueUpdater<String>() {
#Override
public void update(String value) {
//When the button is press
}
});
}
#Override
public String getValue() {
return text;
}
}
You can change this for use an other Cell for your usage.
For a (not-so) complete documentation on custom cells check this link.
You WILL have to override onBrowserEvent(), even if it's clumsy, since you can't use a GWT widget in a cell but you can render it. Yet, it'll lose all it's event handling capabilities.
(from this post) Widgets are never attached to the DOM. They exist to be manipulated in memory and then have their HTML extracted and pushed into the DOM. Events from the Widgets, therefore, are not handled. Cell events ARE handled.
So you could just use widget.getElement.getInnerHTML() to render the widget you want in your header (a toggle button or anything else). Despite having this option at hand, my advice would be to use your own SafeHtmlTemplates instead of using getInnerHTML().

On click functionality of Button Inside ListView in Wicket Framework

Im populating a table using ListView component in wicket.The last column of my table is button. So for each row I'll have a button in the last column.What I'm trying to implement is onlick of the button I need to delete the appropriate row. So for this I need to get the current index of the list on click of button. How to achieve/get this ?
I would extend Ajax button and pass the row reference (item) in the constructor...then you can do anything you want..by overriding the onSubmit method
Example:
private class SpecialButton extends AjaxButton {
final Item<Object> rowItem;
public SpecialButton(final String id, final Item<Object> rowItem) {
super(id);
this.rowItem = rowItem;
}
#Override
protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
// here you cand do everything you want with the item and the model object of the item.(row)
Object object = rowItem.getModelObject();
}
}
You should replace Object from Item<Object> with your reapeater model. After creating this private class you can reuse it for every row in your repeater.
If you want to delete that row you just have to remove the model from the list used to generate the repeater and refresh the repeater container(Wicket does not allow you to refresh the repeater by adding it to the target...instead you have to add the repeater continer.)
Have a look at the repeaters Wicket Examples page to understand how to use ListView and other repeaters:
http://www.wicket-library.com/wicket-examples/repeater/
You can get the current index of the list from item.getIndex()
protected void populateItem(final ListItem<T> item) {
int index = item.getIndex();
...
Look here for inspirations on how to do it properly (without index):
Wicket ListView not refreshing

GWT: On adding custom widget to celltable losing events of the custom widgets

Our requirement is to make an editable grid using the CellTable containing custom widgets in its cell. The custom widget is having text box and search button associated with the text box. To add the custom widget as a cell created a subclass of AbstractEditableCell class (provided by GWT) and had override render() and onBrowserEvent() methods.
The render(Context context, String value, SafeHtmlBuilder sb) method of the custom widget cell creates a Safe html for the widget and render this safe html in to the cell. But the problem i am facing is, the custom widget is rendered correctly but it loses its associates events. The render method in given below :
if (viewData.isEditing()) {
textBoxSelector.setText(text);
OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml safeHtmlObj = new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml(textBoxSelector.toString());
sb.append(safeHtmlObj);
} else {
// The user pressed enter, but view data still exists.
sb.append(html);
}
If I try to add the widget in the render() method using the following code, it does not add the widget.
int left = parent.getAbsoluteLeft();
int top = parent.getAbsoluteTop();
String elementId = "ID" + left + top;
try {
parent.setId(elementId);
// parent.removeFromParent();
RootPanel.get(elementId).add(textBoxSelector);
} catch (AssertionError error) {
RootPanel.get(elementId).add(textBoxSelector);
}
I'd really appreciate if anyone can guide me in achieving addition of widget in the CellTable without it losing associated events.
GWT's Cells are non-compatible with GWT Widgets. This means that you could not have a GWT widget placed inside of a cell and have it still function. Cells do have an alternative event handling mechanism though (covered below)
The reason for this is that Cells are closer to stateless renderers. Given a data object the Cell will spit out HTML. A single Cell will be reused over and over - spitting out HTML for various elements on the page - and never maintaining references to any of the DOM elements it creates.
In your above example, you call "someWidget.toString()". Doing this will only return the HTML representation of your widget and is what is loses your event handling.
Handling Events in Cells
GWT Dev Guide for Custom Cells (has some additional details)
To handle events in cells, you'll need to override a separate method called onBrowserEvent. You'll also need to configure your cell to be notified of particular events by calling super('click', 'keydown') in your constructor with the list of events you are interested in listening to.
Since Cells are stateless renderers, the onBrowserEvent will be passed a context of the rendered element that was clicked on along with the original data object that your cell rendered. You can then apply changes or manipulate the DOM as needed.
Here is an example taken from the linked dev guide above:
#Override
public void onBrowserEvent(
Context context,
Element parent,
String value,
NativeEvent event,
ValueUpdater<String> valueUpdater) {
// Let AbstractCell handle the keydown event.
super.onBrowserEvent(context, parent, value, event, valueUpdater);
// Handle the click event.
if ("click".equals(event.getType())) {
// Ignore clicks that occur outside of the outermost element.
EventTarget eventTarget = event.getEventTarget();
if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
doAction(value, valueUpdater);
}
}
}

GWT ButtonCell Changing Text

How can I change ButtonCell text that's embedded in celltable column when button pressed.
I've onnly seen setFieldUpdater.
Also is there some easy way to update another CellTable column rather then accessing it directly
Cell widgets are "model-based" (MVP), you have to update the object rendered in the row (the one passed to the FieldUpdater) and then tell the CellTable that the value changed and it should redraw (use setRowData, using the index passed to the FieldUpdater).
Something like:
new FieldUpdater<MyObject, String>() {
#Override
public void update(int index, MyObject object, String value) {
object.setSomeField("foo");
cellTable.setRowData(index, Collections.singletonList(object));
}
}