Pritam Kumar
Pritam Kumar

Reputation: 29

How would i get the selected div element color change & Store every selected Div elem in state in ReactJS?

I am trying to create a booking slot.I have store all the available time slot in state, I am getting the max_slots = number from API & from max_slots i am creating slots on each given time.Now i need to store selected Slots in state & Change the colour of selected Slots.Uncheck the slots when double clicked.

I have tried doing here is my code your most welcome for Edit.

https://codesandbox.io/s/2v15vl8rk0

class SlotBookingComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      bookingDate: "",
      buttonColor: "red",
      startTime: "",
      endTime: "",
      AvailableSlots: [],
      slots: null
    };
    this.updateState = this.updateState.bind(this);
    //this.handleSlots = this.handleSlots.bind(this);
  }

  onButtonPress() {
    this.setState({
      buttonColor: "#123eee"
    });
  }

  parseIn(date_time) {
    var d = new Date();
    d.setHours(date_time.substring(11, 13));
    d.setMinutes(date_time.substring(14, 16));

    return d;
  }

  getTimeSlots(time1, time2) {
    var arr = [];
    while (time1 < time2) {
      arr.push(time1.toTimeString().substring(0, 5));
      time1.setMinutes(time1.getMinutes() + 30);
    }
    return arr;
  }

  updateState() {
    var startTime = "2019-05-06T10:30:00+05:30";
    var endTime = "2019-05-06T22:00:00+05:30";

    startTime = this.parseIn(startTime);
    endTime = this.parseIn(endTime);
    var intervals = this.getTimeSlots(startTime, endTime);
    this.setState({
      AvailableSlots: intervals
    });
  }

  componentDidMount() {
    this.updateState();
  }

  componentWillReceiveProps(props) {
    this.setState({ slots: props.SlotsData });
    console.log(this.state.slots);
  }
  handleClick(i, item) {
    this.setState({
      slotsbooked: i,
      time: item
    });
    console.log(i, item);
  }

  render() {
    const AvailableSlots = this.state.AvailableSlots;

    const handleSlots = (max_slot, item) => {
      let slots = [];
      for (let counter = 1; counter <= max_slot; counter++) {
        slots.push(
          <div
            className="col"
            onClick={() => this.handleClick(counter, item)}
            style={{
              margin: 5,
              backgroundColor: "#575756",
              height: "28px"
            }}
          />
        );
      }
      // console.log(slots);
      return slots;
    };

    const RowData = AvailableSlots.map(function(item, index) {
      //max_slot wold come from API
      var max_slot = 4;
      if (max_slot == 1) {
        return (
          <div className="row">
            <p>{item}</p>
            <div
              className="col"
              key={item}
              style={{ backgroundColor: "#123eee", height: "28px" }}
            >
              col
            </div>
          </div>
        );
      } else {
        return (
          <div className="data">
            <div className="row test">
              <div className="slot">{item}- </div>
              {handleSlots(max_slot, item)}
            </div>
          </div>
        );
      }
    });

    return (
      <div className="container">
        <div className="col-md-9 slot-window product-details">{RowData}</div>
      </div>
    );
  }
}

ReactDOM.render(<SlotBookingComponent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

Upvotes: 0

Views: 114

Answers (1)

Junius L
Junius L

Reputation: 16142

Make each time have it's own time slots in the AvailableSlots array. e.g. [{time: '20:00', slots: {slot1: false, slot2: false, slot3: true}].

getTimeSlots(time1, time2) {
  var arr = [];
  while (time1 < time2) {
    arr.push({
      time: time1.toTimeString().substring(0, 5),
      // create slots for each given time
      // change slots object properties to your liking
      slots: {
        '1': false,
        '2': false,
        '3': false,
        '4': false
      }
    });
    time1.setMinutes(time1.getMinutes() + 30);
  }

  return arr;
}

Handle on click

handleClick(i, item, index) {

  const selected = this.state.AvailableSlots[index].slots[i.toString()];

  const slots = Object.assign({}, this.state.AvailableSlots[index].slots, {[i.toString()]: !selected });


  this.setState({
    AvailableSlots: [
      ...this.state.AvailableSlots.slice(0, index),
      Object.assign({}, this.state.AvailableSlots[index], { slots: slots, time: item.time }),
      ...this.state.AvailableSlots.slice(index + 1)
    ]
  });

}

In your handleSlots function check , if slot is selected.

const handleSlots = (max_slot, item, index) => {
  let slots = [];
  for (let counter = 1; counter <= max_slot; counter++) {
    slots.push(
      <div
        className="col"
        onClick={() => this.handleClick(counter, item, index)}
        style={{
          margin: 5,
          backgroundColor: item.slots[counter.toString()] ? 'green' : '#575756',
          height: '28px'
        }}
      />
    );
  }
  // console.log(slots);
  return slots;
};

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script src="//unpkg.com/office-ui-fabric-react/dist/office-ui-fabric-react.js"></script>
<div id="root"></div>

<script type="text/babel">

class SlotBookingComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      bookingDate: '',
      buttonColor: 'red',
      startTime: '',
      endTime: '',
      AvailableSlots: [],
      slots: null
    };
    this.updateState = this.updateState.bind(this);
    //this.handleSlots = this.handleSlots.bind(this);
  }

  onButtonPress() {
    this.setState({
      buttonColor: '#123eee'
    });
  }

  parseIn(date_time) {
    var d = new Date();
    d.setHours(date_time.substring(11, 13));
    d.setMinutes(date_time.substring(14, 16));

    return d;
  }

  getTimeSlots(time1, time2) {
    var arr = [];
    while (time1 < time2) {
      arr.push({
        time: time1.toTimeString().substring(0, 5),
        slots: {
          '1': false,
          '2': false,
          '3': false,
          '4': false
        }
      });
      time1.setMinutes(time1.getMinutes() + 30);
    }

    return arr;
  }

  updateState() {
    var startTime = '2019-05-06T10:30:00+05:30';
    var endTime = '2019-05-06T22:00:00+05:30';

    startTime = this.parseIn(startTime);
    endTime = this.parseIn(endTime);
    var intervals = this.getTimeSlots(startTime, endTime);
    this.setState({
      AvailableSlots: intervals
    });
  }

  componentDidMount() {
    this.updateState();
  }

  componentWillReceiveProps(props) {
    this.setState({ slots: props.SlotsData });
    console.log(this.state.slots);
  }

  handleClick(i, item, index) {
    const selected = this.state.AvailableSlots[index].slots[i.toString()];

    const slots = Object.assign({}, this.state.AvailableSlots[index].slots, {
      [i.toString()]: !selected
    });

    this.setState({
      AvailableSlots: [
        ...this.state.AvailableSlots.slice(0, index),
        Object.assign({}, this.state.AvailableSlots[index], {
          slots: slots,
          time: item.time
        }),
        ...this.state.AvailableSlots.slice(index + 1)
      ]
    });
  }

  render() {
    const AvailableSlots = this.state.AvailableSlots;

    const handleSlots = (max_slot, item, index) => {
      let slots = [];
      for (let counter = 1; counter <= max_slot; counter++) {
        slots.push(
          <div
            className="col"
            onClick={() => this.handleClick(counter, item, index)}
            style={{
              margin: 5,
              backgroundColor: item.slots[counter.toString()]
                ? 'green'
                : '#575756',
              height: '28px'
            }}
          />
        );
      }
      // console.log(slots);
      return slots;
    };

    const RowData = AvailableSlots.map(function(item, index) {
      //max_slot wold come from API
      var max_slot = 4;
      if (max_slot == 1) {
        return (
          <div className="row">
            <p>{item}</p>
            <div
              className="col"
              key={item}
              style={{ backgroundColor: '#123eee', height: '28px' }}
            >
              col
            </div>
          </div>
        );
      } else {
        return (
          <div className="data">
            <div className="row test">
              <div className="slot">{item.time}- </div>
              {handleSlots(max_slot, item, index)}
            </div>
          </div>
        );
      }
    });

    return (
      <div className="container">
        <div className="col-md-9 slot-window product-details">{RowData}</div>
      </div>
    );
  }
}

ReactDOM.render(<SlotBookingComponent />, document.getElementById("root"));

</script>

Upvotes: 1

Related Questions