GWT CellTable Cells readOnly/disabled/non-editable - gwt

I want to make that some cells of the rows can be non-editable.
by now my solution is when i create the columns, if one is readOnly, y make a TextCell, if not, i go with the default Cell wich can be EditTextCell,DatePickerCell,etc.
The problem with this is that i can't make some rows readOnly and others not. Or they are ALL the fields readOnly or they are not.
How can i do to make this for example
TABLE:
Data1 | Data2 | Data3
--------------------------------------
readOnly | non-readOnly | readOnly
readOnly | readOnly | non-readOnly
when i mean "readOnly" it can be "enabled" or make it a "TextCell"
celda = new TextInputCell();
Column<ObjetoDato, String> columna = new Column<ObjetoDato, String>(celda) {
#Override
public String getValue(ObjetoDato object) {
if(actual.getValorDefault()!=null && object.getValor(actual.getNombreCampo()).isEmpty()){
object.setValor(actual.getNombreCampo(), actual.getValorDefault());
return actual.getValorDefault();
}
return object.getValor(actual.getNombreCampo());
}
};
tabla.agregarColumna(columna, actual.getCaption());
columna.setFieldUpdater(new FieldUpdater<ObjetoDato, String>() {
#Override
public void update(int index, ObjetoDato object, String value) {
object.setValor(actual.getNombreCampo(), value);
new Scripter(object,actual.getComportamiento(),true);
tabla.actualizar();
Sistema.get().getIG().actualizarTotales();
}
});
I tried creating my cutom cell already and replacing the TextImputCell, but the methods never trigger
celda = new FabriCel();
and
public class FabriCel extends TextInputCell {
private String campo;
public FabriCel(String campo){
this.campo=campo;
}
#Override
public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event, ValueUpdater<String> valueUpdater){
Boolean editable = false;///get it from your model
if(editable != null && !editable){
event.preventDefault();
}else{
super.onBrowserEvent(context, parent, value, event, valueUpdater);
}
}
Also this
#Override
public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb) {
Boolean editable = false;///get it from your model
if(editable){
Log.log();
sb.appendHtmlConstant("<div contentEditable='false'>" +value+"</div>");
}else{
Log.log("No entra");
super.render(context, value, sb);
}
}
Thanks!

You have to create one custom cell. In that, you have tell runtime like it should be readonly or no-readonly. just example.
private class CustomCell extends EditTextCell {
public void render(com.google.gwt.cell.client.Cell.Context context,
String value, SafeHtmlBuilder sb) {
Data data=context.getKey();
if(data.isReadOnly()){
sb.appendHtmlConstant("<div contentEditable='false'
unselectable='false' >" +value+"</div>");
}else{
super.render(context, value, sb);
}
}
}
In given bean, there is some condition which says readonly or no-readonly.
And create column like
Column<Data, String> nameColumn = new Column<Data, String>(new CustomCell()) {
#Override
public String getValue(Data object) {
return object.getName();
}
};

A way to do this is to override the onBrowserEvent event of your Editable Cells and consume the event if the cell is not editable.
final EditTextCell cell = new EditTextCell(renderer)
{
#Override
public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event, ValueUpdater<String> valueUpdater)
{
Boolean editable = false;///get it from your model
if(editable != null && !editable)
{
event.preventDefault();
}
else
{
super.onBrowserEvent(context, parent, value, event, valueUpdater);
}
}
}

I had the same need; and tested out various combinations of overriding render, isEditing, resetFocus, and edit on EditTextCell (I didn't try the onBrowserEvent solution).
When I only overrode render (to show an HTML value if non-editable); I got errors resetting focus (as discussed here). This continued even if I overrode resetFocus. When I only override isEditing, the cell would flash to editing when clicked, and then flash back. What worked perfectly was overriding edit. I triggered based on adding a tag to the value passed in by Column.getValue, you can trigger however you like, but it turned out to be as simple as:
private static class LockableEditTextCell extends EditTextCell {
#Override
protected void edit(Context context, Element parent, java.lang.String value) {
if (!value.startsWith(LOCKED_CELL_VALUE)) {
super.edit(context, parent, value);
}
}
}

Related

Dynamically and Programatically Uncheck a CheckboxCell

I have a Datagrid with a CheckboxCell column. There will be some rows that cannot be checked, and the way I would like to implement this would be to handle the "checked" event and cancel it if some criteria is met. Here is the code I have tried:
Column<Job, Boolean> selectColumn = new Column<Job, Boolean>(new CheckboxCell()) {
#Override
public Boolean getValue(Job job) {
// do I uncheck the cell here?
return JobDataGrid.this.jobSelection.isSelected(job);
}
#Override
public void onBrowserEvent(Cell.Context context, Element elem, Job object, NativeEvent event)
{
super.onBrowserEvent(context, elem, object, event);
String eventType = event.getType();
if ("change".equals(eventType)) {
// do I uncheck the cell here?
}
}
};
How do I handle the event and set the checkbox to be unchecked?
If you want to prevent the change in a checkbox, you can simply cancel the native event inside your onBrowserEvent method:
event.preventDefault();
Note that if you don't update your object when a checkbox is clicked, you can always refresh() your DataGrid and the checkbox will be displayed in its original state.
If you want to make a check box uncheckable, from the UX perspective it is better be disabled.
You can create a custom check box cell where you can control every aspect of rendering of the element including disabled state:
public class UncheckableCheckboxCell extends CheckboxCell {
interface Template extends SafeHtmlTemplates {
#Template("<input type=\"checkbox\" tabindex=\"-1\" checked/>")
SafeHtml INPUT_CHECKED();
#Template("<input type=\"checkbox\" tabindex=\"-1\"/>")
SafeHtml INPUT_UNCHECKED();
#Template("<input type=\"checkbox\" tabindex=\"-1\" disabled=\"disabled\"/>")
SafeHtml INPUT_UNCHECKED_DISABLED();
}
private static UncheckableCheckboxCell.Template template = GWT.create(UncheckableCheckboxCell.Template.class);
public UncheckableCheckboxCell(boolean dependsOnSelection, boolean handlesSelection) {
super(dependsOnSelection, handlesSelection);
}
#Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
// Get the view data.
Object key = context.getKey();
Boolean viewData = getViewData(key);
if (viewData != null && viewData.equals(value)) {
clearViewData(key);
viewData = null;
}
if (value != null && ((viewData != null) ? viewData : value)) {
sb.append(template.INPUT_CHECKED());
} else if (value == null) {
//use null value as an indicator of unchecked and disable state
sb.append(template.INPUT_UNCHECKED_DISABLED());
} else {
sb.append(template.INPUT_UNCHECKED());
}
}
}
Then inside your getValue() method you can return null when you want the check box to be unchecked/disabled:
#Override
public Boolean getValue(Job job) {
// is my job checkable?
if (job.checkable()) {
//return null explicitly so my custom cell knows it should be rendered as disabled
return null;
} else {
return JobDataGrid.this.jobSelection.isSelected(job);
}
}

GWT ImageCell: Change image dynamically in a DataGrid or CellTable

I have DataGrid where one on of the columns contains images. I used this code to generate the column.
Column<Job, String> expandHideColumn = new Column<Job, String>(
imageCell) {
#Override
public String getValue(Job object) {
return null;
}
#Override
public void render(Context context, Job Object, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<img src='images/expand.jpeg' style='cursor: pointer' />");
}
}
What I want is on clicking the image it has to change. For this I added a click handler on the ImageCell like this
ImageCell imageCell = new ImageCell() {
#Override
public Set<String> getConsumedEvents() {
Set<String> events = new HashSet<String>();
events.add("click");
return events;
}
};
In the onBrowserEvent method I wrote this
#Override
public void onBrowserEvent(Context context, Element element,
Job job, NativeEvent event) {
if (element.getFirstChildElement().isOrHasChild(
Element.as(event.getEventTarget()))) {
if (element.getFirstChildElement().getPropertyString("src")
.matches("(.*)expand.jpeg")) {
element.getFirstChildElement().setPropertyString("src",
"images/collapse.jpeg");
} else {
element.getFirstChildElement().setPropertyString("src",
"images/expand.jpeg");
}
}
}
I don't think this is a good approach to change images on click event. Is there a better solution?
You can use a column value for know the state of the column :
Column<Job, Boolean> expandHideColumn = new Column<Job, Boolean>(new ImageExpandCollapseCell()) {
#Override
public Boolean getValue(Job object) {
return object.isExpand(); //The object know the expand state ?
}
}
expandHideColumn.setValueUpdater(new FieldUpdater<Job, Boolean>() {
void update(int index, Job object, Boolean value) {
object.setExpand(value);
}
});
The ImageExpandCollapseCell look like this :
public class ImageExpandCollapseCell extends AbstractCell<Boolean> {
final String EXPAND = "images/expand.jpeg";
final String COLLAPSE = "images/collapse.jpeg";
interface Template extends SafeHtmlTemplates {
#Template("<div style=\"float:right\"><img src=\"" + url + "\"></div>")
SafeHtml img(String url);
}
private static Template template;
/**
* Construct a new ImageCell.
*/
public ImageCell() {
super("click"); //Replace your getConsumedEvents()
if (template == null) {
template = GWT.create(Template.class);
}
}
#Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(template.img(UriUtils.fromSafeConstant(value ? EXPAND : COLLAPSE)));
}
}
#Override
public void onBrowserEvent(Context context, Element element,
Boolean value, NativeEvent event, ValueUpdater<Boolean> valueUpdater) {
valueUpdate.update(!value);
}
}
I improve the proposed version of user905374
It's not a good idea to instantiate new value in the render method.
The column render method call the Cell render method, you musn't replace it !
With the FieldUpdater, you can change the state of the image : expand or collapse and update the cell display (it will be rendered again).

GWT Header CheckBox requires two clicks to fire setValue, after changing its value programatically

I have a GWT DataGrid, and a CheckBox in the Header to select/deselect all rows in the grid.
The code for the CheckBox Header is as follows:
private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {
private boolean checked;
private HandlerManager handlerManager;
/**
* An html string representation of a checked input box.
*/
private final SafeHtml INPUT_CHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
/**
* An html string representation of an unchecked input box.
*/
private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");
#Override
public void render(Context context, SafeHtmlBuilder sb) {
if (Boolean.TRUE.equals(this.getValue())) {
sb.append(INPUT_CHECKED);
} else {
sb.append(INPUT_UNCHECKED);
}
};
public CheckboxHeader() {
super(new CheckboxCell(true, false));
checked = true;
}
// This method is invoked to pass the value to the CheckboxCell's render method
#Override
public Boolean getValue() {
return checked;
}
#Override
public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent) {
int eventType = Event.as(nativeEvent).getTypeInt();
if (eventType == Event.ONCHANGE) {
nativeEvent.preventDefault();
// use value setter to easily fire change event to handlers
setValue(!checked, true);
}
}
#Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
}
#Override
public void fireEvent(GwtEvent<?> event) {
ensureHandlerManager().fireEvent(event);
}
#Override
public void setValue(Boolean value) {
setValue(value, true);
}
#Override
public void setValue(Boolean value, boolean fireEvents) {
checked = value;
if (fireEvents) {
ValueChangeEvent.fire(this, value);
}
}
private HandlerManager ensureHandlerManager() {
if (handlerManager == null) {
handlerManager = new HandlerManager(this);
}
return handlerManager;
}
}
So, I add the Header to the grid, and I add a ValueChangeHandler to it to do the actual selecting/deselecting of individual CheckBox cells in every row of the grid. This all works.
Every CheckBoxCell has a Field Updater, and on every update it loops through every item in the grid to see if they are all checked, and update the header check box. If at least one is unchecked, the header checkbox will be unchecked. I call setValue() on the header check box, and after that I call redrawHeaders() on the entire grid. This also works.
What doesn't work is - after changing the "state" of the header check box programatically, it takes two clicks for it to fire it's internal setValue again, and therefore trigger my handler. And what's even funnier - the first click does change the state of the check box, but it just doesn't fire the event.
Any help would be appreciated.
How are you constructing the CheckboxCells themselves? I ran into a similar issue with a column of checkboxes "eating" clicks, and the solution was to call CheckboxCell cell = new CheckboxCell(true,true) and then pass that cell into the constructor of the column.

Handling onClick for a checkbox in a CellTable Header

I am trying to create a CellTable that has a column with some text and a checkbox, which will be used as a select all checkbox (see the drawing below, "cb" is checkbox). Currently I am using an class derived from Header and overriding it's render method to output the text and a checkbox. I am overriding onBrowserEvent() however it is only giving me onChange events, which would work fine except that the checkbox doesn't function correctly. Does anyone have any ideas on this?
+-------+------------+
| col 1 | Select All |
| | cb |
+-------+------------+
| row 1 | cb |
+-------+------------+
The issues I'm having with the checkbox is that when it's not checked, you have to click it twice for the checkmark to appear (at least on Chrome), even though it's "checked" property is true the first time. One click unchecks it correctly.
Here is some code:
Setup the CellTable columns:
/** Setup the table's columns. */
private void setupTableColumns() {
// Add the first column:
TextColumn<MyObject> column1 = new TextColumn<MyObject>() {
#Override
public String getValue(final MyObject object) {
return object.getColumn1Text();
}
};
table.addColumn(macColumn, SafeHtmlUtils.fromSafeConstant("Column1"));
// the checkbox column for selecting the lease
Column<MyObject, Boolean> checkColumn = new Column<MyObject, Boolean>(
new CheckboxCell(true, false)) {
#Override
public Boolean getValue(final MyObject object) {
return selectionModel.isSelected(object);
}
};
SelectAllHeader selectAll = new SelectAllHeader();
selectAll.setSelectAllHandler(new SelectHandler());
table.addColumn(checkColumn, selectAll);
}
My Select All Header:
public static class SelectAllHeader extends Header<Boolean> {
private final String checkboxID = "selectAllCheckbox";
private ISelectAllHandler handler = null;
#Override
public void render(final Context context, final SafeHtmlBuilder sb) {
String html = "<div>Select All<div><input type=\"checkbox\" id=\"" + checkboxID + "\"/>";
sb.appendHtmlConstant(html);
}
private final Boolean allSelected;
public SelectAllHeader() {
super(new CheckboxCell());
allSelected = false;
}
#Override
public Boolean getValue() {
Element checkboxElem = DOM.getElementById(checkboxID);
return checkboxElem.getPropertyBoolean("checked");
}
#Override
public void onBrowserEvent(final Context context, final Element element, final NativeEvent event) {
Event evt = Event.as(event);
int eventType = evt.getTypeInt();
super.onBrowserEvent(context, element, event);
switch (eventType) {
case Event.ONCHANGE:
handler.onSelectAllClicked(getValue());
event.preventDefault();
break;
default:
break;
}
}
public void setSelectAllHandler(final ISelectAllHandler handler) {
this.handler = handler;
}
}
It looks like you're rendering a non-checked checkbox whenever you render the header, which could be wiping out the selection state whenever the celltable re-renders.
Try storing the checked state and rendering the checkbox with the state. It looks like you're half way there with allSelected, you're just not using it.
EDIT Here is a working implementation I've just written for Zanata (see SearchResultsView.java). The HasValue interface is implemented so that value change events can be handled in a standard way. I have not overridden the render method, if you want to do so make sure you use getValue() to determine whether you render a checked or an unchecked checkbox. The selection/de-selection logic is handled in the associated presenter class (see SearchResultsPresenter.java).
private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {
private boolean checked;
private HandlerManager handlerManager;
public CheckboxHeader()
{
//TODO consider custom cell with text
super(new CheckboxCell());
checked = false;
}
// This method is invoked to pass the value to the CheckboxCell's render method
#Override
public Boolean getValue()
{
return checked;
}
#Override
public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent)
{
int eventType = Event.as(nativeEvent).getTypeInt();
if (eventType == Event.ONCHANGE)
{
nativeEvent.preventDefault();
//use value setter to easily fire change event to handlers
setValue(!checked, true);
}
}
#Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler)
{
return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
}
#Override
public void fireEvent(GwtEvent<?> event)
{
ensureHandlerManager().fireEvent(event);
}
#Override
public void setValue(Boolean value)
{
checked = value;
}
#Override
public void setValue(Boolean value, boolean fireEvents)
{
checked = value;
if (fireEvents)
{
ValueChangeEvent.fire(this, value);
}
}
private HandlerManager ensureHandlerManager()
{
if (handlerManager == null)
{
handlerManager = new HandlerManager(this);
}
return handlerManager;
}
}

How can I render a ClickableTextCell as an anchor in a GWT CellTable?

I've got a CellTable with multiple columns in simple TextCell()s. Two of the columns are 'clickable' via the ClickableTextCell() class, but I want to change how they look. What's the easiest way to get the cell contents to resemble an anchor tag, while still using a cell in the table?
I've tried the following:
1. Implement a custom renderer to add anchor tags
2. Scouring Google looking for hints
3. Ignoring 'my library does it you just have to change your entire framework' links
4. Rolling my head across they keyboard
It's funny how annoying this simple change is turning out to be.
My current thought is to implement a custom AnchorCell type which puts in an Anchor widget instead of whatever it does in the other ones, but I'm not sure what all would need to be done.
Any help is appreciated.
As an example:
public class MyClickableCellText extends ClickableTextCell {
String style;
public MyClickableCellText()
{
super();
style = "myClickableCellTestStyle";
}
#Override
protected void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendHtmlConstant("<div class=\""+style+"\">");
sb.append(value);
sb.appendHtmlConstant("</div>");
}
}
public void addStyleName(String style)
{
this.style = style;
}
}
And the style (without the div, because you are hardcoding the style on it):
.myClickableCellTestStyle{
text-decoration:underline;
}
You can even create your own cell by not extending ClickableTextCell but extending AbstractCell (more powerful but need more explanation). Ask me if you need it!
Mentioned solution have the problem, these are no links and stylesheets with a:hover and so on doesn't work.
Here is my solution:
private class SellerName {
private final String sellerName;
private final Command cmd;
private SellerName(String displayName, Command cmd) {
this.sellerName = displayName;
this.cmd = cmd;
}
public String getDisplayName() {
return sellerName;
}
public Command getCommand() {
return cmd;
}
};
private class SellerNameCell extends AbstractCell<SellerName> {
public SellerNameCell() {
super("click", "keydown");
}
#Override
public void render(com.google.gwt.cell.client.Cell.Context context, SellerName value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendHtmlConstant("<a href='javascript:;'>");
sb.appendEscaped(value.getDisplayName());
sb.appendHtmlConstant("</a>");
}
}
#Override
public void onBrowserEvent(Context context, Element parent, SellerName value, NativeEvent event, ValueUpdater<SellerName> valueUpdater) {
if (value == null)
return;
super.onBrowserEvent(context, parent, value, event, valueUpdater);
if ("click".equals(event.getType())) {
if (value.getCommand() != null)
value.getCommand().execute();
}
}
};
It creates a real anchorcell which is clickable :)
It would seem that your first instinct (implementing a custom renderer) is way easier:
SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>()
{
#Override
public SafeHtml render(String object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("<a href=\"javascript:;\">")
.appendEscaped(object).appendHtmlConstant("</a>");
return sb.toSafeHtml();
}
};
And then:
Column<YourThingy, String> anchorCol = new Column<YourThingy, String>(
new ClickableTextCell(anchorRenderer))
{
#Override
public String getValue(YourThingy object) {
return object.toString();
}
};
This is what you need:
public class ClickableSafeHtmlCell extends AbstractCell<SafeHtml> {
/**
* Construct a new ClickableSafeHtmlCell.
*/
public ClickableSafeHtmlCell() {
super("click", "keydown");
}
#Override
public void onBrowserEvent(Context context, Element parent, SafeHtml value, NativeEvent event,
ValueUpdater<SafeHtml> valueUpdater) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
if ("click".equals(event.getType())) {
onEnterKeyDown(context, parent, value, event, valueUpdater);
}
}
#Override
protected void onEnterKeyDown(Context context, Element parent, SafeHtml value,
NativeEvent event, ValueUpdater<SafeHtml> valueUpdater) {
if (valueUpdater != null) {
valueUpdater.update(value);
}
}
#Override
public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(value);
}
}
And then usage:
Column<YourProxy, SafeHtml> nameColumn = new Column<YourProxy, SafeHtml>(
new ClickableSafeHtmlCell()) {
#Override
public SafeHtml getValue(YourProxy object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("<a>");
sb.appendEscaped(object.getName());
sb.appendHtmlConstant("</a>");
return sb.toSafeHtml();
}
};
nameColumn.setFieldUpdater(new FieldUpdater<YourProxy, SafeHtml>() {
#Override
public void update(int index, YourProxy object, SafeHtml value) {
Window.alert("You have clicked: " + object.getName());
}
});
This is actually quite simple, but it's amazing how many wrong and convoluted answers there are on Google, and seemingly no correct ones! Anyway, here's the code:
private Column<Object, SafeHtml> getAnchorColumn() {
return new Column<Object, SafeHtml>(new SafeHtmlCell()) {
#Override
public SafeHtml getValue(final Object object) {
Anchor anchor = new Anchor();
anchor.setHref(object.getURL());
anchor.setText(object.getText());
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant(anchor.toString());
return sb.toSafeHtml();
}
};
}
Change object to whatever it is you're trying to render in the table then run this method when creating the column, easy!
If you take a look to the clickableTextCell html code generated by gwt you will see something like (taken from gwt showcase)
<div style="outline:none;" tabindex="0">Click Robert</div>
So I will recommend u doing something like:
ClickableTextCell cell = new ClickableTextCell();
cell.addStyleName("yourStyle");
and in you style.css do whatever you want.
.yourStyle div{
text-decoration:underline;
}
It is essentially a hack to use appendHtmlConstant. Simply using toString of the Anchor or its element or passing a HTML string violates the concept behind SafeHtml entirely.
In my opinion a proper SafeHtmlTemplates should be used to tackle unreadable and unsafe string concatenation of HTML. Similar to:
protected interface AnchorTemplate extends SafeHtmlTemplates {
#Template("{1}")
SafeHtml anchor(String url, String text);
}
Then you can use GWT.create on it and interpolate the arguments properly.
Second part is that reading the HTML string of a widget could be optimized out. I was extending AbstractCell and had this method:
/* do not dare to copy - considered broken */
#Override
public void render(final Context context, final String value, final SafeHtmlBuilder sb) {
final Anchor anchor = new Anchor();
anchor.setText(value);
sb.appendHtmlConstant(anchor.getElement().toString());
}
I just experienced a case where the anchor cell was working fine in superdev mode, but compiling it (probably with more aggressive optimization settings) and then deploying it manually led to an entirely empty cell with no changes in code reproducibly across several systems. Using the template mechanism described above made it work properly (GWT 2.7).
First things first - each GWT CellTable Column is just a stack of Cell(s), as our need is to make each Cell look like an anchor which can listen to Click event lets provide ClickableTextCell as argument to Column.
Column<YourObj, String> col = new Column<YourObj, String>(new ClickableTextCell()) {};
2nd - override "render()" method in your Column instance and build your HTML template that you want, here our need is creating an anchor.
#Override
public void render(Context context, YourObj yourObj, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<a style='text-decoration:underline; cursor: pointer;'>" + yourObj.getX() + "</a>");
}
3rd - as we are using ClickableTextCell, it serves as Click Event source. We need to provide ClickEvent listener, we do that by overriding "onBrowserEvent()" method.
#Override
public void onBrowserEvent(Context context, Element elem, Customer customer, NativeEvent event) {
if ("click".equals(event.getType())) {
Window.alert("ID is : " + customer.getId());
}
}
Complete Code snippet :
Column<YourObj, String> col = new Column<YourObj, String>(new ClickableTextCell()) {
#Override
public String getValue(final YourObj yourObj) {
return yourObj.getX();
}
#Override
public void render(Context context, YourObj yourObj, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<a style='text-decoration:underline; cursor: pointer;'>" + yourObj.getX() + "</a>");
}
#Override
public void onBrowserEvent(Context context, Element elem, YourObj yourObj, NativeEvent event) {
if ("click".equals(event.getType())) {
Window.alert("ID is : " + yourObj.getId());
}
}
};
cellTable.addColumn(col, "First Name");