GWT CellTable - set column width - gwt

Is it possible to set the column width of CellTable in GWT?

EDIT: As of GWT 2.2 table.setWidth and table.setColumnWidth are supported
table.setWidth("100%", true);
table.setColumnWidth(nameColumn, 35.0, Unit.PCT);
table.setColumnWidth(addressColumn, 65.0, Unit.PCT);
I was able to extend the CellTable with a method that sets the widths programmatically. It's a bit of a hack since all the real methods that should do this are private to CellTable and it seems like GWT should provide this method directly, but it seems to work.
public void setColumnWidths(List<Integer> widths)
{
TableElement tel = TableElement.as(getElement());
NodeList<Element> colgroups = tel.getElementsByTagName("colgroup");
if (colgroups.getLength() == 1)
{
TableColElement cge = TableColElement.as(colgroups.getItem(0));
NodeList<Element> cols = cge.getElementsByTagName("col");
for (int j = 0; j < widths.size(); j++)
{
TableColElement column = null;
if (cols.getLength() > j)
{
column = TableColElement.as(cols.getItem(j));
}
else
{
column = cge.appendChild(Document.get().createColElement());
}
column.setWidth(widths.get(j)+"px");
}
}
}

You could use a stylename for the specific column, using the addColumnStyleName(int index, java.lang.String styleName) method.
Javadoc for CellTable

What worked for me is adding a new class in my css. This class gets applied only to select elements whose length varies depending on data.
.__gwt_cell select{
width:170px;
}
Then applying it on my particular cell style like o:
table.getColumn(3).setCellStyleNames("yourstyle");

The GWT documentation for CellTable covers this, see:
http://www.gwtproject.org/doc/latest/DevGuideUiCellTable.html
Under "Controlling Column Widths".

Related

Can I set an ag-grid full-width row to have autoHeight?

I am trying to render a set of footnotes at the end of my data set. Each footnote should be a full-width row. On the docs page for row height, it says that you can set an autoHeight property for the column you want to use to set the height. Full-width rows, however, aren't tied to any column, so I don't think there's a place to set that autoHeight property.
For reference, here is my cell renderer, which gets invoked if a flag in the data object is true.
import { Component } from '#angular/core';
import { ICellRendererComp, ICellRendererParams } from '#ag-grid-community/core';
#Component({
template: '',
})
export class FootnoteRendererComponent implements ICellRendererComp {
cellContent: HTMLElement;
init?(params: ICellRendererParams): void {
this.cellContent = document.createElement('div');
this.cellContent.innerHTML = params.data.title;
this.cellContent.setAttribute('class', 'footnote');
}
getGui(): HTMLElement {
return this.cellContent;
}
refresh(): boolean {
return false;
}
}
The footnote (the "title" property above) could be one line or several depending on its length and the browser's window size. There may also be several footnotes. Is there a way to set autoHeight for each footnote row? Thanks for any help!
Not sure of CSS autoHeight can be use, but here is some example for calculating height dynamically. Take a look to getRowHeight function, it's works for any rows (full-width too):
public getRowHeight: (
params: RowHeightParams
) => number | undefined | null = function (params) {
if (params.node && params.node.detail) {
var offset = 80;
var allDetailRowHeight =
params.data.callRecords.length *
params.api.getSizesForCurrentTheme().rowHeight;
var gridSizes = params.api.getSizesForCurrentTheme();
return (
allDetailRowHeight +
((gridSizes && gridSizes.headerHeight) || 0) +
offset
);
}
};
Here is the solution I ended up with, though I like #LennyLip's answer as well. It uses some ideas from Text Wrapping in ag-Grid Column Headers & Cells.
There were two parts to the problem - 1) calculating the height, and 2) knowing when to calculate the height.
1) Calculating the Height
I updated the footnote's Cell Renderer to add an ID to each footnote text node, and used it in the function below.
const footnoteRowHeightSetter = function(params): void {
const footnoteCells = document.querySelectorAll('.footnote .footnote-text');
const footnoteRowNodes = [];
params.api.forEachNode(row => {
if (row.data.dataType === 'footnote') { // Test to see if it's a footnote
footnoteRowNodes.push(row);
}
});
if (footnoteCells.length > 0 && footnoteRowNodes.length > 0) {
footnoteRowNodes.forEach(rowNode => {
const cellId = 'footnote_' + rowNode.data.id;
const cell = _.find(footnoteCells, node => node.id === cellId);
const height = cell.clientHeight;
rowNode.setRowHeight(height);
});
params.api.onRowHeightChanged();
}
};
To summarize, the function gets all HTML nodes in the DOM that are footnote text nodes. It then gets all of the table's row nodes that are footnotes. It goes through those row nodes, matching each up with its DOM text. It uses the clientHeight property of the text node and sets the row node height to that value. Finally, it calls the api.onRowHeightChanged() function to let the table know it should reposition and draw the rows.
Knowing when to calculate the height
When I set the gridOptions.getRowHeight property to the function above, it didn't work. When the function fires, the footnote rows hadn't yet been rendered, so it was unable to get the clientHeight for the text nodes since they didn't exist.
Instead, I triggered the function using these event handlers in gridOptions.
onFirstDataRendered: footnoteRowHeightSetter,
onBodyScrollEnd: footnoteRowHeightSetter,
onGridSizeChanged: footnoteRowHeightSetter,
onFirstDataRendered covers the case where footnotes are on screen when the grid first renders (short table).
onBodyScrollEnd covers the case where footnotes aren't on screen at first but the user scrolls to see them.
onGridSizeChanged covers the case of grid resizing that alters the wrapping and height of the footnote text.
This is what worked for me. I like #LennyLip's answer and looking more into it before I select an answer.

Dynamically Generated Telerik MVC3 Grid - Add Checkboxes

I have a grid that is dynamically generated based on search criteria. I render the grid in a partial view using Ajax. That all works fine.
I now need to add a checkbox column as the first column.
Also, how do I get filtering, sorting paging etc. to work now since it is in a partial view.
When i click on a header to sort I get a Page not found error and the filter Icon doesnt do anything.
And one more thing. When I try to add a GridCommandColumnSettings to the grid I get the error
"Invalid initializer member declarator"
Code is below for the gridcolumnsettings
public GridColumnSettings[] NewColumns(DataTable fullDT)
{
GridColumnSettings[] newColumns = new GridColumnSettings[fullDT.Columns.Count];
for (int i = 0; i < fullDT.Columns.Count; i++)
{
// set the visibility property for the DeliveryID
bool boolDeliveryID;
if (fullDT.Columns[i].ColumnName == "DeliveryID")
boolDeliveryID = false;
else
boolDeliveryID = true;
newColumns[i] = new GridColumnSettings
{
new GridCommandColumnSettings
{
Commands =
{
new GridEditActionCommand(),
new GridDeleteActionCommand()
},
Width = "200px",
Title = "Commands"
},
Member = fullDT.Columns[i].ColumnName,
Title = fullDT.Columns[i].ColumnName,
Visible = boolDeliveryID,
Filterable = true,
Sortable = true
};
}
return newColumns;
}
Any suggestions would be appreciated.
Thanks
I edited my post to add my partial for the Grid
Here is my partial for the grid
#(Html.Telerik().Grid<System.Data.DataRow>(Model.Data.Rows.Cast<System.Data.DataRow>())
.Name("Grid")
.Columns(columns =>
{
columns.LoadSettings(Model.Columns as IEnumerable<GridColumnSettings>);
})
.DataBinding(dataBinding => dataBinding.Ajax().Select("_DeliveryManagerCustomBinding", "Deliveries"))
.EnableCustomBinding(true)
.Resizable(resize => resize.Columns(true))
)
I don't add columns this way when I use the Telerik Grid control, but looking at what you're doing I would hazard a guess to say you will need to do something like the following:
increase the size of the newColumns array by 1 (because we're going to add in the checkbox column):
GridColumnSettings[] newColumns = new GridColumnSettings[fullDT.Columns.Count + 1];
if you want it at the beginning you will need to do the following before your for-loop:
GridColumnSettings s = new GridColumnSettings() {
ClientTemplate("<input type=\"checkbox\" name=\"checkeditems\" value=\"some value\" />")
Title("title goes in here")
};
Then you will add it into your array:
newColumns[0] = s;
and then increase the start index for your for-loop to 1:
for (int i = 1; i < fullDT.Columns.Count; i++)
the checkbox column will go at the beginning

GWT EditTextCell : How to increase editable TextBox width in EditTextCell?

I am using GWT2.3 in my project.
I want to increase editableTextBox width when user click on editableTextCell.
Problem is My Column width is 200 Px. when user clicks on editableTextCell then that TextBox width is around 125px in EditableTextCell is less as compare to column width.
I added EditTextCell in Celltable's column
Column stringColumn = new Column(new EditTextCell()) {
// My Code
}
cellTable.addColumn(stringColumn, "MyColumn");
cellTable.setColumnWidth(checkBoxColumn, 200, Unit.PX);
I tried following way to increase TextBox width but problem is I cannot edit in textbox + focus not losses
#Override
public void onBrowserEvent(Context context, Element elem,Record object, NativeEvent event) {
String type = event.getType();
int editedTexBoxSize = (cellTable.getOffsetWidth()-100)/cellTable.getColumnCount();
if(elem.getInnerHTML().startsWith("<INPUT")){
String test = elem.getInnerHTML();
// test = <INPUT tabIndex=-1 value=P __eventBits="2048"></INPUT>
test= test.replace("value", " size="+editedTexBoxSize+" value");
// test = <INPUT tabIndex=-1 size=131 value=P __eventBits="2048"></INPUT>
elem.setInnerHTML(test);
}
super.onBrowserEvent(context, elem, object, event);
}
I want to Increase(set) TextBox width appear in EditTextCell is equal to column Width.
Any Solution ?
In my project I do that:
cellTable.getColumn(cellTable.getColumnIndex(column)).setCellStyleNames(CELL_CSS);
.edit-cell input {
width: 290px;
}
Finally the answer !
I tried this even simplier using UIBinder by adding :
.edit-cell input {
width: 30px;
text-align: right;
}
Then for the cell table I added
<c:CellTable
addStyleNames='{style.edit-cell}'
ui:field='itemTable' />
Wonderful !
You'll need to create a custom component. The out of the box EditTextCell does not allow you to set the size attribute of the input field, just the column width.
Have a look at the ValidateableInputCell impl here: In search of a GWT validation example... where art thou? for an example of how to craft a custom cell.
Admittedly the validation does not yet work but the ability to set the size on the input field within the cell does.

Table shows extra blank columns at the end

I am using jface tableViewer.When table has no data in it ,it shows all columns correctly But when Data gets added to the table it shows extra blank space or column at the end of the table.
I am using TreeViewer + TreeViewerColumn and had this problem too, this workaround might work for your TableViewer too: Programmatically set the size of the last column on parent resize:
treeViewer.getTree().addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
packAndFillLastColumn();
}
});
where the action is in
// Resize last column in tree viewer so that it fills the client area completely if extra space.
protected void packAndFillLastColumn() {
Tree tree = treeViewer.getTree();
int columnsWidth = 0;
for (int i = 0; i < tree.getColumnCount() - 1; i++) {
columnsWidth += tree.getColumn(i).getWidth();
}
TreeColumn lastColumn = tree.getColumn(tree.getColumnCount() - 1);
lastColumn.pack();
Rectangle area = tree.getClientArea();
Point preferredSize = tree.computeSize(SWT.DEFAULT, SWT.DEFAULT);
int width = area.width - 2*tree.getBorderWidth();
if (preferredSize.y > area.height + tree.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = tree.getVerticalBar().getSize();
width -= vBarSize.x;
}
// last column is packed, so that is the minimum. If more space is available, add it.
if(lastColumn.getWidth() < width - columnsWidth) {
lastColumn.setWidth(width - columnsWidth);
}
}
Works well for me - you might want to set column resizable to false ;-). This can also be called when data in the last column changes (introducting / removing vertical scroll bar).
Thanks Thomas. Your idea worked for me as well, though I was using TableViewer and TableColumn.
Quoting my code so that others can take some hints.
`public void controlResized(ControlEvent e) {
if ( listOfTableColumns.size() != colProportions.length )
{
logger.warn( "Number of columns passed and size of column proportions array are different. " +
"Columns resizing shall not be effective on GUI window resizing" );
return;
}
Rectangle area = tableBaseComposite.getClientArea();
Point size = theTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);
ScrollBar vBar = theTable.getVerticalBar();
int width = area.width - theTable.computeTrim(0,0,0,0).width - vBar.getSize().x;
if (size.y > area.height + theTable.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = vBar.getSize();
width -= vBarSize.x;
}
Point oldSize = theTable.getSize();
if (oldSize.x > area.width) {
// table is getting smaller so make the columns
// smaller first and then resize the table to
// match the client area width
int index = 0 ;
for ( Iterator<TableColumn> iterator = listOfTableColumns.iterator(); iterator.hasNext(); )
{
TableColumn column = iterator.next();
column.setWidth( (int) numberFromPercentage( width, colProportions[index++] ) );
}
listOfTableColumns.get( listOfTableColumns.size() - 1).pack();
theTable.setSize(area.width, area.height);
} else {
// table is getting bigger so make the table
// bigger first and then make the columns wider
// to match the client area width
int index = 0;
theTable.setSize(area.width, area.height);
for ( Iterator<TableColumn> iterator = listOfTableColumns.iterator(); iterator.hasNext(); )
{
TableColumn column = iterator.next();
column.setWidth( (int) numberFromPercentage( width, colProportions[index++] ) );
}
listOfTableColumns.get( listOfTableColumns.size() - 1).pack();
}
}`
No need for complicated hacks to remove the extra unwanted column space at the end...
Just create a columnLayout:
TableColumnLayout columnLayout = new TableColumnLayout();
and then set it to each of your columns:
columnLayout.setColumnData(YOUR_VIEWER_COLUMN1.getColumn(), new ColumnPixelData(200));
columnLayout.setColumnData(YOUR_VIEWER_COLUMN2.getColumn(), new ColumnWeightData(200, 100));
Finally, set the layout on your parent composite:
parent.setLayout(columnLayout);
Full sample:
public void createPartControl(Composite parent) {
TableViewer viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
TableViewerColumn keyColumn = new TableViewerColumn(viewer, SWT.LEFT);
TableViewerColumn valueColumn = new TableViewerColumn(viewer, SWT.LEFT);
TableColumnLayout columnLayout = new TableColumnLayout();
columnLayout.setColumnData(keyColumn.getColumn(), new ColumnPixelData(200));
columnLayout.setColumnData(valueColumn.getColumn(), new ColumnWeightData(200, 100));
parent.setLayout(columnLayout);
}
Just guessing: maybe your columns do not get resized to fill all the table?
How do you set the widths of columns?
Consider using TableColumnLayout for the table container.
On windows, you will always get an extra column/row if the net width of all the columns that has been set up is less than the dimension of the table. So its always good to make your columns fit your table, also there is some space left for scroll bars, though I am not very sure about this, but its always better to specify whether you want vertical or horizontal scroll bars.
I used the packAndFillLastColumn() method and it worked for me. But I found one issue with it. My table was created with a border. After using the packAndFillLastColumn() method the border for the row no longer exists. I used the setLinesVisible(true) method within the packAndFillLastColumn() method but still that does not work.
So simple! Just remove this line in your table commands inside the createContents function:
table.getColumn(i).pack();
Good-luck
As a workaround use :
-For Column
use TableColumnLayout for the treeViewer's composite and set appropriate column data for each column using:
"tableColumnLayout.setColumnData(column,new ColumnWeightData(...as per your requirement));"
-For Row
Set GridData to the treeViewer's composite and provide height hint using
"gridData.heightHint = table.getItemHeight()*numberOfVisibleRows"
I found eclipse has marked it as WONTFIX.. so can not do much to remove this space..We have tp live with it...:)
To the end column we need to set the setWidth to window size or shell-size, parent-shell size like 1500,5000
final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setResizable(true);
column.setMoveable(true);
//set the setWidth size upto shell size or set upto to some size like 1000,1500,2000,5000
col.setWidth(comp.getShell().getSize().x); // or col.setWidth(1500) ;
return viewerColumn;

GWT CellList Horizontal

Does anybody know how to make a CellList oriented horizontally? If possible, please with UiBinder, but this is not necessary.
Following Thomas Broyer's suggestion on the google-web-toolkit group, and How to style GWT CellList?, we can inject a new CSS resource into the CellList constructor.
The CSS for getting the horizonltal formatting MyCellList.css:
/* This file is based on the CSS for a GWT CellList:
* https://gwt.googlesource.com/gwt/+/master/./user/src/com/google/gwt/user/cellview/client/CellList.css
* The primary purpose is to arrange for the <div> elements that contain each cell to be laid out inline (horizontally).
*/
/* Using inline-block, following Thomas Broyer's recommendations (with link to justification) here:
* https://groups.google.com/forum/#!topic/google-web-toolkit/rPfCO5H91Rk
*/
.cellListEvenItem {
display: inline-block;
padding: 5px;
}
.cellListOddItem {
display: inline-block;
padding: 5px;
}
Define a new Resource like this:
public interface MyCellListResource extends CellList.Resources {
public static MyCellListResource INSTANCE = GWT.create(MyCellListResource.class);
interface MyCellListStyle extends CellList.Style {}
#Override
#Source({CellList.Style.DEFAULT_CSS, "MyCellList.css"})
MyCellListStyle cellListStyle();
}
Inject the new style, and pass it CellList's constructor:
MyCellListResource.INSTANCE.cellListStyle().ensureInjected();
CellList<Fare> cellList = new CellList<Fare>(cell, MyCellListResource.INSTANCE);
Note that the new style appears in the cascade after the DEFAULT style for CellList, so you need only put the modifications you require into your MyCellList.css.
Try to override the CellList.renderRowValues method. You have to be able to create a horizontal presentation template.
There is a lot of logic in that method I didn't want to reproduce, but my hacky solution of just replacing all div's with span's worked:
public class HorizontalCellList<T> extends CellList<T> {
public HorizontalCellList(Cell<T> cell) {
super(cell);
}
#Override
protected void renderRowValues(
SafeHtmlBuilder sb, List<T> values, int start, SelectionModel<? super T> selectionModel) {
SafeHtmlBuilder filteredSB = new SafeHtmlBuilder();
super.renderRowValues(filteredSB, values, start, selectionModel);
SafeHtml safeHtml = filteredSB.toSafeHtml();
String filtered = safeHtml.asString().replaceAll("<div", "<span").replaceAll("div>","span>");
sb.append(SafeHtmlUtils.fromTrustedString(filtered));
}
}
A variant with CSS - set CSS class name on you cell list
CellList<T> list = new CellList<T>(...);
list.addStyleName('myList');
then apply CSS rule to the cells to make them align horizontally:
.myList > div > div > div {
display: inline;
}
I'm able to solve this by extending CellList and creating my own template + overriding the renderRowValues method. Simply changing divs into spans didn't do the trick for me maybe it was because I have custom cells (each cell is rendered as table). Adding display:inline on the CSS didn't work for me also.
My template code is pretty much the same as the original except I added the "float:left;" style:
interface Template extends SafeHtmlTemplates {
#Template("<div onclick=\"\" __idx=\"{0}\" style=\"float:left;\">{1}</div>")
SafeHtml span(int idx, SafeHtml cellContents); ...
Here's a snippet of my renderRowValue method:
int length = values.size();
int end = start + length;
for (int i = start; i < end; i++) {
SingleKeyValueModel value = values.get(i - start);
//super.renderRowValues(sb, values, start, selectionModel);
SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder();
Context context = new Context(i, 0, getValueKey(value));
cell.render(context, value, cellBuilder);
sb.append(TEMPLATE.span(i, cellBuilder.toSafeHtml()));
}