2016-03-03 15 views
22

Sto usando jQuery UI datepicker e voglio visualizzare testo aggiuntivo all'interno di celle di data accanto alla data. Questo è il comportamento desiderato:Mostra testo aggiuntivo accanto a date in jQuery UI datepicker

jQuery UI datepicker with custom text inside cells

Purtroppo, la manipolazione di cellule data usando .text() e .html() funzioni rompe la funzionalità datepicker. Guarda la demo seguente e prova a usare il datepicker. Si noti che quando si seleziona una data (i) il testo personalizzato è andato (ii) che cambiano mesi distrugge il calendario e le terre che il mese "indefinito nan":

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

C'è una soluzione?

+0

Se non ti dispiace per innescare funzionare _addCustomInformation_ molto si può fare qualcosa di simile [questo] (https://jsfiddle.net/aLdx4L0y/2/) – Lends

risposta

16

Beh, si può scimmia-patch jQuery UI e il rischio di rompere il codice con le versioni più recenti oppure è possibile utilizzare documentato callback per aggiungere personalizzati data-* attributi per datepicker e visualizzarli utilizzando 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">

Ecco un aggiornamento JSFiddle


Nota a margine: io non sono sicuro che la funzionalità è rotto nel vostro demo, ma dal momento che questa soluzione sta usando callback documentati e CSS, credo che sia meno probabile che rompere nulla in futuro di scimmia patching

+0

Bel approccio! (La mia versione patch ha praticamente zero possibilità di rompere il widget del calendario stesso, ma naturalmente potrebbe smettere di funzionare se cambiano qualcosa internamente.Non diversamente da questo, in realtà - assume silenziosamente che ci sarà sempre un 'a' all'interno di un' td ', e scommetto che questo non è documentato da nessuna parte.;)) – Tomalak

+0

@Tomalak * praticamente * - sì, è vero, l'interfaccia utente di jQuery in realtà non ottiene tanto aggiornamento (* specialmente se si rompono *) sembra, l'interazione completa la riscrittura con il supporto al tocco (2.0) richiede sempre e oggi ho visto un bug di 3 anni e la sua versione era 1.10 ~, dopo 3 anni di versione stabile è appena 1.11 ~! –

+0

È vero, ha raccolto più di un po 'di polvere in alcune aree. – Tomalak

7

aggiungere questo codice nel vostro 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

Se si desidera testo solo per la data selezionata, quindi puoi dichiararlo nella matrice cellContents ... es var cellContents = {1: '20', 15: '60', 28: '$ 99,99'}; dove 1, 15, 28 sono date e 20, 60, 99,99 sono valori –

11

Dal momento che l'datapicker jQuery UI è abbastanza monolitica è difficile da migliorare in modo pulito.

Vorrei andare con patch di scimmia una delle sue funzioni interne, vale a dire _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

Monkey patch la funzione '_generateHTML' ... perché non ci ho pensato? –

+1

Questo funziona davvero?Quando faccio clic su una data e faccio clic sulla freccia destra o sinistra, viene visualizzato "NaN non definito" e le date vanno via. Se non faccio clic sulla casella della data e semplicemente clic sulle frecce, tutto va bene e il mese cambia. – SacWebDeveloper

+0

Sì, lo fa. L'ho provato su tre browser. Non sei sicuro di dove mostrerebbe "NaN indefinito" per te? Si prega di creare un jsFiddle che mostri il problema. – Tomalak

8

C'è una soluzione molto più semplice basata su the accepted answer:

la funzione beforeShowDay ci permette di impostare l'attributo "title" per ogni data. Possiamo visualizzare l'attributo utilizzando gli pseudo elementi 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

Molto bello, questa è una bellissima soluzione. Pollice su. – Tomalak

+0

Pensandoci su, questo approccio dipende da a) Hai sempre desiderato inserire solo testo semplice, mai funzionalità aggiuntive (come un secondo link, per esempio) eb) Nessun altro '.ui-datepicker td' avrà mai un titolo. Il secondo può essere superato usando '.ui-datepicker-calendar td [title]', comunque. Il primo è probabilmente limitante. – Tomalak

Problemi correlati