29.02.2016, 16:06
|
Аспирант
|
|
Регистрация: 16.01.2016
Сообщений: 57
|
|
Календарь на подобие Datepicker
Добрый день.
У меня есть необходимость для сайта реализовать что-то подобное такому календарику: http://www.lomarengas.fi/ru/cottages...ns= &keyword=
Там надо пролистать на несколько месяцев вперед до зеленых дат. Там можно выбрать период бронирования, причем выбранные дни выделяются подсветкой фона с середины текущего дня до середины следующего.
С одной стороны я уже практически написал такой календарь, но сказать, что это решение кривое - не сказать ничего. HTML гегерится на сервере, при переключении месяца грузится новые слои. В этом решении пока не очень понимаю, как мне передать данные о выбранных днях, но это я смогу решить.
Я вот сейчас думаю, что надо бы переписать всю эту халтуру. Переписывать код Datepicker мне кажется с одной стороны неправильно, и я побаиваюсь (понимание JS более чем условное).
Как стоило бы поступить?
Спасибо.
|
|
29.02.2016, 17:53
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
karden,
Datepicker вполне можно настроить под вашу задачу...передавать можно либо массив либо обьект с занятыми датами и при выводе месяца изменять css занятых дат
|
|
01.03.2016, 00:41
|
Аспирант
|
|
Регистрация: 16.01.2016
Сообщений: 57
|
|
Посмотрел исходники Datepicker. Честно сказать - страшновато лезть в этот код. 2000 строк мозгодробительного кода (хотя фактически формирование вывода - 30-40 строк). Обработку событий пока вообще не нашел. Их тоже придется переписывать.
Завтра попробую вникнуть более внимательно, но что-то трогать не понимая полного устройства механизма мне кажется не самым разумным решением.
Относительно хранения/передачи информации по датам.
Я сейчас сделал хранение информации в БД с следующем виде:
id | HouseID | Year | DayOfYear | Status | Reserv-UserID
Мне, честно сказать, не очень нравится часть "Year | DayOfYear". Да и для передачи между клиентом и сервером простым массивом такое не передашь. Может быть есть опыт/мысли как это лучше сложить в БД?
Спасибо
|
|
01.03.2016, 02:09
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Сообщение от karden
|
Честно сказать - страшновато лезть в этот код.
|
а зачем вам это нужно?
Сообщение от karden
|
Обработку событий пока вообще не нашел.
|
http://api.jqueryui.com/datepicker/#option-onSelect
результат из базы для календаря по вашим условиям проще что-то типа так
var data = {
"01.03.2016" : {start : true, end : false},
"02.03.2016" : {start : true, end : true},
"03.03.2016" : {start : false, end : true}
}
и живой пример как бы это могло быть: Как выбрать несколько дат в календаре
|
|
01.03.2016, 10:58
|
Аспирант
|
|
Регистрация: 16.01.2016
Сообщений: 57
|
|
Да, это очень близко к тому, что мне надо. Спасибо.
Относительно фонов выбранных ячеек. Там всего 2 стиля: выбрано или нет. Я хотел сделать больше вариантов: не выбрано, зарезервиновано, занято - отсекая уже занятые даты и оставшиеся даты можно выбрать.
И в моем случае мне надо поменять фон на текущем элементе и следующим за ним. Вот в этой части мне кажется, что не получится без влезания в код библиотеки. Надеюсь, что я тут не прав
Относительно формата данных - однозначно согласен. Что-то я перемудрил...
Последний раз редактировалось karden, 01.03.2016 в 11:06.
|
|
01.03.2016, 11:26
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Сообщение от karden
|
Надеюсь, что я тут не прав
|
да вы не правы ... в примере выше ... показан способ установить класс ... если можно сделать 1 класс , то можно сделать 100590 ... start : true, 1 класс end : true 2 класс , супер-пупер бронируем 3 класс, более 3 классов не заметил
|
|
01.03.2016, 16:16
|
Аспирант
|
|
Регистрация: 16.01.2016
Сообщений: 57
|
|
Обалдеть! Всего пол дня, и у меня фактически получилось отвоевать этот вопрос.
1. На Disabled даты не выводится ALT-текст. Это исправимо?
2. Раз уж так все красиво получается, то есть ли механизм наложить маску на фон? То есть сделать фон черно-белый, а при выводе в зависимости от статусов менять: черный на один цвет, а белый на другой. В противном случае надо будет делать кучу записей в CSS с перебором всех возможных комбинаций.
Честно сказать - утром был уверен в том, что ничего не получится... Готов проставиться пивом (или учесть Ваши предпочтения).
|
|
01.03.2016, 17:09
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
karden,
нужен код иначе не понимаю о чём речь
|
|
01.03.2016, 17:36
|
Аспирант
|
|
Регистрация: 16.01.2016
Сообщений: 57
|
|
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/humanity/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style type="text/css">
body{
font-size: 12px;
}
.active .ui-state-default{
background: rgba(102, 255, 102, 1)
}
.active:hover .ui-state-default{
background: rgba(255, 255, 0, 1)
}
.test .ui-state-default{
background: rgba(255, 215, 0, 1)
}
</style>
<script>
var SelectableDayStatus = { 0: {Selectable: true, Name: 'Доступно для бронирования'},
1: {Selectable: false, Name: 'Зарезервировано'},
2: {Selectable: false, Name: 'Забронировано'},
3: {Selectable: false, Name: 'Оплачно'},
8: {Selectable: false, Name: 'Техническое обслуживание'},
9: {Selectable: false, Name: 'Нет данных'}
};
// Это будет приходить с сервера на текущий месяц, и при переключении месяца надо будет дополнять массив
var DayStatus = { "25.02.2016" : 0,
"26.02.2016" : 0,
"27.02.2016" : 0,
"28.02.2016" : 0,
"29.02.2016" : 0,
"01.03.2016" : 0,
"02.03.2016" : 0,
"03.03.2016" : 0,
// "04.03.2016" : 0,
// "05.03.2016" : 0,
"06.03.2016" : 0,
"07.03.2016" : 0,
"08.03.2016" : 1,
"09.03.2016" : 1,
"10.03.2016" : 1,
"11.03.2016" : 0,
"12.03.2016" : 0,
"13.03.2016" : 2,
"14.03.2016" : 3,
"MaxDate": 365
};
$(function() {
$.datepicker.regional['ru'] = {
closeText: 'Закрыть',
prevText: '<Пред',
nextText: 'След>',
currentText: 'Сегодня',
monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', 'Июл','Авг','Сен','Окт','Ноя','Дек'],
dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
dateFormat: 'dd.mm.yy',
firstDay: 1,
isRTL: false,
showOtherMonths:true,
selectOtherMonths:true,
changeMonth:false,
changeYear: false
};
var SelectedDays = [];
$.datepicker.setDefaults($.datepicker.regional['ru']);
$( '#datepicker' ).datepicker({ altField: "#show",
altFormat: "yy-mm-dd",
minDate: 0,
maxDate: DayStatus['MaxDate'],
beforeShowDay: function(date) {
var cds = date.toLocaleString().slice(0, 10);
var CurrentDayStyleFlag = (typeof DayStatus[cds] === 'undefined')?9:DayStatus[cds];
var CurrentDaySelectable = SelectableDayStatus[CurrentDayStyleFlag].Selectable;
var pds = new Date(date.getTime()-86400000).toLocaleString().slice(0, 10);
var PrevDayStyleFlag = (typeof DayStatus[pds] === 'undefined')?9:DayStatus[pds];
console.log (cds, '->', CurrentDayStyleFlag, ';', pds, '->', PrevDayStyleFlag);
for (var i=0; i<SelectedDays.length; i++)
{ var d = SelectedDays[i];
d = d.split('.');
if (date.getTime() == (new Date(d[2],d[1]-1,d[0])).getTime()) return[CurrentDaySelectable, "active", SelectableDayStatus[CurrentDayStyleFlag].Name]
};
return[CurrentDaySelectable, "test"]
},
onSelect : function(value,b) {
var ok = $.inArray(value, SelectedDays);
if (ok == -1) SelectedDays.push(value)
else {SelectedDays.splice(ok,1)};
// alert(JSON.stringify(SelectedDays));
$('#JSON_DATA').html (JSON.stringify(SelectedDays, null, '\t'));
}
})
}); // Function
</script>
</head>
<body>
<div id="datepicker"></div>
<input id="show">
<pre id="JSON_DATA"></pre>
</body>
</html>
Стили фонов пока не прописывал...
|
|
01.03.2016, 18:35
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
datepicker и бронирование на несколько дней
karden,
осталось только проглотить ... далее сами ... перевести под свой формат, думаю сможите.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/sunny/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<style type="text/css">
body{
font-size: 12px;
}
.active .ui-state-default{
background-color: #32CD32;
background-image: none;
}
.ui-state-default{
position: relative;
}
.end .ui-state-default:before{
position: absolute;
top:0;
left:0;
content: '';
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 8px 8px 0 0;
border-color: #FF0000 transparent transparent transparent;
margin: 0;
padding: 0;
}
.start .ui-state-default:after{
position: absolute;
right: 0;
bottom: 0;
content: '';
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 8px 8px;
border-color: transparent transparent #FF0000 transparent;
margin: 0;
padding: 0;
}
.active:hover .ui-state-default{
background: rgba(255, 255, 0, 1)
}
#period_id{
width: 100px;
}
:focus{
outline:0;
border:0;
}
.busy .ui-state-default{
background-color: #FFC0CB;
background-image: none;
}
</style>
<script>
$(function() {
$.datepicker.regional['ru'] = {
closeText: 'Закрыть',
prevText: '<Пред',
nextText: 'След>',
currentText: 'Сегодня',
monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', 'Июл','Авг','Сен','Окт','Ноя','Дек'],
dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
dateFormat: 'dd.mm.yy',
firstDay: 1,
isRTL: false,
showOtherMonths:true,
selectOtherMonths:true,
changeMonth:true,
changeYear: false,
showAnim:'scale'
};
$.datepicker.setDefaults($.datepicker.regional["ru"]);
var $sel = $("#period_id"), $picker = $("#datepicker"), $end = $(".title"),
obj = {start : false, end : false},
data = {
"01.03.2016" : {start : true, end : false},
"02.03.2016" : {start : true, end : true},
"03.03.2016" : {start : false, end : true}
}
;
function selected() {
var selectedDate = $picker.val();
var period_date = +$sel.val() || 1,
instance = $picker.data("datepicker"),
date = $.datepicker.parseDate("dd.mm.yy", selectedDate, instance.settings);
obj.start = date.getTime();
date.setDate(date.getDate() + period_date);//тут нужна проверка нет ли в диапазоне занятых дней
obj.end = date.getTime();
date = $.datepicker.formatDate("dd.mm.yy", date, instance.settings);
$end.text("Дата заезда : " + selectedDate + " Дата выезда: " + date);
$picker.datepicker( "refresh" );
}
function show(date) {
var instance = $picker.data("datepicker"),
dateStr = $.datepicker.formatDate("dd.mm.yy", date, instance.settings),
cls = "", title = "свободно", ev = true;
if(data[dateStr]){
cls = "busy";
data[dateStr].end && (cls += " end", title = "заезд после обеда");
data[dateStr].start && (cls += " start", title = "занято", ev = false);
}
if (obj.start && date.getTime() >= obj.start && date.getTime() <= obj.end) {
title = "Забронировано вами";
if(date.getTime() == obj.start) {cls += " active start"; title = "день заезда";}
else if(date.getTime() == obj.end) {cls += " active end"; title = "день выезда";}
else cls += " active start end";
return[ev, cls, title]
} ;
return[ev, cls, title]}
$picker.datepicker({
dateFormat: "dd.mm.yy",
minDate: 0,
onSelect: selected,
beforeShowDay: show,
showWeek: true,
weekHeader: "Нед."
}).tooltip();
//$sel.on("change", selected); нужна проверка диапазона
var plural = function (b) {
return function (a) {
return b[1 == a % 10 && 11 != a % 100 ? 0 : 2 <= a % 10 && 4 >= a % 10 && (10 > a % 100 || 20 <= a % 100) ? 1 : 2]
}
};
var d = plural([' день',' дня',' дней'])
for (var i=1; i< 25; i++) {
$("<option>", {text : i + d(i), value : i}).appendTo($sel)
};
$sel.selectmenu({change: function( event, ui ) {
$(this).change()
}});
});
</script>
</head>
<body>
<h2 class="title">Выберите количество дней и дату заезда</h2>
<br>
<label>Количество дней проживания
<select id="period_id"></select>
</label><br>
<div id="datepicker"></div>
</body>
</html>
|
|
|
|