I have a selectable Tree with checkbox appearance. I need to select all sibling TreeNode on selection of a specific TreeNode.
I could get all the sibling tree nodes, but I don't know what is the attribute name of TreeNode to make that checkbox selected.
Can anybody help me giving some way to select those nodes.
compareGrid.addSelectionChangedHandler(new SelectionChangedHandler() {
#Override
public void onSelectionChanged(SelectionEvent event) {
TreeNode node = (TreeNode) event.getSelectedRecord();
TreeNode parent = tree.getParent(node);//tree is Tree object
treeGrid.selectRecord(parent);
TreeNode[] nodes = tree.getAllNodes(parent);
for(int i=0; i< nodes.length; i++){
if(!nodes[i].getAttributeAsBoolean("isSelected"))
treeGrid.selectRecord(nodes[i]);
}
}
}
});
You can use any of the following:
treeGrid.selectAllRecords();
treeGrid.selectRecord(record);
treeGrid.selectRecords(records);
The first method will select all the TreeNodes of the tree.
The 2nd one will select only one specified TreeNodes of the tree.
And the 3rd one will select multiple specified TreeNodes of the tree.
There are multiple overloaded methods for the last 2 methods, which allows you to specify Nodes in terms of, TreeNode(s) itself, or index of the TreeNode(s).
Here's a solution quite close (without checkboxes) to what you need.
employeeTreeGrid.addNodeClickHandler(new NodeClickHandler() {
public void onNodeClick(NodeClickEvent event) {
if (event.getNode() != null) {
TreeNode node = event.getNode();
TreeNode parent = employeeTree.getParent(node);
if (employeeTreeGrid.isSelected(node)) {
List<TreeNode> nodesToSelect = new ArrayList<TreeNode>();
// omit parent (root) if on first level
if (!"1".equals(node.getAttribute("ReportsTo"))) {
nodesToSelect.add(parent);
}
TreeNode[] siblings = employeeTree.getChildren(parent);
nodesToSelect.addAll(Arrays.asList(siblings));
RecordList recordList = employeeTreeGrid.getOriginalRecordList();
for (TreeNode treeNode : nodesToSelect) {
Record record = recordList.find("EmployeeId", treeNode.getAttribute("EmployeeId"));
if (record != null) {
employeeTreeGrid.selectRecord(record);
}
}
}
}
}
});
Have to use the RecordList and first find required records in order to use ListGrid.selectRecord() methods.
Using SelectionAppearance.CHECKBOX and SelectionChangedHandler can be tricky as programmatic selections are going to trigger further selection events.
This is based on Checkbox tree sample with below changes.
// employeeTreeGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
// employeeTreeGrid.setShowSelectedStyle(false);
employeeTreeGrid.setShowPartialSelection(false);
// employeeTreeGrid.setCascadeSelection(true);
employeeTreeGrid.setSelectionType(SelectionStyle.SIMPLE);
To get the value of selected checkbox from tree grid in smart gwt I have following solution ListGridRecord[] arrRec = event.getSelection(); sample code is below.
employeeTreeGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
employeeTreeGrid.setSelectionType(SelectionStyle.SIMPLE);
employeeTreeGrid.addSelectionChangedHandler(new SelectionChangedHandler() {
#Override
public void onSelectionChanged(SelectionEvent event)
//selectedCounties Set to add selected checkbox or deslected checkbox names/title
if (selectedCounties == null || selectedCounties.size() == 0)
selectedCounties = new TreeSet<String>();
selectedCounties.clear();
ListGridRecord[] arrRec = event.getSelection();
for (ListGridRecord listGridRecord : arrRec) {
selectedCounties.add(listGridRecord.getAttribute("Name"));
}
// You can do iteration over it if needed
selectedCounties.remove("All Counties");
Iterator<String> it = selectedCounties.iterator();
while (it.hasNext()) {
if (it.next().contains("Zone")) {
it.remove();
}
}
}
});
Related
Here , setIdList is list of student ids. I want to add these ids into table.
The ids are set in dragSetData() method.
I am able to access the list of ids by dropping into table. But it is adding at last of table.
I want it to add this list in between any row selected by mouse pointer.
Drag code...
private void addDragSupport()
{
int operations = DND.DROP_COPY | DND.DROP_MOVE;
Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
viewer.addDragSupport(operations, transferTypes, new DragSourceListener()
{
#Override
public void dragStart(DragSourceEvent event) {
event.doit = false;
if (null != myVariable) {
if (myVariable instanceof StudentDetails) {
event.doit = true;
}
}
}
#Override
public void dragSetData(DragSourceEvent event) {
event.data = setIdList;
}
#Override
public void dragFinished(DragSourceEvent event) {
}
});
}
I tried below in drop code
IStructuredSelection structuredSelection = this.getStructuredSelection();
List<StudentDetails> studentDetailList = structuredSelection.toList();
But it is giving me the selected row. I want the pointer selected by mouse.
Considering you are using table viewer.
In drop handler :
1) Get the model object from TableViewer : tableViewer.getInput()
2) From dropTarget object find the object location where you want to add dropped object.
Then insert new object in the model at that location and refresh the tableviewer
I am using a Grid where the first column is checkbox. Every row is a folder which can have many other elements to be selected. There could be another folder inside a folder.
Now, when I have to select a element I have to select it one by one. I am not able to understand that how could I make it possible that if I check a folder checkbox, It checks the all selectable elements inside this folder.
Please let me know if more info required.
RemoteSortTreeLoader<BasicModel> loader =
new BaseRemoteSortTreeLoader<BasicModel>(proxy, reader) {
public boolean hasChildren(BasicModel parent) {
//code;
}
};
TreeStore store = new TreeStore(loader);
List<ColumnConfig> columnList = new ArrayList<ColumnConfig>();
CheckBoxSelectionModel checkBoxSelectionModel =
new CheckBoxSelectionModel();
columnList.add(checkBoxSelectionModel.getColumn());
ColumnModel columns = new ColumnModel(columnList);
EditorTreeGrid grid = new EditorTreeGrid<BasicModel>(store,columns);
grid.getSelectionModel().setSelectionMode(SelectionMode.SIMPLE);
grid.getSelectionModel().addListener(Events.BeforeSelect,
new Listener<SelectionEvent<BasicModel>>() {
#Override
public void handleEvent(SelectionEvent<BasicModel> event) {
if (event.getModel() instanceof SDPTimelineCatalogModel) {
event.setCancelled(false);
}
} // handleEvent
}
);
grid.getSelectionModel().addSelectionChangedListener(
new SelectionChangedListener<BasicModel>() {
#Override
public void selectionChanged(SelectionChangedEvent<BasicModel> event) {
logger.info(" Inside addSelectionChangedListener ");
if (event.getSelection().size() == 0) {
disableNext();
} else {
enableNext();
}
} // selectionChanged
}
);
thanks
I am trying to delete more than one row from NatTable. Following the solution described in Delete rows from Nattable. I have created a the following classes:
the Command class looks like this :
public class DeleteMultiRowCommand extends AbstractMultiRowCommand {
public DeleteMultiRowCommand(AbstractMultiRowCommand command) {
super(command);
}
protected DeleteMultiRowCommand(ILayer layer, int[] rowPositions) {
super(layer, rowPositions);
}
#Override
public ILayerCommand cloneCommand() {
return new DeleteMultiRowCommand(this);
}
}
Command Handler class:
public class DeleteMultiRowCommandHandler<T> implements ILayerCommandHandler<DeleteMultiRowCommand> {
private List<T> bodyData;
private SelectionLayer layer;
public DeleteMultiRowCommandHandler(List<T> bodyData, SelectionLayer selectionLayer) {
this.bodyData = bodyData;
this.layer = selectionLayer;
}
public DeleteMultiRowCommandHandler(List<T> bodyData){
this.bodyData = bodyData;
}
#Override
public Class<DeleteMultiRowCommand> getCommandClass() {
return DeleteMultiRowCommand.class;
}
#Override
public boolean doCommand(ILayer targetLayer, DeleteMultiRowCommand command) {
//convert the transported position to the target layer
if (command.convertToTargetLayer(targetLayer)) {
Collection<Integer>rowpos = command.getRowPositions();
//remove the element
for(Integer val : rowpos){
this.bodyData.remove(val.intValue());
targetLayer.fireLayerEvent(new RowDeleteEvent(targetLayer, val.intValue()));
}
return true;
}
return false;
}
}
and the Command will be triggered on clicking a MenuItem
this.contextMenu = new PopupMenuBuilder(natTable)
.withInspectLabelsMenuItem()
.withClearAllFilters()
.withColumnRenameDialog()
.withMenuItemProvider(new IMenuItemProvider() {
#Override
public void addMenuItem(final NatTable natTable, Menu popupMenu) {
MenuItem deleteRow = new MenuItem(popupMenu, SWT.PUSH);
deleteRow.setText("Delete Row(s)");
deleteRow.setEnabled(true);
deleteRow.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
//int rowPosition = MenuItemProviders.getNatEventData(event).getRowPosition();
ILayer bl = ((GridLayer)natTable.getLayer()).getBodyLayer();
BodyLayerStack bl1 = (BodyLayerStack) bl;
SelectionLayer sl = bl1.getSelectionLayer();
int []poss = new int[sl.getFullySelectedRowPositions().length];
int i=0;
for(int pos1 : sl.getFullySelectedRowPositions()){
poss[i]=sl.getRowIndexByPosition(pos1);
i++;
}
//System.out.println("Menu item selected "+rowPosition);
//natTable.doCommand(new DeleteRowCommand(natTable, rowPosition));
natTable.doCommand(new DeleteMultiRowCommand(natTable, poss));
}
});
}
})
.build();
when I try to delete the rows, rows which not selected are deleted. Seems like an issue with the row postion to row index conversion. is the row postion to row index conversion correct within my IMenuItemProvider right ?
It seems like you do the conversion from position to index twice: once in the menu item selection listener and once in the command handler (by calling convertToTargetLayer). The first is not necessary.
That is not an issue of NatTable, but an issue on how to work with collections. You need to remove the items backwards if you remove the elements one by one. Otherwise the items for the indexes are changing while processing.
Let's assume you want to delete the elements at index 1 and 2. After removing the element at index 1, the elements below will move up. So the element that was before on index 2 will be on index 1 now, and the element at index 3 will be on index 2. Therefore the removal of the element at index 2 in the next iteration will remove the item that was before on index 3.
I'd suggest to sort and reverse the collection of indexes before iterating to remove items from the collection. Than it should work.
When using TableBuilder to create rows and sub rows, selection model isn't working as expected.
When clicking on a subrow's checkbox the row isn't been selected, however, the parent row become selected instead.
I tried to overload onBrowserEvent of the CheckboxCell in order to manually handle the selection but it seems that the DataGrid itself fires the selection event when pressing the checkboxcell.
In case where rows and subrows are from the same type, how can I add selection model that supports both rows and subrows?
#Override
public void onBrowserEvent(Context context, Element elem, final T object,
NativeEvent event) {
// The provided row is always the root row, so we need to find the
// correct one when a sub row was edited
actualIndex = context.getSubIndex();
actualObject = object;
if (0 != context.getSubIndex() && object instanceof RowDTO) {
actualIndex = context.getSubIndex();
actualObject = (T) ((RowDTO) object).getChild(actualIndex - 1);
context = new Context(context.getIndex(), context.getColumn(),
actualObject, actualIndex);
}
ValueUpdater<C> valueUpdater = (getFieldUpdater() == null) ? null
: new ValueUpdater<C>() {
#Override
public void update(C value) {
getFieldUpdater().update(actualIndex, object, value);
}
};
getCell().onBrowserEvent(context, elem, getValue(actualObject), event,
valueUpdater);
}
I have a CellTable with one custom column where I render it manually and put a FlowPanel with a bunch of HTMLPanel/Anchor/FlowPanel widgets, and among them is DecoratorPanel.
DecoratorPanel renders as a table, of course.
Rendering happens like this:
public class MyExpandableCell extends AbstractCell<String> {
...
#Override
public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb) {
if (value != null) {
FlowPanel fp = createDetailsFlowPanel(value);
sb.appendHtmlConstant(fp.getElement().getString());
}
}
Now, I have added a handler for click events to my main CellTable. In my handler I traverse the tree to find a first TR belonging to my CellTable, by checking if it contains "even row" or "odd row" CSS classes.
However, when click happens inside of the DecoratorPanel (which is inside of my cell table's TD), my handler also gets triggered, since the click belongs to the cell table area.
I can detect this my seeing that parent TR does not have CellTable CSS classes.
QUESTION: how can I return processing of such click events to the DecoratorPanel - where it really belongs to? As it is now, my DecoratorPanel does not expand and I think because my click handler intercepts and suppresses all clicks on the CellTable level.
table = setupMyCellTable(PAGE_SIZE, CLIENT_BUNDLE, myCellTableResources);
mydataprovider.addDataDisplay(table);
table.sinkEvents(Event.ONCLICK);
table.addDomHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent e) {
boolean isClick = "click".equals(e.getNativeEvent().getType());
if (isClick) {
Element originalElement = e.getNativeEvent().getEventTarget().cast();
Element element = originalElement;
String ctTrClassEven = CLIENT_BUNDLE.mainCss().cellTableEvenRow();
String ctTrClassEven = CLIENT_BUNDLE.mainCss().cellTableOddRow();
// Looking for closest parent TR which has one
// of the two row class names (for this cellTable):
while (element != null
&& !"tr".equalsIgnoreCase(element.getTagName())
&& !(element.getClassName().contains(ctTrClassEven) ||
element.getClassName().contains(ctTrClassEven))) {
element = element.getParentElement();
}
if (element != null) {
if (element.getClassName().contains(ctTrClassEven)
|| element.getClassName().contains(ctTrClassEven)) {
// Found cell table's TR. Set new TR height.
} else {
// Found TR from DecoratorPanel inside of the celltable's cell.
// Do nothing. But how do I make sure
// that decorator panel processes this click and expands?
return;
// Did not work: NS_ERROR_ILLEGAL_VALUE javascript exception.
// if (originalElement != null) {
// originalElement.dispatchEvent(e.getNativeEvent());
// }
}
} else {
debugStr.setText("(did not find tr)");
}
}
}
}, ClickEvent.getType());
Looks like a bug in GWT, triggered because decorator panel uses table to render itself:
http://code.google.com/p/google-web-toolkit/issues/detail?id=5714
(another example http://code.google.com/p/google-web-toolkit/issues/detail?id=6750)
Fix is expected to be shipped with GWT 2.5.