2009-08-09 3 views
13

Hi collega StackOverflow: ERS,jQuery Datepicker: impedire la chiusura selettore quando si fa clic una data

Sto utilizzando il jQuery Datepicker plugin, insieme a Martin Milesich Timepicker plugin. Tutto funziona alla grande, fatta eccezione per il fatto che facendo clic su una data nel datepicker, si chiude il widget, senza lasciare il tempo per scegliere l'ora. opzione

Domanda:: Quindi mi chiedo se c'è un modo per evitare che il widget di chiudere quando si fa clic una data, e invece obbligare gli utenti a fare clic sul pulsante "Done" (che si presenta quando si abilita la "vera showButtonPanel"), o facendo clic all'esterno del widget. Non voglio che i miei utenti debbano aprire il widget due volte! Vedi il comportamento online at the timepicker demo

Qualsiasi aiuto per risolvere questo problema, o anche i puntatori nella giusta direzione, è apprezzato!

Maggiori informazioni: Sto utilizzando i file forniti da Martins link per il download: http://milesich.com/tpdemo/timepicker-0.2.0.zip

  • jquery-ui-1.7.2.custom.min.js
  • timepicker.js (ultima versione 0.2 .0)

Queste sono le opzioni che sto usando:

$(document).ready(function(){ 
    $(".datepicker").datepicker({ 
     duration: '', 
     showTime: true, 
     constrainInput: false, 
     stepMinutes: 5, 
     stepHours: 1, 
     time24h: true, 
     dateFormat: "yy-mm-dd", 
     buttonImage: '/static/images/datepicker.png', 
     buttonImageOnly: true, 
     firstDay: 1, 
     monthNames: ['Januari','Februari','Mars','April','Maj','Juni','Juli','Augusti','September','Oktober','November','December'], 
     showOn: 'both', 
     showButtonPanel: true 
    }); 
}) 
+0

Una breve nota per dire che la questione non è più un problema nella versione corrente di TimePicker collegare. –

+0

@JamesMcGrath: Grazie, buono a sapersi! –

+2

@lucifer: Siamo spiacenti, no. Stai usando StackOverflow in modo errato. Se hai una domanda, scrivine una nuova con tutte le informazioni che puoi. Probabilmente riceverai una risposta entro un paio d'ore. –

risposta

19

piuttosto che modificare la fonte è meglio utilizzare gli eventi esistenti

onSelect: function() { 
    $(this).data('datepicker').inline = true;        
}, 
onClose: function() { 
    $(this).data('datepicker').inline = false; 
} 
+0

Questa è una soluzione molto migliore. Nota: questo rimuoverà il pulsante "done" se avete 'showButtonPanel: true' abilitato. Non ho capito come fermare questo comportamento. –

+0

Grazie mille. Questa è la soluzione perfetta. – RY35

+0

@PhilMoorhouse Un po 'tardi, ma forse aiuta ancora qualcuno: in jquery-ui troverai una funzione '_generateHTML' che non aggiungerà il pulsante" done "se l'istanza ha' inline: true'set. Puoi cercare l'unica occorrenza di 'ui-datepicker-close' e liberarti di questo comportamento. – lexith

8

Dovrai hackerare il datepicker da solo. Questo è il codice che usa. Se non è in linea, si nasconde quando si seleziona una data.

È possibile passare il proprio metodo onSelect e modificare rapidamente l'istanza di datePicker per essere in linea e quindi modificarla di nuovo senza dover modificare gli interni di datepicker ma è una soluzione molto complessa.

if (inst.inline) 
     this._updateDatepicker(inst); 
else { 
     this._hideDatepicker(null, this._get(inst, 'duration')); 
     this._lastInput = inst.input[0]; 
     if (typeof(inst.input[0]) != 'object') 
     inst.input[0].focus(); // restore focus 
     this._lastInput = null; 
} 
+0

Grazie mille redsquare, la tua risposta mi ha portato nella giusta direzione. Sembra che onSelect venga attivato solo quando si seleziona una data, quindi semplicemente chiamare show() nell'istanza di select mi dà il comportamento che voglio. ... onSelect: function (dateText, inst) { inst.show(); } –

+0

No, colpa mia. Quanto sopra genera un errore, qualcosa che sembra impedire al raccoglitore di nascondersi. Non riesco ancora a far funzionare il tuo suggerimento. Se lo trasformo in "in linea", il pulsante Fine scompare e non c'è altro modo per chiudere la finestra piuttosto che fare clic al di fuori di essa. Ho provato a impostare un timeout e ripristinare la modalità in linea senza alcun effetto. –

+0

Ok, ho trovato un secondo modo di fare quello che voglio. In realtà, è possibile sovrascrivere il metodo _selectDate, da cui proviene il codice da cui viene fornito in precedenza, con un metodo personalizzato. Questo metodo contiene esattamente lo stesso codice del file originale, ma senza la riga "_hideDatepicker". Semplice, e piuttosto hacker, ma funziona. –

26

Per riferimento, e poiché la gente mi ha chiesto questo per posta. Ecco un pezzo di codice che deve essere aggiunto alla timepicker.js:

/** 
* Don't hide the date picker when clicking a date 
*/ 
$.datepicker._selectDateOverload = $.datepicker._selectDate; 
$.datepicker._selectDate = function(id, dateStr) { 
    var target = $(id); 
    var inst = this._getInst(target[0]); 
    inst.inline = true; 
    $.datepicker._selectDateOverload(id, dateStr); 
    inst.inline = false; 
    this._updateDatepicker(inst); 
} 

Buona fortuna a farlo funzionare sul tuo sito!

+0

+1 una vecchia domanda ma funziona ancora! grazie per aver aggiunto questo riferimento – zaf

+0

@zaf: Grazie per avermi contattato e aver votato :) –

+0

Ancora funziona nel maggio 2012 :) – Tzafrir

0

In seguito a ciò che suggeriva Emil, ho trovato un modo più semplice e più semplice per modificare il widget per supportare un widget di chiusura su evento selezionato.

In primo luogo, ho aggiunto un'altra proprietà ai valori predefiniti DICT sul widget:

closeOnSelect:true //True to close the widget when you select a date 

secondo luogo, trovare questa dichiarazione nel metodo _selectDate:

if (inst.inline) 
     this._updateDatepicker(inst); 
else { 
     ... 
    } 

e cambiare la condizione per essere come questo :

var closeOnSelect = this._get(inst, "closeOnSelect");   
if (inst.inline || !closeOnSelect) 
     this._updateDatepicker(inst); 
else { 
     ... 
    } 

Fare un tentativo, funziona per me. L'ho fatto sulla versione 1.8.5 di JQuery UI.

0

Fresco, se si utilizza jquery-ui-1.8.5.custom.min.js e jquery-ui.multidatespicker.js, è possibile modificare jquery-ui-1.8.5.custom.min.JS: da:

if(a.inline)this._updateDatepicker(a); 

in:

if(a.inline || !this._get(a, 'closeOnSelect'))this._updateDatepicker(a); 
0

bene questa una soluzione sporca ... ma funziona per me ... anche con showButtonPanel: true

$(function() { 
    var dp_c = null, dp_once = false; 
    $('#datepicker').datepicker({ 
     showButtonPanel: true, 
     onSelect: function() { 
     $(this).data('datepicker').inline = true; 
     setTimeout(function() { 
      $('#ui-datepicker-div').find('.ui-datepicker-buttonpane').append(dp_c); 
     }, 1); 

     }, 
     onClose: function() { 
     $(this).data('datepicker').inline = false; 
     } 
    }).click(function() { 
     if(!dp_once) { 
     setTimeout(function() { 
      dp_c = $('#ui-datepicker-div').find('.ui-datepicker-close').clone(); 
     }, 500); 
     dp_once = !!1; 
     } 
    }); 

    $('#ui-datepicker-div').on('click', '.ui-datepicker-close', function() { 
     $('#datepicker').datepicker("hide"); 
    }); 

    }); 
0

Si dovrebbe ignorare nativa funzione js:

/* Update the input field with the selected date. */ 
     _selectDate: function(id, dateStr) { 
      var target = $(id); 
      var inst = this._getInst(target[0]); 
      dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); 
      if (inst.input) 
       inst.input.val(dateStr); 
      this._updateAlternate(inst); 
      var onSelect = this._get(inst, 'onSelect'); 
      if (onSelect) 
       onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback 
      else if (inst.input) 
       inst.input.trigger('change'); // fire the change event 
      if (inst.inline) 
       this._updateDatepicker(inst); 
      else { 
       if(inst.settings.hideOnSelect != false){ 
        this._hideDatepicker(); 
       } 
       this._lastInput = inst.input[0]; 
       if (typeof(inst.input[0]) != 'object') 
        inst.input.focus(); // restore focus 
       this._lastInput = null; 
      } 
     }, 

E aggiungere opzione appropriata per datepicker configurazione, come ad esempio:

var defaultDatePickerOptions = { 
     hideOnSelect: false, 
     ... 
    }; 
var birthDate = jQuery.extend({}, defaultDatePickerOptions); 
$('#birthdate').datepicker(birthDate); 
3

Ecco una soluzione:

onSelect: function (dateText, inst) { 
    ..... // Your code like $(this).val(dateText);` 


    //Set inline to true to force "no close" 
    inst.inline = true; 
}, 
onClose: function(date,inst){ 
    //Set inline to false => datapicker is closed 
    // onClose is called only if you click outside the datapicker, onSelect will not 
    // trig onClose due to inline = true 
    inst.inline = false; 
} 

`

2

Perché tutti i commenti forniscono soluzioni alternative? è straigtfarword:

usare il calendario in linea con Altfield :)

<input type="text" id="alternate" size="30" /> 
    <div id="datepicker"></div> 

    <script> 
     $("#datepicker").datepicker({ 
      altField: "#alternate" 
     }); 
    </script> 

controllo questo violino: http://jsfiddle.net/menocomp/y2s662b0/1/