$('input').datepicker('option', { /* // 문서에는 있지만 코드에는 없음. 이걸 사용했으면 다른 방식이 가능했을지도 모르겠다. ,create: function(event, ui) { } */ // datepicker 위젯을 나타내기 전에 최초 연월에 대한 값을 가져온다. beforeShow: function(input, instance) { var date=$(input).datepicker('getDate'); var year=date.getFullYear(), month=date.getMonth()+1 // 현재 연월의 일별 정보를 가져오는 Ajax 호출 var args = [{...}]; $.ajax({ type: 'get' ,url: '...' ,data: $.param(args) ,beforeSend: function(request, status) { // 선택 가능한 날짜에 마우스를 가져갔을 때의 동작 해제 (중복 이벤트 방지. INPUT에서 INPUT으로 바로 포커스를 옮기면 onClose를 타지 않음) instance.dpDiv.undelegate('.ui-datepicker-calendar td a', 'mouseenter.customHover'); // 선택 가능한 날짜에 마우스를 가져갔을 때 (선택 불가능할 경우 span 태그가 쓰여서 여기 해당하지 않음) instance.dpDiv.delegate('.ui-datepicker-calendar td a', 'mouseenter.customHover', function() { var year=instance.selectedYear, month=instance.selectedMonth+1, ymd=year+'-'+month.zerofill(2)+'-'+$(this).text().zerofill(2); var slice = $(input).data(year+'-'+month.zerofill(2)); // 가져온 정보가 해당 연월일에 대한 값을 갖고 있으면 적용 if (typeof slice != 'undefined' && typeof slice[ymd] != 'undefined' && !$.isEmptyObject(slice[ymd])) { // datepicker가 thead와 tbody만 사용하고 있으므로 tfoot을 쓰기로 한다. var foot = $('table.ui-datepicker-calendar',instance.dpDiv).children('tfoot'); if (foot.length>0) { foot.empty().append('<td colspan="7"><ul></ul></td>'); } else { var foot = $('<tfoot><td colspan="7"><ul></ul></td></tfoot>').appendTo($('table.ui-datepicker-calendar',instance.dpDiv)); } var cell = foot.find('td>ul'); $.each(slice[ymd], function(index, obj) { cell.append('<li>'+index+'</li>'); }); } }); // 해당 연월의 자료가 있으면 이미 API 호출했던 것이므로 호출하지 않음 var slice = $(input).data(year+'-'+month.zerofill(2)); if (typeof slice != 'undefined') { return false; } } ,success: function(data, status, request) { if (!data || !data.error) return false; if (data.error.code == 1) { alert(data.error.message); return false; } // 가져온 정보 반영해서 달력 새로 그리기 $(input).data(year+'-'+month.zerofill(2), data.timeSlice); $(input).datepicker('refresh'); } ,complete: function(request, status) { } ,dataType: 'json' }); } ,onClose: function(dateText, instance) { // 선택 가능한 날짜에 마우스를 가져갔을 때의 동작 해제 instance.dpDiv.undelegate('.ui-datepicker-calendar td a', 'mouseenter.customHover'); } // 변경된 연월의 정보를 가져온다. ,onChangeMonthYear: function(year, month, instance) { var input=this; var args = [{...}]; $.ajax({ type: 'get' ,url: '...' ,data: $.param(args) ,beforeSend: function(request, status) { // 해당 연월의 자료가 있으면 이미 API 호출했던 것이므로 호출하지 않음 var slice = $(input).data(year+'-'+month); if (typeof slice != 'undefined') return false; } ,success: function(data, status, request) { if (!data || !data.error) return false; if (data.error.code == 1) { alert(data.error.message); return false; } // 가져온 정보 반영해서 달력 새로 그리기 $(input).data(year+'-'+month.zerofill(2), data.timeSlice); $(input).datepicker('refresh'); } ,complete: function(request, status) { } ,dataType: 'json' }); } // 개별 일자를 그리기 전에 선택 가부를 반환 ,beforeShowDay: function(date) { var input=this; var year=date.getFullYear(), month=date.getMonth()+1, ymd=year+'-'+month.zerofill(2)+'-'+date.getDate().zerofill(2); var slice = $(input).data(year+'-'+month.zerofill(2)); // 가져온 값에 해당 일자가 있으면 선택 가능 if (typeof slice!='undefined' && typeof slice[ymd]!='undefined' && !$.isEmptyObject(slice[ymd])) { return [true, '']; } return [false, '']; } ,onSelect: function(dateText, instance) { } });위의 코드는 jQuery UI Datepicker를 직접 수정하지 않고 선택 가능한 일자에 대한 정보를 Ajax로 호출해 달력에 반영하는 방법이다. 핵심은 가져온 값을 갖고 있다가 beforeShowDay 콜백에서 그 정보에 따라 선택 가능 여부를 반환하는 것이다.beforeShow에서 정의하는 각 일자(td a)에 대한 mouseenter 이벤트 정의는 부가적인 사항으로, 해당 일자에 대해 추가정보를 달력 하단에 출력한다. 화면상의 위치에 따라 달력이 위로 올라붙을 때는 하단에 추가되는 내용 때문에 문제가 있을 수 있는데 이에 대해서는 따로 고려하지 않았다. |