Is there a way to enable dragging of only leaf nodes in a tree component?
First you need to intercept the dragStart event from your tree
dragStart="tree_dragStartHandler(event)"
Then in the event handler you can check to see if the selected item is a branch, if it is then you cancel the dragStart event's default behavior with preventDefault()
protected function tree_dragStartHandler(event:DragEvent):void
{
var item:Object = event.currentTarget.selectedItem
if (tree.dataDescriptor.isBranch(item)) {
event.preventDefault();
}
}
Related
I have an ASP.net webForms, using .NET 4.7.2 TreeView.
I'm using the TreeView component to render a webpage. this renders the tree as a series of tables for node labels and div elements containing child nodes.
I'm trying to add a click event to the node, which is an element located in the table.
The TreeNode has been overriden, to make use of RenderPreText, which adds an attribute role="treeitem" to each of these node's label.
ie
protected override void RenderPreText(HtmlTextWriter writer) {
writer.AddAttribute("role", "treeitem");
}
The following code is what I'm using to add the click event to each node's label element:
window.addEventListener("load", (event) => {
var treeItems = document.querySelectorAll('[role="treeitem"]');
for (var i = 0; i < treeItems.length; i++)
{
treeItems[i].addEventListener('click', OnNodeSelect);
}
});
function OnNodeSelect(event) { alert('Node Selected'); }
The issue i'm having, is that when the node is selected, the event fires and is then removed, so can only be clicked a single time.
What am I doing wrong, how do I add an event that doesn't get removed after single activation?
JavaFX scene has an object of class inherited from the Region. This object has a handler of MOUSE_DRAGGED event. When this handler is called, all object's child nodes are removed and new child nodes are added. The problem is when all children are removed from my object, it doesn't receive any events anymore, because target of MOUSE_DRAGGED event is removed child node. How to solve it?
I cannot use setMouseTransparent method, because some elements inside my object have mouse event handlers.
Ok, perhaps I got the question:
A region has many children. If the user left-clicks and dragges on these children, they will be modified or even removed. As the Mouse-Drag event is 'locked' to the first child where the drag started, no other child will receive further events if the mouse is dragged over some of the other children.
You might benefit from the fact, that the MouseDrag event is passed to the parent region after removing the child. So it is possible to register an onMouseDragged handler on th eparent regon receiving that event. Now the handler is able to 'pick' any childs below mouse for further actions using event.getPickEvent():
void mouseDragPop(Pane region) {
region.setOnMouseDragged(e -> {
Node node = e.getPickResult().getIntersectedNode();
if (node instanceof Circle) {
region.getChildren().remove(node);
}
});
for (int i = 1; i < 10; i++) {
final int n = i;
Circle circle = new Circle(20);
circle.setTranslateX(0);
circle.setTranslateY(0);
circle.setFill(Color.rgb(180, 200, 170));
circle.setLayoutX(System.nanoTime()/1000 % 200);
circle.setLayoutY(System.nanoTime()/3000 % 100);
region.getChildren().add(circle);
circle.setOnMouseDragged(e -> {
region.getChildren().remove(circle);
e.consume();
});
}
}
Now you are able to click and 'pop' all circle on your mouse-drag way...
I have made a hierarchy in which there is a main page, using add element i have attached a component mxml of type group. There is a single button on main page when clicked it should add children of type group in that group type mxml component along with two buttons. Now using one of buttons i am attaching another component mxml type group. the problem is even they overlap i can still excess the children groups of first group component mxml. how can i stop this mouse events to happen.
I think those kind of events usually bubble up to parent components.
You can try using the following code in your mouse click event listener to stop further propagation:
private function onMouseClicked(event: MouseEvent): void {
event.stopPropagation();
... do whatever you wanted when smth was clicked ...
}
By setting enabled, mouseChildren, mouseEnabled to false, you will disable the entire component and it's children. example below
private var myPreviousGroupComponent:Group = null;
function addNewGroup():void
{
if(myPreviousGroupComponent != null)
{
myPreviousGroupComponent.enabled = false;
myPreviousGroupComponent.mouseChildren = false;
myPreviousGroupComponent.mouseEnabled = false;
}
var newGroup:Group = new Group();
addElement(newGroup);
myPreviousGroupComponent = newGroup;
}
Rather than assign to every buttons with MouseEvent, I assign to AIR application with:
private function init():void {
this.addEventListener(MouseEvent.MOUSE_DOWN,mpressKey);
}
However, I only want the mouse_down to execute if it detect a "button" property instead of Demo0.WindowedApplicationSkin2.Group3.contentGroup.g4 (g4 is an id).
Don't rely on event.target to check if a button was clicked or not. The target property is set to the innermost item that was clicked on. When you click on a button, you're not always clicking on The Button; you might be clicking on the text field that displays the label, or the background image if any, or some other child skinning part etc - the target will be set to this inner item.
If you want to have a single click handler for all buttons and take appropriate action based on the button clicked, you can assign same function as handlers for each button and check the event.currentTarget property; when an event handler is invoked, currentTarget is set to the object with which that handler was registered.
btn1.addEventListener(MouseEvent.CLICK, clickHandler);
btn2.addEventListener(MouseEvent.CLICK, clickHandler);
btn3.addEventListener(MouseEvent.CLICK, clickHandler);
public function clickHandler(e:MouseEvent):void
{
if(e.currentTarget == btn1){
/* Handle btn1 here */
}
else if(e.currentTarget == btn2){
/* Handle btn1 here */
}
else if(e.currentTarget == btn3){
/* Handle btn1 here */
}
}
When you add a single mouse handler using airApp.addEventListener, the currentTarget will always be your airApp and thus you can't use it to act as a single function to handle them all.
Are you asking how to test to see if the target is a Button, or a particular button?
If it's a Button
if ( e.target is Button ) { ... }
or if it's a particular button
if ( e.target == myButton ) { ... }
I have a method to add an XML node structure to the currently selected tree node.
This appends the xml, and opens the parent node to display the newly added node.
I then select the node by setting the selectedItem of the tree.
I have an editing form that updates its values on the tree change event. When I set the selectedItem in this method, The node is selected correctly but the change event never fires (thus the editor doesnt update). I have tried to call it in a call later block to no avail.
Is there a way I can force the tree to dispatch a change event at this point?
public function addSelected(node:XML):void{
tree_expandItem(false);
var selectedItem:XML = tree.selectedItem as XML;
selectedItem.appendChild(node);
tree_expandItem(true);
callLater(function():void { tree.selectedItem = node; } );
}
To extend this question in a general sort of way - I would have thought that changing the selectedItem of the tree would result in a change event anyway? Or is a change only considered a change if the user makes it?
You could move the logic that is currently in your change event handler to a separate function, and then call that function directly:
private function changeHandler(event:ListEvent):void
{
doChangeLogic();
}
private function doChangeLogic():void
{
//statements
}
public function addSelected(node:XML):void
{
tree_expandItem(false);
var selectedItem:XML = tree.selectedItem as XML;
selectedItem.appendChild(node);
tree_expandItem(true);
callLater(function():void { tree.selectedItem = node; } );
doChangeLogic();
}
Is there a way I can force the tree to dispatch a change event at this point?
Use the dispatchEvent() method. Thanks James!