Afficher du texte supplémentaire à côté des dates dans jQuery UI datepicker

J'utilise jQuery UI datepicker et je veux afficher du texte supplémentaire dans les cellules de date à côté de la date. C'est le comportement souhaité:

jQuery UI datepicker avec du texte personnalisé à l'intérieur des cellules

Malheureusement, la manipulation des cellules de date à l'aide des fonctions .text() et .html() interrompt la fonctionnalité datepicker. Voir la démo suivante et essayer d'utiliser le datepicker. Notez que lorsque vous sélectionnez une date (i) le texte personnalisé a disparu (ii) les mois changeants détruisent le calendrier et vous atterrissent sur " Nan indéfini" mois:

Https://jsfiddle.net/salman/aLdx4L0y/

Y a-t-il une solution?

23
demandé sur Salman A 2016-03-03 10:38:03

4 réponses

Eh bien, vous pouvez monkey-patch jQuery UI et risquer de casser le code avec des versions plus récentes ou vous pouvez utiliser des rappels documentés pour ajouter des attributs data-* personnalisés à datepicker et les afficher en utilisant pseudo éléments CSS :

$(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">

Voici une mise à jour JSFiddle


Note latérale: Je ne suis pas sûr de la fonctionnalité qui est cassée dans votre démo, mais comme cette solution utilise des rappels documentés et CSS, je crois qu'elle est moins susceptible de cassez quoi que ce soit à l'avenir que le patch de singe

18
répondu T J 2016-03-09 07:09:01

Comme le datapicker de l'interface utilisateur jQuery est assez monolithique, il est difficile de l'améliorer proprement.

J'irais avec singe-Patcher une de ses fonctions internes, à savoir _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>
11
répondu Tomalak 2016-03-05 12:10:56

Il existe une solution beaucoup plus simple basée sur la réponse acceptée :

Le beforeShowDay la fonction permet de fixer l'attribut "title" pour chaque date. Nous pouvons afficher l'attribut en utilisant des pseudo-éléments 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.1/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>
9
répondu Salman A 2018-05-30 10:32:37

Ajoutez ce code dans votre 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);
}
}

Lien de démonstration... http://jsfiddle.net/pratikgavas/e3uu9/131/

7
répondu Pratik Gavas 2016-03-05 10:04:42