2010-03-14 14 views
14

Mam div, w którym znajduje się datepicker. Używam czegoś takiego do sklonowania go:problem podczas klonowania 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(); 

To jest uproszczona wersja mojego kodu. Działa i kalendarz wyświetla się zgodnie z oczekiwaniami tam, gdzie jest to oczekiwane, ale po kliknięciu daty, wartość datepicker'a zostanie zaktualizowana .. (z której została sklonowana).

Próbowałem przed zniszczyć (inexisting) instancji tak:

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

Brak powodzenia ..

Sprawdziłem jak to śledzi instancji i ręcznie usunięte dane jak to:

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

Nadal nie ma szczęścia.

Nie rozumiem, że tylko zachowanie wyboru daty jest błędne, wszystko inne działa zgodnie z oczekiwaniami.

ja naprawdę nie wiem co jeszcze sprawdzić teraz ..

Odpowiedz

23

Oto problem. datepicker tworzy atrybuty ID oparte na UUID dla pól wejściowych, które wiąże podczas inicjowania. Klonowanie tych elementów powoduje, że więcej elementów ma ten sam identyfikator (którego jQuery nie lubi) lub inny identyfikator, jeśli rutyna klona nim zarządza (co oznacza, że ​​datepicker nie wie o klonach). Innymi słowy, datepicker inicjalizuje tylko wszystkie elementy pasujące do selektora w momencie, w którym go wywołasz. W rzeczywistości nie ma sensu próbować niszczyć/dezaktywować/włączać w kółko, kiedy można po prostu owinąć wywołanie init wewnątrz jakiejkolwiek funkcji, której używasz do tworzenia klonów.

Ponieważ moje funkcje klonowania zazwyczaj kopiują z ukrytych elementów DOM, a nie widoczne, mam luksus decydujący o tym, czy muszę powiązać przed czy po klonowaniu. Zrób # elementplateDiv ukrytym elementem na twojej stronie z elementem INPUT już tam.

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

i że prawie to robi. Klonowanie (prawda), kiedy tylko możesz, na dłuższą metę zaoszczędzi ci bólu głowy.

+0

Dzięki, myślę, że naprawdę wskazałeś mój problem. –

0

Co o zmianę kolejności?

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

Szczerze mówiąc, nie wiem, jak datepicker działa wewnętrznie. Moje przeczucie polega na tym, że przechowuje coś w pamięci DOM DOMU jQuery. Unikajmy kopiowania go za wszelką cenę.

(Można mieć dużo logiki biznesowej pomiędzy tymi liniami kodu. Chodzi o to, aby mieć kopię zapasową #someDiv przed oddanie datepicker na nim.)

+0

to jest mój problem .. powiedzmy, że mam 2 tabele wiersze z złożone w nich dynamiczne formy. Jest przycisk "+", który po kliknięciu kopiuje DOM DOMU ostatniego wiersza i wstawia go z powrotem po tym ostatnim wierszu. Więc pierwszy datepicker * * ma być włączony do pierwszego i drugiego może być lub może nie uzyskać włączona .. –

+0

http://vonautomatisch.at/media/uploads/grappelli/inlinetabular_big.jpg tak .. ale z datepickers. –

+0

@ h3: Nadal nie rozumiem, dlaczego nie można zrobić kopii czystej części DIV. Kopii zapasowej nie trzeba wstawiać do DOM ... – pestaa

0

Upewnij się, że nowo sklonowane datepicker ma inną nazwę i ID niż oryginał. Jeśli obie mają taką samą nazwę, zachowanie, które opisujesz, będzie normalne.

Spróbuj zmienić tę ostatnią linię do czegoś jak:

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

Prawdopodobnie ma on powiązania z klasami, pod warunkiem, że dostarczył nam identyfikator ze względu na prezentację. – pestaa

36

To działa na mnie z 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(); 

Sprawdź http://jsbin.com/ahoqa3/2 na szybkie demo

btw. wydaje się, że masz różne błędy w kodzie swojego pytania. Klasa css to hasDatepicker, a nie hadDatepicker i raz napisałeś mydiv, a następnym razem zmienna to myDiv, która nie jest taka sama.

+1

Doskonały. Wiem, że to jest stare, ale ta odpowiedź wyleczyła problem, gdy natknąłem się na niego dziś rano, zmieniłem go w małą funkcję, którą mogę wykorzystać w razie potrzeby: 'function initialiseDates() { $ ('. DatePicker ') .each (function() { $ (this) .removeClass ("hasDatepicker"). removeData (' datepicker '). unbind(). datepicker ({dateFormat:' dd/mm/rr '});; }); }; ' Doskonale, dzięki! : D –

+0

Dobra robota.Ale jeśli sklonujesz cały wiersz formularza (na przykład dane zaproszonych osób), wiersz może zawierać inne pola wejściowe, które mogą mieć różne walidatory danych wejściowych, których nie chcemy stracić. W tym przypadku powinieneś zniszczyć datepicker na myDiv i zrobić clone (true), a następnie ponownie uruchomić datepicker dla myDiv. Przed inicjalizacją datepicker na newDiv, wyczyść jego id .attr ("id", ""). Pomogło mi to. –

+0

Kontynuacja komentarza @JamieHartnoll: Jeśli masz 2 pola, do których klonujesz i używasz zajęć, sekretnym dla mnie sposobem było przejście przez nowy klon twojego fragmentu kodu; następnie przechodzimy przez każdą i '$ (this) .removeData ('datepicker'). unbind(). datepicker ({format: 'yourformathere'});' – pjammer

3

prostu zrobić

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

przed klonowanie div. Następnie po wkładając klon wiążą datepicker ponownie

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

rodzaju rozwiązanie „hacky”, ale działa doskonale.

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

działa dobrze. Ale robiąc to, datepicker otworzy się na sklonowanym wejściu i ustawi datę na oryginalnym wejściu (ponieważ mają ten sam identyfikator)

Aby rozwiązać ten problem, należy zmienić atrybut id sklonowanego wejścia.

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

i będzie działać świetnie!

+0

Znalazłem to bardzo pomocne dziękuję! – user1190132

7

Jeśli zadzwonisz pod numer .datepicker('destroy').removeAttr('id') przed klonowaniem, a następnie ponownie uruchom selektor dat, to zadziała.

Wygląda na to, że jest to błąd z niszczeniem, ponieważ ma przywrócić element do pierwotnego stanu.

+0

to przez wiele dni mnie dręczyło. Mogłem dodać datepickery, ale nie działałem po drugim wierszu, ponieważ "identyfikator" zawsze był taki sam. przez dodanie removeAttr ('id') naprawił to. thans! @dfmiller – Aris

+0

To zadziałało dla mnie –

0

Kompletne rozwiązanie, które działa dla mnie.

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

I tabela html td.

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

Mam nadzieję, że to pomoże.

Dzień dobry

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 używaj tylko języka ANGIELSKIEGO jako języka, a nie innego. –

+0

Chodzi mi o to, że nie ma reguł co do tego, w jakim języku mówisz ... Tak, programowanie jest tylko po angielsku, ale nazwy zmiennych mogą być w dowolnym języku ... na końcu jest to tylko ciąg znaków! –

0

To może być trochę za późno, ale wszystkie powyższe sugestie nie działa dla mnie, wpadłem proste rozwiązanie dla tego produktu.

Po pierwsze, co powoduje problem: JQuery przypisuje datepicker do identyfikatora elementu. jeśli klonujesz element, to również ten sam identyfikator może zostać sklonowany. którego jQuery nie lubi. Może się zdarzyć, że otrzymasz zerowy błąd odniesienia lub datę przypisaną do pierwszego pola wejściowego, niezależnie od tego, które pole wejściowe klikniesz.

Rozwiązanie:

1) zniszczyć datepicker 2) przypisać nowe unikalne identyfikatory dla wszystkich polu wprowadzania 3) przydziela datepicker dla każdego wejścia

Upewnij się, że wejście jest coś takiego

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

Przed sklonowaniem zniszcz datepicker

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

Po sklonować, dodać te linie, jak również

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

i dzieje się magia

0

Datepicker nie jeśli identyfikator elementu ulega zmianie. Dlatego lepiej nie zmieniać identyfikatora elementu, jeśli jest on wymagany. Ale jeśli naprawdę musi się zmienić identyfikator i który zmienił id musi współpracować z datepicker następnie po nim:

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