Does anybody know if this is possible to add a column to CellTable depending on the some value od displayed row?
Normally addColumn is used but the access to row properties is enabled only in getValue method. I need to gain this access earlier to decide either to add some value to column or lewave it blank.
The answer is to write custom cell class that extends the appropriate cell class (provided with GWT). Then in render method the column's content might be empty or not depending on the value of displayed/rendered object. E.g.
private class VersionCell<T> extends ActionCell<MovieDTO> {
public VersionCell(String text, Delegate<MovieDTO> delegate) {
super(text, delegate);
}
#Override
public void render(MovieDTO m, Object key, SafeHtmlBuilder sb) {
if (m != null && m.getId() != -1) {
super.render(m, key, sb);
} else if (m != null && m.getId() == -1) {
sb.append(new SafeHtmlBuilder().appendHtmlConstant("").toSafeHtml());
}
}
}
Related
i am new to GWT.I know tablename.removeColumn(columnname) can be used to remove the column, but instead of removing i want to disable it. Can anybody please help
thnx in advance!
There are some ways to do this, but an easy and clean way to do it is the following :
public static class CustomTextInputCell extends TextInputCell {
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
String url = Window.Location.getHref();
boolean isEditable = url.contains("xyz");
if (isEditable) //Condition if editable or not
super.render(context, value, sb);
else if (value != null) {
sb.appendEscaped(value);
}
}
}
The render method will be called every time this cell is rendered. So every time it will check if the condition is met to be enabled or not.
This allows you to keep all the functionality of an editable cell but disable it easily when the condition is met.
You use it like this
Column<YOUR_OBJECT_HERE, String> column = new Column<YOUR_OBJECT_HERE, String>(new CustomTextInputCell());
cellTable.addColumn(column , "YOUR_HEADER_HERE");
I ended up creating a new component that has the columns that i want and called that component based on the url
String url = Window.Location.getHref();
boolean value = url.contains("xyz");
if(value)
{
component.setEnable(true);
}
else{
componentprevious.setEnable(true);
}
enter code here
I have a widget that I render in a GWT cell, which extends the AbstractCell, via the render function below. The column is created as below with the getValue and the FieldUpdater (update) function being defined. The intent is to set selected row to correspond to the clicked widget. However, when I click on the widget, the onBrowserEvent function of the cell is not called. I think this is happening because the widget in question contains a FlexTable within it.
I verified this by setting a breakpoint in the function AbstractCellTable.onBrowserEvent2 and noticed that the function does not fire a cell event since the
else if (section == getTableBodyElement())
return false. This is false because the section is a sub-section of the table body element corresponding to the table that I inserted via the widget.
Is there a way to pass the click in the inner table (widget) to the outer cell table?
//Render function to add widget to cell
public void render(Context context, MyItem value, SafeHtmlBuilder sb) {
if (value != null) {
SafeHtml safeValue = SafeHtmlUtils.fromTrustedString(value
.getWidget().getElement().getString());
sb.append(safeValue);
}
}
//Creating the corresponding column, setting up the field update,
// and adding the column to cell table
// Create Cell
MyItemCell myItemCell = new MyItemCell();
// Create Column
Column<MyItem, MyItem> myItemColumn = new Column<MyItem, MyItem>(myItemCell) {
#Override
public MyItem getValue(MyItem object) {
return object;
}
};
// add field updater
myItemColumn.setFieldUpdater(new FieldUpdater<MyItem, MyItem>() {
#Override
public void update(int index, MyItem object, MyItem value) {
// This function, for some reason,
// is not getting called when I click
// on the widget corresponding to MyItem
MyDataTable.this.getSelectionModel().setSelected(object, true);
}
});
// Add column to table
this.getDataTable().addColumn(myItemColumn);
FieldUpdater method is called when updating values in the column.
To catch click event, if I am not wrong then MyItemCell is your custom cell. so inside that cell implement onBrowserEvent event and handle click event there.
public void onBrowserEvent(final Event event) {
// TODO Auto-generated method stub
super.onBrowserEvent(event);
if (DOM.eventGetType(event) == Event.ONCLICK) {
System.out.println("event type -->> " + event.getType());
}
}
I'm using GWT 2.4. When using a CellTable, I've seen its possible to add a column in which all of the cells are editable ...
final TextInputCell nameCell = new TextInputCell();
Column<Contact, String> nameColumn = new Column<Contact, String>(nameCell) {
#Override
public String getValue(Contact object) {
return object.name;
}
};
table.addColumn(nameColumn, "Name");
but what if I don't want every cell in the column to be editable, only specific ones, based on properties in my "Contact" object? How would I set this up? Thanks, - Dave
The way I would do it is extend the TextInputCell and override the render method to render something else, if you don't want the value in that particular row editable.
Something like this:
public class MyTextInputCell extends TextInputCell {
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
YourObject object = getYourObject();
if ( object.isThisCellEditable() ) {
super.render(context,value,sb);
} else {
sb.appendEscaped(value); // our some other HTML. Whatever you want.
}
}
}
In the render method you have access to the cell's context. Context.getIndex() returns the absolute index of the object. I can't remember of the top of my wad right now, but if you do not provide a ProvidesKey implementation when creating your CellTable you will get one that will use the object itself as the key. So you can get the object using Context.getKey().
I have a CellTable with one custom column where I render it manually and put a FlowPanel with a bunch of HTMLPanel/Anchor/FlowPanel widgets, and among them is DecoratorPanel.
DecoratorPanel renders as a table, of course.
Rendering happens like this:
public class MyExpandableCell extends AbstractCell<String> {
...
#Override
public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb) {
if (value != null) {
FlowPanel fp = createDetailsFlowPanel(value);
sb.appendHtmlConstant(fp.getElement().getString());
}
}
Now, I have added a handler for click events to my main CellTable. In my handler I traverse the tree to find a first TR belonging to my CellTable, by checking if it contains "even row" or "odd row" CSS classes.
However, when click happens inside of the DecoratorPanel (which is inside of my cell table's TD), my handler also gets triggered, since the click belongs to the cell table area.
I can detect this my seeing that parent TR does not have CellTable CSS classes.
QUESTION: how can I return processing of such click events to the DecoratorPanel - where it really belongs to? As it is now, my DecoratorPanel does not expand and I think because my click handler intercepts and suppresses all clicks on the CellTable level.
table = setupMyCellTable(PAGE_SIZE, CLIENT_BUNDLE, myCellTableResources);
mydataprovider.addDataDisplay(table);
table.sinkEvents(Event.ONCLICK);
table.addDomHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent e) {
boolean isClick = "click".equals(e.getNativeEvent().getType());
if (isClick) {
Element originalElement = e.getNativeEvent().getEventTarget().cast();
Element element = originalElement;
String ctTrClassEven = CLIENT_BUNDLE.mainCss().cellTableEvenRow();
String ctTrClassEven = CLIENT_BUNDLE.mainCss().cellTableOddRow();
// Looking for closest parent TR which has one
// of the two row class names (for this cellTable):
while (element != null
&& !"tr".equalsIgnoreCase(element.getTagName())
&& !(element.getClassName().contains(ctTrClassEven) ||
element.getClassName().contains(ctTrClassEven))) {
element = element.getParentElement();
}
if (element != null) {
if (element.getClassName().contains(ctTrClassEven)
|| element.getClassName().contains(ctTrClassEven)) {
// Found cell table's TR. Set new TR height.
} else {
// Found TR from DecoratorPanel inside of the celltable's cell.
// Do nothing. But how do I make sure
// that decorator panel processes this click and expands?
return;
// Did not work: NS_ERROR_ILLEGAL_VALUE javascript exception.
// if (originalElement != null) {
// originalElement.dispatchEvent(e.getNativeEvent());
// }
}
} else {
debugStr.setText("(did not find tr)");
}
}
}
}, ClickEvent.getType());
Looks like a bug in GWT, triggered because decorator panel uses table to render itself:
http://code.google.com/p/google-web-toolkit/issues/detail?id=5714
(another example http://code.google.com/p/google-web-toolkit/issues/detail?id=6750)
Fix is expected to be shipped with GWT 2.5.
Here iam using a wicketText Textfield component to which an Integer type is mapped, Now on load of page iam getting the '0' as default value in that textfield. How to remove that 0 from the textfield.
Don't use int as the property type: that can't be null. Use Integer instead.
The TextField converts the value of the object in the model to a String. In case the object is null, the String will be empty.
You are probably using a int as Matrijn indicated. The java built-in primitive type can never be null but defaults to 0
So use a Integer. (Or you could create a custom Converter, but that is just messy)
what about using NumberTextField like this
NumberTextField numberField = (NumberTextField) new NumberTextField("numberField",
new Model(10));
I believe You may be using int instead of Integer. (int cannot be null, while Integer can)
Try to customize the Converter of your TextField
public class Converter<C> implements IConverter<C> {
#Override
public C convertToObject(String s, Locale locale) throws ConversionException {
return (C) s;
}
#Override
public String convertToString(C c, Locale locale) {
Class<? extends Object> aclass = c.getClass();
if (aclass == Long.class) {
return ((Long) c != 0) ? String.valueOf(c) : "";
} else if (aclass == Integer.class) {
return ((Integer) c != 0) ? String.valueOf(c) : "";
} else if (aclass == BigDecimal.class) {
return (!BigDecimal.ZERO.equals(c)) ? String.valueOf(c) : "";
}
return c.toString();
}
}
and then, override the default IConverter
new TextField<BigDecimal>("id") {
#Override
public <C> IConverter<C> getConverter(Class<C> type) {
return new Converter<C>();
}
}
The generic type of text field should be a reference. The Integer is good choice. But for a good programming choice it is better to use String.The new Model("") make your text field empty.
TextField<Integer> a = new TextField<Integer>("id",new Model(""));
you can get the integer value of your textfield by a.getValue() method.You can parse the such strings to int by Integer.parseInt(a.getValue()); property.
TextField<String> a = new TextField<String>("id",new Model(""));