React-grid-layout: [Question] Change grid item size on click?

Created on 26 Jan 2018  路  3Comments  路  Source: STRML/react-grid-layout

  • [ ] Bug
  • [ ] Feature Request
  • [x] Question

Hi,
Is it possible to resize grid item on click? I have components structure like the following, and I need to toggle item's size on click to the button inside of the div.

<ResponsiveReactGridLayout>
  <div key="1">
    <button onClick={this.handleResize} />
  </div>
  <div key="2">
    <button onClick={this.handleResize} />
  </div>
</ResponsiveReactGridLayout>

Most helpful comment

Yeah, it is possible. Dirty implementation of handleResize will look like pseudocode below.

  handleResize(ev) {
      const newLayout = [];
      _.each(this.state.layout, (item) => {
          if (id !== clickedItemId) {
              newLayout.push(item);
          }
      });
      newLayout.push(myNewItemWithUpdatedDimensions);
      this.setState({
          layout: newLayout,
      });
    }

You just need to figure out how to associate layout data with particular <div> and then associate that <div> with its <button>. If I had to do it, I'd create a separate React component with its own state and props to take care of that and notify RGL to re-render grid when necessary. So it will look like:

<ResponsiveReactGridLayout>
  <GridItem ...props/>
    .....
  <GridItem ...props/>
</ResponsiveReactGridLayout>

All 3 comments

I am searching for an answer to this question as well. However I am trying to make the component clickable and resizable on a sort of "auto size" on click.

Yeah, it is possible. Dirty implementation of handleResize will look like pseudocode below.

  handleResize(ev) {
      const newLayout = [];
      _.each(this.state.layout, (item) => {
          if (id !== clickedItemId) {
              newLayout.push(item);
          }
      });
      newLayout.push(myNewItemWithUpdatedDimensions);
      this.setState({
          layout: newLayout,
      });
    }

You just need to figure out how to associate layout data with particular <div> and then associate that <div> with its <button>. If I had to do it, I'd create a separate React component with its own state and props to take care of that and notify RGL to re-render grid when necessary. So it will look like:

<ResponsiveReactGridLayout>
  <GridItem ...props/>
    .....
  <GridItem ...props/>
</ResponsiveReactGridLayout>

Thanks @kutyepov!
Finally I've done resizing on click like this:
First, keep the layout in state.

state = {
  layouts: [
    {
      i: '1',
      w: 3,
      h: 2,
      x: 0,
      y: 0
    },
    ...
  ],
  collapsedWidgets: {},
}

Then added come methods to handle click event:

toggleWidget = (id) => {
  return () => {
    const newState = {...this.state.collapsedWidgets};
    const collapsed = typeof newState[id] === 'boolean' ? newState[id] : false;

    newState[id] = !collapsed;
    this.setState({
      collapsedWidgets: newState,
    });
  }
};

onResize = (layouts) => {
  this.setState({
    layouts,
  });
};

getLayouts() {
  return this.state.layouts.map(layout => {
    const newLayout = {...layout };
    if (this.state.collapsedWidgets[newLayout.i]) {
      newLayout.w = layout.w * 2;
    }
    return newLayout;
  });
}

And use them in components:

<ResponsiveReactGridLayout
  layouts={{lg: this.getLayouts()}}
  onResizeStop={this.onResize}
>
  <div key="1">
    <button onClick={this.toggleWidget('1')} />
  </div>
  ...
</ResponsiveReactGridLayout>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

gfafei picture gfafei  路  3Comments

fsalamida picture fsalamida  路  3Comments

uc-rpr picture uc-rpr  路  4Comments

dphaener picture dphaener  路  3Comments

ConfigurableUIComponents picture ConfigurableUIComponents  路  4Comments