Giter Site home page Giter Site logo

Comments (8)

cheton avatar cheton commented on July 26, 2024

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 infinite-tree-toggler) to specify the toggler class using in your rowRenderer.

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:
https://github.com/cheton/infinite-tree/blob/master/src/infinite-tree.js#L77

from infinite-tree.

cheton avatar cheton commented on July 26, 2024

Here is an example of custom rowRenderer using the togglerClass option:
https://github.com/cheton/infinite-tree/blob/master/examples/classic/renderer.js#L29

from infinite-tree.

cheton avatar cheton commented on July 26, 2024

If you're using React, you can import { renderToString } from 'react-dom/server' to render a React element into HTML string.

The sample code shown below is a direct translation from the original custom rowRenderer example:
https://github.com/cheton/react-infinite-tree/blob/master/examples/renderer.js

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;

from infinite-tree.

confusingstraw avatar confusingstraw commented on July 26, 2024

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.

from infinite-tree.

cheton avatar cheton commented on July 26, 2024

Clusterize.js provides the contentElem option to load DOM nodes during initialization, once it has finished its initialization, it will use a sliding buffer mechanism by removing invisible DOM nodes from HTML to provide good scrolling performance, thus you will not be able to attach event listeners to specific DOM elements. In such a case, event delegation is the only option to listen events for DOM elements with infinite scrolling support.

The event delegation example I provided above is a bit cumbersome because it has to query the .infinite-tree-content element to attach an event listener, I can provide a click event for the tree to make things easier. For example:

var tree = new InfiniteTree(el, options);
tree.on('click', function(event) {
    var target = event.target || event.srcElement; // IE8
    // do stuff with node
});

from infinite-tree.

cheton avatar cheton commented on July 26, 2024

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);
});

from infinite-tree.

aalbul avatar aalbul commented on July 26, 2024

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 :)

from infinite-tree.

cheton avatar cheton commented on July 26, 2024

Thanks! I just updated the sample code in FAQ and Wiki page.

https://github.com/cheton/infinite-tree#faq
https://github.com/cheton/infinite-tree/wiki/Events#click

from infinite-tree.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.