Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Checkbox in each row using a Redux store not rendering correctly #476

Open
szszoke opened this issue Jan 26, 2017 · 0 comments
Open

Checkbox in each row using a Redux store not rendering correctly #476

szszoke opened this issue Jan 26, 2017 · 0 comments

Comments

@szszoke
Copy link

szszoke commented Jan 26, 2017

Hi,

I've been trying to create a table which has a checkbox in each row and also one in the header.

This is the desired behavior:
a. Header checkbox toggles the checkboxes in the rows - this works
b. Individual chechboxes can be checked/unchecked - this doesn't works

I have a Redux store where I have a boolean field for the header checkbox and an array of objects each having a boolean field for the checkbox in the row.

In my example code, if I click a checkbox at a row, the correct action get fired, the state gets updated but the table is not updated. The strange thing is that the checkbox in the header can toggle the checkboxes in the rows without problem.

Am I missing something when I set the value for the checkboxes for rows or this is a bug?

Here is a complete example in typescript:

import * as React from "react";
import * as ReactDOM from "react-dom";

import {
    createStore,
    applyMiddleware,
} from "redux";

import { connect, Provider } from "react-redux";

import { Table, Column, Cell } from "fixed-data-table";

import "fixed-data-table/dist/fixed-data-table.min.css";

const createLogger = require("redux-logger");

const middlewares = applyMiddleware(createLogger({ colapsed: true }));

interface IData {
    checked: boolean;
    id: number;
    value: string;
};

interface IState {
    allChecked: boolean;
    data: IData[];
};

const INITIAL_STATE: IState = {
    allChecked: false,
    data: [
        {
            checked: false,
            id: 1,
            value: "One"
        },
        {
            checked: false,
            id: 2,
            value: "Two"
        },
        {
            checked: true,
            id: 3,
            value: "Three"
        },
        {
            checked: false,
            id: 4,
            value: "Four"
        },
        {
            checked: false,
            id: 5,
            value: "Five"
        }
    ]
};

const CHECK = "CHECK";
const CHECK_ALL = "CHECK_ALL";

function check(checked: boolean, index: number) {
    return {
        type: CHECK,
        payload: {
            checked: checked,
            index: index
        }
    };
}

function checkAll(checked: boolean) {
    return {
        type: CHECK_ALL,
        payload: {
            checked: checked
        }
    };
}

function rootReducer(state: IState = INITIAL_STATE, action: any): IState {
    switch (action.type) {
        case CHECK: {
            const {
                checked,
                index
            } = action.payload;

            state.data[index].checked = checked;

            return {
                ...state,
                allChecked: false
            };
        }

        case CHECK_ALL: {
            const { checked } = action.payload;

            state.data.forEach(d => {
                d.checked = checked;
            });

            return {
                ...state,
                allChecked: checked
            };
        }

        default: {
            return state;
        }
    }
}

const store = createStore<IState>(rootReducer, INITIAL_STATE, middlewares);

interface IAppProps extends React.Props<any> {
    allChecked: boolean;
    data: IData[];
    onCheck: (checked: boolean, index: number) => void;
    onCheckAll: (checked: boolean) => void;
};

class App extends React.Component<IAppProps, void> {
    handleAllChecked(event) {
        const {
            onCheckAll
        } = this.props;

        onCheckAll(event.target.checked);
    }

    handleChecked(event, index) {
        const {
            onCheck
        } = this.props;

        onCheck(event.target.checked, index);
    }

    render() {
        const {
            allChecked,
            data
        } = this.props;

        return (
            <Table
                rowsCount={data.length}
                rowHeight={30}
                headerHeight={50}
                width={800}
                height={600}>
                <Column
                    width={100}
                    header={props => (
                        <Cell>
                            <label>
                                <input type="checkbox" checked={allChecked} onChange={event => this.handleAllChecked(event)} />
                                All
                            </label>
                        </Cell>
                    )}
                    cell={({rowIndex, ...props}) => (
                        <Cell>
                            <input type="checkbox" checked={data[rowIndex].checked} onChange={event => this.handleChecked(event, rowIndex)} />
                        </Cell>
                    )} />
                <Column
                    width={100}
                    header={
                        <Cell>
                            Id
                        </Cell>
                    }
                    cell={({rowIndex, ...props}) => (
                        <Cell>
                            {data[rowIndex].id}
                        </Cell>
                    )} />
                <Column
                    width={100}
                    header={
                        <Cell>
                            Value
                        </Cell>
                    }
                    cell={({rowIndex, ...props}) => (
                        <Cell>
                            {data[rowIndex].value}
                        </Cell>
                    )} />
            </Table>
        );
    }
}

function mapPropsToState(state: IState) {
    return {
        allChecked: state.allChecked,
        data: state.data
    };
}

function mapDispatchToState(dispatch: any) {
    return {
        onCheck: (checked: boolean, index: number) => dispatch(check(checked, index)),
        onCheckAll: (checked: boolean) => dispatch(checkAll(checked))
    };
}

const AppComponent = connect(
    mapPropsToState,
    mapDispatchToState
)(App);

ReactDOM.render(
    <Provider store={store}>
        <AppComponent />
    </Provider>,
    document.getElementById("app")
);
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant