Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   помогите доработать календарь (https://javascript.ru/forum/misc/78011-pomogite-dorabotat-kalendar.html)

Блондинка 21.07.2019 20:10

рони,
насколько я поняла строка 212
var table = createCalendar('wrapper', 2019, 6);
устанавливает июнь 2019 г при загрузке страницы, как исправить на текущий месяц/год?

рони 21.07.2019 20:55

Цитата:

Сообщение от Блондинка
как исправить на текущий месяц/год?

создать дату, получить год, получить месяц + 1.
смотри строки 129 - 132 пост #53

рони 21.07.2019 21:19

Цитата:

Сообщение от Блондинка
как исправить на текущий месяц/год?

вариант для текущей даты
<!DOCTYPE html>

<html>
  <head>
    <title>Untitled</title>
    <meta charset="utf-8" />
    <style type="text/css">


      #wrapper button:after {
        content: 'prev';
      }
      #wrapper button:nth-of-type(2):after {
        content: 'next';

      }
      #wrapper button:nth-of-type(3):after {
        content: 'сегодня';
      }
      #wrapper button:nth-of-type(3){
          order: 2;
      }
      #wrapper button:nth-of-type(2){
          order: 3;
      }
      #wrapper button:nth-of-type(1){
          order: 1;
      }

      #wrapper input {
        width: 50px;
        height: 18px;
        margin-top: -3px;
        text-align: center;
      }

      #wrapper {
        width: 320px;
        padding: 5px;
        margin: 5px;
        border: 1px solid #a9a9a9;
        border-radius: 6px/4px;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }

      #wrapper table {
        flex: 1 0 100%;
        border-collapse: separate;
         width: 100%;
        padding: 1px;
      }
      table,
      th,
      td {
        border: 1px solid #a9a9a9;
        border-radius: 6px/4px;
        margin: 1px;
      }
      th,
      td {
        text-align: center;
      }

      .currentMonthWeek {
        background-color: #def1ff;
        color: #0091ff;
      }
      .currentMonthWeek:nth-child(n + 6) {
        background-color: #ffc3d7;
        color: #dc143c;
      }
      td.currentDay {
        background-color: #c2d6ff;
        border: 1px solid #00f;
        font-weight: bold;
        color: #fff;
        text-shadow: 1px 1px #00f, -1px 1px #00f, 1px -1px #00f, -1px -1px #00f,
          1px 0 #00f, 0 1px #00f, -1px 0 #00f, 0 -1px #00f;
      }
      td.currentDay:nth-child(n + 6) {
        background-color: #ffc3d7;
        border: 1px solid #ff69b4;
        text-shadow: 1px 1px #ff0000, -1px 1px #ff0000, 1px -1px #ff0000, -1px -1px #ff0000, 1px 0px #ff0000, 0px 1px #ff0000, -1px 0px #ff0000, 0px -1px #ff0000;

      }

      #wrapper th {
        background-color: #c2d6ff;
        color: #0069ff;
      }
      #wrapper th:nth-child(n + 6) {
        background-color: #ffb4d2;
        color: #b92346;
      }
      #wrapper th.currentDay {
        border: 1px solid #285fcd;
        background-color: #6b9cff;
        color: #e6f5ff;
      }
      #wrapper th:nth-child(n + 6).currentDay {
        background-color: #ff389c;
        color: #ffed85;
      }

     #wrapper button {
        flex 0;
        border: 1px solid #a9a9a9;
        border-radius: 6px/4px;
      }
    </style>
   <script src="https://polyfill.io/v3/polyfill.min.js"></script>
  </head>

  <body>
    <div id="wrapper"></div>
    <script>
      "use strict";

var timer;

function createCalendar(id, year, month) {
  var table = document.createElement('table');
  var header = document.createElement('tr');
  var daysOfWeek = ['пнд', 'втр', 'срд', 'чтв', 'птн', 'сбт', 'вск'];
  var monthNames = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
  var currentData = new Date();
  var currentDay = currentData.getDate();
  var currentMonth = currentData.getMonth();
  var currentFullYear = currentData.getFullYear();
  if(month == void 0) month = currentMonth + 1;
  if(year == void 0) year = currentFullYear;
  var data = new Date(year, month, 0);
  var daysInMonth = data.getDate();
  var indexMonth = data.getMonth();
  var yearFull = data.getFullYear();
  var selectHtml = monthNames.reduce(function (html, nameMonth, i) {
    return html += "<option value=".concat(i, " ").concat(indexMonth == i ? 'selected' : '', ">").concat(nameMonth);
  }, "<select>");
  selectHtml += "<input value=".concat(yearFull, ">");
  table.insertAdjacentHTML('beforeend', "<tr><th colspan='7'>".concat(selectHtml, "</th></tr>"));

  for (var _i = 0, _daysOfWeek = daysOfWeek; _i < _daysOfWeek.length; _i++) {
    var _day = _daysOfWeek[_i];
    header.insertAdjacentHTML('beforeend', "<th>".concat(_day, "</th>"));
  }

  table.append(header);
  var firstDay = (new Date(yearFull, indexMonth).getDay() + 6) % 7;
  var nextDayToAdd = 1 - firstDay;

  while (nextDayToAdd <= daysInMonth) {
    var week = document.createElement('tr');

    for (var i = 0; i < 7; i++) {
      var day = document.createElement('td');
      var cls = 'currentMonthWeek';

      if (nextDayToAdd > 0 && nextDayToAdd <= daysInMonth) {
        if (currentMonth == indexMonth && currentFullYear == yearFull && nextDayToAdd == currentDay) {
          cls = 'currentDay';
          table.querySelectorAll('th')[i + 1].className = 'currentDay';
        }

        day.innerHTML = nextDayToAdd;
      }

      cls && day.classList.add(cls);
      nextDayToAdd++;
      week.append(day);
    }

    table.append(week);
  }

  var div = document.getElementById(id);
  div.innerHTML = '';
  div.append(table);
  [-1, 1].forEach(function (n) {
    var button = document.createElement('button');
    button.addEventListener('click', function () {
      return createCalendar(id, year, month + n);
    });
    div.append(button);
  });
  table.querySelector('select').addEventListener('change', function () {
    createCalendar(id, yearFull, ++this.value);
  });
  table.querySelector('input').addEventListener('input', function () {
    if (/^\d{4}$/.test(this.value)) createCalendar(id, +this.value, indexMonth + 1);
  });

  if (currentMonth != indexMonth || currentFullYear != yearFull) {
    var button = document.createElement('button');
    button.addEventListener('click', function () {
      return createCalendar(id, currentFullYear, currentMonth + 1);
    });
    div.append(button);
  }

  function refresh() {
    window.clearTimeout(timer);
    var finish = new Date().setHours(24, 0, 0, 0);
    finish -= currentData;
    timer = window.setTimeout(function () {
      createCalendar(id, yearFull, indexMonth + 1);
      refresh();
    }, finish);
  }

  refresh();
  return table;
}

var table = createCalendar('wrapper'); //без параметров текущий месяц и год, createCalendar('wrapper', 2019, 6); июнь 2019
    </script>
  </body>
</html>

Блондинка 22.07.2019 10:46

рони,
можно исправить ошибку в работе кнопки назад? перед январём 19г идёт декабрь 18г, но почему показывает текущий месяц, кнопка вперёд работает вроде правильно...

рони 22.07.2019 12:32

Блондинка,
исправил prev, проверьте пост# 59 снова.

Блондинка 23.07.2019 12:16

Кто может сделать календарь из 59 поста самым удобным?

добавить кнопки вперёд/назад для года

скомпоновать все элементы навигации в одном месте, приблизительно как тут

заполнить пустые ячейки числами пред/след месяца приблизительно как в 16 посте.

Блондинка 23.07.2019 20:36

Цитата:

Сообщение от Русский
Да все могут, тут же биржа бесплатного сриланса.

с этого надо было начинать...

Блондинка 23.07.2019 20:41

Кто может сделать календарь из 59 поста самым удобным? и сколько будет стоить

добавить кнопки вперёд/назад для года

скомпоновать все элементы навигации в одном месте, приблизительно как тут

заполнить пустые ячейки числами пред/след месяца приблизительно как в 16 посте.

рони 23.07.2019 23:03

Rise,
спасибо, буду знать.

Блондинка 24.07.2019 14:13

Попробую подробнее пояснить, почему хотелось бы добавить вышеперечисленное

чтобы посмотреть календарь за какой нибудь давно прошедший год, например период великой отечественной неудобно листать года на 75 лет назад, удобнее ввести с клавиатуры, а чтобы посмотреть этот месяц за следующий год, удобнее кликнуть на кнопку, поэтому считаю что дублирование перемещения по годам с помощью кнопок, а не только поля будет намного удобнее пользоваться календарём.

к примеру у вас на кухне стоит мойка и подведена холодная и горячая вода, не очень удобно когда холодная включается на мойке а горячая в другом углу кухни, так и с календарём, непонятно зачем размещать кнопки вперёд назад сегодня ниже таблицы, гораздо удобнее если они будут рядом с выпадающим списком и полем ввода, вариант расположения предложеный мной выглядит достаточно стильно и интуитивно понятно какая кнопка относится к месяцу а какая к году

гораздо удобнее когда видно сколько дней в пред месяце, а в случае необходимости скрыть, достаточно минимальных познаний в css.

Блондинка 27.07.2019 23:13

Видимо никто на сможет помочь, и доработать календарь...

laimas 28.07.2019 00:01

Цитата:

Сообщение от Блондинка
доработать календарь...

Слишком много букв в нем. :) А если без шутки, то для того чтобы календарь "не дергался" на странице его размер должен быть фиксирован. Все месяцы можно вывести в размер 7х6, что с шапкой дней недели будет составлять 7х7.

А для того чтобы вывести дни календаря с учетом предыдущего месяца, нужно получить метку времени первого дня этого месяца, затем день недели этого месяца. После этого можно получить метку времени, дату с которой будет начинаться календарь, которая получится коррекций его первого дня минус его дня недели. Останется в цикле добавлять к этой дает итератор цикла от 0 до 41 и получится календарь и с пред, и следующим месяцем.

Блондинка 28.07.2019 00:21

laimas,
чтобы не дёргался? думаю что тут ничего не надо трогать в скрипте, достаточно дополнить стили

ну а вывести даты других месяцев, добавить кнопки плюс минус для года, сорри но моих познаний недостаточно, поэтому и прошу помочь доделать, чтобы стал более удобным...

laimas 28.07.2019 00:30

Цитата:

Сообщение от Блондинка
думаю что тут ничего не надо трогать в скрипте, достаточно дополнить стили

Причем тут стили, в месяцах разное количество дней и начинаться месяц может как с понедельника, так и с воскресенья, то есть разное смещение вниз будет. А значит высота календаря будет не постоянна. Именно поэтому и фиксируют его размер, добавляя в вывод дни предыдущего и последующего месяцев.

Блондинка 28.07.2019 00:37

если установить у таблицы высоту равную той что будет при 6 неделях, будет просто разная высота строк-ячеек при разном количестве недель, и я в чём то не права?

laimas 28.07.2019 00:41

А вы как думаете? Откройте системный календарь и посмотрите на него - его размер по высоте определяется количеством дней месяца. А высота ячеек его как раз постоянна.

Блондинка 28.07.2019 01:58

laimas,
я бы предпочла, чтобы высота блока с элементами управления была постоянной, независимо от наличия скрытой кнопки "сегодня" во второй строчке, и выпавнивалось по вертикали, и таблица 5х7, 6х7, 7х7 была одной высоты, а высота строк-ячеек растягивалась в случае необходимости...

Блондинка 28.07.2019 02:00

...хотя о чём разговор, если даже на платной основе никто не берется сделать то, о чём я просила выше...

laimas 28.07.2019 02:05

Цитата:

Сообщение от Блондинка
я бы предпочла, чтобы высота блока с элементами управления была постоянной

А я о чем? В календаре вашем, о котором вы говорите, количество строк "заточено" по текущий месяц, и получится, в зависимости от количества дней и дня недели начала месяца, это количество будет разным.

Собственно, грубо говоря, весь календарь, это:

<html>
<head>
<meta charset="utf-8">
<style>
table {
    border-collapse: separate;
}
td {
    padding: 2px 4px;
    border: 1px solid #c6c6c6;
    text-align: right;
    color: #000;
    font: 12px Arial;
}
tr:first-child td {
    background-color: #d0d0d0;
    border-color: #999;
}
tr td:last-child {
    color: #f70707;
}
tr:first-child td:last-child {
    border-color: #f06565;
    background-color: #fdafaf;
    color: #000;
}
td.gray {
    border-color: #cecece;
    background-color: #e6e6e6;
    color: #999!important
}
td.today {
    background-color: #f6fdb5;
}
</style>
</head>
<body>
<table>
<tr><td>Пн</td><td>Вт</td><td>Ср</td><td>Чт</td><td>Пт</td><td>Сб</td><td>Вс</td></tr>
</table>
<script>
var d = new Date(),
    currentYear = d.getFullYear(),
    currentMonth = d.getMonth(),
    today = d.getDate(),
    d = new Date(currentYear, currentMonth, 1),
    day = (d.getDay()||7)-1,
    d = new Date(currentYear, currentMonth, 1 - day),
    startDate = d.getDate(),
    tbl = document.querySelector('table'),
    row, cell, date,
    n = 42; //даты календаря как 7х6
    
   
for(var i=0; i<n; ++i) {
    if(!(i % 7)) row = tbl.insertRow(-1);
    cell = row.insertCell(-1);
    d = new Date(currentYear, currentMonth, startDate + i);
    date = d.getDate();
    cell.textContent = date; 
    if(date==today && currentMonth==d.getMonth() && currentYear==d.getFullYear()) cell.classList.add("today");
    if(d.getMonth() != currentMonth) cell.classList.add("gray");
}
</script>
</body>
</html>


Вы можете стилями разукрасить календарь как угодно, какие угодно размеры ячеек его определять, но независимо от месяца дни его будут вписаны в один и тот же размер.

Блондинка 28.07.2019 03:03

laimas,
если в феврале 2010 года 4 строки-недели, в текущем 5,в сентябре 6,что будет если задать фиксированную высоту таблицы?

laimas 28.07.2019 03:08

Цитата:

Сообщение от Блондинка
что будет если задать фиксированную высоту таблицы?

Календарь будет менять вид. Не высотой таблицы нужно манипулировать, ибо ячейки календаря независимо от месяца должны иметь один и тот же размер, а фиксировать число ячеек календаря. А вписать все месяцы так, чтобы соблюсти эти условия можно только в минимум 7х6 (без учета шапки).

Вы вольны поступать как вам хочется, но календарь который "скачет" по высоте, не самое лучше зрелище. ;)

Блондинка 28.07.2019 03:35

Цитата:

Сообщение от laimas
Календарь будет менять вид.

как будет менять вид? высота таблицы останется неизменной, а высоту строк браузер будет вычислять явтоматически?

laimas 28.07.2019 05:16

То есть, вычисление новых размеров, а значит неизбежное их изменение, это никак не изменение вида?

Мне в общем то все равно, считаете это нормальным, ради бога, я же вам не запрещаю. :) Но интерфейс календаря должен быть таким, что даже стрелка на кнопках назад/вперед под курсором не должна менять позицию при сменах в календаре, иначе грош цена такому интерфейсу.

Malleys 28.07.2019 08:34

Блондинка, чтобы выбрать дату, вы можете...
  • использовать...
    <input type="date">
    
  • поискать js datepicker, решении очень много!
  • попытаться начать делать самим!
    • например, вы можете к варианту из сообщения №80, написанного laimas, добавить программно заголовок типа ◀ Июль, 2019 ▶ И добавить обработчики событии: чтобы при нажатии на стрелки происходило переключение на предыдущий/следующий месяц, при нажатии на название месяца можно было выбрать в раскрывающемся списке любой месяц года, и при нажатии на год можно было ввести любой год! Подумайте, что вам нужно сделать, чтобы достичь такого!

Блондинка 28.07.2019 12:54

laimas,
могу привести несколько пословиц

у каждого свой вкус сказал индус, натягивая на' хрен обезьяну

у каждого художника свои любимые фломастеры

о вкусах не спорят

одним словом такой вариант где высота строк меняется динамически мне больше нравится...

Блондинка 28.07.2019 17:04

...

Malleys 28.07.2019 17:21

Цитата:

Сообщение от Блондинка
могу привести несколько пословиц

А работающий пример вашей идеи можете сделать?

Цитата:

Сообщение от Блондинка
...

Блондинка, получилось добавить программно заголовок типа ◀ Июль, 2019 ▶ ?

Блондинка 28.07.2019 17:31

Русский,
это бесполезно, из-за собственного комплекса неполноценности (из-за незнания Eenglish), пытаться выяснить насколько хорошо я знаю русский язык, а именно область ненормативной лексики... не волнуйся, со временем к окончанию школы твои знания английского улучшатся и комплексы сами пропадут...

Блондинка 30.07.2019 16:24

Цитата:

Сообщение от Malleys
Блондинка, получилось добавить программно заголовок типа ◀ Июль, 2019 ▶ ?

сорри но моих познаний явно недостаточно, я хотела приблизительно такой календарь, который управляется с помощью списка поля ввода и кнопок
<!DOCTYPE HTML>
<html lang="ru">
<head>
  <meta charset="utf-8">
<title></title>
  <style type="text/css">
body { width: 960px; }
body, select, input { font: 14px serif; }
#calendar { width: 330px; display: inline-block; border: 1px solid #a9a9a9; border-radius: 6px/4px; padding: 5px; }
#navigation_panel { background-color: #c5e3ff; height: 53px; border: 1px solid #a9a9a9; border-radius: 6px/4px; padding: 5px; margin-bottom: 3px; text-align: center; vertical-align: middle; }
#navigation_panel button, #navigation_panel #calendar_year { background-color: #94cdff; color: #00f; font: 14px serif; border: 1px solid #00f; }
#calendar_month { background-color: transparent; color: #00f; font: 14px serif; border: 1px solid #00f; }
#navigation_panel button { height: 24px; vertical-align: middle; }
#background_month { background-color: #94cdff; display: inline-block; }
button_minus, button_plus { width: 28px; }
button.minus { border-radius: 6px 0 0 6px / 4px 0 0 4px; margin-right: -5px; }
button.plus { border-radius: 0 6px 6px 0 / 0 4px 4px 0; margin-left: -5px; }
#month_plus { margin-right: 35px; }
#presently { width: 252px; margin-top: 5px; border-radius: 6px/4px; }
#calendar_month { width: 89px; display: inline-block; }
#calendar_year { width: 54px; display: inline-block; }
select { height: 24px; }
input { height: 20px; border: 1px solid #a9a9a9; display: inline-block; text-align: center; }
#table { width: 100%; height: 222px; padding: 2px; }
#table, td { border: 1px solid #a9a9a9; border-radius: 6px/4px; }
td { margin: 1px; text-align: center; }
td.week-day { height: 33px; }
</style>
</head>
<body>
<div id="calendar">
<div id="navigation_panel">
<button class="minus">‹</button>
<span id="background_month"><select id="calendar_month"><option>Август</option></select></span>
<button class="plus" id="month_plus">›</button>
<button class="minus">‹</button>
<input type="text" size="4" id="calendar_year">
<button class="plus">›</button><br>
<button id="presently">сегодня</button>
</div>
<table id="table">
<tr><td class="week-day">Пн.</td><td class="week-day">Вт.</td><td class="week-day">Ср.</td><td class="week-day">Чт.</td><td class="week-day">Пт.</td><td class="week-day">Сб.</td><td class="week-day">Вс.</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
</table>
</div>
</body>
</html>

могу только предположить что начинать нужно с того что сначала надо вставить блок с элементами управления а потом уже таблицу.

Блондинка 30.07.2019 16:35

laimas,
а такой вопрос, может элементы навигации лучше разместить в одну строчку и выравнивать По центру в обоих случаях, когда кнопка сегодня видна или скрыта...

laimas 30.07.2019 16:39

Блондинка,
не знаю, у нас разное видение интерфейса. ;) А я не понимаю, почему кнопка "сегодня" должна быть скрыта? Она может быть недоступной у дня сегодняшнего, иначе это изменение размеров, хотя убрать можно и не изменяя размер.

Блондинка 30.07.2019 17:19

laimas,
думаю что лучше если будет изменятся расстояние от элементов УПРАВЛЕНИЯ до верхнего и нижнего края блока а по горизонтали отступы должны быть постоянными, если кнопка сегодня скрыта при отображение сетки текущего месяца и показывается при других месяцах, это дополнительно показывает что при наличии кнопки отображается не текущий месяц...

laimas 30.07.2019 19:20

Цитата:

Сообщение от Блондинка
думаю что лучше если будет изменятся расстояние

Думаете, пробуйте, проверяйте оправдает ли это ваше ожидание. Я же ранее высказался, что это не интерфейс. Если бы календарь был на месяц, а значит изменял свой вид раз в месяц, еще ладно, но если изменяется сам календарь, элементы его управления меняют размеры/положение, то это уже плохо.

Блондинка 30.07.2019 19:36

laimas,
в принципе календарь и будет менять свой вид раз в месяц, поскольку он будет встраиваться в страницу, а не использоваться как отдельная страница сайта...

laimas 30.07.2019 19:49

Цитата:

Сообщение от Блондинка
календарь и будет менять свой вид раз в месяц

Это как, если у него есть кнопки управления для перелистывания его?
Не спрашивайте у меня как сделать, как хотите так и делайте, я не имею цели переубедить вас.

Блондинка 30.07.2019 23:22

ну если основной контент страницы несёт свою смысловую информацию, и где-то в левой или правой боковой колонке страницы несущей дополнительную информацию расположен календарь с элементами управления и возможностью просмотра других месяцев, то это не значит что посетители будут игнорить основной контент и ежесекундно щёлкать календарь...

laimas 31.07.2019 01:39

Если следовать вашей логике, то вы опираетесь на предположение, что пользователи будут игнорировать ваш календарь. Тогда встает вопрос зачем он вообще нужен, зачем ему элементы управления, зачем вообще вы тратите на него столько времени?

Блондинка 31.07.2019 12:53

laimas,
если календарём в основном не будут пользоваться, то это не значит что не может возникнуть ситуация у кого нибудь из пользователей что нужно посмотреть сетку за другой месяц, и хотелось бы чтобы в этих случаях календарь был максимально удобным в навигации...

laimas 31.07.2019 13:38

Цитата:

Сообщение от Блондинка
может возникнуть ситуация у кого нибудь из пользователей что нужно посмотреть сетку за другой месяц, и хотелось бы чтобы в этих случаях календарь был максимально удобным в навигации...

К чему тогда разговоры об ином, вот и делайте удобный интерфейс.

Блондинка 31.07.2019 23:26

рони,
не могу разобраться с твоим примером
<!DOCTYPE html>

<html>
  <head>
    <title>тест-каледарь (рони)</title>
    <meta charset="utf-8" />
    <style type="text/css">


      #wrapper button:after {
        content: 'пред.';
      }
      #wrapper button:nth-of-type(2):after {
        content: 'след.';

      }
      #wrapper button:nth-of-type(3):after {
        content: 'сегодня';
      }
      #wrapper button:nth-of-type(3){
          order: 2;
      }
      #wrapper button:nth-of-type(2){
          order: 3;
      }
      #wrapper button:nth-of-type(1){
          order: 1;
      }

      #wrapper input {
        width: 50px;
        height: 18px;
        margin-top: -3px;
        text-align: center;
      }

      #wrapper {
        width: 320px;
        padding: 5px;
        margin: 5px;
        border: 1px solid #a9a9a9;
        border-radius: 6px/4px;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }

      #wrapper table {
        flex: 1 0 100%;
        border-collapse: separate;
         width: 100%;
        padding: 1px;
      }
      table,
      th,
      td {
        border: 1px solid #a9a9a9;
        border-radius: 6px/4px;
        margin: 1px;
      }
      th,
      td {
        text-align: center;
      }

      .currentMonthWeek {
        background-color: #def1ff;
        color: #0091ff;
      }
      .currentMonthWeek:nth-child(n + 6) {
        background-color: #ffc3d7;
        color: #dc143c;
      }
      td.currentDay {
        background-color: #c2d6ff;
        border: 1px solid #00f;
        font-weight: bold;
        color: #fff;
        text-shadow: 1px 1px #00f, -1px 1px #00f, 1px -1px #00f, -1px -1px #00f,
          1px 0 #00f, 0 1px #00f, -1px 0 #00f, 0 -1px #00f;
      }
      td.currentDay:nth-child(n + 6) {
        background-color: #ffc3d7;
        border: 1px solid #ff69b4;
        text-shadow: 1px 1px #ff0000, -1px 1px #ff0000, 1px -1px #ff0000, -1px -1px #ff0000, 1px 0px #ff0000, 0px 1px #ff0000, -1px 0px #ff0000, 0px -1px #ff0000;

      }

      #wrapper th {
        background-color: #c2d6ff;
        color: #0069ff;
      }
      #wrapper th:nth-child(n + 6) {
        background-color: #ffb4d2;
        color: #b92346;
      }
      #wrapper th.currentDay {
        border: 1px solid #285fcd;
        background-color: #6b9cff;
        color: #e6f5ff;
      }
      #wrapper th:nth-child(n + 6).currentDay {
        background-color: #ff389c;
        color: #ffed85;
      }

     #wrapper button {
        flex 0;
        border: 1px solid #a9a9a9;
        border-radius: 6px/4px;
      }
    </style>
   <script src="https://polyfill.io/v3/polyfill.min.js"></script>
  </head>

  <body>
    <div id="wrapper"></div>
    <script>
      "use strict";

var timer;

function createCalendar(id, year, month) {
  var table = document.createElement('table');
  var header = document.createElement('tr');
  var daysOfWeek = ['Пн.', 'Вт.', 'Ср.', 'Чт.', 'Пт.', 'Сб.', 'Вс.'];
  var monthNames = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
  var currentData = new Date();
  var currentDay = currentData.getDate();
  var currentMonth = currentData.getMonth();
  var currentFullYear = currentData.getFullYear();
  if(month == void 0) month = currentMonth + 1;
  if(year == void 0) year = currentFullYear;
  var data = new Date(year, month, 0);
  var daysInMonth = data.getDate();
  var indexMonth = data.getMonth();
  var yearFull = data.getFullYear();
  var selectHtml = monthNames.reduce(function (html, nameMonth, i) {
    return html += "<option value=".concat(i, " ").concat(indexMonth == i ? 'selected' : '', ">").concat(nameMonth);
  }, "<select>");
  selectHtml += "<input value=".concat(yearFull, ">");
  table.insertAdjacentHTML('beforeend', "<tr><th colspan='7'>".concat(selectHtml, "</th></tr>"));

  for (var _i = 0, _daysOfWeek = daysOfWeek; _i < _daysOfWeek.length; _i++) {
    var _day = _daysOfWeek[_i];
    header.insertAdjacentHTML('beforeend', "<th>".concat(_day, "</th>"));
  }

  table.append(header);
  var firstDay = (new Date(yearFull, indexMonth).getDay() + 6) % 7;
  var nextDayToAdd = 1 - firstDay;

  while (nextDayToAdd <= daysInMonth) {
    var week = document.createElement('tr');

    for (var i = 0; i < 7; i++) {
      var day = document.createElement('td');
      var cls = 'currentMonthWeek';

      if (nextDayToAdd > 0 && nextDayToAdd <= daysInMonth) {
        if (currentMonth == indexMonth && currentFullYear == yearFull && nextDayToAdd == currentDay) {
          cls = 'currentDay';
          table.querySelectorAll('th')[i + 1].className = 'currentDay';
        }

        day.innerHTML = nextDayToAdd;
      }

      cls && day.classList.add(cls);
      nextDayToAdd++;
      week.append(day);
    }

    table.append(week);
  }

  var div = document.getElementById(id);
  div.innerHTML = '';
  div.append(table);
  [-1, 1].forEach(function (n) {
    var button = document.createElement('button');
    button.addEventListener('click', function () {
      return createCalendar(id, year, month + n);
    });
    div.append(button);
  });
  table.querySelector('select').addEventListener('change', function () {
    createCalendar(id, yearFull, ++this.value);
  });
  table.querySelector('input').addEventListener('input', function () {
    if (/^\d{4}$/.test(this.value)) createCalendar(id, +this.value, indexMonth + 1);
  });

  if (currentMonth != indexMonth || currentFullYear != yearFull) {
    var button = document.createElement('button');
    button.addEventListener('click', function () {
      return createCalendar(id, currentFullYear, currentMonth + 1);
    });
    div.append(button);
  }

  function refresh() {
    window.clearTimeout(timer);
    var finish = new Date().setHours(24, 0, 0, 0);
    finish -= currentData;
    timer = window.setTimeout(function () {
      createCalendar(id, yearFull, indexMonth + 1);
      refresh();
    }, finish);
  }

  refresh();
  return table;
}

var table = createCalendar('wrapper'); //без параметров текущий месяц и год, createCalendar('wrapper', 2019, 6); июнь 2019
    </script>
  </body>
</html>
возможно ли переместить кнопки "пред" "след" и разместить их возле выпадающего списка, и возможно ли задать таблице фиксированную высоту?


Часовой пояс GMT +3, время: 12:16.