How to create CellTable based on the response from the server - gwt

I want to create a CellTable. But Columns of the celltable should be based on the response from the server. I'm getting the server response as List.
No of Columns = Size of the list.
CellTable column header should be the value from the server.
For ex. Server response: List<Contacts> contacts
Header should be contacts.getName().

I achieved it by the following code.
for (Contacts contact : contacts) {
final String city = contact.getCity();
final TextColumn<String> addressColumn = new TextColumn<String>() {
#Override
public String getValue(Contacts object) {
return city;
}
};
cellTable.addColumn(addressColumn, contact.getAddress());
}
Regards,
Gnik

Use CellList with an AsyncDataProvider:
//Create a cellList
#UiField
CellList<Contact> cellList;
//Creating dataProvider and completion of the cellList
#UiFactory
CellList<Contact> makeCellList() {
private AsyncDataProvider<Contact> provider = new AsyncDataProvider<Contact>() {
#Override
public void onRangeChanged(final HasData<Contact> display) {
rpcService.getContact(new AsyncCallback<List<Contact>>() {
#Override
public void onSuccess(List<Contact> result) {
display.setRowData(0, result);
}
#Override
public void onFailure(Exception ex) {
//TODO
}
});
}
};
//Adding the cellList to the provider in a constructor
provider.addDataDisplay(cellList);
Here's full example and docs.

Related

Unable to get GWT ListDataProvider to work with DataGrid

I had my data in a FlexTable, but am migrating to a DataGrid so I can easily add pagination. I get the data via a REST call. I can't seem to get the data to actually display. Here are the relevant snippets:
private DataGrid<SearchResult> resultsGrid = new DataGrid<SearchResult>();
resultsGrid.setAutoHeaderRefreshDisabled(true);
TextColumn<SearchResult> titleColumn = new TextColumn<SearchResult>() {
#Override
public String getValue(SearchResult object) {
return object.getTitle();
}
};
resultsGrid.addColumn(titleColumn, "Document Title");
ButtonCell buttonCell = new ButtonCell();
Column<SearchResult, String> buttonColumn = new Column<SearchResult, String>(buttonCell){
#Override
public String getValue(SearchResult object) {
return "Show";
}
};
resultsGrid.addColumn(buttonColumn, "");
buttonColumn.setFieldUpdater(new FieldUpdater<SearchResult, String>() {
public void update(int index, SearchResult object, String value) {
doPreview(object.title);
}
});
TextColumn<SearchResult> roleColumn = new TextColumn<SearchResult>() {
#Override
public String getValue(SearchResult object) {
return object.getRoles();
}
#Override
public String getCellStyleNames(Context context, SearchResult object) {
if (object.containsCurrentRole)
return "highlight";
else
return null;
}
};
resultsGrid.addColumn(roleColumn, "Associated Roles");
final SingleSelectionModel<SearchResult> selectionModel = new SingleSelectionModel<SearchResult>();
resultsGrid.setSelectionModel(selectionModel);
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
public void onSelectionChange(SelectionChangeEvent event) {
SearchResult selected = selectionModel.getSelectedObject();
if (selected != null) {
clearWordCloud();
getWordCloud(selected.getTitle());
}
}
});
dataProvider.addDataDisplay(resultsGrid);
// Create a Pager to control the table.
SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
pager.setDisplay(resultsGrid);
resultsGrid.setVisible(true);
resultsGrid.addStyleName("results");
mainPanel.add(resultsGrid);
...
The function that gets called after a search:
private void updateTable(List<SearchResult> results) {
dataProvider.getList().addAll(results);
dataProvider.refresh();
dataProvider.flush();
resultsGrid.setVisible(true);
resultsFlexTable.setVisible(true);
}
At first I was missing the flush and refresh, but adding them had no effect. I'm kind of stumped.
The most likely problem is that your DataGrid has a height of zero. DataGrid implements RequiresResize, which means that its height either has to be set explicitly, or it will acquire its height from a parent widget if this parent widget implements ProvidesResize. FlexTable does not implement ProvidesResize interface.
NB: You don't need flush and refresh - adding data to the DataProvider refreshes the grid.

Why can't I use GWT Button in a CellTable and how to combine cell buttons with cell text

I want to put some text and severals Buttons in a CellTable. I can display the text and buttons, but when I click on a button, nothing happens.
final SafeHtmlCell detailsCell = new SafeHtmlCell();
Column<UIRow, SafeHtml> detailsColumn = new Column<UIRow, SafeHtml>(
detailsCell) {
#Override
public SafeHtml getValue(UIRow object) {
String details = "some informations xxx <br/>";
Button addButton = new Button("Add value", new ClickHandler() {
public void onClick(ClickEvent event) {
Window.alert("hello");
}
});
details += addButton;
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant(details);
return sb.toSafeHtml();
}
};
detailsColumn.setCellStyleNames(CSS_DETAILS_TD);
table.setColumnWidth(detailsColumn, "10%");
table.addColumn(detailsColumn, new SafeHtmlHeader(SafeHtmlUtils.fromSafeConstant("details")));
But, if I put a Button per Cell, it's working, onClick method is called:
final ButtonCell btnCell = new ButtonCell() {
#Override
public void render(
final Context context,
final SafeHtml data,
final SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<button type=\"button\" style=\"height: 25px\" title=\"submit\" class=\"btn btn-success btn-small\" tabindex=\"-1\">");
if (data != null) {
sb.append(data);
}
sb.appendHtmlConstant("</button>");
}
};
Column<UIRow, String> btnColumn = new Column<UIRow, String>(btnCell) {
#Override
public String getValue(UIRow object) {
return "";
}
};
btnColumn.setCellStyleNames("td-actions");
table.addColumn(btnColumn, "");
table.setColumnWidth(btnColumn, "5%");
btnColumn.setFieldUpdater(new FieldUpdater<UIRow, String>() {
public void update(int index, UIRow object, String value) {
...
service.submit(object, false, new AsyncCallback<String>() {
#Override
public void onFailure(Throwable caught) {
Window.alert(caught.getMessage());
}
#Override
public void onSuccess(String result) {
Window.alert(result);
}
});
}
});
}
I want to display Html text and Buttons in one Col/Cell, is it possible ?
Thanks
Cell widgets (CellTable, DataGrid, etc) are not designed to embed regular GWT widgets like Button.
For buttons you can use ButtonCell
Take a look at official example:
http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwCellSampler
Update:
As for the second part of the question regarding how to combine cells, there is a few options:
Check out CompositeCell where you can combine multiple cells (eg ButtonCell and TextCell).
Another option is to use custom CellTableBuilder where you can customize all aspects of table rendering like colspans, column/row decorations, etc

Gwt Simple pager issues with a column sort handler

I have set up an AsyncDataProvider for my CellTable and added it to a SimplePager. I have hooked up a ListHandler to take care of sorting based on a column.
When I click the header of that column, the data doesn't change but on going to the next/previous page within the pager the data is then sorted. Also before the column is clicked there is no visual indicator on the column that would indicate that it is meant to be sortable.
How can I get the data to update when I click the header of the Column?
Here's my code snippet
service.getHosts(environment, new AsyncCallback<Set<String>>() {
#Override
public void onSuccess(final Set<String> hosts) {
final List<String> hostList = new ArrayList<String>(hosts);
//Populate the table
CellTable<String> hostTable = new CellTable<String>();
TextColumn<String> hostNameColumn = new TextColumn<String>(){
#Override
public String getValue(String string){
return string;
}
};
NumberCell numberCell = new NumberCell();
Column<String, Number> lengthColumn = new Column<String, Number>(numberCell){
#Override
public Number getValue(String string) {
return new Integer(string.length());
}
};
AsyncDataProvider<String> dataProvider = new AsyncDataProvider<String>() {
#Override
protected void onRangeChanged(HasData<String> data) {
int start = data.getVisibleRange().getStart();
int end = start + data.getVisibleRange().getLength();
List<String> subList = hostList.subList(start, end);
updateRowData(start, subList);
}
};
// Hooking up sorting
ListHandler<String> columnSortHandler = new ListHandler<String>(hostList);
columnSortHandler.setComparator(lengthColumn, new Comparator<String>(){
#Override
public int compare(String arg0, String arg1) {
return new Integer(arg0.length()).compareTo(arg1.length());
}
});
hostTable.setPageSize(10);
hostTable.addColumnSortHandler(columnSortHandler);
hostTable.addColumn(hostNameColumn,"Host Name");
lengthColumn.setSortable(true);
hostTable.addColumn(lengthColumn, "Length");
VerticalPanel verticalPanel = new VerticalPanel();
SimplePager pager = new SimplePager();
pager.setDisplay(hostTable);
dataProvider.addDataDisplay(hostTable);
dataProvider.updateRowCount(hosts.size(), true);
verticalPanel.add(hostTable);
verticalPanel.add(pager);
RootPanel.get().add(verticalPanel);
}
#Override
public void onFailure(Throwable throwable) {
Window.alert(throwable.getMessage());
}
});
I'm not sure how to make sure that the list is shared by both the table and the Pager. Before adding the pager I was using
ListDataProvider<String> dataProvider = new ListDataProvider<String>();
ListHandler<String> columnSortHandler = new ListHandler<String>(dataProvider.getList());
The AsyncDataProvider doesn't have the method getList.
To summarize I want the data to be sorted as soon as the column is clicked and not after I move forward/backward with the pager controls.
As per the suggestion I have changed the code for the AsyncDataProvider to
AsyncDataProvider<String> dataProvider = new AsyncDataProvider<String>() {
#Override
protected void onRangeChanged(HasData<String> data) {
int start = data.getVisibleRange().getStart();
int end = start + data.getVisibleRange().getLength();
List<String> subList = hostList.subList(start, end);
// Hooking up sorting
ListHandler<String> columnSortHandler = new ListHandler<String>(hostList);
hostTable.addColumnSortHandler(columnSortHandler);
columnSortHandler.setComparator(lengthColumn, new Comparator<String>(){
#Override
public int compare(String v0, String v1) {
return new Integer(v0.length).compareTo(v1.length);
}
});
updateRowData(start, subList);
}
};
But there is no change in the behavior even after that. Can someone please explain the process. The GWT showcase app seems to have this functionality but how they've done it isn't all that clear.
When using an AsyncDataProvider both pagination and sorting are meant to be done on the server side. You will need an AsyncHandler to go with your AsyncDataProvider:
AsyncHandler columnSortHandler = new AsyncHandler(dataGrid) {
#Override
public void onColumnSort(ColumnSortEvent event) {
#SuppressWarnings("unchecked")
int sortIndex = dataGrid.getColumnIndex((Column<Entry, ?>) event.getColumn());
boolean isAscending = event.isSortAscending();
service.getPage(0, sortIndex, isAscending, new AsyncCallback<List<Entry>>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(List<Entry> result) {
pager.setPage(0);
provider.updateRowData(0, result);
}
});
}
};
dataGrid.addColumnSortHandler(columnSortHandler);
Clicking on a column header will then fire a columnSortEvent. Then you have to get the column clicked. I am overloading my servlet to provide both sorting and pagination, so I pass a -1 for the column index when only pagination is desired.
provider = new AsyncDataProvider<Entry>() {
#Override
protected void onRangeChanged(HasData<Entry> display) {
final int start = display.getVisibleRange().getStart();
service.getPage(start, -1, true, new AsyncCallback<List<Entry>>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(List<Entry> result) {
provider.updateRowData(start, result);
}
});
}
};
provider.addDataDisplay(dataGrid);
provider.updateRowCount(0, true);
Then your servlet implementation of getPage performs the sorting and pagination. The whole thing is much easier to follow with separate event handlers.
I think the problem is with the ListHandler initialization. You are passing hostList as a parameter to List Handler and in onRangeChange method you are calling updateRowData with a different list (sublist).
Make sure you use the same list in both the places.
or
Move your ListHander initialization and cellTable.addColumnSortHandler method call to onRangeChange method after updateRowData call.

how to get cell value in a cell table using GWT

am using GWT 2.4, Hibernate and MysQL
I created a cell table , when i click on a cell i want to display the data/value in that particular cell
Thanks in advance
#override
public Widget onInitialize(){
CellTable grid = new CellTable<Bean>();
grid.setWidth("100%",true);
setColumns(grid);
}
private void setColumns(CellTable grid){
Column<Bean, String> firstNameColumn = new Column<Bean, String>(
new EditTextCell()) {
#Override
public String getValue(Bean object) {
return object.getFirstName();
}
};
firstNameColumn.setSortable(true);
grid.addColumn(firstNameColumn, "First Name");
Column<Bean, String> imageColumn = new Column<Bean, String>(
new ClikableTextCell()) {
#Override
public String getValue(Bean object) {
return "clickhere";
}
};
imageColumn.setSortable(true);
grid.addColumn(imageColumn, "Add Information");
firstNameColumn.setFieldUpdater(new FieldUpdater<Bean, String>() {
public void update(int index, Bean object, String value) {
Window.alert("You clicked " + object.getFullName());
}
});
cellTable.setColumnWidth(firstNameColumn, 20, Unit.PCT);
}
Use DataProvider and SingleSelectionModel for you cellTable:
private final ListDataProvider<SomeClass> dataProvider = new ListDataProvider<SomeClass>();
private final SingleSelectionModel<SomeClass> selectionModel = new SingleSelectionModel<SomeClass>();
//then
table.setSelectionModel(selectionModel);
dataProvider.addDataDisplay(table);
Heres how u can get the selected objects info:
showDataValueOfCellBtn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
SomeClass selected = selectionModel.getSelectedObject();
Window.alert (selected.getValue());
}
});

GWT CellTable and SimplePager issue

I am using a CellTable<Contact> in my GWT 2.4 project. Everything worked perfectly, so I decided to add paging to the table by using a SimplePager. The CellTable now displays the correct number of entries (page size), but all the pager buttons are disabled.
I am doing the following:
...
#UiField(provided=true) CellTable<Contact> contactsTable = new CellTable<Contact>();
#UiField SimplePager pager;
private TextColumn<Contact> nameColumn;
private TextColumn<Contact> surnameColumn;
public ViewContactsViewImplDesktop() {
initWidget(uiBinder.createAndBindUi(this));
initTable();
}
#Override
public final void updateContactList(final ArrayList<Contact> contacts) {
contactsTable.setRowCount(contacts.size());
final ListDataProvider<Contact> dataProvider = new ListDataProvider<Contact>();
List<Contact> list = dataProvider.getList();
for (final Contact c : contacts) {
list.add(c);
}
dataProvider.addDataDisplay(contactsTable);
pager = new SimplePager();
pager.setDisplay(contactsTable);
pager.setPageSize(3);
ListHandler<Contact> nameColumnSorter = new ListHandler<Contact>(list);
ListHandler<Contact> surnameColumnSorter = new ListHandler<Contact>(list);
nameColumnSorter.setComparator(nameColumn, new Comparator<Contact>() {
#Override
public int compare(Contact c1, Contact c2) {
return c1.getName().compareTo(c2.getName());
}
});
surnameColumnSorter.setComparator(surnameColumn, new Comparator<Contact>() {
#Override
public int compare(Contact c1, Contact c2) {
return c1.getSurname().compareTo(c2.getSurname());
}
});
contactsTable.addColumnSortHandler(nameColumnSorter);
contactsTable.addColumnSortHandler(surnameColumnSorter);
contactsTable.getColumnSortList().push(nameColumn);
}
private void initTable() {
nameColumn = new TextColumn<Contact>() {
#Override
public String getValue(Contact contact) {
return contact.getName();
}
};
surnameColumn = new TextColumn<Contact>() {
#Override
public String getValue(Contact contact) {
return contact.getSurname();
}
};
nameColumn.setSortable(true);
surnameColumn.setSortable(true);
contactsTable.addColumn(nameColumn, "Name");
contactsTable.addColumn(surnameColumn, "Surname");
}
Thanks!
Not setting the page size and/or not setting the table's row count manually could do the trick, as hinted in my comment.
I'd love to provide a concise code sample but do not have access to any code using cell widgets right now.