Double Click event for DataGrid - gwt

I added double click event for DataGrid, but it doesn't work correctly. The code handles a single click, but it does not handle double click.
Please help.
private DataGrid<Contract> table = new DataGrid<Contract>();
table.addCellPreviewHandler(new Handler<Contract>() {
#Override
public void onCellPreview(final CellPreviewEvent<Contract> event) {
if (BrowserEvents.DBLCLICK.equals(event.getNativeEvent().getType())) {
//it doesn't handle
Window.alert("Tro-lo-lo");
}
if (BrowserEvents.CLICK.equals(event.getNativeEvent().getType())) {
//it handles
Window.alert("Tru-la-la");
}
}
});

DataGrid has many things in common with CellTable. So solutions from this question must work for you too:
Using CellPreviewHandler count time between two clicks
Or you can add DoubleClickHandler using addDomHandler method

dataGrid.addDomHandler(new DoubleClickHandler() {
#SuppressWarnings("unchecked")
#Override
public void onDoubleClick(DoubleClickEvent event) {
DataGrid<YourDataProviderType> grid = (DataGrid<YourDataProviderType>) event.getSource();
int row = grid.getKeyboardSelectedRow();
YourDataProviderType item = grid.getVisibleItem(row);
Window.alert("Do Something Here");
}
}, DoubleClickEvent.getType());

Related

CellTable click swallowed

I've an combo box which is composed of a text field and a popup with a CellTable showing the suggestion items. The text field has a change handler that updates the CellTable's selection.
When typing a character and clicking an already selected suggestion, the first click is swallowed. The second click works and triggers the selection via the CellTable.addDomHandler(...).
Any idea why first click is swallowed?
Example code:
private static class SuggestFieldTextAndPopupSandbox extends SimplePanel {
private final TextField mText;
private CellTable<Handle<String>> mTable;
private SingleSelectionModel<Handle<String>> mTableSelection;
private SingleSelectionModel<Handle<String>> mSelection;
private ProvidesKey<Handle<String>> mKeyProvider = new SimpleKeyProvider<Handle<String>>();
private PopupPanel mPopup;
private List<Handle<String>> mData;
public SuggestFieldTextAndPopupSandbox() {
mData = Lists.newArrayList(new Handle<String>("AAA"), new Handle<String>("AAB"), new Handle<String>("ABB"));
mSelection = new SingleSelectionModel<Handle<String>>();
mText = new TextField();
mText.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent pEvent) {
mPopup.showRelativeTo(mText);
}
});
mText.addBlurHandler(new BlurHandler() {
#Override
public void onBlur(BlurEvent pEvent) {
mTableSelection.setSelected(startsWith(mText.getValue()), true);
}
});
mText.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent pEvent) {
mText.setText(mText.getText().toUpperCase());
}
});
mTable = new CellTable<Handle<String>>(0, GWT.<TableResources>create(TableResources.class));
mTable.setTableLayoutFixed(false);
mTableSelection = new SingleSelectionModel<Handle<String>>(mKeyProvider);
mTable.setSelectionModel(mTableSelection);
mTable.addDomHandler(new ClickHandler() {
#Override
public void onClick(final ClickEvent pEvent) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
#Override
public void execute() {
mSelection.setSelected(mTableSelection.getSelectedObject(), true);
mText.setFocus(true);
mPopup.hide();
}
});
}
}, ClickEvent.getType());
mTable.addColumn(new TextColumn<Handle<String>>() {
#Override
public String getValue(Handle<String> pObject) {
return pObject.get();
}
});
mTable.setRowData(mData);
mPopup = new PopupPanel();
mPopup.setAutoHideEnabled(true);
mPopup.setWidget(mTable);
mPopup.setWidth("200px");
mPopup.setHeight("200px");
VerticalPanel p = new VerticalPanel();
p.add(mText);
setWidget(p);
}
private Handle<String> startsWith(final String pValue) {
final String val = nullToEmpty(pValue).toLowerCase();
int i = 0;
for (Handle<String> item : mData) {
String value = item.get();
if (value != null && value.toLowerCase().startsWith(val)) {
return item;
}
i++;
}
return null;
}
}
I reproduced your issue and here is the problem:
when you click on the suggestions the following is happening:
The text field is loosing focus which causes the corresponding ChangeEvent to be dealt with followed by the BlurEvent.
The click causes the popup to get the focus now which is why it is swallowed.
If you remove the ChangeHandler and the BlurHandler of the text field the issue disappears. But I think I found another solution
Try replacing the DOM handler of the mTable with a selection handler relative to the mTableSelection as follows:
mTableSelection.addSelectionChangeHandler(new Handler(){
#Override
public void onSelectionChange(SelectionChangeEvent event) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
#Override
public void execute() {
mSelection.setSelected(mTableSelection.getSelectedObject(), true);
mText.setFocus(true);
mPopup.hide();
}
});
}
});
Found a way how to properly solve this.
Skipping the blur handler when user hovers the suggestion list area seemed to fix that issue, at least from the tests that were done didn't see any more issues.
This was necessary because just before the user clicks a suggestion item, the text is blurred and it fires a selection change. This in turn cancels the selection made when user clicks an item.

Access row data in DoubleCLickListener of TableViewer

I need to show some information related to the row or cell being clicked in table of TableViewer.
As far as I understand I can use (TableViewer) event.getViewer() in viewer.addDoubleClickListener() to retrieve data of current row or cell being clicked. Correct me if I am wrong.
But my run() function is in private void makeActions() where I can't access event. How can I overcome this problem?
private void hookDoubleClickAction()
{
viewer.addDoubleClickListener(new IDoubleClickListener()
{
public void doubleClick(DoubleClickEvent event)
{
//TableViewer chek = (TableViewer) event.getViewer();
doubleClickAction.run();
}
});
}
private void makeActions()
{
doubleClickAction = new Action()
{
public void run()
{
}
}
}
Keep a reference to the TableViewer as a field in your main class (or pass it as a parameter to the action constructor). You can then get the current selection from the viewer in your action using:
IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();

Add ClickHandler to every button

I am trying to implement a click logging system in GWT, so I know where people are going around my app.
I want to be able to do this automatically with out adding the handler to every single Button?
I tried in a Composite class:
this.addDomHandler(new ClickHandler() {...}, ClickEvent.getType());
But the ClickEvent didn't give me any specifics on what had been clicked. The below didn't work as well.
NodeList<Element> elements = Document.get().getElementsByTagName("a");
EventListener el = new EventListener() {
#Override
public void onBrowserEvent(Event event) {
System.out.println(event.toString());
}
};
for (int i = 0; i < elements.getLength(); i++) {
Element e = elements.getItem(i);
com.google.gwt.user.client.Element castedElem = (com.google.gwt.user.client.Element) e;
DOM.sinkEvents(castedElem, Event.ONCLICK);
DOM.setEventListener(castedElem, el);
}
Any tips?
Take a look here:
Notice every click in a gwt application
This will be called on every click in your applilcation.
So, if you have this code:
Event.addNativePreviewHandler(new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getNativeEvent().getType().equals("click")) {
Element eventTarget = DOM.eventGetTarget(Event.as(event.getNativeEvent()));
// check if eventTarget is an a-tag
}
}
});
Any time the mouse is clicked, you will get an event. Exame the event to see, if an a-tag is clicked.
Hope that helps.

GWT: how can i add/remove a button in a celltable on the go

I have this button cell in my CellTable
ButtonCell reListCell = new ButtonCell();
reListColumn = new Column<EmployerJobs, String>(reListCell) {
#Override
public String getValue(EmployerJobs object) {
return "ReList";
}
};
ctJobs.addColumn(reListColumn,
EmployerDashBoardConstants.EMPTYHEADERCOLUMN);
but i only want this cell to be appear if the below condition pass
public void getDateDiff(final EmployerJobs object) {
rpcService.getDateDiff(object.getJobValidDate(), new AsyncCallback<Boolean>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(Boolean jobExpired) {
if(jobExpired) {
// HERE I WANT TO SHOW MY RELISTCELL, means if the job is expired only then
// there will be a button showing relist would be appear in that row ,for
// the jobs which are not expired NO button should appear..
}
}
});
}
how can i achieve this?
thanks
I agree with DTing.
Quering the backend for each cell/row is not really efficient.
I would rather put the info (jobExpired) into your EmployerJobs class and transfer the info when you request the list of your EmployerJobs to be displayed in your CellTable.
You can update the list periodically to account for changes (see the expenses sample on how to do that).
But to your initial question (hiding the cell). There are two solutions:
Use an ActionCell and override the render method.
ActionCell:
ActionCell<EmployerJobs> reListCell = new ActionCell<EmployerJobs>("ReList",
new ActionCell.Delegate<EmployerJobs>() {
#Override
public void execute(EmployerJobs object) {
// code to be executed
}
})
{
#Override
public void render(Cell.Context context,EmployerJobs value,SafeHtmlBuilder sb) {
if (value.isJobExpired()) // isJobExpired returns the field jobExpired.
super.render(context,value,sb);
}
};
reListColumn = new Column<EmployerJobs, EmployerJobs>(reListCell) {
#Override
public String getValue(EmployerJobs object) {
return object;
}
};
ctJobs.addColumn(reListColumn,
EmployerDashBoardConstants.EMPTYHEADERCOLUMN);
Use a ButtonCell and override the render method of your Column.
ButtonCell:
ButtonCell reListCell = new ButtonCell();
reListColumn = new Column<EmployerJobs, String>(reListCell) {
#Override
public String getValue(EmployerJobs object) {
return "ReList";
}
#Override
public void render(Cell.Context context,EmployerJobs object,SafeHtmlBuilder sb) {
if (value.isJobExpired()) // isJobExpired returns the field jobExpired.
super.render(context,value,sb);
}
};
ctJobs.addColumn(reListColumn,
EmployerDashBoardConstants.EMPTYHEADERCOLUMN);
Just tried Umit solution #2 ButtonCell. It works!
To link an specific action to the button, reListColumn.setFieldUpdater(new FieldUpdater....
would be needed
I tried ButtonCell solution too. But if you click in a cell who as no button then an error on client side occur:
com.google.gwt.core.client.JavaScriptException: (TypeError) #com.google.gwt.core.client.impl.Impl::apply(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)([JavaScript object(445), JavaScript object(240), JavaScript object(637)]): parent is null
So I added this to override the Event and avoid Event if I want:
#Override
public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context,
Element parent, YourObject object, NativeEvent event) {
if (object.isCompleted())
super.onBrowserEvent( context, parent, object, event);
}
I don't know if it's the better way to do it but it works.

How to add a Clickhandler to a cellTable cell (or row )

I would like to have a handler on a column of my cellTable.The column is an ImageResourceCell and I would that when I click on it, it delete the row
Here is my code
Column<MyObject, ImageResource> imageColumn =
new Column<MyObject, ImageResource>(newImageResourceCell()) {
#Override
public ImageResource getValue(MyObject object) {
return Bundle.Util.getInstance().deleteRegexButton();
}
};
cellTable.addColumn(imageColumn,SafeHtmlUtils.fromSafeConstant("<br/>");
But I didn't know how to insert a handler as described
Is it possible ??
any suggestions are welcome
Thanks.
Cells have to declare the events they handle, then the browser event can be passed to the cell.
ImageResourceCell myImgCell = new ImageResourceCell() {
public Set<String> getConsumedEvents() {
HashSet<String> events = new HashSet<String>();
events.add("click");
return events;
}
};
Column<MyObject, ImageResource> imageColumn = new Column<MyObject, ImageResource>(myImgCell) {
#Override
public ImageResource getValue(MyObject dataObj) {
return Bundle.Util.getInstance().deleteRegexButton();
}
#Override
public void onBrowserEvent(Context context, Element elem,
MyObject object, NativeEvent event) {
super.onBrowserEvent(context, elem, object, event);
if ("click".equals(event.getType())) {
//call your click event handler here
}
}
};
More info here: http://code.google.com/webtoolkit/doc/latest/DevGuideUiCustomCells.html
Note: this works with GWT 2.4, did not try with GWT 2.2.
Have you seen Adding clickHandler to row in CellTable in GWT??
A CellTable has built in support for handling click events. You can add a CellPreviewHandler that will be called among others when a row is clicked. It will receive a number of items in the event like the native event, cell, and data row value. Because it fires not only for click events you need to check if the click event was fired. Simply test the event passed:
boolean isClick = "click".equals(event.getNativeEvent().getType())