2

I am trying to design a React layout that does the following:

  1. Presents user with Calendar and Checkboxes. (Already done)
  2. User can select date and select options from checkboxes. (Already done)
  3. User input will write to array the following info (Need to implement) - Date - Options selected for that date
  4. The ability to revisit (click-on) a date with options and show which boxes have been checked and change inputs. (Need to implement)

Here is my code so far:

import React, { Component } from 'react';
import './App.css';
import 'react-calendar/dist/Calendar.css';
import Calendar from "react-calendar";
import Checkbox from './components/Checkbox'

class App extends Component {

  let sympt = [];

  function {
    if (sympt.includes(date)) {
        // check boolean values in sympt to options & change if necessary
    }
    // append sympt to add new record
  };

  render() {
    return (
      <div>
          <Checkbox />
          <Calendar />
      </div>
    );
  }
}

export default App;
checkbox.js

class Checkbox extends Component {

  constructor() {
    super();
    this.state = {
      categories: [
        {id: 1, value: "Symptom 1"},
        {id: 2, value: "Symptom 2"},
        {id: 3, value: "Symptom 3"},
        {id: 4, value: "Symptom 4"}
      ],
      checkedItems: new Map()
    };

    this.handleChange = this.handleChange.bind(this);

  }

  handleChange(event) {
        var isChecked = event.target.checked;
        var item = event.target.value;
        this.setState(prevState => ({ checkedItems: prevState.checkedItems.set(item, isChecked) }));

  }


render() {
  return (
    <div>
    <h1>Add Notes to Calendar</h1>
    <form onSubmit={this.handleSubmit}>
      {
        this.state.categories.map(item => (
          <li>
            <label>
              <input
                type="checkbox"
                value={item.id}
                onChange={this.handleChange}
              /> {item.value}
            </label>
          </li>
        ))
      }

    </form>
</div>
  );
}

}

  export default Checkbox;

Calendar is using the react-calendar

Here is what is being presented: Calendar and options

What I don't understand how to do are the following:

  1. Write data to the array in a standardized format. I only want to write to an array once an option is selected, not just when a date is selected.
  2. Check the array to see if a date already has options attached and "re-check" those boxes.
  3. Change existing data within the array.
5
  • You can store the data in an array of objects where the date will be the property and the corresponding value will be one of the checkbox value. 1. If none of the checkboxes are checked, prevent date selection. If a checkbox is checked, then only allow date selection. After this, uncheck all the checkboxes. 2. when you check a checkbox and select a date, iterate through the array using map() to see if the value already exists or not. Commented Aug 5, 2020 at 4:35
  • Can you post the code for your Checkbox and Calendar component as well? Commented Aug 5, 2020 at 4:36
  • 1
    Just edited to add Checkbox component. Calendar component is a react package I have linked. It does have a onChange prop that I think will be useful. Commented Aug 5, 2020 at 4:41
  • 1
    Thanks @Hayden. I will post an answer later today. Not at home now :D Commented Aug 5, 2020 at 5:09
  • 1
    Sorry for the late reply @Hayden! Just posted an answer, hope it helps you. Commented Aug 6, 2020 at 4:43

2 Answers 2

1

What you need to do is:

  1. Keep track of the selected date in your App.js component
  2. Keep track of each date with its corresponding selected checkboxes in your Checkbox.js component
  3. Update your selected date when the calendar change (onChange callback)
  4. Update your checkbox based on the new selected date

Point 1 and Point 3:

// In your constructor:
this.state = {
  dateValue: new Date()
};

// A handle to update your local state:
handleDateChange = newDate => {
  this.setState({
    dateValue: newDate
  });
};

// Your calendar:
<Calendar
  onChange={this.handleDateChange}
  value={this.state.dateValue}
/>

Point 2:

// In your constructor:
this.state = {
  savedValues: {}
};

// When your date change (componentDidMount and componentDidUpdate):
this.setState({
  savedValues: {
    [this.props.selectedDate]: [
      { id: "1", value: "Symptom 1", checked: false },
      { id: "2", value: "Symptom 2", checked: false },
      { id: "3", value: "Symptom 3", checked: false },
      { id: "4", value: "Symptom 4", checked: false }
     ]
  }
});
// Note that I changed id to a string to make it easier to track
// We also need to add a "checked" status

Point 4:

// In your App.js
<Checkbox selectedDate={this.state.dateValue.getTime()} />
// Note that I used .getTime() to use timestamp instead of a full date
// It is easier to track "123123..." then "Thu Aug 06 2020 16:42:21..."

// Update your current map function to load the checkboxes from your saved state
// Also include the "checked" attribute
this.state.savedValues[this.props.selectedDate].map(item => (
  <li key={item.id}>
    <label>
      <input
        type="checkbox"
        value={item.id}
        onChange={this.handleChange}
        checked={item.checked}
      />{" "}
      {item.value}
    </label>
  </li>
))}

Here is a working demo: https://codesandbox.io/s/crimson-morning-e553p

Sign up to request clarification or add additional context in comments.

1 Comment

Absolutely fabulous! Thank you so much. As I'm just learning React, this helps me so much understand how to solve a problem using React.
0

For the above-mentioned scenario:

To write the data into standard formate u can use map refer [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map]. Something like this

let calendarMap = new Map();

calendarMap["4-may"] = {
    'options':["Sympt1"],
    'eventTitle':"This is test decription"
}

console.log(calendarMap);

calendarMap["5-may"]={'options':["Symt3"],'eventTitle':'Second event'};
console.log(calendarMap);

By this, you would be able to check if the respective date has options select or not you can update and remove the data from the map by dates.

You have to bind (emit the events from the , component) to listen for user action.

2 Comments

Thanks so much! I think the map is perfect. On binding the events, I'm struggling to figure out where that should be done. In the component or the App.js?
This should be done in the app.js and the events are emited from components

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.