-
12 Apr 2010 7:07 AM #1
Custom CheckBoxSelectionModel - change default icon
Custom CheckBoxSelectionModel - change default icon
Simplified problem:
I have a grid with a CheckBoxSelectionModel and i want to change default checkbox icons with my own, programmatically. Basically i think the best solution would be to extend gxt CheckBoxSelectionModel class and create a method setIcon(String imageUrl) that points to my image. I tried following code in my CustomCheckBoxSelectionModel ctor but it dowsn't work properly, it just append my image right to default image.
I just want to replace this image :Code:public CustomCheckBoxSelectionModel(String myImage) { super(); this.getColumn().setRenderer(new GridCellRenderer<M>() { public String render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store, Grid<M> grid) { config.cellAttr = "rowspan='2'"; config.style = "background-image: url(" + myImage + ");"; return "<div class='x-grid3-row-checker'> </div>"; } }); }
With my own one. Can anyone advice me how to approach the problem ?Code:.x-grid3-row-checker, .x-grid3-hd-checker { background-image:url(../images/default/grid/row-check-sprite.gif); }
Extended problem.
If i want to use a larger image then toggle selection area will have to be increased. Although size of this area is defined din css file. How do i change it dynamically in code ? I don;t want to override css, since i don;t want to apply this change to all grids that uses a checkbox selection model.
Another abandoned solution was to use a custom identifier instead of checker
This solution worked better but is not really ok. i shouldn't have different different css classes for same thing(even icons are different).Code:void replaceDivs() { grid.addListener(Events.ViewReady, new Listener<ComponentEvent>() { @Override public void handleEvent(ComponentEvent be) { El header = grid.getView().getHeader().el(); El headerBody = header.getChild(1); header.setInnerHtml(header.getInnerHtml().replace("-checker", "-mychecker")); El hdc = headerBody.child("div.x-grid3-hd-checker"); if (hdc != null) { hdc.child("x-grid3-hd-checker"); hdc.getId(); hdc.getParent().setStyleName(hdc.getParent().getStyleName().replace("-checker", "-mychecker")); hdc.getChild(0).getParent().setStyleName( hdc.getChild(0).getParent().getStyleName().replace("-checker", "-mychecker")); } } }); }
-
13 Apr 2010 4:53 AM #2
After one more day i've progressed but still not have a full working solution.
At this point all i have to change only background-position for "selected" image (checker-on)
So, i set my custom image to header( in constructor)
I set my image to rows after ViewReady eventCode:this.getColumn().setRenderer(new GridCellRenderer<M>() { public String render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store, Grid<M> grid) { config.cellAttr = "rowspan='2'"; return "<div class='x-grid3-row-checker' style=' height: " + (imageSize + 2 * 2) + "px; background-image: " + imageURL + "; '> </div>"; } });
, change checker size according to row height and place image in center to look niceCode:El hdc = grid.getView().getHeader().el().getChild(1).child("div.x-grid3-hd-checker"); hdc.dom.getStyle().setBackgroundImage(imageURL);
THE PROBLEM:Code:hdc.setStyleAttribute("height", this.rowHeight - 2); this.padding = (this.rowHeight - 2 - this.imageSize)/2; hdc.setStyleAttribute("background-position", padding + "px " + padding + "px");
When a selection is changed, html structure is builded dynamically in code(in CheckBoxSelectionModel implementation)
After this call html element checker is replaced with checke checker-on. and the new background-position value is taken from css, to display checked image.Code:private void setChecked(boolean checked) { if (grid.isViewReady()) { El hd = grid.getView().innerHd.child("div.x-grid3-hd-checker"); if (hd != null) { hd.getParent().setStyleName("x-grid3-hd-checker-on", checked); } } }
Now the problem is that offset my image has other value (my images are larger) so i haven't access to this css checker-on background-position to change it. So i have to change it but i don't know how. Any advice will be more than welcome.HTML Code:.x-grid3-row-selected .x-grid3-row-checker,.x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker { background-position: -23px 2px; }
Another question would be if my approach is correct, to change css values programmatically in the code? Unfortunately I didn't a better solution.
-
14 Apr 2010 4:55 AM #3
Adopted solution:
Please feel free to make any comments or suggestions.Code:package mypackage.controls; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.store.StoreEvent; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.grid.CheckBoxSelectionModel; import com.extjs.gxt.ui.client.widget.grid.ColumnData; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; public class CustomCheckBoxSelectionModel<M extends ModelData> extends CheckBoxSelectionModel<M> { protected String imageURL = "url(\"/res/images/selectColumnModel.gif\")"; protected int imageSize = 24; protected int padding = 2; protected int leftPadding = padding; protected int rowHeight = imageSize + padding * 2; public CustomCheckBoxSelectionModel(String image, int size) { super(); this.imageURL = image; this.imageSize = size; this.rowHeight = this.imageSize + padding * 2; initConfig(); } public CustomCheckBoxSelectionModel() { super(); initConfig(); } private void initConfig() { this.getColumn().setId("checker"); this.getColumn().setWidth(rowHeight + 2); this.getColumn().setRenderer(new GridCellRenderer<M>() { public String render(M model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<M> store, Grid<M> grid) { config.cellAttr = "rowspan='2'"; return "<div class='x-grid3-row-checker' style=' height: " + rowHeight + "px; background-image: " + imageURL + "; '> </div>"; } }); } @Override public void init(Component component) { super.init(component); modifyElement(); } private void modifyElement() { grid.addListener(Events.ViewReady, new Listener<ComponentEvent>() { @Override public void handleEvent(ComponentEvent be) { replaceBackgroundImage(); } }); } void replaceBackgroundImage() { El hdc = grid.getView().getHeader().el().getChild(1).child("div.x-grid3-hd-checker"); hdc.dom.getStyle().setBackgroundImage(imageURL); hdc.setStyleAttribute("height", this.rowHeight - 2); hdc.setStyleAttribute("background-position", padding + "px " + padding + "px"); } @Override protected void onSelectChange(M model, boolean select) { super.onSelectChange(model, select); if (grid.isViewReady()) { boolean change = getSelection().size() == grid.getStore().getCount(); changeHeaderOffset(change); changeRowOffset(grid.getStore().indexOf(model), change); } } @Override protected void onClear(StoreEvent<M> se) { super.onClear(se); changeHeaderOffset(false); } private void changeHeaderOffset(boolean select) { if (select/* && leftPadding == padding */) { leftPadding = padding - 12 - imageSize; } else/* if(leftPadding != padding) */{ leftPadding = padding; } El hdc = grid.getView().getHeader().el().getChild(1).child("div.x-grid3-hd-checker"); hdc.setStyleAttribute("background-position", leftPadding + "px " + padding + "px"); } private void changeRowOffset(int index, boolean select) { El hdr = El.fly(grid.getView().getRow(index)).child("div.x-grid3-row-checker"); int itemPadding = padding; if (isSelected(grid.getStore().getAt(index))) { itemPadding = padding - 12 - imageSize; } hdr.setStyleAttribute("background-position", itemPadding + "px " + padding + "px"); } }


Reply With Quote