简体   繁体   中英

Moment.js | not displaying with intended date format

Overview

I am using moment.js in my webapp to allow a user to select a date range for their vacation. After they select the desired date range (for instance, November 1 to November 3), the app renders a container (in this case 3 containers) for each day that allow the user to plan each day. One of the divs in that container holds the date for that day, which is based on the original dates selected.

Goal

I need each day to have the date formatted in "MMM-Do-YY" (Nov 11th 19). However, I'm getting a format that includes much more for each day: Sun Nov 10 2019 00:00:00 GMT-0500.

What I've tried

I'm using an event handler function, onDateChange (see below), where I attempt to provide formatting for both the start and end dates. The onDateChange is being updated by two input fields in the render method. After onDateChange sets the state, I have a ul in the render method that maps through the state and creates a container for each day. That container is a component instance named DayContainer (the code for that component is far below).

My best guess for what I think is wrong

I'm thinking the problem lies in the DayContainer class's render method. The second div inside of that is what renders the date. I'm using this.state.date.toString and I'm thinking that is what needs to be modified.

import React from 'react';
import './ItineraryContainer.css';
import * as moment from "moment";
import DayContainer from '../DayContainer/DayContainer';


class ItineraryContainer extends React.Component {
  constructor(props){
    super(props);

    this.state = {
      startDate: '',
      endDate: '',
      days: [],
    }
  }

  onDateChange(e){
    this.setState({
      [e.target.name]: e.target.value,
    }, () => {

      let startDate = moment(this.state.startDate, "YYYY-MM-DD");
      if(!startDate.isValid()){
        return;
        //returns start date in this format startDate is valid//
      }
      let endDate = moment(this.state.endDate, "YYYY-MM-DD").startOf('day');
      if(!endDate.isValid()){
        return;
        //returns end date in this format if endDate is valid//
      }
      if(endDate.toDate() < startDate.toDate()){
        return;
        //checks whether endDate is greater than startDate
      }
      let numberOfDays = endDate.diff(startDate, 'days') + 1;
        //stores difference between start/end dates
      let days = [];
        //pushes number of days to setState below
      for(let i = 0; i < numberOfDays; i++){
        days.push({
          id: days.length,
          date: startDate.clone().add(i, "days"),
          events: [{
            time: '',
            type: '',
            summary: '',
            notes: '',
          }],
        });
      }
      //outputs the above key/values to days above
      this.setState({
        days: days,
      //grabs days from 'let days' variable on line 42
      })
    });
  }

  addNewDay(index, item) {
    index = index + 1;
    let newDay = {
      id: this.state.days.length,
      date: item.date.clone().add(1, "days"),
      events: [{
        time: '',
        type: '',
        summary: '',
        notes: '',
      }],
    };

    let daysAfter = [...this.state.days.slice(index)];
    daysAfter.forEach((oldDay) => {
      oldDay.date.add(1, 'days');
    })

    this.setState(prevState => {
      let updatedDays = [...prevState.days.slice(0, index), newDay, ...daysAfter];

        return {
          days: updatedDays
        };
      })
    }

  render(){
    return (
      <div className="itinerary-container">

          <h1 className="TripHeader-background-color">TripHeader</h1>

          <input name="startDate" type="date" value={this.state.startDate} onChange={(e) => this.onDateChange(e)}/ >
            {/* captures startDate */}
          <input name="endDate"  type="date" value={this.state.endDate} onChange={(e) => this.onDateChange(e)}/>
            {/* captures endDate */}

          <ul>
            {this.state.days.map((item, index) => (
              <li key={item.id}>
                  <DayContainer day={item} />
                  <button onClick={() => this.addNewDay(index, item)}>Add Day
                  </button>
              </li>
            ))}
          </ul>
      </div>
    )
  }
}

export default ItineraryContainer;

//DayContainer below

import React from 'react';
import './DayContainer.css';
import EventContainer from '../EventContainer/EventContainer';

class DayContainer extends React.Component {
  constructor(props){
    super(props);

    this.state = {
      ...props.day
    };

    this.pushNewEventContainerToState = this.pushNewEventContainerToState.bind(this);
  }

      pushNewEventContainerToState(index) {
        console.log(index);
        index = index + 1;
        let newEvent = {key: this.state.events.length};

        this.setState(prevState => {
          let updatedEvents = [...prevState.events.slice(0, index), newEvent, ...prevState.events.slice(index)];

            return {
              events: updatedEvents
            };
          })
        }

  render(){
    return (
        <div className="day-container-bottom-border">
        <div>
          {this.state.date.toString()}
        </div>
        <div className="DayLabels-container">
          <h1 className="time-margins">Time</h1>
          <h1 className="activity-margins">Activity Summary</h1>
          <h1 className="notes-margins">Notes</h1>
        </div>

          <ul>
            {this.state.events.map((item, index) => (
              <li key={item.key}>
                  < EventContainer event={item} / >
              </li>
                ))}
          </ul>
        </div>
    )
  }
}

export default DayContainer;

Thanks for your edit to include the <DateContainer /> . Unfortunately, now there's an undefined <EventContainer /> .

No matter where you render the date, you can use the format method from moment to create the desired output.

 <ul> {this.state.days.map((item, index) => ( <li key={item.id}>{item.date.format('MMM Do YY')}</li> ))} </ul>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM