WordPress Dynamic Block with multiple checkboxes

Question

I am trying to create a Dynamic WordPress Block where the user can choose from categories (using checkboxes). Content for each of these categories will then be displayed where the block is used.

My problem is that when I click on one checkbox, all the values are changed.

Here is my attributes:

attributes: {
    categories: {
        type: 'categories',
    },
    checkboxes: {
        type: 'array',
    },
},

Here is my edit function (I added the comments to explain what I am doing):

    edit: function( props ) {
//Get the categories from the WordPress API.
        if ( ! props.attributes.categories ) {
            wp.apiFetch( {
                url: '/wp-json/wp/v2/categories',
            } ).then( categories => {
                props.setAttributes( {
                    categories: categories,
                } );
            } );
        }
//Wait for the categories to load before continuing.
        if ( ! props.attributes.categories ) {
            return 'Loading ...';
        }
//If no categories are loaded.
        if ( props.attributes.categories && props.attributes.categories.length === 0 ) {
            return 'No Categories found.  Please add some.';
        }
//If no attribute for checkboxes exists, create one.
        if ( ! props.attributes.checkboxes ) {
//map through the categories to get their ID.  Set the state to false.
            const result = props.attributes.categories.map( s=>( { id: s.id, state: false } ) );
//Save the array to the 'checkboxes' attribute.
            props.setAttributes( {
                checkboxes: result,
            } );
            return 'Checkbox data not found.  Loading ...';
        }
//Function to see if a checkbox should be checked on not based on its ID.
        function checkedState( id ) {
            const result = props.attributes.checkboxes.filter( obj => {
                return obj.id === id;
            } );

            const checkedStatus = ( result[ 0 ].state === undefined ? false : result[ 0 ].state );

            return checkedStatus;
        }
//Function to update the checkboxes onChange.
        function updateCheckbox( id ) {
//Get the current status of all the checkboxes.
            const currentStatusAll = props.attributes.checkboxes;
//Find the index of the object based on the ID.
            const objIndex = currentStatusAll.findIndex( ( obj => obj.id === id ) );
//Toggle the state based on the index in the array.
            currentStatusAll[ objIndex ].state = ! currentStatusAll[ objIndex ].state;
//Update
            props.setAttributes( {
                checkboxes: currentStatusAll,
            } );
        }

        return (
            <div>
                <h3>Categories</h3>
                {
                    props.attributes.categories.map( ( category, index ) => {
                        return (
                            <div key={ index }>
                                <label htmlFor={ `custom-checkbox-${ category.id }` }>
                                    <input
                                        type="checkbox"
                                        id={ `custom-checkbox-${ category.id }` }
                                        name={ category.id }
                                        checked={ checkedState( category.id ) }
                                        onChange={ updateCheckbox( category.id ) }
                                    />
                                    { category.name }
                                </label>
                            </div>
                        );
                    } )
                }
            </div>
        );
    },

I would appreciate any help, or if you have a better solution I can use that too. I use create-guten-block. I can easily work with one checkbox, but I really struggle with multiple checkboxes.

0
user1303840 1 month 2021-10-20T02:06:25-05:00 0 Answers 0 views 0

Leave an answer

Browse
Browse