I would like to know how I can have Grid Cell Widgets automatically without having to actually call setFields for them, like the built in canRemove capability you provide. The showcase example works well, but I would rather not have to keep creating redundant fields to get them rendered if possible.
Announcement
Collapse
No announcement yet.
X
-
I want to add 3 ImgButtons on the right side of a list grid. One to view details, one to copy to a new record, and one to remove(invokes a listener to confirm delete). I want them to behave exactly like your implementation of the remove button.
This implementation requires that I define the 3 ListGridFields and add them. However this then means that I have broken the ability to use ListGrids ability to auto generate columns from a datasource. So I am trying to figure the correct approach so that I can still use the autogeneration from a datasource, and have these 3 columns added to every record. Precisely the way your remove works.Last edited by jpappalardo; 24 Sep 2014, 09:44.
Comment
-
I tried calling setUseAllDataSourceFields and then setFields, and I end up with a list grid that only displays the datasource fields. however, if I dont set that field and add my fields in an override of setFields they do appear. Can you tell me what I am doing wrong here.Last edited by jpappalardo; 24 Sep 2014, 09:44.
Comment
-
If you simply want all the dataSource fields to show up, plus your additional controller fields, you could achieve this via a simple
setUseAllDataSourceFields(true);
and
setFields(viewField, copyField, removeField);
and you should see all the dataSource fields, plus your custom fields show up, with no need for a 'setFields()' override.
However if you did this, if 'setFields()' was explicitly called anywhere by application code you'd then lose your special fields, and, as you noted earlier in the thread this wouldn't allow you to show only some of the dataSource fields (plus the additional control fields).
Therefore it seems like you need to do two things here:
1) Override setFields() to apply the additional "special fields" to whatever fields are passed in.
2) Ensure this method is called, even if 'useAllDataSourceFields' is true and the application code doesn't explicitly call 'setFields()' directly.
This seems to imply your setFields override should exist and handle appending the custom fields to the fields array passed in, and should be called (with no arguments) as part of init to ensure that even if application code never calls setFields directly and the app relies on 'useAllDataSourceFields' type behavior, your fields do show up.
Here's a tweaked version of your class demonstrating this:
Code:public DefaultListGrid(boolean useAllDataSourceFields, boolean canView, boolean canCopy, boolean canRemove) { this.useAllDataSourceFields = useAllDataSourceFields; setShowRecordComponents(true); setShowRecordComponentsByCell(true); setLeaveScrollbarGap(false); setUseAllDataSourceFields(useAllDataSourceFields); this.canView = canView; viewField = new ListGridField("viewField", " "); viewField.setWidth(22); viewField.setCanHide(false); viewField.setCanSort(false); viewField.setCanGroupBy(false); viewField.setCanFreeze(false); viewField.setCanDragResize(false); this.canCopy = canCopy; copyField = new ListGridField("copyField", " "); copyField.setWidth(22); copyField.setCanHide(false); copyField.setCanSort(false); copyField.setCanGroupBy(false); copyField.setCanFreeze(false); copyField.setCanDragResize(false); this.canRemove = canRemove; removeField = new ListGridField("removeField", " "); removeField.setWidth(22); removeField.setCanHide(false); removeField.setCanSort(false); removeField.setCanGroupBy(false); removeField.setCanFreeze(false); removeField.setCanDragResize(false); // Call our override to setFields() once. This will ensure we show our // view / copy / remove fields even if no explicit call to setFields() is made // externally. setFields(); } @Override public void setFields(ListGridField... fields) { List<ListGridField> list = Arrays.asList(fields); // If 'setFields()' was called with no arguments we're just initializing // the 3 special fields. // Ensure we show all dataSourceFields even if useAllDataSourceFields was not explicitly set - this // is how we would behave if setFields had never been called. // If an explicit set of fields was specified, respect useAllDataSourceFields if (list.size() == 0) { this.setUseAllDataSourceFields(true); } else { this.setUseAllDataSourceFields(useAllDataSourceFields); } ArrayList<ListGridField> allFields = new ArrayList<ListGridField>(list); if(canView) { allFields.add(viewField); } if(canCopy) { allFields.add(copyField); } if(canRemove) { allFields.add(removeField); } ListGridField[] array = new ListGridField[allFields.size()]; super.setFields(allFields.toArray(array)); }
Comment
-
Yes I would like them to render on the right side, if you could please elaborate on the process required.
By the way I came to realize that my problem was that I needed to call setFields() in an override of setDataSource(ds). Perhaps I should have elaborated that for the ListGrid using all DataSource fields I was wanting to reuse the grid for multiple DataSources.Last edited by jpappalardo; 30 Jan 2012, 04:00.
Comment
-
When "useAllDataSourceFields" is set to true on a grid, dataSource fields will render in the order specified within the DataSource.
If the fields array passed to 'setFields()' contains additional fields not specified in the dataSource, these appear at the beginning of the set of columns (on the left) by default. You can change this behavior by including actual dataSourceFields as well as custom fields. The custom fields will then slot in after the dataSourceField that precedes them in the array passed to setFields().
In other words if you have a dataSource with 2 fields "f1" and "f2", and you want a grid to show both these fields plus an additional field "custom", you could specify "useAllDataSourceFields" and
a) call 'setFields()', passing in just the "custom" field to have the custom field show up on the left, or
b) pass in an array like ["f1", "custom"] to have the grid show field f1, then the custom field, then the rest of the dataSource fields... or
c) you could pass in ["f2", "custom"] to have the dataSource fields show up in order ("f1", "f2"), then the custom field show up on the right (after field "f2").
Here's a reworked version of your custom class that uses this approach to ensure that the custom fields always show up after the dataSource fields (on the right). It also handles having 'setDataSource()' called at runtime to re-bind to a new dataSource.
Code:public class DefaultListGrid extends ListGrid { private final boolean useAllDataSourceFields; private final boolean canView; private final boolean canCopy; private final boolean canRemove; private final ListGridField viewField; private final ListGridField copyField; private final ListGridField removeField; public DefaultListGrid(boolean useAllDataSourceFields, boolean canView, boolean canCopy, boolean canRemove) { this.useAllDataSourceFields = useAllDataSourceFields; setShowRecordComponents(true); setShowRecordComponentsByCell(true); setLeaveScrollbarGap(false); setUseAllDataSourceFields(useAllDataSourceFields); this.canView = canView; viewField = new ListGridField("viewField", " "); viewField.setWidth(22); viewField.setCanHide(false); viewField.setCanSort(false); viewField.setCanGroupBy(false); viewField.setCanFreeze(false); viewField.setCanDragResize(false); this.canCopy = canCopy; copyField = new ListGridField("copyField", " "); copyField.setWidth(22); copyField.setCanHide(false); copyField.setCanSort(false); copyField.setCanGroupBy(false); copyField.setCanFreeze(false); copyField.setCanDragResize(false); this.canRemove = canRemove; removeField = new ListGridField("removeField", " "); removeField.setWidth(22); removeField.setCanHide(false); removeField.setCanSort(false); removeField.setCanGroupBy(false); removeField.setCanFreeze(false); removeField.setCanDragResize(false); // Call our override to setFields() once. This will ensure we show our // view / copy / remove fields even if no explicit call to setFields() is made // externally. setFields(); } private ListGridField[] specifiedFields; @Override public void setFields(ListGridField... fields) { // remember the explicitly specified fields. specifiedFields = fields; this.setCombinedFields(); } private void setCombinedFields() { ListGridField[] fields; if (specifiedFields == null) { fields = new ListGridField[] {}; } else { fields = specifiedFields; } List<ListGridField> list = Arrays.asList(fields); ArrayList<ListGridField> allFields = new ArrayList<ListGridField>(list); // We need to explicitly combine with dataSource fields. Cases to consider: // - no explicit fields passed in: // In this case we want to show all dataSource fields, even if the // useAllDataSourceFields flag isn't explicitly set. Grab all the fields from the dataSource // and slot the custom fields after it. // - useAllDataSourceFields is true: // In this case the dataSource fields show up in the order defined in the DS. // In order to have the custom fields show up on the right, we need to include // the last field defined in the dataSource in our explicit fields array, and slot the // custom fields after it. DataSource ds = this.getDataSource(); boolean emptyFields = list.size() == 0; if (ds != null && (useAllDataSourceFields || emptyFields)) { DataSourceField[] dsFields = ds.getFields(); if (emptyFields) { for (int i = 0; i < dsFields.length; i++) { allFields.add(new ListGridField(dsFields[i].getName())); } } else if (useAllDataSourceFields) { String lastDSField = dsFields[dsFields.length-1].getName(); boolean hasLastField = false; for (int i = 0; i < list.size(); i++) { if (list.get(i).getName().equals(lastDSField)) { hasLastField = true; break; } } if (!hasLastField) { allFields.add(new ListGridField(lastDSField)); } } } if(canView) { allFields.add(viewField); } if(canCopy) { allFields.add(copyField); } if(canRemove) { allFields.add(removeField); } ListGridField[] array = new ListGridField[allFields.size()]; super.setFields(allFields.toArray(array)); } // Override setDataSource to reset the set of displayed fields to include the // new custom fields. @Override public void setDataSource(DataSource ds, ListGridField... fields) { super.setDataSource(ds); setFields(fields); } @Override public void setDataSource(DataSource ds) { super.setDataSource(ds); setCombinedFields(); } // private DefaultListGridListener listener; @Override protected Canvas createRecordComponent(final ListGridRecord listGridRecord, Integer col) { String fieldName = getFieldName(col); if(fieldName.equals("viewField")) { ImgButton view = new ImgButton(); view.setSrc("[SKIN]/actions/view.png"); view.setPrompt("View"); view.setSize(16); view.setShowDown(false); view.setShowRollOver(false); view.setAlign(Alignment.CENTER); view.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { // if(listener != null) { // listener.onView(listGridRecord); // } } }); return view; } else if(fieldName.equals("copyField")) { ImgButton copy = new ImgButton(); copy.setSrc("[SKIN]/RichTextEditor/copy.png"); copy.setPrompt("Copy"); copy.setSize(16); copy.setShowDown(false); copy.setShowRollOver(false); copy.setAlign(Alignment.CENTER); copy.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { // if (listener != null) { // listener.onCopy(listGridRecord); // } } }); return copy; } else if(fieldName.equals("removeField")) { ImgButton remove = new ImgButton(); remove.setSrc("[SKIN]/actions/remove.png"); remove.setPrompt("Remove"); remove.setSize(16); remove.setShowDown(false); remove.setShowRollOver(false); remove.setAlign(Alignment.CENTER); remove.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent clickEvent) { // if (listener != null) { // listener.onView(listGridRecord); // } } }); return remove; } else { return null; } } // public void setListener(DefaultListGridListener listener) { // this.listener = listener; // } }
Comment
Comment