<div class="calendar">
  <div class="calendar__input">
    <div class="calendar__icon"></div>
    <input
      data-required
      id="date"
      autocomplete="off"
      value="Календарь"
      type="text"
      name="form[]"
      readonly
      class="_focus"
    />
  </div>
  <div class="calendar__content _hidden">
    <div class="calendar__header">
      <button class="calendar__btn-prev calendar-btn"></button>
      <span></span>
      <button class="calendar__btn-next calendar-btn"></button>
    </div>
    <div class="calendar__wrapper">
      <div class="calendar__days"></div>
      <div class="calendar__main"></div>
    </div>
    <div class="calendar__buttons">
      <button type="button" class="calendar__button button">применить</button>
      <button type="button" class="calendar__clear">сбросить фильтр</button>
    </div>
  </div>
</div>
.calendar {
  position: relative;
}

.calendar__icon {
  cursor: pointer;
  position: absolute;
  top: 51%;
  -webkit-transform: translate(0px, -50%);
      -ms-transform: translate(0px, -50%);
          transform: translate(0px, -50%);
  left: 14px;
  z-index: 5;
}

.calendar__icon::before {
  font-size: 20px;
  margin: -2px 0px 0px 0px;
}

.calendar__input {
  position: relative;
}

.calendar__input input {
  color: #a9a9a9;
  cursor: pointer;
  padding: 18px 18px 18px 50px;
}

.calendar__input._active input {
  border: 1px solid #272727;
}

.calendar__content {
  opacity: 1;
  pointer-events: auto;
}

.calendar__content._hidden {
  pointer-events: none;
  opacity: 0;
  -webkit-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

.calendar__header {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  margin: 0px 0px 12px 0px;
}

.calendar__header span {
  font-family: "Montserrat", sans-serif;
  font-weight: 600;
  font-size: 16px;
  line-height: 150%;
  text-transform: uppercase;
  text-align: center;
  -webkit-box-flex: 1;
      -ms-flex: 1 1 auto;
          flex: 1 1 auto;
}

.calendar__btn-prev {
  width: 26px;
  height: 24px;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
  margin: 0px 10px 0px 0px;
}

.calendar__btn-prev::before {
  font-size: 12px;
  -webkit-transform: rotate(-180deg);
      -ms-transform: rotate(-180deg);
          transform: rotate(-180deg);
}

.calendar__btn-prev:hover::before {
  color: #127aee;
}

.calendar__btn-next {
  width: 26px;
  height: 24px;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  margin: 0px 0px 0px 10px;
  -webkit-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

.calendar__btn-next::before {
  font-size: 12px;
}

.calendar__btn-next:hover::before {
  color: #127aee;
}

.calendar__days {
  display: -ms-grid;
  display: grid;
  -webkit-column-gap: 4px;
     -moz-column-gap: 4px;
          column-gap: 4px;
  -ms-grid-columns: (1fr)[7];
  grid-template-columns: repeat(7, 1fr);
  margin: 0px 0px 12px 0px;
  pointer-events: none;
}

.calendar__main {
  display: -ms-grid;
  display: grid;
  -webkit-column-gap: 4px;
     -moz-column-gap: 4px;
          column-gap: 4px;
  row-gap: 4px;
  -ms-grid-columns: (1fr)[7];
  grid-template-columns: repeat(7, 1fr);
  -ms-grid-rows: (41px)[5];
  grid-template-rows: repeat(5, 41px);
}

.calendar__buttons {
  margin: 30px 0px 0px 0px;
}

.calendar__button {
  width: 100%;
}

.calendar__clear {
  width: 100%;
  margin: 30px 0px 0px 0px;
  font-family: "europeext", sans-serif;
  font-weight: 700;
  font-size: 16px;
  line-height: 100%;
  text-transform: uppercase;
  -webkit-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
}

.calendar__clear:hover {
  color: #127aee;
}

.calendar__popup {
  display: none;
}

.cell_wrapper.current {
  color: #272727;
}

.cell_wrapper {
  cursor: pointer;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  width: 41px;
  height: 41px;
  border-radius: 50%;
  font-family: "Montserrat", sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 140%;
  text-align: center;
  -webkit-transition: all 0.3s ease 0s;
  -o-transition: all 0.3s ease 0s;
  transition: all 0.3s ease 0s;
  border: 1px solid transparent;
  background: transparent;
  color: #a9a9a9;
}

.cell_wrapper.isCurrent {
  border: 1px solid #272727;
  background: transparent;
  color: #272727;
}

.cell_wrapper.isCurrent.isSelected {
  border: 1px solid #272727;
  background: transparent;
  color: #272727;
}

.cell_wrapper.cal_date.current.isSelected {
  color: #fff;
  background: #272727;
}

.cell_wrapper.cal_date.current.isSelected:last-child {
  background: #841212;
}

.cell_wrapper.cal_date.current.isSelected:first-child {
  background: #841212;
}
const calendar = document.querySelector(".calendar__main")
if (calendar) {
  const input = document.querySelector("#date")
  const calHeaderTitle = document.querySelector(".calendar__header span")
  const calDays = document.querySelector(".calendar__days")

  const days = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]
  const months = [
    "Январь",
    "Февраль",
    "Март",
    "Апрель",
    "Май",
    "Июнь",
    "Июль",
    "Август",
    "Сентябрь",
    "Октябрь",
    "Ноябрь",
    "Декабрь",
  ]

  let oneDay = 60 * 60 * 24 * 1000
  let todayTimestamp =
    Date.now() -
    (Date.now() % oneDay) +
    new Date().getTimezoneOffset() * 1000 * 60

  let selectedDay = todayTimestamp

  const getNumberOfDays = (year, month) => {
    return 40 - new Date(year, month, 40).getDate()
  }

  const getDayDetails = (args) => {
    let date = args.index - args.firstDay
    let day = args.index % 7

    let prevMonth = args.month - 1
    let prevYear = args.year
    if (prevMonth < 0) {
      prevMonth = 11
      prevYear--
    }
    let prevMonthNumberOfDays = getNumberOfDays(prevYear, prevMonth)

    let _date =
      (date < 0 ? prevMonthNumberOfDays + date : date % args.numberOfDays) + 1
    let month = date < 0 ? -1 : date >= args.numberOfDays ? 1 : 0
    let timestamp = new Date(args.year, args.month, _date).getTime()

    return {
      date: _date,
      day,
      month,
      timestamp,
      dayString: days[day],
    }
  }

  const getMonthDetails = (year, month) => {
    let firstDay = new Date(year, month).getDay()
    let numberOfDays = getNumberOfDays(year, month)
    let monthArray = []
    let rows = 5
    let currentDay = null
    let index = 0
    let cols = 7

    for (let row = 0; row < rows; row++) {
      for (let col = 0; col < cols; col++) {
        currentDay = getDayDetails({
          index,
          numberOfDays,
          firstDay,
          year,
          month,
        })
        monthArray.push(currentDay)
        index++
      }
    }
    return monthArray
  }

  let date = new Date()
  let year = date.getFullYear()
  let month = date.getMonth()
  let monthDetails = getMonthDetails(year, month)

  const isCurrentDay = (day, cell) => {
    if (day.timestamp === todayTimestamp) {
      cell.classList.add("isCurrent")
      cell.classList.add("active")
    }
  }

  const isSelectedDay = (day, cell) => {
    if (day.timestamp === selectedDay) {
      cell.classList.toggle("isSelected")
    }
  }

  const getMonthStr = (month) =>
    months[Math.max(Math.min(11, month), 0)] || "Month"
  const setHeaderNav = (offset) => {
    month = month + offset
    if (month === -1) {
      month = 11
      year--
    } else if (month === 12) {
      month = 0
      year++
    }
    monthDetails = getMonthDetails(year, month)
    // console.log(getMonthDetails(year, month))
    return {
      year,
      month,
      monthDetails,
    }
  }

  const setHeader = (year, month) => {
    calHeaderTitle.innerHTML = getMonthStr(month) + " " + year
  }

  setHeader(year, month)

  const getDateStringFromTimestamp = (timestamp) => {
    let dateObject = new Date(timestamp)
    let month = dateObject.getMonth()
    let date = dateObject.getDate()

    return `${getMonthStr(month)} ${date}, ${dateObject.getFullYear()}`
  }

  const setDateToInput = (timestamp) => {
    let dateString = getDateStringFromTimestamp(timestamp)
    //input.value = dateString;
  }
  setDateToInput(todayTimestamp)

  for (let i = 0; i < days.length; i++) {
    let div = document.createElement("div"),
      span = document.createElement("span")

    div.classList.add("cell_wrapper")
    div.classList.add("cal_days")
    span.classList.add("cell_item")

    span.innerText = days[i].slice(0, 2)

    div.appendChild(span)
    calDays.appendChild(div)
  }

  const setCalBody = (monthDetails) => {
    for (let i = 0; i < monthDetails.length; i++) {
      let div = document.createElement("div"),
        span = document.createElement("span")

      div.classList.add("cell_wrapper")
      div.classList.add("cal_date")
      monthDetails[i].month === 0 && div.classList.add("current")
      monthDetails[i].month === 0 && isCurrentDay(monthDetails[i], div)

      span.classList.add("cell_item")
      span.innerText = monthDetails[i].date

      div.appendChild(span)
      calendar.appendChild(div)
    }
  }

  setCalBody(monthDetails)

  const updateCalendar = (btn) => {
    let newCal, offset
    if (btn.classList.contains("calendar__btn-prev")) {
      offset = -1
    } else if (btn.classList.contains("calendar__btn-next")) {
      offset = 1
    }
    newCal = setHeaderNav(offset)
    setHeader(newCal.year, newCal.month)
    calendar.innerHTML = ""
    setCalBody(newCal.monthDetails)
  }

  // Only one calendar date is selected
  const selectOnClick = () => {
    document.querySelectorAll(".cell_wrapper").forEach((cell) => {
      cell.classList.contains("isSelected") && cell.classList.remove("active")
      if (
        cell.classList.contains("isCurrent") &&
        !cell.classList.contains("active")
      ) {
        cell.querySelector("span").classList.add("inactive_indicator")
      }
    })
  }

  const updateInput = () => {
    let currentDay = document.querySelector(".isCurrent")

    document.querySelectorAll(".cell_wrapper").forEach((cell) => {
      if (cell.classList.contains("current")) {
        cell.addEventListener("click", (e) => {
          let cell_date = e.target.textContent

          currentDay !== null && currentDay.classList.remove("active")

          for (let i = 0; i < monthDetails.length; i++) {
            if (monthDetails[i].month === 0) {
              if (monthDetails[i].date.toString() === cell_date) {
                selectedDay = monthDetails[i].timestamp
                setDateToInput(selectedDay)
                selectOnClick()

                isSelectedDay(monthDetails[i], cell)

                cell
                  .querySelector("span")
                  .classList.contains("inactive_indicator") &&
                  cell
                    .querySelector("span")
                    .classList.remove("inactive_indicator")
              }
            }
          }
        })
      }
    })
  }

  updateInput()

  document.querySelectorAll(".calendar-btn").forEach((btn) => {
    btn.addEventListener("click", () => {
      updateCalendar(btn)
      updateInput()
    })
  })

  input.addEventListener("click", () => {
    document.querySelector(".calendar__content").classList.toggle("_hidden")
    document.querySelector(".calendar__input").classList.toggle("_active")
    document.querySelector("#date").classList.toggle("_focus")
  })
  window.addEventListener("click", (e) => {
    const target = e.target
    if (
      !target.closest("#date") &&
      !target.closest(".calendar__input") &&
      !target.closest(".calendar__content")
    ) {
      document.querySelector(".calendar__content").classList.add("_hidden")
      document.querySelector(".calendar__input").classList.remove("_active")
      document.querySelector("#date").classList.add("_focus")
    }
  })
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.