Showing posts with label grid. Show all posts
Showing posts with label grid. Show all posts

Tuesday, April 20, 2010

Grid Row Refresh GXT

Probably most of you out there must have known how to do that. But to just put it in paper, this is how we can refresh a particular grid row instead of refreshing or reloading the entire grid.

                      GridView has a refreshRow method inbuilt but it is not publicly available for some reason. So we can extend the GridView class as shown below to create our own method of refreshRow. Using refreshRow instead of refreshing the whole grid is faster when you are working on a grid with way too much data.

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.widget.grid.GridView;
public class MyGridView extends GridView{
	@Override
	public void refreshRow(int row) {
		super.refreshRow(row);
	}
}

Friday, February 19, 2010

Grouping and Sorting grid GXT

If sorting has to be applied with grouping, grouping should be done first and then sort should be applied. This is because GXT grid grouping changes the sort order based on the grouping.

Monday, November 9, 2009

Changing the grid CSS

Well, most of you guys might have known this, I am just putting it in for my reference.

Problem: If my application uses multiple grids and i want to have different CSS for each of the grids. What should i do?

Solution: 1) Set the Id of the grid.

grid.setId("myGrid");

2) Lets say I want to change the cell height and add borders to the cell of the above grid, I can change it by changing the css for that particular grid.

#myGrid .x-grid3-cell-inner 
{
    HEIGHT : 30px !important;  
    border: 1px solid #C0C0C0 !important;
}

Monday, October 19, 2009

How to set the grid row style?

Well the column style can be set using the GridCellRenderer, but there is a completely different way to set the style of a row.

GridViewConfig gvc = new GridViewConfig(){
public String getRowStyle(ModelData model, int rowIndex, ListStore ds) {
    return "row-Style";  // Style to be set to a row
  }
};
grid.getView().setViewConfig(gvc);

User specific conditions can be checked in getRowStyle to set different styles to different rows.

Friday, August 21, 2009

Multi cell selection in a row using shift and control key – grid GXT

This post is an extension to this previous post. Code in the previous post is used to multi select cell in a row using the shift keys. It is updated to add functionality to select cells in a particular row using control key and also highlight the row that we are currently working on.

import java.util.ArrayList;
import java.util.List;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.widget.grid.CellSelectionModel;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
/**
 * This class is an extension of CellSelectionModel. 
 * The CellSelectionModel allows us to select only one cell at a particular time. 
 * This Class allows us to select multiple cells in a particular row in a grid.
 * Multi select is performed by pressing the shift key with the mouse click
 *  
 * @author Ravikanth Kolli
 * @version 1.0
 * 
 * 
 * @param <M>
 */
public class RowCellSelectionModel<M extends ModelData> extends CellSelectionModel<M> { 
int lastSelectedRow = -1;
int lastSelectedCol = -1;
private CellSelection selected ;
List<CellSelection> cellsSelected = new ArrayList<CellSelection>();
/**
 * Overriding the handleMouseDown event.
 * MultiSelect is done by pressing the shiftkey 
 */
@Override
protected void handleMouseDown(GridEvent e) {
super.handleMouseDown(e);
if(lastSelectedRow == -1)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),e.getColIndex());
cellsSelected.add(selected);
lastSelectedRow = e.getRowIndex();
lastSelectedCol = e.getColIndex();
}else if (lastSelectedRow == e.getRowIndex() && (e.isShiftKey() || e.isControlKey())) {
// control key press adding or removing cell from the cellsSelected list. 
if(e.isShiftKey())
{
if(cellsSelected.size() > 0)
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).removeStyleName("x-grid3-row-selected");
cellsSelected.clear();
for (int i = 1 ; i < e.getGrid().getColumnModel().getColumnCount(); i++) {
Element cell = grid.getView().getCell(lastSelectedRow, i);
if (cell != null) {
El.fly(cell).removeStyleName("x-grid3-cell-selected");
}
}
if(lastSelectedCol > e.getColIndex()){
for (int iter = e.getColIndex(); iter < lastSelectedCol+1 ; iter++)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),iter);
cellsSelected.add(selected);
}
lastSelectedRow = e.getRowIndex();
}else
{
for (int iter = lastSelectedCol; iter < e.getColIndex() + 1 ; iter++)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),iter);
cellsSelected.add(selected);
}
lastSelectedRow  = e.getRowIndex();
} 
}
// control key press adding or removing cell from the cellsSelected list. 
else if(e.isControlKey())
{
if(cellsSelected.size() > 0)
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).removeStyleName("x-grid3-row-selected");
boolean isSelected = false;
for (int i =0 ; i < cellsSelected.size();i++)
{
El.fly(grid.getView().getCell(cellsSelected.get(i).row, cellsSelected.get(i).cell)).removeStyleName("x-grid3-cell-selected");
if(cellsSelected.get(i).row == e.getRowIndex() && cellsSelected.get(i).cell == e.getColIndex())
{
isSelected = true;
cellsSelected.remove(i);
}
}
if(!isSelected)
{
selected = new CellSelection(listStore.getAt(e.getRowIndex()), e.getRowIndex(), e.getColIndex());
cellsSelected.add(selected);
}
lastSelectedRow = e.getRowIndex();
}
}
else
{
if(!e.isRightClick() 
||  cellsSelected.size() == 0
|| !(cellsSelected.get(0).row == e.getRowIndex() && cellsSelected.get(0).cell <= e.getColIndex() && e.getColIndex() <= cellsSelected.get(cellsSelected.size() - 1).cell) 
||  cellsSelected.get(0).row != e.getRowIndex()){
if(cellsSelected.size() > 0)
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).removeStyleName("x-grid3-row-selected");
cellsSelected.clear();
for (int i = 1 ; i < e.getGrid().getColumnModel().getColumnCount(); i++)
{
Element cell = grid.getView().getCell(lastSelectedRow, i);
if (cell != null) {
El.fly(cell).removeStyleName("x-grid3-cell-selected");
}
}
selected = new CellSelection(listStore.getAt(e.getRowIndex()),e.getRowIndex(),e.getColIndex());
cellsSelected.add(selected);
lastSelectedRow = e.getRowIndex();
lastSelectedCol = e.getColIndex();
}
}
/**
 * Add the cell selected style after all the events are handled
 */
DeferredCommand.addCommand(new Command() {
public void execute() {
      if(cellsSelected.size() > 0)
       {
El.fly(grid.getView().getRow(cellsSelected.get(0).row)).addStyleName("x-grid3-row-selected");
       }
for (int iter = 0 ; iter < cellsSelected.size() ; iter++) {
Element element = grid.getView().getCell(cellsSelected.get(iter).row,cellsSelected.get(iter).cell);
if (element != null) {
El.fly(element).addStyleName("x-grid3-cell-selected");
}
El.fly(grid.getView().getHeaderCell(cellsSelected.get(iter).cell)).setStyleName("x-setItalics");
}     
}
});
}
/**
 * Method to get the list of all the selected cells at a particular time
 * @return list of selected CellSelections.
 */
public List<CellSelection> getSelectedCells()
{
return cellsSelected;
}
/**
 * clear the selections in cellsSelected
 */
public void clearSelections()
{
cellsSelected.clear();
}
}

Thursday, August 13, 2009

Improving grid performance of an application GXT

For over a month now, I have been working on improving the performance of my application and get feedback from the clients for areas of improvement. My application was running really slow and the reason

1) IE being the only browser that our company supports, is pretty bad in handling white spaces(we do a lot of server side processing in ColdFusion which comes up with a lot white spaces)

Solution: shrink the ColdFusion file into a single line

2) JSONReader is taking a whole lot of time to extract the data and put it in a store.

Solution: After a lot of debugging, I figured out that “com.google.gwt.json.client.JSONObject” that is used in the JSONReader uses a HashMap to store the JSONValue and the get method of HashMap it the most time consuming.

GXT has FastMap which is pretty fast than HashMap. I try to override the mapping part of the JSONObject and try to generate my custom map using FastMap.

public Map<String, Object> decode(JSONObject jso) {
Map<String, Object> map = new FastMap<Object>();
for (String key : jso.keySet()) {
JSONValue j = jso.get(key);
map.put(key, j.isString().stringValue());
}
return map;
}

Whenever I try to get a single JSONValue i use the map to get the data. I tested it and is about 50-60% faster than the previous.

3) Grid rendering also takes a long time which increases with the number of rows.

Solution: I was going through the GXT blog and read about the buffered view for a grid, using which we can render only the rows in the grid that are visible, and each time the scroll bar is used previous rows are cleared from the DOM and new rows are added. This makes the rendering pretty fast and also the speed of the editing features in the grid is increased.

  1: BufferView view = new BufferView();
  2: view.setScrollDelay(10);
  3: view.setRowHeight(28);
  4: grid.setView(view);
The row height has to specified in the view and I think it is needed to decide the number of rows to be displayed.

Tuesday, May 12, 2009

Grid Plugins

Additions to the grids like the Row Numberer, checkboxes, Row Expander are added as plugins to the Grid.

Adding Row Expander:

  1: XTemplate tpl = XTemplate.create("<p><b>Company:</b> {name}</p><br><p><b>Summary:</b> {desc}</p>");
  2: RowExpander expander = new RowExpander();
  3: expander.setTemplate(tpl);  

and then we need to add the plugin to the grid. We cannot apply a rowExpander to a Summary Grid.

grid.addPlugin(expander);

The XTemplate contains the information that has to be displayed when the “+” is clicked.

Adding Row Numberer:

  1: RowNumberer r = new RowNumberer();
  2: List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
  3: configs.add(r);  

and then add the plugin to the grid.

grid.addPlugin(r);
Adding Checkboxes:
  1: CheckBoxSelectionModel sm = new CheckBoxSelectionModel();
  2: configs.add(sm.getColumn());

Add the plugin to the grid

grid.addPlugin(sm);
Adding the grid plugin will provide automatic reorganization when the grid store values have changed.

Monday, May 4, 2009

Cell color change in grid

Some of the applications require a different color for a cell to distinguish it from the others. This feature can be achieved using GridCellRenderer and setting the CSS for the cell using config.css which is a parameter for the renderer.

  1: day.setRenderer(new GridCellRenderer<ModelData>(){
  2:     public String render(ModelData model, String property,
  3:       ColumnData config, int rowIndex, int colIndex,
  4:       ListStore<ModelData> store) {
  5:      if(!((String)model.get(colIndex+"adjcode")).equals(""))
  6:       {
  7:        config.css = "x-cell-Color-Change";
  8:        model.set(colIndex+"cellvalue", model.get(colIndex+"adjcode"));
  9:       }else {
 10:        config.css = "";
 11:        if(model.getPropertyNames().contains(colIndex+"deptno2") && !((String)model.get(colIndex+"deptno2")).equals("")) {
 12:         config.css = "x-cell-double";
 13:         model.set(colIndex+"cellvalue", model.get(colIndex+"deptno")+" - "+model.get(colIndex+"shift")+"<br/>"+model.get(colIndex+"deptno2")+" - "+model.get(colIndex+"shift2"));
 14:        }
 15:        else
 16:         model.set(colIndex+"cellvalue", model.get(colIndex+"deptno")+" - "+model.get(colIndex+"shift"));
 17:       }
 18:       return model.get(colIndex+"cellvalue");
 19:      
 20:     }
 21:    });

We need to take care that if the condition is not met we need to remove the CSS style else the CSS is applied to all the rows following that column.

Monday, April 13, 2009

Adding a listener to a HTML element in gxt

I was trying to add a listener to a HTML element and finally figured out how to do that.

The current scenario is that of a grid, which has a HTML image in one column and a listener has to be attached, so that it performs a task when clicked.

I placed the HTML tag in the grid cell renderer for that particular column

  1: employeeColumn.setRenderer(new GridCellRenderer<ModelData>(){
  2:  public String render(ModelData model, String property,
  3:   ColumnData config, int rowIndex, int colIndex,
  4:   ListStore<ModelData> store) {
  5:    return model.get("fullname")+"<span qtip='copy'><image class=\"copy\" src = 'image/arrow_right.png'></image></span>";
  6:  }
  7: });
The image used has a class name which is used to identify that image in the listener. 
Writing the listener
  1: grid.addListener(Events.CellClick, new Listener<BaseEvent>(){
  2:        public void handleEvent(BaseEvent be) {
  3:          GridEvent ge = (GridEvent)be;
  4:           if(ge.colIndex == 0)
  5:   {
  6:           if(ge.getTarget(".copy", 1) != null)
  7:    {
  8:                         }
  9:                 }
 10:        }
 11: });

My employeeColumn is my first column in the grid, so i select this column in the cell click event. And then I try to select the image with the class copy by checking with the highlighted condition if the target is “copy”.

Wednesday, April 8, 2009

Setting tool tip for data in grid cells GXT

I have been working a lot on grid lately and had to get a tool tip with some information when we go over the grid cell that has data. I looked around and found QuickTip class in GXT that can be used. The data in the tooltip has to be written in HTML.

How to use it?

Create and initialize quickTip for the grid or for any widget you want the tool tip for

QuickTip quickTip = new QuickTip(grid);

using quickTip when rendering a grid column

1:    cm.getColumn(i).setRenderer(new GridCellRenderer<ModelData>(){  
2:          public String render(ModelData model,  
3:                     String property, ColumnData config,  
4:       int rowIndex, int colIndex,  
5:       ListStore<ModelData> store) {  
6:      String myColumnData = model.get( "satCellValue" );  
7:      StringBuffer  tooltip = new StringBuffer();  
8:      tooltip.append(model.get("satsiteno")).append(" - ").append(model.get("satdeptno"))  
9:     .append("<br>").append(model.get("satstartTime")).append(" - ").append(model.get("satendTime")); 
10:              String html = "<span qtip='" + tooltip + "'>" 
11:     + myColumnData + "</span>"; 
12:     return html; 
13:    } 
14:    return ""; 
15:    } 
16:   });

In the render method of gridCellRenderer add the quickTip html to the data for that column using qtip which indicates the quickTip data. I have not tried it but i think quickTip works the same for all the other widgets as well.

Tuesday, March 24, 2009

setting cell height of a grid

Actually the cell height of the grid in gxt changes based on the text and the initial line height is set to 15px. I tried to set it through CSS, but i wasn’t able to. So i decided to change the CSS in the “ext-all.css” which is a very bad idea. But this is one of the easier approaches that i could think of, but it works since we have javascript developed for each module as such, so using the changed CSS for one module doesn’t effect much. Anyways, the following has been modified to change the height of the cell to 50px.

.x-grid3-cell-inner
{
    HEIGHT : 50px;
    PADDING-BOTTOM: 3px;
    PADDING-LEFT: 5px;
    TEXT-OVERFLOW: ellipsis;
    PADDING-RIGHT: 3px;
    WHITE-SPACE: nowrap;
    OVERFLOW: hidden;
    PADDING-TOP: 3px;
    border: 1px solid #ffff;
    -o-text-overflow: ellipsis
}
and also 
.x-grid3-row TD
{
    LINE-HEIGHT : 15px;
    PADDING-LEFT: 1px;
    PADDING-RIGHT: 1px;
    VERTICAL-ALIGN: top;
    -moz-user-select: none
}

I am adding the highlighted attributes to the CSS, which will set the cell height to 50px and the line height for the cell to be 15px. So, the cell is display a total of 3 lines correctly.