react-redux-grid icon indicating copy to clipboard operation
react-redux-grid copied to clipboard

Question: Hideable header and collapsible rows

Open jkganzan13 opened this issue 8 years ago • 9 comments

Hi Ben,

Is there a way to hide the grid header row? Based on the documentation, I can only find an option to hide the columns but not the header or any rows for that matter.

Also, does the grid support a collapsible row similar to this http://jsfiddle.net/rnqZu/2/? A row click event should open a new row underneath the clicked one.

Many Thanks!

jkganzan13 avatar Aug 07 '16 09:08 jkganzan13

For hiding rows and the header, currently the grid doesn't support such an action. But I'm ok with adding an action to do it.

It would look something like

store.dispatch(
    Actions.GridActions.hideRow({
        stateKey: 'unique',
        rowIndex: 0
    })
);

And to hide the header

store.dispatch(
    Actions.GridActions.hideHeader({
        stateKey: 'unique'
    })
);

I like the row expander feature, but this is a much larger concept, which would require more time. The first question I have is how does the grid receive the rowExpander prop, and where does that data occur on the row?

Initially, I think you would install rowExpander as a plugin:

const plugins = {
    ROW_EXPANDER: {
        enabled: true,
        isExpandable: ({ row, column, columns, store }) => {
            // this function would determine if the parent row
            // should be expandable
            if (row.values.name === 'Michael') {
                return true;
            }
            return false;
        },
        children: ({ row }) => {
            // inside the row object would be the rowValues
            return <div> This div would be shown when row is expanded </div>
        }
    }
};

When I get some time, I will add the actions to hide the header and rows, but let me know what you think about the ROW_EXPANDER API. If you have any suggestions, we can talk about how it should be consumed.

bencripps avatar Aug 07 '16 13:08 bencripps

My grid rows should all be expandable and I was thinking of rendering a component within each expanded row, so your ROW_EXPANDER implementation is perfect, and more customizable for others.

I was going to suggest adding a separate datasource for the child rows similar to the remote datasource for the grid, but if I can render a component in the child row, I think I can just pass the parent id as props and dispatch an action in that component.

Can't wait til you implement these features. Thanks Ben!

jkganzan13 avatar Aug 07 '16 20:08 jkganzan13

@jkganzan13 I've add the header action, which will work when you call the following action:

store.dispatch(
    Actions.GridActions.setHeaderVisibility({
        stateKey: 'unique', hidden: true
    })
);

I will publish a new release with these changes.

bencripps avatar Aug 09 '16 20:08 bencripps

Hi I use your Grid component as a report on the work of the service organization for the period. In the tree grid I display the hierarchy of departments, engineers and their orders in the first column. I calculate the data locally when I go to the report page. All entries are displayed, but all rows are expanded. I need to stop expanding rows by condition. What can be done?

const plugins = {
    ROW_EXPANDER: {
        enabled: true,
        isExpandable: ({ row }) => {
            if (row.type == 'department') {
                return true;
            }
            return false; // else row.type == 'employee' || row.type == 'order'
        }
    }
}

Many Thanks!

FreeClimb avatar May 05 '17 13:05 FreeClimb

The ROW_EXPANDER plugin hasn't been implemented yet :/ so this functionality doesn't currently exist. I will mark this as help wanted and get to it as soon as I can.

bencripps avatar May 05 '17 15:05 bencripps

Yes, I understand that this functionality has not yet been implemented Thank you very much for your prompt reply I'll wait when it happens

FreeClimb avatar May 05 '17 15:05 FreeClimb

Just curious, does setting expandable on the nodes which do/dont need to be expandable solve this problem for you?

bencripps avatar May 06 '17 12:05 bencripps

Yes, of course, Ben Now, as a workaround, I added my css class to the employee and order nodes, with the help of ColRenderer. And then on the button onClick handler, unexpanded <tr> elements of table contained <span> element with my css class.

        renderer: ({ row }) => {
              if (row.type == 'department' || row.type == 'employee') {
                  return (<span className="row-unexpanded">{row.name}</span>);
              } else {
                  return (<span className="row-disabled">{row.name}</span>);
              }
        }

and expanded groups in the Button onClick handler:

                       <Button
                            color="secondary"
                            size="sm"
                            style={{ marginTop: '0.3rem' }}
                            className="form-control"
                            onClick={this.toggleExpanded}>
                            {this.state.expanded ? 'Свернуть группы' : 'Развернуть группы'}
                        </Button>
    constructor(props) {
        super(props);
        this.state = {
            ...
            expanded: true
        };
    }

    toggleExpanded = (e) => {
        e.preventDefault();
        let cells = document.getElementsByClassName('row-unexpanded'),
            x, i;

        for (i = 0; i < cells.length; i++) {
            x = cells[i].parentNode.previousSibling.firstChild;
            if (this.state.expanded) {
                x.classList.remove('react-grid-node-expanded');
                x.classList.add('react-grid-node-unexpanded');
            } else {
                x.classList.remove('react-grid-node-unexpanded');
                x.classList.add('react-grid-node-expanded');
            }
        }

        cells = document.getElementsByClassName('row-disabled');
        for (i = 0; i < cells.length; i++) {
            x = cells[i].parentNode.parentNode.parentNode;
            x.style.display = this.state.expanded ? 'none' : 'table-row';
        }

        this.setState({ expanded: !this.state.expanded });
    }

If you implement this plugin expandable by condition, this will allow me to finished my project. I think that this will be useful for many who use Grid with tree hierarchy. Thank you!

FreeClimb avatar May 06 '17 17:05 FreeClimb

Ben, one more suggestion: You pass for formatting in function renderer one parameter object, contained column, row and cell. However, these parameters do not allow formatting an <td> element, containing a cell. It would be convenient to add a ref to <td> element in the parameters renderer function Now to set backgroundColor of the <td> element, I perform the following:

     renderer: ({ row }) => {
       return (
           <span className="percent-cell" 
                 style={{ backgroundColor: row.agree_percent.bgColor }}>
                 {row.agree_percent.str}
           </span>);
     }

and I added code in componentDidMount() and componentDidUpdate() methods:

    styleTreeGrid() {
        let cells = document.getElementsByClassName('percent-cell'),
            i;

        for (i = 0; i < cells.length; i++) {
            // add backgroundColor to the <td> element
            cells[i].parentNode.parentNode.style.backgroundColor = 
                                                             cells[i].style.backgroundColor;
            cells[i].parentNode.parentNode.style.textAlign = 'center';
        }
    }

    componentDidMount() {
        this.styleTreeGrid();
    }

    componentDidUpdate() {
        this.styleTreeGrid();
    }

FreeClimb avatar May 08 '17 16:05 FreeClimb