PDA

View Full Version : Row hover event for grid



MarcT
8 Mar 2012, 5:12 PM
I need to take action whenever the mouse hovers over a row in my Grid. I can't find an event for that, though; the closest I've found is MouseMoveEvent but I can't get the row index (or the object under the mouse) from that directly. Is there an easy way to do it? I've seen some solutions for 2.0, but nothing I can figure out how to translate to 3.0.

MarcT
14 Mar 2012, 12:44 PM
After digging around in the GridView code to see how Sencha does their row hilighting, I cobbled together the following solution:



private MyObject curHover = null;
?private MouseMoveHandler myMouseMove = new MouseMoveHandler() {
@Override
public void onMouseMove(MouseMoveEvent event) {
MyObject newHover = null;
NativeEvent natev = event.getNativeEvent();
if (Element.is(natev.getEventTarget())) {
int hoverIdx = grid.getView().findRowIndex( Element.as(natev.getEventTarget()) );
newHover = grid.getStore().get(hoverIdx);
}
if(newHover == curHover) return;
setObjHover(curHover, false);
curHover = newHover;
setObjHover(curHover, true);
}
};

private MouseOutHandler myMouseOut = new MouseOutHandler() {

@Override
public void onMouseOut(MouseOutEvent event) {
EventTarget to = event.getNativeEvent().getRelatedEventTarget();
// This event is chatty; make sure we're actually moving off the grid
if (to == null
|| (Element.is(to) && !DOM.isOrHasChild(grid.getElement(),
(com.google.gwt.user.client.Element) Element.as(to)))) {
setObjHover(curHover, false);
curHover = null;
}
}
};


grid.addHandler(myMouseMove, MouseMoveEvent.getType());
grid.addHandler(myMouseOut, MouseOutEvent.getType());




I would prefer that the Grid handled this for me and just sent me a GridRowHoverChanged event or something, with the index and probably the new object as well. This code feels like I'm breaking through an abstraction layer. But it works. Hope it helps somebody else.

Colin Alworth
17 Mar 2012, 10:54 AM
This seems to be a very reasonable way of implementing this - you are asking the view which row a given element belongs to, and not checking other dom properties. One suggestion I might offer would be to make a single class that handles all of this internally for easier reuse.


public abstract class GridHoverHandler<T> implements MouseOutHandler, MouseMoveHandler {
private T curHover = null;
public abstract void setObjHover(T object, boolean isHovered);

@Override
public void onMouseMove(MouseMoveEvent event) {
T newHover = null;
NativeEvent natev = event.getNativeEvent();
if (Element.is(natev.getEventTarget())) {
int hoverIdx = grid.getView().findRowIndex( Element.as(natev.getEventTarget()) );
newHover = grid.getStore().get(hoverIdx);
}
if(newHover == curHover) return;
setObjHover(curHover, false);
curHover = newHover;
setObjHover(curHover, true);
}

@Override
public void onMouseOut(MouseOutEvent event) {
EventTarget to = event.getNativeEvent().getRelatedEventTarget();
// This event is chatty; make sure we're actually moving off the grid
if (to == null
|| (Element.is(to) && !DOM.isOrHasChild(grid.getElement(),
(com.google.gwt.user.client.Element) Element.as(to)))) {
setObjHover(curHover, false);
curHover = null;
}
}
}

To build this into the grid, it would need to monitor these mouse events, needed or not, and would try to issue a hypothetical GridRowHoverChangedEvent whether or not anything was listening. This would add some overhead to all cases, whether or not it was used. Additionally, individual cells may want to handle their own hover code, such as buttons which are styled on hover to indicate that they can be clicked.