2010-03-14 14 views
14

Ich habe ein Div, in dem es ein Datepicker ist. Ich verwende so etwas, um es zu klonen:Problem beim Klonen jQuery UI Datepicker

mydiv = $('#someDiv'); 

// works fine so far 
mydiv.find('input.datefield').datepicker(); 

// clone without the events and insert 
newDiv = myDiv.clone(false).insertAfter(myDiv); 

// datepicker won't re-init if this class is present 
newDiv.find('.hadDatepicker').removeClass('hadDatepicker'); 

// reinitialize datepicker 
newDiv.find('input.datefield').datepicker(); 

Dies ist eine abgespeckte Version meines Codes. Es funktioniert und der Kalender erscheint wie erwartet, wo es erwartet wird .. aber wenn ein Datum angeklickt wird, wird der vorherige Wert von datepicker aktualisiert .. (der, von dem es geklont wurde).

Ich habe versucht, wie dies vor der (inexisting) Instanz zu zerstören:

newDiv.find('input.datefield').datepicker('destroy').datepicker(); 

Kein Glück ..

ich eingecheckt haben, wie es den Überblick über Instanzen hält und manuell gelöscht, die Daten wie dies:

newDiv.find('input.datefield').data('datepicker', false).datepicker('destroy').datepicker(); 

Immer noch kein Glück.

Was ich nicht verstehe ist, dass nur das Datum Auswahl Verhalten fehlerhaft ist, alles andere funktioniert wie erwartet.

Ich weiß nicht wirklich, was sonst noch jetzt prüfen ..

Antwort

23

Hier ist das Problem. datepicker erstellt UUID-basierte ID-Attribute für die Eingabefelder, die bei der Initialisierung gebunden werden. Wenn Sie diese Elemente klonen, erhalten Sie mehr Elemente mit entweder derselben ID (was jQuery nicht mag) oder einer anderen ID, wenn Ihre Klonroutine dies verwaltet (was bedeutet, dass datepicker nichts über die Klone weiß). Mit anderen Worten, Datepicker initialisiert nur alle Elemente, die zu Ihrem Selektor passen, als Sie es aufrufen. es macht eigentlich weniger Sinn zu versuchen zu zerstören/deaktivieren/aktivieren immer und immer wieder, wenn Sie nur den Init-Aufruf in jede Funktion wrappen können, die Sie verwenden, um die Klone zu erstellen.

Da meine Klonfunktionen normalerweise aus versteckten DOM-Elementen statt aus sichtbaren DOM-Elementen kopieren, habe ich den Luxus, zu entscheiden, ob ich vor oder nach dem Klonen binden muss. Machen Sie #templateDiv also zu einem versteckten Element auf Ihrer Seite mit dem INPUT-Element, das bereits darin enthalten ist.

mydiv = $('#templateDiv'); 
mydest = $('#someDiv'); 

function make_the_donuts() { 
    newDiv = myDiv.clone(true).insertAfter(mydest); 
    // attach datepickers by instance rather than by class 
    newDiv.find('input.datefield').datepicker(); 
} 

und das tut es ziemlich viel. Klonen Sie (wahr) wann immer Sie können, es wird Ihnen auf lange Sicht Kopfschmerzen ersparen.

+0

Danke, ich glaube, du hast mich wirklich auf mein Problem hingewiesen. –

0

Was ist die Reihenfolge zu ändern?

mydiv = $('#someDiv'); 

// clone without the events and insert 
newDiv = myDiv.clone(false).insertAfter(myDiv); 

// datepicker won't re-init if this class is present 
// not necessary anymore 
// newDiv.find('.hadDatepicker').removeClass('hadDatepicker'); 

newDiv.find('input.datefield').datepicker(); 

// datepicker attached as a last step 
mydiv.find('input.datefield').datepicker(); 

Ehrlich ich weiß nicht, wie datepicker intern arbeitet. Meine Vermutung ist, dass es etwas in jQuery DOM-Speicher speichert. Vermeiden wir es, es um jeden Preis zu kopieren.

(Sie können zwischen diesen Zeilen Code langen Business-Logik haben. Der Punkt eine Sicherung #someDiv haben, bevor sie eine Datepicker auf sie setzen.)

+0

dies mein Problem ist .. sagen wir, ich habe 2 Tabellen Zeilen mit komplexe dynamische Formen in ihnen. Es gibt eine "+" - Schaltfläche, die nach dem Anklicken das DOM der letzten Zeile kopiert und nach der letzten Zeile wieder einfügt. So ist der erste Datepicker * werden muss * aktiviert erste und die zweite Macht oder nicht aktiviert bekommen könnte .. –

+0

http://vonautomatisch.at/media/uploads/grappelli/inlinetabular_big.jpg Like this .. aber mit Datumsauswahl. –

+0

@ h3: Ich verstehe immer noch nicht, warum du keine Kopie von einem sauberen someDiv machen kannst. Das Backup muss nicht in das DOM eingefügt werden ... – pestaa

0

Stellen Sie sicher, Ihre neu geklont picker einen anderen Namen hat und ID als das Original. Wenn beide den gleichen Namen haben, wäre das von Ihnen beschriebene Verhalten normal.

Versuchen Sie, dass die letzte Zeile, um etwas wie das Ändern:

btw
newDiv.find('input.datefield').attr('id', 'newDatePicker').attr('name', 'newDatePicker').datepicker(); 
+0

Wahrscheinlicher, dass er Klassen zugeordnet hat, hat uns nur eine ID aus Gründen der Präsentation zur Verfügung gestellt. – pestaa

36

Dies funktioniert für mich mit jQuery UI 1.7.2

var mydiv = $('#someDiv'); 
mydiv.find('input.datefield').datepicker(); 
var newDiv = mydiv.clone(false).attr("id", "someDiv2").insertAfter(mydiv); 
newDiv.find('input.datefield') 
    .attr("id", "") 
    .removeClass('hasDatepicker') 
    .removeData('datepicker') 
    .unbind() 
    .datepicker(); 

prüfen http://jsbin.com/ahoqa3/2 für eine schnelle Demo

. Sie scheinen verschiedene Fehler im Code Ihrer Frage zu haben. Die CSS-Klasse ist hasDatepicker nicht hadDatepicker und auf einmal schrieb Sie mydiv und das nächste Mal ist die Variable myDiv, die nicht das gleiche ist.

+1

Ausgezeichnet. Ich weiß, das ist schon sehr alt, aber diese Antwort hat das Problem kuriert, als ich heute morgen darauf stieß. Ich habe es zu einer kleinen Funktion gemacht, die ich wo immer gebraucht wiederverwenden kann: 'function initialiseDates() { $ ('. DatePicker ') .each (function() { $ (diese) .removeClass (' hasDatepicker '). removeData (' datepicker '). unbind(). datepicker ({Datumsformat:' TT/MM/JJ '});; }); }; ' Perfekt, danke! : D –

+0

Gute Arbeit.Wenn Sie jedoch die gesamte Zeile eines Formulars klonen (z. B. eingeladene Personendaten), enthält die Zeile möglicherweise noch weitere Eingabefelder, die möglicherweise unterschiedliche Validierer für Eingabedaten haben, die wir nicht verlieren wollen. In diesem Fall sollten Sie datepicker auf myDiv zerstören und clone (true) machen, dann init datypicker erneut für myDiv. Vor der Initialisierung datepicker auf newDiv, löschen Sie die ID .attr ("id", ""). Es hat mir geholfen. –

+0

Im Anschluss an den Kommentar von @JamieHartnoll: Wenn Sie zwei Felder haben, die Sie klonen und Klassen verwenden, war die geheime Soße für mich, den neuen Klon Ihres Code-Blocks zu durchlaufen; dann gehe durch jede und '$ (this) .removeData ('datepicker'). unbind(). datepicker ({format: 'yourformathere'});' – pjammer

3

tun nur

$('input.datefield').datepicker("destroy"); 

vor dem div klonen. Dann nach Einsetzen der Klon die picker wieder

$('input.datefield').datepicker(); 

Art eines ‚Hacky‘ Lösung binden, aber es funktioniert perfekt.

1
$('input.datefield').datepicker("destroy"); 
$('input.datefield').datepicker(); 

es funktioniert gut. Aber gerade dadurch öffnet sich datepicker bei geklonter Eingabe und setzt das Datum auf die ursprüngliche Eingabe (da sie die gleiche ID haben)

Um dies zu lösen, müssen Sie das ID-Attribut der geklonten Eingabe ändern.

dp = < cloned input > 
var d = $('input.vDateField'); 
dp.removeClass('hasDatepicker'); 
dp.attr('id', dp.attr('id')+d.length); 
d.datepicker("destroy"); 
d.datepicker(); 

und es wird gut funktionieren!

+0

Ich fand das sehr hilfreich danke! – user1190132

7

Wenn Sie vor dem Klonen .datepicker('destroy').removeAttr('id') aufrufen und dann die Datumsauswahl neu starten, wird es funktionieren.

Dies scheint ein Fehler mit destroy zu sein, da es das Element in seinen ursprünglichen Zustand zurückbringen soll.

+0

das nervt mich seit Tagen. Ich könnte Datumsangaben hinzufügen, arbeitete aber nach der zweiten Zeile nicht mehr, weil "id" immer gleich war. Durch das Hinzufügen von removeAttr ('id') wurde es repariert. Danke! @dfmiller – Aris

+0

Dies funktionierte für mich –

0

Die komplette Lösung, die für mich funktioniert.

//before 
$('input.fecha').datepicker("destroy"); 
newcell.innerHTML = table.rows[0].cells[i].innerHTML; 
//change de input id 
$("input.fecha").attr("id", function (arr) {return "fecha" + arr;}); 
//after 
$('input.fecha').datepicker({defaultDate: "+1w",changeMonth: true,numberOfMonths: 1, showOn: "button", buttonImage: "<?php echo base_url() ?>images/calendar.gif", buttonImageOnly: true, showLabel:false, dateFormat:"yy-mm-dd"}); 

Und die HTML-td-Tabelle.

<td><?php echo form_input(array('name' => 'fecha','id' => 'fecha','class' => 'fecha')); ?></td> 

Hoffe das hilft Ihnen.

Guten Tag

0
var dt = new Date(); 
var month = dt.getMonth(); 
var day = dt.getDate(); 
var year = dt.getFullYear()-5; 
      $newClone.children().children("#fna"+clickID) 
    .attr({ 
     'id': 'fna1'+newID, 
     'name': 'fna'+newID, 
     'value': day + '-' + month + '-' + year 
    }) 
    .datepicker("destroy") 
    .datepicker({ 
     firstDay: 1, 
     changeMonth: true, 
     changeYear: true, 
     yearRange: 'c-100:c', 
     defaultDate: '-1y', 
     dateFormat: 'dd-mm-yy' , 
     nextText: "Mes siguiente", 
     prevText: "Mes anterior", 
     monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'], 
     dayNamesMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'] 
    }); 
+1

plz verwenden Sie nur Englisch als Ihre Sprache, nicht andere. –

+0

Ich meine, es gibt keine Regel darüber, welche Sprache Sie sprechen können ... Ja, Programmierung ist nur ENGLISCH ABER Variablenname kann in jeder Sprache sein ... am Ende ist es nur eine Zeichenfolge! –

0

Dieses ein wenig zu spät sein könnte, aber alle oben genannten Vorschläge nicht für mich arbeiten, kam ich mit einer einfachen Lösung für diese auf.

Zuerst, was das Problem verursacht: JQuery zuweisen datepicker Element-ID. Wenn Sie ein Element klonen, kann dieselbe ID auch geklont werden. was jQuery nicht mag. Möglicherweise erhalten Sie entweder den Null-Referenzfehler oder das dem ersten Eingabefeld zugewiesene Datum, unabhängig davon, auf welches Eingabefeld Sie klicken.

Lösung:

1) zerstören picker 2) zuweisen neue eindeutige IDs für alle Eingabefeld 3) zuweisen picker für jeden Eingang

Stellen Sie sicher, Ihre Eingabe so etwas wie dieses ist

<input type="text" name="ndate[]" id="date1" class="n1datepicker"> 

Bevor du klonst, zerstöre datepicker

$('.n1datepicker').datepicker('destroy'); 

Nachdem Sie klonen, fügen Sie diese Zeilen als auch

var i = 0; 
$('.n1datepicker').each(function() { 
    $(this).attr("id",'date' + i).datepicker(); 
    i++; 
}); 

und die Magie passiert

0

Datepicker nicht, wenn die ID eines Elements geändert wird. Daher ist es besser, die ID eines Elements nicht zu ändern, wenn es erforderlich ist. Aber wenn Sie wirklich die ID und die geänderte ID mit picker muss sich ändern muss arbeiten dann folgen sie:

$(selector).removeClass('hasDatepicker'); 
 
$(selector).datepicker({ 
 
    changeMonth: true, 
 
    changeYear: true 
 
});