I want to build a CheckBox List like...
|===========|
| x label0 |
| x label1 |
| x label2 |
|===========|
...using CellList and I've done the following:
final List<Boolean> checks = Arrays.asList(true, false, true, true, false);
final CheckboxCell checkboxCell = new CheckboxCell();
final CellList<Boolean> checkBoxCellList = new CellList<Boolean(checkboxCell);
checkBoxCellList.setRowData(checks);
...so I get:
|=======|
| x |
| x |
| x |
|=======|
But how can I supply not only the value of a CheckBox (Boolean) but also its
label like it's possible with
CheckBox#setText("label0")
CheckBox#setValue(true)
?
I have done a similar thing for CellTable. So maybe SOMETHING like this will work. You need to provide your own render() method. So in the render() method below, you can add whatever you want.
Column<MyJSONObject, String> selectCheckBoxColumn =
new Column<MyJSONObject, String>(new MyCheckBoxCell()) {
#Override
public String getValue(MyJSONObject object) {
return object.getInternalId() + SEPERATOR + "true";
}
};
MyCellTable.addColumn(selectCheckBoxColumn, "Display title");
.....
.....
.....
private class MyCheckBoxCell extends AbstractCell<String> {
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
// ##############################################
String[] values = value.split(SEPERATOR);
// NOW values[0] contains the string value
// AND values[1] contains the boolean value
// ##############################################
sb.appendHtmlConstant("<input type='checkbox' name='" + htmlDOMId1 + "'" +
" id='" + htmlDOMId1 + "'" +
" value='" + value + "'" +
"></input>");
}
}
I know this question is old but I've just done this, so thought I would provide an answer anyway.
A CellList can only hold a vertical list of a single cell type. If you want to have a Checkbox in there, along with some other data, you need to build a custom cell and extend CompositeCell, which will combine and render multiple cells inside a single cell. You can see this in action here in the GWT Showcase (the innermost cell in the CellTree).
So your code should look something like this:
// first make a list of HasCell type - MyClass is the type of object being displayed in the CellList (could be String for simple labels)
List<HasCell<MyClass, ?>> hasCells = new ArrayList<HasCell<MyClass, ?>>();
// then add your checkbox cell to it
hasCells.add(new HasCell<MyClass, Boolean>()
{
private CheckboxCell cell = new CheckboxCell(true, false);
public Cell<Boolean> getCell()
{
return cell;
}
public FieldUpdater<MyClass, Boolean> getFieldUpdater()
{
return null;
}
#Override
public Boolean getValue(MyClass object)
{
return selectionModel.isSelected(object);
}
});
// then add your TextCell
hasCells.add(new HasCell<MyClass, MyClass>()
{
private TextCell cell = new TextCell(myString);
#Override
public Cell<MyClass> getCell()
{
return cell;
}
public FieldUpdater<MyClass, MyClass> getFieldUpdater()
{
return null;
}
public MyClass getValue(MyClass object)
{
return object;
}
});
// now construct the actual composite cell using the list (hasCells)
Cell<MyClass> myClassCell = new CompositeCell<MyClass>(hasCells)
{
#Override
public void render(Context context, MyClass value, SafeHtmlBuilder sb)
{
sb.appendHtmlConstant("<table><tbody><tr>");
super.render(context, value, sb);
sb.appendHtmlConstant("</tr></tbody></table>");
}
#Override
protected Element getContainerElement(Element parent)
{
// Return the first TR element in the table.
return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement();
}
#Override
protected <X> void render(Context context, MyClass value, SafeHtmlBuilder sb, HasCell<MyClass, X> hasCell)
{
// this renders each of the cells inside the composite cell in a new table cell
Cell<X> cell = hasCell.getCell();
sb.appendHtmlConstant("<td>");
cell.render(context, hasCell.getValue(value), sb);
sb.appendHtmlConstant("</td>");
}
};
// then make the actual cellList, passing the composite cell
myList = new CellList<MyClass>(myClassCell);
// add selectionModel, making sure to pass in a checkBoxManager as a second parameter, or the selectionModel will not work
myList.setSelectionModel(selectionModel, DefaultSelectionEventManager.<MyClass> createCheckboxManager());
// construct a dataProvider for dynamic editing of the list (alternative to list.setRowData())
dataProvider = new ListDataProvider<MyClass>(data);
// associate the dataProvider with the CellList
dataProvider.addDataDisplay(myList);
The easiest way to do this is to use a CellTable and dont add column headings (so it looks like a CellList)
Have a column for the checkbox (using CheckBoxCell) and have a column for your other data.
This is the cleanest way. No mucking around with your own custom cells with html-checkboxes inside of them.
This also works well with things like having a MultiSelectionModel on the cell table to get the values of the checkboxes.
A GWT book I'm reading has an example of this, except the author uses a vertical panel with checkboxes in the panel. With a little styling, you have a listbox look
Related
I have successfully created a datagrid table with two columns. A checkbox col and a string col. When I press a button I want to get the selected strings. Currently when I press the button i get an empty hash set.
Selection Model:
private MultiSelectionModel<String> selectionModel = new MultiSelectionModel<String>(KEY_PROVIDER);
Here is how I create the column
Column<String, Boolean> checkColumn =
new Column<String, Boolean>(new CheckboxCell(true, false)) {
#Override
public Boolean getValue(String object) {
// Get the value from the selection model.
return selectionModel.isSelected(object);
}
};
Here is the method that is called from the button
public Set<String> getSelectedItems(){
Set<String> s = selectionModel.getSelectedSet();
return s;
}
Two pieces are missing. You need to add a FieldUpdater to your checkColumn, and you need to link it to a checkbox manager. Replace T with your Object:
checkColumn.setFieldUpdater(new FieldUpdater<T, Boolean>() {
#Override
public void update(int index, T object, Boolean value) {
getSelectionModel().setSelected(object, value);
dataProvider.refresh();
}
});
setSelectionModel(selectionModel, DefaultSelectionEventManager.<T> createCheckboxManager(0));
Ok, i have a CellTable that has 3 columns and 2 rows. I want the text in SOME specific cells (not all cell) in the table to be BOLD.
Please look at this code:
ListDataProvider<List<String>> dataProvider = new ListDataProvider<List<String>>();
dataProvider.addDataDisplay(table);
List<List<String>> list = dataProvider.getList();
List<String> sublist1= Arrays.asList("223","546","698");
List<String> sublist2= Arrays.asList("123","876","898");
List<String> sublist2= Arrays.asList("123","896","438");
IndexedColumn column1=new IndexedColumn(0);
table.addColumn(column1, "Col1");
IndexedColumn column2=new IndexedColumn(1);
table.addColumn(column2, "Col2");
IndexedColumn column3=new IndexedColumn(2);
table.addColumn(column3, "Col3");
Now, I want the Cell that is the intersect of row2 & col3 (ie "898") to be BOLD, so if i do like this
column3.setCellStyleNames(getView().getRes().css().myBoldColor());
Then it will make the whole column BOLD.
So, i think properly we need to loop over each cell in column3 & set the style accordingly, so that we can have the result like this:
Col1 - Col2 - Col3
223 - 546 - 698
123 - 876 - 898
123 - 896 - 438
You can try it be extending AbstractCell also.
Read here about Implementing the render() Method.
Sample code:
static class BoldCell extends AbstractCell<String> {
/**
* The HTML templates used to render the cell.
*/
interface Templates extends SafeHtmlTemplates {
#SafeHtmlTemplates.Template("<div style=\"{0}\">{1}</div>")
SafeHtml cell(SafeStyles styles, SafeHtml value);
}
/**
* Create a singleton instance of the templates used to render the cell.
*/
private static Templates templates = GWT.create(Templates.class);
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
/*
* Always do a null check on the value. Cell widgets can pass null to cells if the
* underlying data contains a null, or if the data arrives out of order.
*/
if (value == null) {
return;
}
// If the value comes from the user, we escape it to avoid XSS attacks.
SafeHtml safeValue = SafeHtmlUtils.fromString(value);
// Use the template to create the Cell's html.
FontWeight weight = FontWeight.NORMAL;
if (safeValue.asString().equals("898")) {
weight = FontWeight.BOLD;
}
SafeStyles styles = SafeStylesUtils.forFontWeight(weight);
SafeHtml rendered = templates.cell(styles, safeValue);
sb.append(rendered);
}
}
In above code you can try it with row no also (Bold value for 0th column of 3rd row)
...
FontWeight weight = FontWeight.NORMAL;
if (context.getIndex()==2) {
weight = FontWeight.BOLD;
}
...
Cell<String> cell = new BoldCell();
Column<Contact, String> nameColumn = new Column<Contact, String>(cell) {
#Override
public String getValue(Contact object) {
return object.name;
}
};
table.addColumn(nameColumn, "Name");
Override getCellStyleNames() for a column:
Column<Document, Date> dueColumn = new Column<Document, Date>(new DateCell(DateTimeFormat.getFormat(PredefinedFormat.MONTH_ABBR_DAY))) {
#Override
public Date getValue(Document document) {
return document.getDueDate();
}
#Override
public String getCellStyleNames(Context context, Document document) {
if (document.getDueDate().getTime() < new Date().getTime()) {
return "boldStyle";
}
};
I have a class ContactCell based on AbstractCell.
It has two Labels and one Image (defined in GWT 2.5's UiBinder).
How do I Column.addColumn() to add a this custom cell to a CellTable?
And If so, how do I use the method getValue() to populate the fields of ContactCell when getValue() only returns simple values (such as String).
Column<Contact, String> column = new Column<Contact, String>(
new ContactCell()) {
#Override
public String getValue(Contact object) {
return object... CAN ONLY RETURN ONE VALUE. HOW TO POPULATE 2 LABELS & IMAGE?
}
};
You can change the render string by overridding the onrender mathod of the cell as follows.
Assuming 2 labels and a image can be computed from the value returned by getValue mathod.
ContactCell contactCell = new ContactCell()
{
#Override
public void render( com.google.gwt.cell.client.Cell.Context context, SafeHtml value, SafeHtmlBuilder sb )
{
// do value check and compute label1 and label2 and calso compute the image path.
sb.appendHtmlConstant( "<label>LABEL1</label>" +"<label>LABEL2</label>"+"<image></image>" )
}
});
Column<Contact, String> column = new Column<Contact, String>( contactCell )
{
#Override
public String getValue(Contact object)
{
return object... CAN ONLY RETURN ONE VALUE. HOW TO POPULATE 2 LABELS & IMAGE?
}
};
You can either use an IdentityColumn instead of a normal Column (will pass through the entire Contact object) or you use a normal Column like this:
Column<Contact, String[]> column = new Column<Contact, String[]>(
new ContactCell()) {
#Override
public String[] getValue(Contact object) {
String[] retvalue = new String[2];
retvalue[0] = "SOMETHING";
retvalue[1] = "SOME OTHER THING";
return retvalue;
}
};
If the cell based on AbstractCell is defined using UiBinder then it's not currently (GWT 2.5) possible to add such cells to a CellTable.
I am trying to add a Link in my cell table (I just want the item to be underlined and mouse symbol change on hover)
and on click I just want to give a window Alert .
for that i have tried these Options : ( but no luck )
1)
final Hyperlink hyp = new Hyperlink("test", "test");
Column<EmployerJobs, Hyperlink> test = new Column<EmployerJobs, Hyperlink>(new HyperLinkCell())
{
#Override
public Hyperlink getValue(EmployerJobs object)
{
return hyp;
}
};
Problem with option 1 is , it takes me to navigation page "test", whereas I dont want to go any other page i just want a window alert.
2)
Column<EmployerJobs, SafeHtml> test = new Column<EmployerJobs, SafeHtml>(new SafeHtmlCell())
{
#Override
public SafeHtml getValue(EmployerJobs object)
{
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendEscaped("test");
return sb.toSafeHtml();
}
};
problem with option 2 is I dont know what exactly to return here and its not getting underlined.
3) at last i am trying to add anchor in my celltable with a compositecell(as ideally i want three different anchors in my ONE cell)
final Anchor anc = new Anchor();
ArrayList list = new ArrayList();
list.add(anc);
CompositeCell ancCell = new CompositeCell(list);
Column testColumn1 = new Column<EmployerJobs, Anchor>(ancCell) {
#Override
public Anchor getValue(EmployerJobs object) {
return anc;
}
};
Option 3 is giving some exception .
If you can help me get working any of the above option, I'll be grateful
Thanks
You are doing it totally wrong. You need to use ActionCell for stuff like this or create your own cell. Example code:
ActionCell.Delegate<String> delegate = new ActionCell.Delegate<String>(){
public void execute(String value) { //this method will be executed as soon as someone clicks the cell
Window.alert(value);
}
};
ActionCell<String> cell = new ActionCell<String>(safeHtmlTitle,delegate){
#Override
public void render(com.google.gwt.cell.client.Cell.Context context, //we need to render link instead of default button
String value, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<a href='#'>");
sb.appendEscaped(value);
sb.appendHtmlConstant("</a>");
}
};
Column testColumn1 = new Column<EmployerJobs, String>(cell) {
#Override
public String getValue(EmployerJobs object) {
//we have to return a value which will be passed into the actioncell
return object.name;
}
};
I recommend to read official documentation for Cell Widgets, since it is pretty much everything what you need to know about cell widgets.
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().