Code Monkey home page Code Monkey logo

grouped-checkboxes's Introduction

Grouped Checkboxes

codecov Build Status GitHub npm React

An easy to use React Component to create a checkbox group with a checkbox to check all checkboxes and a checkbox to check none.

Installation

npm install --save @createnl/grouped-checkboxes
yarn add @createnl/grouped-checkboxes

Example

See examples

Live examples: https://v5sww.csb.app/

Codesandbox: https://codesandbox.io/s/grouped-checkboxes-v5sww

import React from "react";
import { AllCheckerCheckbox, Checkbox, CheckboxGroup } from '@createnl/grouped-checkboxes';

const MyGroupedCheckboxes = (props) => {
    const onCheckboxChange = (checkboxes) => {
        console.log(checkboxes);
    }    

    return (
        <CheckboxGroup onChange={onCheckboxChange}>
          <AllCheckerCheckbox />
          <Checkbox value="option-1"/>
          <Checkbox value="option-2" />
          <Checkbox value="option-3" />
        </CheckboxGroup>
    );
};

Note that Checkbox and AllCheckerCheckbox must be inside a CheckboxGroup

Features

  • Multiple AllCheckerCheckboxes and NoneCheckerCheckboxes inside a group
  • onChange callback on group
  • Possibility to nest checkboxes in your own components
  • Possibility to check or disable by default
  • You can do anything with a Checkbox you can do to an input component
  • Fully Typed

Advanced examples

Checking checkboxes

<CheckboxGroup defaultChecked> // Set defaultChecked to check all by default
  <AllCheckerCheckbox checked/> // Error: You cant contol allCheckerCheckboxes individually (will check automatically if necessary)
  <Checkbox value="anything" checked/> // Check individual checkboxes
</CheckboxGroup>

Disabling checkboxes

<CheckboxGroup defaultDisabled> // Set defaultDisabled to disable all by default
  <AllCheckerCheckbox disabled/> // Disable allCheckerCheckbox, will still check if all checkboxes are checked
  <Checkbox value="anything" disabled/> // Disable individual checkboxes
</CheckboxGroup>

Real life example (with check all)

import React from "react";
import { AllCheckerCheckbox, Checkbox, CheckboxGroup } from '@createnl/grouped-checkboxes';

const PermissionsFrom = (props) => {
    const onCheckboxChange = (checkboxes) => {
        console.log(checkboxes);
    }    

    return (
        <CheckboxGroup onChange={console.log}>
          <label>
            <Checkbox value="tos" />
            Terms and Conditions
          </label>
          <label>
            <Checkbox value="privacy-policy" />
            Privacy Policy
          </label>
          <label>
            <Checkbox value="advertisements" />
            Advertisements
          </label>
          <label>
            <AllCheckerCheckbox />
            Agree to all
          </label>
        </CheckboxGroup>
    );
};

The value of an onChange parameter looks like:

[
    {
        "checked": true,
        "disabled": false,
        "value": "tos"
    },
    {
        "checked": true,
        "disabled": false,
        "value": "privacy-policy"
    }, 
    {
        "checked": true,
        "disabled": false,
        "value": "advertisements"
    }
]

All given props will be accessible.

Real life example (with none-checker)

If you need a checkbox that will check when nothing is checked you can use the NoneCheckerCheckbox. This checkbox can be clicked to uncheck everything else, but can't be unchecked to check everything else.

import React from "react";
import { NoneCheckerCheckbox, Checkbox, CheckboxGroup } from '@createnl/grouped-checkboxes';

const LunchDeclaration = (props) => {
    const onCheckboxChange = (checkboxes) => {
        console.log(checkboxes);
    }    

    return (
        <CheckboxGroup onChange={console.log}>
          <h1>What did you eat for lunch?</h1>
          <label>
            <Checkbox value="pizza" />
            Pizza
          </label>
          <label>
            <Checkbox value="burger" />
            Burger
          </label>
          <label>
            <Checkbox value="fries" />
            Fries
          </label>
          <label>
            <NoneCheckerCheckbox />
            Nothing
          </label>
        </CheckboxGroup>
    );
};

The value of an onChange parameter looks like:

[
    {
        "checked": true,
        "disabled": false,
        "value": "pizza"
    },
    {
        "checked": true,
        "disabled": false,
        "value": "burger"
    }, 
    {
        "checked": true,
        "disabled": false,
        "value": "fries"
    }
]

Note that the value of the NoneCheckerCheckbox will not be passed.

Accessing the native input

The Checkbox, AllCheckerCheckbox and NoneCheckerCheckboxes are nothing more than controlled native input elements and uses the forwardRef function for you to pass your ref to. This enables you to control the DOM node and for example focus on the element.

import React from "react";
import { AllCheckerCheckbox, Checkbox, CheckboxGroup } from '@createnl/grouped-checkboxes';

const MyGroupedCheckboxes = (props) => {
    const checkboxRef = React.createRef();

    React.useEffect(() => {
        if (checkboxRef.current) {
            // Focus on the input element
            checkboxRef.current.focus();
        }
    }, [checkboxRef])

    return (
        <CheckboxGroup>
          <AllCheckerCheckbox />
          <Checkbox ref={checkboxRef} value="option-1"/>
          <Checkbox value="option-2" />
          <Checkbox value="option-3" />
        </CheckboxGroup>
    );
};

grouped-checkboxes's People

Contributors

alexlisenkov avatar dependabot[bot] avatar rslijkhuis avatar superthinking avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

grouped-checkboxes's Issues

Minor fix required in documentation ๐Ÿ˜…

First of all, great work!
But can you just change a small thing in the documentation that it's
import { AllCheckerCheckbox, Checkbox, CheckboxGroup } from "@createnl/grouped-checkboxes";

and not just from "grouped-checkboxes"

Or just merge it #11 ๐Ÿ˜…

Nested CheckboxGroup

Hi, can we use multiple CheckboxGroup inside the parent CheckboxGroup.
Like for example i have a table and i want to toggle each row with a Master checkbox and then i need another to toggle all checkboxes in table.
Is this possible.
I tried but only the inner ones (AllCheckerCheckbox) work. And master does not.

Infinite re-rendering when trying to update a state with CheckboxGroup

Hi @AlexLisenkov

It's me again.

When I want to update a state through the onChange props of CheckboxGroup, it's re-renders forever. The infinite re-rendering starts on page load, not waiting for a change event to happen first. It only does that for state update whether I'm using this.setState() or useState.
I think there is an issue between the CheckboxGroup and updating a state, or with react-table.

How can I stop the infinite re-rendering, please?

import React, { useState } from 'react;
import ReactTable, { ReactTableDefaults } from 'react-table';

function Table(props) {
  const [role, setRole] = useState({
      name: '',
      permissions: [],
      checked: false,
  });

  const data = [{ name: "Uzumaki" }, { name: "Goku" }];
  const actionHeaders = [{ name: "ADD" }, { name: "DELETE" }];

  const columns = [
    {
      Header: "Name",
      accessor: "name",
      Cell: row => {
        return (
          <span>
            <AllCheckerCheckbox />
            Select all
          </span>
        );
      }
    },
    ...renderActionColumns()
  ];

  const onCheckAll = checkboxes => {
    console.log("AllCheckboxes", checkboxes);
    
    // For some reason, this triggers an infinite re-rendering when the handler is on CheckboxGroup!
    setRole({
      ...role,
      permissions: checkboxes
    });
  };

  function renderActionColumns() {
    return actionHeaders.map(action => {
      return {
        Header: action.name,
        Cell: row => {
          return (
            <Checkbox />
          );
        }
      };
    });
  }

  // Where the issue starts.
  function TRComponent({ children, ...rest }) {
    return (
      <div className="rt-tr" role="row">
        <CheckboxGroup onChange={onCheckAll}>
          <span>{children}</span>
        </CheckboxGroup>
      </div>
    );
  }

  Object.assign(ReactTableDefaults, {
    TrComponent: TRComponent
  });

  return (
    <ReactTable data={data} columns={columns} />
  );
}

export default Table;

Logging dynamic ID's to console

I upgraded to 1.1.0 and I notice the dynamic ID's get logged to the console. Was this intended? Is there a way to disable this? It looks like it comes from CheckboxGroup.tsx line 103.
output

individual checkbox remains selected even after the state change

The below is the snippet.

there is term list, when user selects a term, the below component is called and a new term details is passed. But the issue is , if i have selected a checkbox for term1 and the same checkbox remain selected for term2 and so on as well.

Please help. I am state inside class component.

const Sentences = ({term,onCheckboxChanged})=>(

<CheckboxGroup onChange={onCheckboxChanged}  >
    <table>
        <thead>
            <tr>
                <th width="5%" className="text-center"> <AllCheckerCheckbox /></th>
                <th>All</th>
            </tr>
        </thead>  
        <tbody>
            {term.sentences.map((sentence,index) =>
                <tr>
                    <td className="text-center align-top"><Checkbox className="checkbox" value={index} /></td>
                    <td>{sentence}</td>
                </tr>
            )}
           
        </tbody>
</table>

defaultChecked not working

Hi Team

I'm trying to apply defaultChecked to Checkbox but it's not working. I get a warning saying:

Warning: ForwardRef contains an input of type checkbox with both checked and defaultChecked props..., etc.

How can I apply defaultChecked especially for pre-populating checkboxes?

Many Thanks

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.