How do I obtain the GWT widget that wraps a given DOM element? - events

When a click event occurs, I want to determine which of my widgets was clicked. Note that, for performance reasons, I specifically don't want to add click handlers to each of my widgets.
It's easy enough to obtain the element that was clicked (it'll be the event target of the native event), but then how do I find the corresponding widget?

There is no standard functionality for it, afaik. But you can do it in a similar way as is done in GWT's com.google.gwt.user.client.ui.Tree class.
Basically it work there by first collecting the chain of Elements from the Element of your root Widget to the element of the Widget that clicked (see private method collectElementChain in Tree class). With this chain of Elements the Widget is found by traversing from the Root widget down to the Widget clicked (see private method findItemByChain in the Tree class).
This works for Tree because the Widget and Element index of the children of each Widget/Element match, and because it only allows a specific widget set as TreeItem's.

Actually you can get the widget associated with the main element of a widget using either gwtquery or the DOM.getEventListener(element) method which returns the widget associated with an element.
You can check out my response in another thread for some working code: GWT - How to retrive real clicked widget?

Related

Is it possible to stop the propagation of a taghelpers in one of the taghelpers linked to that tag?

I would like to stop the propagation of any taghelpers linked to a tag. I have a attribute based taghelper that I use to check whether the user can see or use a tag, and based on that I would like to stop any further processing to happen.
output.SuppressOutput();
does not work in this regard.
Some more detail.
I have a grid that has rows and actions per row ( actually there are other types of actions, ie on the grid etc) the rendering of the actions happens using a grid renderer.
The actions are added to a context that is provided to the grid via the items property.
I have another taghelper that can be placed on any tag element which determines whether the user has rights to see the element or whether it is disabled. This taghelper is first in the hierarchy.
Now since the actual action taghelper doesn't render itself, the grid renders it, I can't suppress the output of the action, as it continues to the next taghelper in the hierarchy and adds it to the context.
I would like it stop executing the taghelper hierarchy and not add it to the context, without being able to stop the execution I have to now pass whether the action should be displayed or disabled along in the context and update all my various renderers code to handle this. Stopping the exectution is much simpler and touches a lot less code.

GWT - How to stop propagation from a child's event to its parent

I'm building a GWT application with a Tree.
Every tree items represent an object which has a boolean attribute that we can set through a checkbox displayed in the tree item itself.
I have a selection handler to do some stuff on my tree which gets called on click on every tree items.
What I want to do, is to prevent selection event to firing up when I'm clicking on the checkboxes ...
However, checkboxes don't have a SelectionHandler, so I tried to put a ClickEventHandler with event.stopPropagation(), but SelectionHandler is still getting called ...
EDIT: actually SelectionHandler is getting fired before ClickEventHandler anyway ...
Thanks in advance
You might consider following this method provided in the GWT documentation here. That should do the bit what you are interested in.
Try using the separate click handler for the checkbox and use the event.StopProgation() there after inorder to prevent the event bubbling.
For stop propagation from child's event to parent in GWT you need to use
event.stopPropagation();

Setting the parent elements of Kendo UI content

I'm using some KendoUI web widgets such as DropDownList, which create 'div' elements that are being added to the bottom of the Body. is there a way to configure those to be added as children of one specific div, instead of being direct children of 'body'?
Some widgets have an appendTo configuration option, e.g. kendoWindow, but most don't. kendo.ui.Popup (which is used by widgets like kendoDropDownList and kendoComboBox) appears to be using that configuration option, so it might be relatively easy to make some changes to achieve what you're after.
In response to your follow-up question: there is no document for kendo.ui.Popup because it's not intended to be used independently - it's just a reusable component for the framework itself.
If you're concerned about having to clean up the DOM elements created by a widget, you can achieve that by using the widget's destroy method.

Moving an ItemView from one CollectionView in another without deleting it, best practice?

I'm building a dashboard builder and view interface with Marionette. I have some views from legacy code that are pretty heavyweight(large reports) and the html is thus pre-constructed on the server.
I have a Marionette CollectionView for each row in the dashboard which contains an ItemView for each widget that was dragged onto the row during dashboard building.
When the user moves a widget from one row to another I want to avoid deleting the view and having to reconstruct it (because it would be a lot of unnecessary dom manipulation) but instead want to just detach the element from one(row) CollectionView and add it to another. What's the best practice for accomplishing this with CollectionViews in Marionette?
It seems by default moving a item across CollectionViews would destroy the view/model from one and re-instantiate/re-render it in the other.
The concern I have is that the tablereport in the DOM that would be moving from one collection to another is not original Marionette/Backbone template generated View, it would be just a predefined DOM element we set as the view's el.
The tablereport DOM element has lots of children elements with events associated with it via legacy code not the Backbone view events array nor via Backbone's listenTo calls. So destroying the DOM tablereport element is what we need to avoid to preserve those events, we just want to relocate it in the DOM.
Whats the best way to handle this functionality efficiently in Marionette.
A couple options spring to mind, but the fact that your event-binding code is not easily callable means you'll probably want to use the jQuery detach() method to keep all your events bound when you remove an element.
One option is to cache your view elements as you build them:
- write a view factory which you delegate to in the buildItemView method of your CompositeView.
- have your factory cache the elements for the views it creates against the model.cid of the model that is passed in as the first parameter to the buildItemView method.
- when your factory method is called, retrieve the element from the cache if it exists, call detach() on it, and set it as the ItemView's element.
- override the render method on the view to stop it from rebuilding the html
- move the model from one CollectionView's collection and put it into the other CollectionView's collection, and Marionette will then build your view as described above and insert the element (with events still bound) into the DOM.
Instead of doing the above, you could, assuming you know which ItemView has been dropped:
- remove the ItemView from the first CollectionView's children container (this is a Backbone.Babysitter instance, I believe, and there is documentation for it)
- detach the ItemView's element
- insert the ItemView's element into its new place in the DOM
- insert the ItemView into the second CollectionView's children container
- remove the model from the first CollectionView's collection
- add the model into the second CollectionView's collection silently, which prevents the CollectionView from triggering its normal behaviour of building a new view, rendering it and inserting it.
The first way is probably more elegant as you are still letting Marionette do its thing, but just altering the building, rendering and inserting of the ItemViews. The second way is less complex, but means you have to manually keep everything in sync yourself - essentially doing what Marionette would normally do behind the scenes and stopping it from 'interfering', so to speak.

When handling browser events in a GWT CellTable, how do I get the most specific within a cell?

The onBrowserEvent method of an abstract cell returns a parent element.
If I have multiple HTML items rendered within the cell, such as spans or divs, how do I get and distinguish which one triggered the event?
NativeEvent#getEventTarget() will give you the exact element that fired the event. You can then walk up until you find an element with some discriminant (e.g. a specific CSS class name), or walk down from the parent element and use Element#isOrHasChild().
Have a look at how CompositeCell dispatches the event to the appropriate cell,or how ButtonCell checks that you clicked the button inside the cell.

Resources