Ajay Gupta
Ajay Gupta

Reputation: 2033

How to mark a number of checkboxes as checked and others unchecked in ReactJS?

I have two arrays

masterList:

[
  { id: 0, description: "a" },
  { id: 1, description: "b" },
  { id: 2, description: "c" },
  { id: 3, description: "d" }
]

preferencesList:

[
  {id: 0, description: "a" },
  {id: 2, description: "c" }
]

What I want to do is, render four checkboxes (or more, depending on the length of masterList) and pre-check only those checkboxes that are listed in preferencesList.

I tried but couldn't get it to work.

This is what I have done so far:

{
  this.state.masterList && this.state.masterList.length ? (
    this.state.masterList.map((item, index) => (
      <div key={`item_${index}`} className="form-group">
        <div className="checkbox">
          <label>
            {this.state.preferencesList && this.state.preferencesList.length
              ? this.state.preferencesList.map(
                  insurerFeature =>
                    insurerFeature.id == item.id ? (
                      <input
                        type="checkbox"
                        onChange={this.changeFeaturePreferences}
                        value={item.id}
                        defaultChecked
                      />
                    ) : (
                      <input
                        type="checkbox"
                        onChange={this.changeFeaturePreferences}
                        value={item.id}
                      />
                    )
                )
              : "failed to get insurers items"}
            {item.description}
          </label>
        </div>
      </div>
    ))
  ) : (
    <p>There are no items available.</p>
  );
}

changeFeaturePreferences Method:

changeFeaturePreferences = event => {
  let { id } = this.state.resource;
  let featureId = event.target.value;
  let checkbox = event.target;

  // Reset state
  this.setState({ success: null });

  // Add Feature
  if (checkbox.checked) {
    let payload = [featureId];
    return MyService.setMyFeatures(id, payload).then(
      response => this.setState({ success: true }),
      error => this.setState({ success: false })
    );
  }
  // Remove Feature
  if (!checkbox.checked) {
    return MyService.deleteMyFeatures(id, featureId).then(
      response => this.setState({ success: true }),
      error => this.setState({ success: false })
    );
  }
  // Return with error
  return this.setState({ success: false });
};

Upvotes: 0

Views: 47

Answers (2)

bennygenel
bennygenel

Reputation: 24660

You can use Array.prototype.some() to determine if the object exists in preferencesList.

The some() method tests whether at least one element in the array passes the test implemented by the provided function.

Example

{
  this.state.masterList && this.state.masterList.length ? (
    this.state.masterList.map((item, index) => {
      const checked = preferencesList.some((checkedItem) => checkedItem.id === item.id);
      return (
      <div key={`item_${index}`} className="form-group">
        <div className="checkbox">
          <label>
            <input
              type="checkbox"
              onChange={this.changeFeaturePreferences}
              value={item.id}
              checked={checked}
            />
            {item.description}
          </label>
        </div>
      </div>
    )})
  ) : (
    <p>There are no items available.</p>
  );
}

Upvotes: 2

Ross Allen
Ross Allen

Reputation: 44880

I would first convert the preferencesList into an Object so you have constant-time look up after the initial mapping and simpler logic in your JSX. You could do something like the following:

const isChecked = {};
preferencesList.forEach(preference => { isChecked[preference.id] = true; });

{
  this.state.masterList && this.state.masterList.length ? (
    this.state.masterList.map((item, index) => (
      <div key={`item_${index}`} className="form-group">
        <div className="checkbox">
          <label>
            <input
              type="checkbox"
              onChange={this.changeFeaturePreferences}
              value={item.id}
              defaultChecked={isChecked[item.id]}
            />
            {item.description}
          </label>
        </div>
      </div>
    ))
  ) : (
    <p>There are no items available.</p>
  );
}

Upvotes: 2

Related Questions