-
-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding event handlers to rowRenderer elements. #1
Comments
The infinite-tree depends on Clusterize.js to display large data set, and it only accepts HTML string, so you cannot return an element within your rowRenderer. To attach event listeners for nodes, I'd suggest you use event delegation, it allows you to avoid adding event listeners to specific nodes, or it will cause performance issues while handling large data sets. See event delegation examples as shown below: Example 1: Pure JavaScript // JavaScript
var el = document.getElementById('tree');
var tree = new InfiniteTree(el, { /* options */ });
el.querySelector('.infinite-tree-content').onclick = function(event) {
event = event || window.event;
var target = event.target || event.srcElement;
console.log(target);
if (!hasClass(target, 'my-specific-class')) {
return;
}
// do stuff with node
};
// Checks if an element contains a specific class
var hasClass = function(el, className) {
if (!el) {
return false;
}
var classes = el.className.split(' ');
return (classes.indexOf(className) >= 0);
}; Example 2: Use jQuery // jQuery
$('#tree .infinite-tree-content').on('click', 'your-event-selector', function() {
// do stuff with node
}); For the use case of handling '+' and '-' that you mentioned, it's not necessary to handle the click event yourself to call tree.openNode or tree.closeNode. You can pass the togglerClass option (it defaults to var tree = new InfiniteTree({
togglerClass: 'infinite-tree-toggler'
}); The infinite-tree library use the togglerClass to determine if the mouse is clicking on the toggler to open/close a tree node. Check the source code below for details: |
Here is an example of custom rowRenderer using the |
If you're using React, you can The sample code shown below is a direct translation from the original custom rowRenderer example: import React from 'react';
import ReactDOMServer from 'react-dom/server';
import classNames from 'classnames';
const renderer = (node, treeOptions) => {
const { id, name, loadOnDemand = false, children, state, props = {} } = node;
const droppable = (treeOptions.droppable) && (props.droppable);
const { depth, open, path, total, loading = false, selected = false } = state;
const childrenLength = Object.keys(children).length;
const more = node.hasChildren();
return ReactDOMServer.renderToString(
<div
className={classNames(
'infinite-tree-item',
{ 'infinite-tree-selected': selected }
)}
data-id={id}
data-expanded={more && open}
data-depth={depth}
data-path={path}
data-selected={selected}
data-children={childrenLength}
data-total={total}
droppable={droppable}
>
<div
className="infinite-tree-node"
style={{ marginLeft: depth * 18 }}
>
<a
className={(() => {
if (!more && loadOnDemand) {
return classNames(treeOptions.togglerClass, 'infinite-tree-closed');
}
if (more && open) {
return classNames(treeOptions.togglerClass);
}
if (more && !open) {
return classNames(treeOptions.togglerClass, 'infinite-tree-closed');
}
return '';
})()}
>
{!more && loadOnDemand &&
<i className="glyphicon glyphicon-triangle-right" />
}
{more && open &&
<i className="glyphicon glyphicon-triangle-bottom" />
}
{more && !open &&
<i className="glyphicon glyphicon-triangle-right" />
}
</a>
<i
className={classNames(
'infinite-tree-folder-icon',
'glyphicon',
{ 'glyphicon-folder-open': more && open },
{ 'glyphicon-folder-close': more && !open },
{ 'glyphicon-file': !more }
)}
>
</i>
<span className="infinite-tree-title">{name}</span>
<i
style={{ marginLeft: 5 }}
className={classNames(
{ 'hidden': !loading },
'glyphicon',
'glyphicon-refresh',
{ 'rotating': loading }
)}
/>
<span className="count">{childrenLength}</span>
</div>
</div>
);
};
export default renderer; |
Thanks for the response! After a quick look at clusterize on the link you provided, it looks like they provide the ability to use existing markup with scrollElem instead of the rows option. Just for the sake of interest, I'd recommend checking out react-virtualized, since it seems to aim to solve many of the same problems. |
Clusterize.js provides the The event delegation example I provided above is a bit cumbersome because it has to query the var tree = new InfiniteTree(el, options);
tree.on('click', function(event) {
var target = event.target || event.srcElement; // IE8
// do stuff with node
}); |
The click event is provided in v1.2.0. I also wrapped event.stopPropagation that allows you to stop subsequent executions (e.g. selectNode, openNode, closeNode) as needed. var tree = new InfiniteTree(el, options);
tree.on('click', function(event) {
var target = event.target || event.srcElement; // IE8
// Call event.stopPropagation() if you want to prevent the execution of
// default tree operations like selectNode, openNode, and closeNode.
event.stopPropagation();
// do stuff with the target element.
console.log(target);
}); |
Gosh. This must be somewhere in documentation. I spent quiet a lot of time trying to figure out what's going on with my events :) |
Thanks! I just updated the sample code in FAQ and Wiki page. https://github.com/cheton/infinite-tree#faq |
Hi, I was just wondering if there was a preferred way to listen for events in the HTML string returned by a custom rowRenderer.
If it was an option, I'd just return a premade Element, but it looks like only strings are accepted, and as such, I would need to use some kind of event delegation to be able to listen for something like a click on the element.
One example of a use case for this would be to have a "+" or "-" depending on node.state.open, and to call tree.openNode or tree.closeNode when it is clicked.
If there is an existing feature that allows this, I'd be happy to use it.
Thanks.
The text was updated successfully, but these errors were encountered: