Как сделать календарь бронирования на js html css?

Всем привет! Не могу как сделать календарь как на фото, чтобы были зеленые поля(свободные даты) и красные поля(забронированные даты). Бронироваться(краситься в красный) будет при нажатии на дату.

введите сюда описание изображения


Ответы (2 шт):

Автор решения: ΝNL993

Вы разметки не дали так что пришлось импровизировать :)

JS

Сначала объявил переменные, сам календарь и дни недель (на английском).

let $calendar = document.querySelector('#calendar')
let days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

Дальше за каждый день недели создал новый столб с первой буквой дня (каждой дал класс name).

days.forEach(e => {
  let day = document.createElement('div')

  day.textContent = e[0]
  day.className = 'name'
  $calendar.appendChild(day)
})

Дальше через цикл создал сами дни недель, там думаю объяснять не стоит, весь код спокойно читается (Если хотите, напишите в комментариях и я вам объясню).

for (let i = 1; i < 36; i++) {
  let day = document.createElement('div')
  let dayNum = i - 5
  let isEmpty = dayNum < 1

  day.className = 'block' + (isEmpty ? ' empty' : '')
  day.textContent = isEmpty ? '' : dayNum
  $calendar.appendChild(day)
}

Дальше используя метод делегации событий повесил событие на сам календарь, и если пользователь нажимал на ячейку у которой из классов только block, то тогда к блоку добавляется класс active (Соответственно к блоку будет добавляться класс active только тогда, когда блок не пустой и не активный).

$calendar.addEventListener('click', e => {
  if(e.target.matches('[class="block"]')) {
    e.target.classList.add('active')
  }
})

CSS

Добавил стандартные стили и ещё более красивый шрифт.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: Arial, 'Segoe UI';
}

Дальше через grid сделал 7 колонн (т.к. 7 дней недели).

#calendar {
  display: grid;
  grid-template-columns: repeat(7, auto);
}

Сделал высоту 50 пикселей (3.125em == 50px) и немного разделил блоки, также сделал так, чтобы текст был в центре блока и его нельзя было бы выделить.

.block {
  height: 3.125em;
  margin: .125em;
  display: grid;
  background-color: rgb(221, 255, 204);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}

Ну и дальше самые простые CSS стили которые даже не нуждаются в объяснении

.name, .block {
  text-align: center;
}

.name {
  font-weight: 700;
}

.empty {
  background-color: rgb(247, 247, 247);
}

.active {
  background-color: rgb(255, 192, 189);
}

Вот тут вся HTML разметка :)

<div id="calendar"></div>
→ Ссылка
Автор решения: Ivan Chuzhmakov

Я бы конечно подошёл с другого конца. Раз вопрос о бронировании, то нужно хранить об этом инфу и считывать постоянно актуальную, т.е. в момент нажатия проверять не занят ли день, соответственно логика такая: кликаем->получаем id элемента и его значение -> отправляем на сервак аяксом и смотрим не занят ли день другим пользователем(логику проверки пользователя нет смысла описывать), далее закрепляем бронь за текущим пользователем и возвращаем ответ в виде перекраски бэеграунда элемента или полной его перерисовке. P.S. Если же вам без логики, просто менять цвет дива, то вам при добавлении элемента, всё ровно необходимо присваивать уникальный id с нарастающим значением, например 'id_'+i, далее вешать обработчик на клик по диву и вылавливать его функцией, которая будет уже заниматься всеми манипуляциями с элементом.

→ Ссылка