Friday, March 20, 2009

Multi cell selection in a row in a grid in gxt

I have been working on selecting multiple cells in a particular row of a grid. This is a requirement for the schedule calendar that i am trying to build at work. This functionality as far as i know is not provided by gxt and thus i wrote a class that extends the CellSelectionModel and   that uses the same technique to select multiple rows in the grid. The user has to press the shift key for multi cell selection and also it should be noted that the selection is for only one row in a grid.

After working it out, in my selection the first cell is always not selected. On looking into it, i figured out that it is the problem of the focus. The gxt’s onfocus event occurs after i set the selected cells, so the first cell looses focus. In-order to  figure out a solution, i am not sure if this is the right way to do this, but i decided to use the DeferredCommand class from GWT. The code written in DeferredCommand is used executed after all the events are handled. So in this case i am setting the style to “cell-selected” after all the events are done, so it works perfectly fine. And the multi selection works only with the shift key.

package com.peoplenet.weekView.client;
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;
	int lastSelectedCol;
	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) {
		if(e.colIndex ==0 )
			return;
		if(lastSelectedRow == 0)
		{
			selected = new CellSelection(store.getAt(e.rowIndex),e.rowIndex,e.colIndex);
			cellsSelected.add(selected);
			lastSelectedRow = e.rowIndex;
			lastSelectedCol = e.colIndex;
		}else if (lastSelectedRow == e.rowIndex && e.isShiftKey())
		{
			cellsSelected.clear();
			for (int i = 1 ; i < 8; i++) {
				Element cell = grid.getView().getCell(lastSelectedRow, i);
				if (cell != null) {
					El.fly(cell).removeStyleName("x-grid3-cell-selected");
				}
			}
			
			if(lastSelectedCol > e.colIndex){
				for (int iter = e.colIndex; iter < lastSelectedCol ; iter++)
				{
					selected = new CellSelection(store.getAt(e.rowIndex),e.rowIndex,iter);
					cellsSelected.add(selected);
				}
				lastSelectedRow = e.rowIndex;
			}else
			{
				for (int iter = lastSelectedCol; iter < e.colIndex + 1 ; iter++)
				{
					selected = new CellSelection(store.getAt(e.rowIndex),e.rowIndex,iter);
					cellsSelected.add(selected);
				}
				lastSelectedRow  = e.rowIndex;
			}
		}else
		{
			cellsSelected.clear();
			for (int i = 1 ; i < 8; i++)
			{
				Element cell = grid.getView().getCell(lastSelectedRow, i);
				if (cell != null) {
					El.fly(cell).removeStyleName("x-grid3-cell-selected");
				}
			}
			selected = new CellSelection(store.getAt(e.rowIndex),e.rowIndex,e.colIndex);
			cellsSelected.add(selected);
			lastSelectedRow = e.rowIndex;
			lastSelectedCol = e.colIndex;
		}
		
		DeferredCommand.addCommand(new Command() {
	        public void execute() {
	        	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");
	    			}	
	    		}     
	        }
	      });
		
		super.handleMouseDown(e);
	}
	/**
	 * 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;
	}
}

No comments: