Airbnb clone, sync the start and end dates

This post is part of a new series where we build a clone of Airbnb with Next.js. See the first post here.

Now we can select a start and end date to book a place (something we’ll implement later!) but we have one thing to do: start and end dates are not synced!

To start with, the end date can’t be today: it must default to “tomorrow” if the start date is set to “today” by default

Then, we must make and ensure a relationship between the start and end date: the end date can’t be before the start date. When we change the start date, the end date will point to the day after it, unless the end date is still a valid one (e.g. it’s still after the start date)

Let’s start.

First, I’m going to set that “today” is not a valid selectable date for the end day:

components/DateRangePicker.js

dayPickerProps={{
  modifiers: {
    disabled: [
      new Date(),
      {
        before: new Date()
      }
    ]
  }
}}

Then, I am going to set the end date to “tomorrow” by default. I do so by passing the value prop to the DayPickerInput component. To the first I pass startDate, to the second endDate, which correspond, at page load time, at today and tomorrow’s dates:

import { useState } from 'react'

const today = new Date()
const tomorrow = new Date(today)
tomorrow.setDate(tomorrow.getDate() + 1)

//...

export default function DateRangePicker() {
  const [startDate, setStartDate] = useState(today)
  const [endDate, setEndDate] = useState(tomorrow)

  return (
    <div className='date-range-picker-container'>
      <div>
        <label>From:</label>
        <DayPickerInput
          formatDate={formatDate}
          format={format}
          value={startDate}
          parseDate={parseDate}
          placeholder={`${dateFnsFormat(new Date(), format)}`}
          dayPickerProps={{
            modifiers: {
              disabled: {
                before: new Date()
              }
            }
          }}
          onDayChange={day => {
            setStartDate(day)
          }}
        />
      </div>
      <div>
        <label>To:</label>
        <DayPickerInput
          formatDate={formatDate}
          format={format}
          value={endDate}
          parseDate={parseDate}
          placeholder={`${dateFnsFormat(new Date(), format)}`}
          dayPickerProps={{
            modifiers: {
              disabled: [
                new Date(),
                {
                  before: new Date()
                }
              ]
            }
          }}
          onDayChange={day => {
            setEndDate(day)
          }}
        />
      </div>

      ....

Cool!

Now let’s make the end date adjust when I choose a start date after the end date. I am going to +1 on the end date, so if I select, let’s say, January 21 and the end date is January 4, the end date will be changed to January 22.

How? Let’s first add this function that counts the difference of days between 2 dates:

const numberOfNightsBetweenDates = (startDate, endDate) => {
  const start = new Date(startDate) //clone
  const end = new Date(endDate) //clone
  let dayCount = 0

  while (end > start) {
    dayCount++
    start.setDate(start.getDate() + 1)
  }

  return dayCount
}

I picked it from https://flaviocopes.com/how-to-count-days-between-dates-javascript/.

Now inside the onDayChange prop of the first DayPickerInput, which now contains:

onDayChange={day => {
  setStartDate(day)
}}

I add:

onDayChange={day => {
  setStartDate(day)
  if (numberOfNightsBetweenDates(day, endDate) < 1) {
    const newEndDate = new Date(day)
    newEndDate.setDate(newEndDate.getDate() + 1)
    setEndDate(newEndDate)
  }
}}

Now, let’s make sure we can’t select an end date prior to startDate. How?

In the end date’s DayPickerInput I change the dayPickerProps to:

dayPickerProps={{
  modifiers: {
    disabled: [
      startDate,
      {
        before: startDate
      }
    ]
  }
}}

so we can’t select startDate (which defaults to “today”) and we can’t select dates prior to startDate.

That’s it! Now if you choose a checkin date in the future, or the same day of the checkout date, the checkout date will change!

See the code on GitHub


This content originally appeared on flaviocopes.com and was authored by flaviocopes.com

This post is part of a new series where we build a clone of Airbnb with Next.js. See the first post here.

Now we can select a start and end date to book a place (something we’ll implement later!) but we have one thing to do: start and end dates are not synced!

To start with, the end date can’t be today: it must default to “tomorrow” if the start date is set to “today” by default

Then, we must make and ensure a relationship between the start and end date: the end date can’t be before the start date. When we change the start date, the end date will point to the day after it, unless the end date is still a valid one (e.g. it’s still after the start date)

Let’s start.

First, I’m going to set that “today” is not a valid selectable date for the end day:

components/DateRangePicker.js

dayPickerProps={{
  modifiers: {
    disabled: [
      new Date(),
      {
        before: new Date()
      }
    ]
  }
}}

Then, I am going to set the end date to “tomorrow” by default. I do so by passing the value prop to the DayPickerInput component. To the first I pass startDate, to the second endDate, which correspond, at page load time, at today and tomorrow’s dates:

import { useState } from 'react'

const today = new Date()
const tomorrow = new Date(today)
tomorrow.setDate(tomorrow.getDate() + 1)

//...

export default function DateRangePicker() {
  const [startDate, setStartDate] = useState(today)
  const [endDate, setEndDate] = useState(tomorrow)

  return (
    <div className='date-range-picker-container'>
      <div>
        <label>From:</label>
        <DayPickerInput
          formatDate={formatDate}
          format={format}
          value={startDate}
          parseDate={parseDate}
          placeholder={`${dateFnsFormat(new Date(), format)}`}
          dayPickerProps={{
            modifiers: {
              disabled: {
                before: new Date()
              }
            }
          }}
          onDayChange={day => {
            setStartDate(day)
          }}
        />
      </div>
      <div>
        <label>To:</label>
        <DayPickerInput
          formatDate={formatDate}
          format={format}
          value={endDate}
          parseDate={parseDate}
          placeholder={`${dateFnsFormat(new Date(), format)}`}
          dayPickerProps={{
            modifiers: {
              disabled: [
                new Date(),
                {
                  before: new Date()
                }
              ]
            }
          }}
          onDayChange={day => {
            setEndDate(day)
          }}
        />
      </div>

      ....

Cool!

Now let’s make the end date adjust when I choose a start date after the end date. I am going to +1 on the end date, so if I select, let’s say, January 21 and the end date is January 4, the end date will be changed to January 22.

How? Let’s first add this function that counts the difference of days between 2 dates:

const numberOfNightsBetweenDates = (startDate, endDate) => {
  const start = new Date(startDate) //clone
  const end = new Date(endDate) //clone
  let dayCount = 0

  while (end > start) {
    dayCount++
    start.setDate(start.getDate() + 1)
  }

  return dayCount
}

I picked it from https://flaviocopes.com/how-to-count-days-between-dates-javascript/.

Now inside the onDayChange prop of the first DayPickerInput, which now contains:

onDayChange={day => {
  setStartDate(day)
}}

I add:

onDayChange={day => {
  setStartDate(day)
  if (numberOfNightsBetweenDates(day, endDate) < 1) {
    const newEndDate = new Date(day)
    newEndDate.setDate(newEndDate.getDate() + 1)
    setEndDate(newEndDate)
  }
}}

Now, let’s make sure we can’t select an end date prior to startDate. How?

In the end date’s DayPickerInput I change the dayPickerProps to:

dayPickerProps={{
  modifiers: {
    disabled: [
      startDate,
      {
        before: startDate
      }
    ]
  }
}}

so we can’t select startDate (which defaults to “today”) and we can’t select dates prior to startDate.

That’s it! Now if you choose a checkin date in the future, or the same day of the checkout date, the checkout date will change!

See the code on GitHub


This content originally appeared on flaviocopes.com and was authored by flaviocopes.com


Print Share Comment Cite Upload Translate Updates
APA

flaviocopes.com | Sciencx (2021-12-10T05:00:00+00:00) Airbnb clone, sync the start and end dates. Retrieved from https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/

MLA
" » Airbnb clone, sync the start and end dates." flaviocopes.com | Sciencx - Friday December 10, 2021, https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/
HARVARD
flaviocopes.com | Sciencx Friday December 10, 2021 » Airbnb clone, sync the start and end dates., viewed ,<https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/>
VANCOUVER
flaviocopes.com | Sciencx - » Airbnb clone, sync the start and end dates. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/
CHICAGO
" » Airbnb clone, sync the start and end dates." flaviocopes.com | Sciencx - Accessed . https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/
IEEE
" » Airbnb clone, sync the start and end dates." flaviocopes.com | Sciencx [Online]. Available: https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/. [Accessed: ]
rf:citation
» Airbnb clone, sync the start and end dates | flaviocopes.com | Sciencx | https://www.scien.cx/2021/12/10/airbnb-clone-sync-the-start-and-end-dates/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.