arrow_back
View code

<div class="datepicker-container range width-30 margin-x-auto margin-top-lg">
  <button class="cdt-btn cdt-btn-gray cdt-btn-rounded position-relative trigger">
    <span class="material-icons">
      date_range
    </span>
    <span class="margin-left-sm">
      <span class="start-date">Start date</span>
      <span>-</span>
      <span class="end-date">End date</span>
    </span>
  </button>
  <div class="datepicker shadow-md radius-md">
    <div class="header">
      <div class="controls">
        <span class="position-absolute width-100 text-xs font-medium month-label flex items-center height-100 justify-center padding-sm">April
          2021</span>
        <nav>
          <div class="prev control radius-sm">
            <span class="material-icons">
              chevron_left
            </span>
          </div>
          <div class="next control radius-sm">
            <span class="material-icons">
              chevron_right
            </span>
          </div>
        </nav>
      </div>
      <div class="weekdays-label">
        <div><span>M</span></div>
        <div><span>T</span></div>
        <div><span>W</span></div>
        <div><span>T</span></div>
        <div><span>F</span></div>
        <div><span>S</span></div>
        <div><span>S</span></div>
      </div>
    </div>
    <div class="days"></div>
  </div>
</div>
                        
Copy HTML

/*
 * File: _date-range-picker.scss
 * Location /src/scss/components
 * Date range picker component
 */

:root {
    --datepicker-item-size: 2.7em;
    --datepicker-nav-size: 2em;
    --datepicker-item-font-size: 0.9em;
    --datepicker-distance: 0.3em;
}
.datepicker-container {
    position: relative;
    input {
        padding-right: 2rem;
        font-size: var(--text-xs);
    }
    .icon {
        position: absolute;
        right: 0.2em;
        top: 50%;
        transform: translateY(-50%);
        cursor: pointer;
        color: var(--color-higher);
        transition: transform 0.2s;
        &:active {
            transform: translateY(-50%) scale(1.05);
        }
    }
    .datepicker {
        display: inline-block;
        visibility: hidden;
        opacity: 0;
        pointer-events: none;
        left: 0;
        top: calc(100% + var(--datepicker-distance));
        position: absolute;
        padding: 0.4em;
        transition: visibility 0.2s, opacity 0.2s;
        
        &.show {
            opacity: 1;
            visibility: visible;
            pointer-events: inherit;
        }

        .header {
            position: relative;
            .month-label {
                z-index: -1;
            }
            .controls {
                position: relative;
                nav {
                    display: flex;
                    justify-content: space-between;
                    .control {
                        width: var(--datepicker-item-size);
                        height: var(--datepicker-item-size);
                        transition: transform 0.2s;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        cursor: pointer;
                        &:hover {
                            background-color: var(--color-lowest);
                        }
                        span {
                            font-size: var(--datepicker-nav-size);
                            font-size: var(--datepicker-nav-size);
                            color: var(--color-mid);
                            user-select: none;
                        }
                        &.next {
                            &:active {
                            transform: translateX(0.05em);
                            }
                        }
                        &.prev {
                            &:active {
                            transform: translateX(-0.05em);
                            }
                        }
                    }
                }
            }
        
            .weekdays-label {
                display: flex;
                flex-wrap: wrap;
                color: var(--color-mid);
                div {
                    width: var(--datepicker-item-size);
                    height: var(--datepicker-item-size);
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    span {
                        font-size: var(--datepicker-item-font-size);
                        user-select: none;
                    }
                }
            }
        }
        .days {
            display: flex;
            flex-wrap: wrap;
            color: var(--color-higher);
            width: calc(7 * var(--datepicker-item-size));
            div {
                text-align: center;
                width: var(--datepicker-item-size);
                height: var(--datepicker-item-size);
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                border-radius: var(--radius-sm);
                &.today {
                    color: var(--primary-color);
                }
                &.selected {
                    background-color: var(--primary-color);
                    color: var(--color-white);
                }
                &.in-range {
                    background-color: var(--primary-color-lighter);
                }
                &:not(.selected):hover {
                    background-color: var(--color-lowest);
                }
                span {
                    font-size: var(--datepicker-item-font-size);
                }
            }
        }
    }
    &.range {
        .days {
            div {
                border-radius: 0;
                &.in-range {
                    background-color: var(--primary-color-lightest);
                }
            }
        }
    }
}



                        
Copy SCSS

/*
 * File: date-range-picker.js
 * Location /src/js/components
 * Date range picker component
*/

class DateRangepicker {
  constructor(options) {
    const date = new Date();
    this.todayIndex = date.getDate();
    this.year = date.getFullYear();
    this.month = date.getMonth();
    this.callback = options.callback ? options.callback : null;
    this.currentMonth = this.month;
    this.startDate = options.startDate ? options.startDate : null;
    this.endDate = options.endDate ? options.endDate : null;
    this.userSelectedYear = null;
    this.userSelectedMonth = null;
    this.currentYear = this.year;
    this.day = null;
    this.dayEnd = null;
    this.userSelectedYearEnd = null;
    this.userSelectedMonthEnd = null;
    this.numClicks = 0;
    this.separator = options.separator ? options.separator : "/";
    this.months = options.months
      ? options.months
      : [
          "January",
          "February",
          "March",
          "April",
          "May",
          "June",
          "July",
          "Auguest",
          "September",
          "October",
          "November",
          "December"
        ];
    const datePickerContainer = options.selector;
    this.monthLabel = datePickerContainer.querySelector(".month-label");
    this.daysContainer = datePickerContainer.querySelector(".days");
    this.nextTrigger = datePickerContainer.querySelector(".next");
    this.prevTrigger = datePickerContainer.querySelector(".prev");
    this.datePicker = datePickerContainer.querySelector(".datepicker");
    this.buttonTrigger = datePickerContainer.querySelector(".trigger");
    this.startDateText = this.buttonTrigger.querySelector(".start-date");
    this.endDateText = this.buttonTrigger.querySelector(".end-date");

    this.buttonTrigger.addEventListener("click", () => {
      this.datePicker.classList.add("show");
    });

    if (this.startDate) {
      this.startDateArray = this.startDate.split(this.separator);
      this.userSelectedYear = parseInt(this.startDateArray[0]);
      this.userSelectedMonth = parseInt(this.startDateArray[1]) - 1;
      this.day = parseInt(this.startDateArray[2]);
      this.startDateText.innerHTML = this.startDate;
    }
    if (this.endDate) {
      this.endDateArray = this.endDate.split(this.separator);
      this.userSelectedYearEnd = parseInt(this.endDateArray[0]);
      this.userSelectedMonthEnd = parseInt(this.endDateArray[1]) - 1;
      this.dayEnd = parseInt(this.endDateArray[2]);
      this.endDateText.innerHTML = this.endDate;
    }

    document.addEventListener("click", (e) => {
      if (e.target.closest(".datepicker") || e.target.closest(".trigger"))
        return;
      this.datePicker.classList.remove("show");
    });
    this.initializeControls();
    this.generateDatePickerPanel();
  }
  initializeControls() {
    this.nextTrigger.addEventListener("click", () => this.next());
    this.prevTrigger.addEventListener("click", () => this.prev());
  }
  next() {
    if (this.month === 11) {
      this.month = 0;
      this.year = this.year + 1;
    } else {
      this.month = this.month + 1;
    }
    this.generateDatePickerPanel();
  }
  prev() {
    if (this.month === 0) {
      this.month = 11;
      this.year = this.year - 1;
    } else {
      this.month = this.month - 1;
    }
    this.generateDatePickerPanel();
  }
  getDate() {
    return { startDate: this.startDate, endDate: this.endDate };
  }
  generateDatePickerPanel() {
    this.monthLabel.innerHTML = `${this.months[this.month]} ${this.year}`;
    const startingDayIndex = new Date(this.year + "/" + (this.month + 1) + "/01").getDay();
    const numberOfDays = this.numberOfDaysInMonth();
    this.daysContainer.innerHTML = "";
    for (let i = 1; i < startingDayIndex; i++) {
      this.createDay("");
    }
    for (let i = 1; i <= numberOfDays; i++) {
      this.createDay(i, this.todayIndex);
    }
    this.selectDateRange();
  }
  numberOfDaysInMonth() {
    return new Date(this.year, this.month + 1, 0).getDate();
  }
  createDay(day, today) {
    const dayContainer = document.createElement("div");
    if (
      day === today &&
      this.month === this.currentMonth &&
      this.year === this.currentYear
    ) {
      dayContainer.classList.add("today");
    }
    if (day === "") {
      dayContainer.classList.add("empty");
    }

    dayContainer.addEventListener("click", () => {
      if (
        this.month < this.userSelectedMonth &&
        this.year <= this.userSelectedYear
      ) {
        this.numClicks = 0;
      }
      if (this.numClicks === 0) {
        this.userSelectedMonth = this.month;
        this.userSelectedYear = this.year;
        this.day = day;
        this.startDate = `${this.userSelectedYear}${
          this.separator
        }${this.format(this.userSelectedMonth + 1)}${
          this.separator
        }${this.format(this.day)}`;
        this.startDateText.innerHTML = this.startDate;
      }
      if (this.numClicks === 1) {
        this.userSelectedMonthEnd = this.month;
        this.userSelectedYearEnd = this.year;
        this.dayEnd = day;
        this.endDate = `${this.userSelectedYearEnd}${
          this.separator
        }${this.format(this.userSelectedMonthEnd + 1)}${
          this.separator
        }${this.format(this.dayEnd)}`;
        this.endDateText.innerHTML = this.endDate;
        this.datePicker.classList.remove("show");
        if (this.callback) {
          this.callback(this.getDate());
        }
      }

      if (
        this.numClicks === 2 &&
        this.daysContainer.querySelector(".selected")
      ) {
        this.daysContainer.querySelectorAll(".selected").forEach((selected) => {
          selected.classList.remove("selected");
        });

        this.daysContainer.querySelectorAll(".in-range").forEach((inRange) => {
          inRange.classList.remove("in-range");
        });
      }
      dayContainer.classList.add("selected");
      this.numClicks = this.numClicks === 2 ? 1 : this.numClicks + 1;
    });
    dayContainer.addEventListener("mouseover", () => {
      if (this.numClicks === 1) {
        this.datePicker.querySelectorAll(".days div").forEach((item, i) => {
          item.classList.remove("in-range");
        });
        this.datePicker.querySelectorAll(".days div").forEach((item, i) => {
          const dayNumber = parseInt(item.querySelector("span").innerHTML);
          if (
            this.month === this.userSelectedMonth &&
            this.year === this.userSelectedYear
          ) {
            if (dayNumber > this.day && dayNumber < day) {
              item.classList.add("in-range");
            }
          } else if (
            this.month >= this.userSelectedMonth &&
            this.year >= this.userSelectedYear
          ) {
            if (dayNumber < day) {
              item.classList.add("in-range");
            }
          }
        });
      }
    });
    const dayEl = document.createElement("span");
    dayContainer.appendChild(dayEl);
    dayEl.innerHTML = day;
    this.daysContainer.appendChild(dayContainer);
  }
  selectDateRange() {
    this.datePicker.querySelectorAll(".days div").forEach((day, i) => {
      const dayNumber = day.querySelector("span").innerHTML;
      if (
        dayNumber == this.day &&
        this.month === this.userSelectedMonth &&
        this.year === this.userSelectedYear
      ) {
        day.classList.add("selected");
      }
      if (
        dayNumber == this.dayEnd &&
        this.month === this.userSelectedMonthEnd &&
        this.year === this.userSelectedYearEnd
      ) {
        day.classList.add("selected");
      }
    });

    if (this.day && this.dayEnd) {
      this.datePicker.querySelectorAll(".days div").forEach((item, i) => {
        const dayNumber = parseInt(item.querySelector("span").innerHTML);
        if (
          this.year === this.userSelectedYear &&
          this.month === this.userSelectedMonth &&
          this.year === this.userSelectedYearEnd &&
          this.month === this.userSelectedMonthEnd
        ) {
          if (dayNumber > this.day && dayNumber < this.dayEnd) {
            item.classList.add("in-range");
          }
        } else if (
          this.year === this.userSelectedYear &&
          this.month === this.userSelectedMonth
        ) {
          if (dayNumber > this.day) {
            item.classList.add("in-range");
          }
        } else if (
          this.year === this.userSelectedYearEnd &&
          this.month === this.userSelectedMonthEnd
        ) {
          if (dayNumber < this.dayEnd) {
            item.classList.add("in-range");
          }
        } else if (
          this.year >= this.userSelectedYear &&
          this.month > this.userSelectedMonth &&
          this.year <= this.userSelectedYearEnd &&
          this.month < this.userSelectedMonthEnd
        ) {
          if (!item.classList.contains("empty")) {
            item.classList.add("in-range");
          }
        }
      });
    }
  }
  format(val) {
    return (val + "").length === 1 ? "0" + val : val;
  }
}
new DateRangepicker({
  selector: document.querySelector(".datepicker-container"),
  months: [
    "Jan",
    "Feb",
    "Mar",
    "Apr",
    "May",
    "Jun",
    "Jul",
    "Aug",
    "Sep",
    "Oct",
    "Nov",
    "Dec"
  ],
  separator: "-",
  callback: function (daterange) {
    console.log(daterange);
  }
  // startDate: '2021-04-01',
  // endDate: '2021-05-23'
});

Copy JS
Upgrade to professional version

Using professional version, you will have unlimited number of projects and unlimited access to materials in Kodhus.com.