2013-02-19 9 views
7

Ho bisogno di mostrare testo personalizzato in alcune date su Jquery UI datepicker, per essere più precisi, per il rendering di un prezzo specifico per alcune date. La mia idea era di usare beforeShowDay per allegare un prezzo specifico nei titoli di tali date e poi, in beforeShow per controllare ogni td e inserire il testo del titolo nella cella. Esempio:Quale modo per aggiungere testo a jquery ui datepicker cell?

var m, d, y, checkDate, specificPrice = '';  
var specificPrices = {"2013-3-8":"300 EUR", "2013-2-26":"263 EUR"} 

$('#my-datepicker').datepicker({ 
    beforeShowDay:  function checkAvailable(date) { 
    m = date.getMonth(); 
    d = date.getDate(); 
    y = date.getFullYear(); 
    checkDate = y + '-' + (m+1) + '-' + d; 
    if(specificPrices[checkDate]){ 
     specificPrice = specificPrices[checkDate]; 
    }else{ 
     specificPrice = ''; 
    } 
    return [true, "", specificPrice]; 
}, 
    beforeShow: function(elem, inst){ 
     $('table.ui-datepicker-calendar tbody td', inst.dpDiv).each(function(){ 
      var calendarPrice = $(this).attr('title'); 
      if(calendarPrice != undefined){ 
       $(this).find('a').append('<span class="calendar-price">' + calendarPrice + '<span>'); 
      } 
     });   
    } 
}); 

Questo renderà i prezzi sul primo calendario rendono (prima mese/anno sono cambiate) e solo per il calendario in linea.

Ho bisogno che i prezzi vengano mostrati sul calendario non in linea e su qualsiasi cambio mese/anno.

Ho provato altre varianti e ho provato a utilizzare onChangeMonthYear, ma finora non ha avuto esito positivo.

Grazie per l'attenzione, le vostre idee sono ben accette.

+0

Ho sviluppato una soluzione che funziona per datepickers standard e in linea che potrebbe interessarti, vedere la mia [risposta] (http://stackoverflow.com/a/22822254/2464634) qui sotto . –

+0

Scusa, più di un anno è passato da quando ho fatto questa domanda. In questo momento sono fuori da questo problema. Anche se cercherò di trovare un po 'di tempo libero per rivedere il tuo approccio più tardi per accettare è una soluzione. – yuga

risposta

8

Mi sono imbattuto in questo stesso scenario e ho pensato di pubblicare la mia soluzione per un datepicker in linea, ma dovrebbe funzionare anche per un popup di date popup.

Prima di tutto, non è possibile modificare il contenuto delle celle della tabella create dal plugin datepicker. In questo modo si interromperà la sua funzionalità principale mentre legge il contenuto della cella per generare la stringa di data selezionata. Quindi, i contenuti devono essere aggiunti usando puro css.

Crea il tuo datepicker

$('#DatePicker').datepicker({ 
    changeMonth: true, 
    changeYear: true, 
    minDate: 0, 
    //The calendar is recreated OnSelect for inline calendar 
    onSelect: function (date, dp) { 
     updateDatePickerCells(); 
    }, 
    onChangeMonthYear: function(month, year, dp) { 
     updateDatePickerCells(); 
    }, 
    beforeShow: function(elem, dp) { //This is for non-inline datepicker 
     updateDatePickerCells(); 
    } 
}); 
updateDatePickerCells(); 

Creare il metodo per inserire il contenuto della cella

function updateDatePickerCells(dp) { 
    /* Wait until current callstack is finished so the datepicker 
     is fully rendered before attempting to modify contents */ 
    setTimeout(function() { 
     //Fill this with the data you want to insert (I use and AJAX request). Key is day of month 
     //NOTE* watch out for CSS special characters in the value 
     var cellContents = {1: '20', 15: '60', 28: '100'}; 

     //Select disabled days (span) for proper indexing but apply the rule only to enabled days(a) 
     $('.ui-datepicker td > *').each(function (idx, elem) { 
      var value = cellContents[idx + 1] || 0; 

      /* dynamically create a css rule to add the contents with the :after       
       selector so we don't break the datepicker functionality */ 
      var className = 'datepicker-content-' + value; 

      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); 
} 

Aggiungere un metodo per creare nuove regole CSS al volo, tenendo traccia di quelli già creati.

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

E, infine, un po 'di CSS di default per il nuovo contenuto della cella

.ui-datepicker td a:after 
{ 
    content: ""; 
    display: block; 
    text-align: center; 
    color: Blue; 
    font-size: small; 
    font-weight: bold; 
} 

Questo funziona per i contenuti di base, ma se si vuole ottenere fantasia con qualcosa come '$ 20.95'(contiene i caratteri speciali CSS) , è possibile utilizzare un hash MD5 del contenuto per creare la variabile className.

EDIT JSFiddle modificato da @ di yuga JSFiddle di includere un hash MD5 del nome della classe unica per i contenuti più complessi.

+0

Ho creato un [fiddle] (http://jsfiddle.net/yugene/e3uu9) in base alla tua risposta e sembra funzionare. Accetto la tua risposta anche se ora non ho la possibilità di verificare se tutti i requisiti che avevo inizialmente per questo comportamento sono soddisfatti. Grazie per aver condiviso la soluzione comunque :). – yuga

0

Sulla base della risposta di @ PrestonS e this post, ho una soluzione semplice e semplice che non ha bisogno di aggiungere i tag <style> all'intestazione.

La mia soluzione aggiorna in quanto tale di Preston:

Modificato updateDatePickerCells funzione:

function updateDatePickerCells(dp) { 
    /* Wait until current callstack is finished so the datepicker 
     is fully rendered before attempting to modify contents */ 
    setTimeout(function() { 
     //Fill this with the data you want to insert (I use and AJAX request). Key is day of month 
     //NOTE* watch out for CSS special characters in the value 
     var cellContents = {1: '20', 15: '60', 28: '100'}; 

     //Select disabled days (span) for proper indexing but apply the rule only to enabled days(a) 
     $('.ui-datepicker td > *').each(function (idx, elem) { 
      var value = cellContents[idx + 1] || 0; 

      /***** MAGIC! *****/ 

      $(this).attr('data-content', value); 

      // and that's it! (oh, so easy) 
     }); 
    }, 0); 
} 

Con questa soluzione, non è necessario la funzione addCSSRule a tutti.

css Modificato:

/* to target all date cells */ 
.ui-datepicker td > *:after { 
    content: attr(data-content); /***** MAGIC! *****/ 

    /* add your other styles here */ 
} 

/* to target only allowed date cells */ 
.ui-datepicker td > a:after { 
} 

/* to target only disabled date cells */ 
.ui-datepicker td > span:after { 
} 

inizializzazione con l'oggetto datepicker

Se è necessario l'oggetto DatePicker nella funzione updateDatePickerCells, ecco un modo per farlo in fase di inizializzazione. (Sulla base di this post)

var calendarElem = $('#DatePicker').datepicker({ 
    changeMonth: true, 
    changeYear: true, 
    minDate: 0, 
    //The calendar is recreated OnSelect for inline calendar 
    onSelect: function (date, dp) { 
     updateDatePickerCells(dp); 
    }, 
    onChangeMonthYear: function(month, year, dp) { 
     updateDatePickerCells(dp); 
    }, 
    beforeShow: function(elem, dp) { //This is for non-inline datepicker 
     updateDatePickerCells(dp); 
    } 
}); 

var datepicker = $.datepicker._getInst(calendarElem[0]); 
updateDatePickerCells(datepicker); 
Problemi correlati