2016-03-03 20 views
22

Używam datepicker jQuery UI i chcę wyświetlić dodatkowy tekst w komórkach daty obok daty. Jest to pożądane zachowanie:Wyświetl dodatkowy tekst obok dat w jquery UI datepicker

jQuery UI datepicker with custom text inside cells

Niestety, manipulując date komórki za pomocą .text() i .html() funkcje łamie funkcjonalność datepicker. Zobacz poniższą prezentację i spróbuj użyć datepika. Zauważ, że po wybraniu dat (i) tekst zwyczaj znika (ii) zmiana miesiąc niszczy kalendarz i ziemie ci na „undefined NaN” miesiącu:

https://jsfiddle.net/salman/aLdx4L0y/

Czy istnieje rozwiązanie?

+0

Jeśli nie masz nic do wyzwalania _addCustomInformation_ funkcjonować dużo można zrobić coś takiego [to] (https://jsfiddle.net/aLdx4L0y/2/) – Lends

Odpowiedz

16

Cóż, można małpa-łata jQuery UI i ryzyko złamania kodu z nowszymi wersjami lub użyć udokumentowane wywołania zwrotne, aby dodać niestandardowe data-* atrybuty datepicker i wyświetlać je za pomocą CSS pseudo elements:

$(function() { 
 
    $("#datepicker").datepicker({ 
 
    beforeShow: addCustomInformation, 
 
    //---^----------- if closed by default (when you're using <input>) 
 
    beforeShowDay: function(date) { 
 
     return [true, date.getDay() === 5 || date.getDay() === 6 ? "weekend" : "weekday"]; 
 
    }, 
 
    onChangeMonthYear: addCustomInformation, 
 
    onSelect: addCustomInformation 
 
    }); 
 
    addCustomInformation(); // if open by default (when you're using <div>) 
 
}); 
 

 
function addCustomInformation() { 
 
    setTimeout(function() { 
 
    $(".ui-datepicker-calendar td").filter(function() { 
 
     var date = $(this).text(); 
 
     return /\d/.test(date); 
 
    }).find("a").attr('data-custom', 110); // Add custom data here 
 
    }, 0) 
 
}
.ui-datepicker .weekend .ui-state-default { 
 
    background: #FEA; 
 
} 
 
.ui-datepicker-calendar td a[data-custom] { 
 
    position: relative; 
 
    padding-bottom: 10px; 
 
} 
 
.ui-datepicker-calendar td a[data-custom]::after { 
 
    /*STYLE THE CUSTOME DATA HERE*/ 
 
    content: '$' attr(data-custom); 
 
    display: block; 
 
    font-size: small; 
 
}
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script> 
 
<link href="//code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet" /> 
 
<script src="//code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script> 
 
<input id="datepicker">

Oto zaktualizowana JSFiddle


dygresja: Nie jestem pewien, którego funkcjonalność jest bankrutem w demo, ale od tego rozwiązania korzysta udokumentowane wywołania zwrotne i CSS, uważam, że jest mniej prawdopodobne, aby przełamać coś w przyszłości niż małpy łatanie

+0

Ładne podejście! (Moja łatana wersja ma praktycznie zerową szansę na złamanie samego widżetu kalendarza, ale oczywiście może przestać działać, jeśli coś zmieni wewnętrznie.Nie inaczej, tak naprawdę - to po cichu zakłada, że ​​zawsze będzie "a" wewnątrz 'td ', i mógłbym się założyć, że to nie jest udokumentowane nigdzie;)) – Tomalak

+0

@ Tomalak * praktycznie * - tak, to prawda, jQuery UI tak naprawdę nie otrzymuje tak dużo aktualizacji (* zwłaszcza te zrywające *) wydaje się, że pełna interakcja ponowne pisanie z obsługą dotyku (2.0) trwa wiecznie i dziś widziałem 3-letni błąd, a jego wersja to 1.10 ~, po 3 latach stabilna wersja to zaledwie 1,11! –

+0

To prawda, że ​​zebrał więcej niż trochę kurzu w niektórych obszarach. – Tomalak

7

Dodaj ten kod do JS ...

$('#DatePicker').datepicker({ 
changeMonth: true, 
changeYear: true, 
minDate: 0, 
onSelect: function (date, dp) { 
    updateDatePickerCells(); 
}, 
onChangeMonthYear: function(month, year, dp) { 
    updateDatePickerCells(); 
}, 
beforeShow: function(elem, dp) { 
    updateDatePickerCells(); 
}}); 
updateDatePickerCells(); 
function updateDatePickerCells(dp) { 

setTimeout(function() { 

    var cellContents = {1: '20', 15: '60', 28: '$99.99'}; 


    $('.ui-datepicker td > *').each(function (idx, elem) { 
     var value = '$125';//cellContents[idx + 1] || 0; 


     var className = 'datepicker-content-' + CryptoJS.MD5(value).toString(); 

     if(value == 0) 
      addCSSRule('.ui-datepicker td a.' + className + ':after {content: "\\a0";}'); //&nbsp; 
     else 
      addCSSRule('.ui-datepicker td a.' + className + ':after {content: "' + value + '";}'); 

     $(this).addClass(className); 
    }); 
}, 0); 
} 
var dynamicCSSRules = []; 
function addCSSRule(rule) { 
if ($.inArray(rule, dynamicCSSRules) == -1) { 
    $('head').append('<style>' + rule + '</style>'); 
    dynamicCSSRules.push(rule); 
} 
} 

Demo Link ... http://jsfiddle.net/pratikgavas/e3uu9/131/

+0

Jeśli chcesz tekst tylko dla wybranej daty, możesz ją zadeklarować w tablicy cellContents ... np var cellContents = {1: '20', 15: "60", 28: "99,99 $"}; gdzie 1, 15, 28 to daty, a 20, 60, 99,99 to wartości –

11

Ponieważ datapicker jQuery UI jest dość monolityczny trudno jest zwiększyć czysto.

Poszedłbym z łataniem małpy jedną z jego wewnętrznych funkcji, a mianowicie _generateHTML.

$.datepicker._generateHTML = (function() { 
 
    var realGenerateHtml = $.datepicker._generateHTML; 
 
    return function (instance) { 
 
     var html = realGenerateHtml.apply(this, arguments), $temp; 
 
     
 
     if (instance.input.is(".datepicker-price")) { 
 
      $temp = $("<table></table>").append(html); 
 
      $temp.find(".ui-datepicker-calendar td a").each(function() { 
 
       var yy = $(this).parent().data("year"), 
 
        mm = $(this).parent().data("month"), 
 
        dd = +$(this).text(); 
 

 
       $(this).append("<br><small class='price'>$100</small>"); 
 
      }); 
 
      html = $temp[0].innerHTML; 
 
     } 
 
     return html; 
 
    }; 
 
})(); 
 

 
$(function() { 
 
    $("#datepicker").datepicker(); 
 
});
.ui-datepicker .weekend .ui-state-default { 
 
    background: #FEA; 
 
} 
 
.price { 
 
    color: blue; 
 
}
<link href="https://code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script> 
 

 
<div id="datepicker" class="datepicker-price"></div>

+0

Małpa łata funkcję '_generateHTML' ... dlaczego nie pomyślałem o tym? –

+1

Czy to faktycznie działa całkowicie?Kiedy klikam datę i klikam strzałkę w prawo lub w lewo, pokazuje ona "niezdefiniowany NaN", a daty znikają. Jeśli nie kliknę pola daty i po prostu klikną strzałki, wszystko będzie dobrze, a miesiąc się zmieni. – SacWebDeveloper

+0

Tak, robi. Przetestowałem to w trzech przeglądarkach. Nie wiesz, gdzie dla ciebie będzie wyświetlany "undefined NaN"? Zrób jsFiddle, który demonstruje problem. – Tomalak

8

jest znacznie prostsze rozwiązanie oparte na the accepted answer:

funkcja beforeShowDay pozwala nam ustawić atrybut „title” na każdy dzień. Możemy wyświetlić atrybut za pomocą pseudo elementów CSS.

$(function() { 
 
    var dayrates = [100, 150, 150, 150, 150, 250, 250]; 
 

 
    $("#datepicker").datepicker({ 
 
    beforeShowDay: function(date) { 
 
     var selectable = true; 
 
     var classname = ""; 
 
     var title = "\u20AC" + dayrates[date.getDay()]; 
 
     return [selectable, classname, title]; 
 
    } 
 
    }); 
 
});
@import url("https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/blitzer/jquery-ui.min.css"); 
 

 
.ui-datepicker td span, 
 
.ui-datepicker td a { 
 
    padding-bottom: 1em; 
 
} 
 

 
.ui-datepicker td[title]::after { 
 
    content: attr(title); 
 
    display: block; 
 
    position: relative; 
 
    font-size: .8em; 
 
    height: 1.25em; 
 
    margin-top: -1.25em; 
 
    text-align: right; 
 
    padding-right: .25em; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> 
 

 
<div id="datepicker"></div>

+2

Bardzo ładne, jest to piękne rozwiązanie. Kciuki w górę. – Tomalak

+0

Myśląc o tym, to podejście zależy od a) Zawsze chcesz wstawić czysty tekst, nigdy dodatkowe funkcje (np. Drugi link, na przykład) i b) Żaden inny ".ui-datepicker td" nigdy nie będzie miał tytułu. Drugi problem można przezwyciężyć, używając '.ui-datepicker-calendar td [title]'. Pierwsza prawdopodobnie ogranicza. – Tomalak

Powiązane problemy