IE, JavaScript i bug związany z onclick.

Pisanie aplikacji internetowych wymusza na mnie konieczność stosowania JavaScriptu. Niestety nigdy wcześniej nie korzystałem z jego dobrodziejstw i z obiektowego modelu dokumentu DOM. Ponieważ jestem samoukiem i nie bardzo mam czas na naukę z kursów, pewne proste problemy próbuję rozwiązywać sam. No i raz się naciąłem… Stracone 3 godziny przez głupi błąd w Internet Explorerze.

Miałem do zrobienia prostą rzecz: przycisk w formularzu który tworzy swoją kopię, a samego siebie deaktywuje. Była to mała część formularza w którym użytkownik miał możliwość dodawania kolejnych pól, ale tutaj nie jest to istotne.

Rozwiązałem to prostą funkcją JavaScript wykorzystującą DOM:

function addButton(counter)
{
// pobiera div id="buttons"
box = document.getElementById("buttons");

// tworzy element input wraz z atrybutami
btn = document.createElement("input");
btn.setAttribute("type", "button");
btn.setAttribute("value", (counter+1)+". Add new button");
btn.setAttribute("name", "myButton"+(counter+1));
btn.setAttribute("onclick", "addButton("+(counter+1)+"); this.disabled = true;");

// dodaje element input do div id="buttons"
box.appendChild(btn);
}

Całość w gotowym przykładzie 1.

Funkcja dodaje nowe przyciski, a ich nazwy zawierają kolejne liczby. Proste prawda? Działa poprawnie w Operze i Firefoxie. Okazało się jednak, że w IE to nie działa. Dodawany jest nowy przycisk, jednak jego metoda onclick w IE zupełnie nie działa. Dosyć to dziwne prawda? Nie znam się na JS, dopiero zaczynam w tej dziedzinie, ale powinno to działać…

Dogłębna analiza, sprawdzanie Firebugiem i nic, wszystko wydaje się być ok, ale w IE dalej nie działa.

W końcu poszukiwania w Google pomogły rozwiązać ten problem. Okazało się, że IE ignoruje metodę onclick elementów dodawanych dynamicznie

Rozwiązałem to przez własność innerHTML elementu w którym znajdują się przyciski:

function addButton(counter)
{
// pobiera div id="buttons"
box = document.getElementById("buttons");

// dodaje HTML do div id="buttons"
div = document.createElement("div");
div.innerHTML = '<input type="button" value="'+(counter+1)+'. Add new button" name="myButton'+(counter+1)+'" onclick="addButton('+(counter+1)+'); this.disabled = true;" />';

box.appendChild(div);
}

Całość w gotowym przykładzie 2.

Możliwe, że ten kod można napisać lepiej – nie jestem specem od JavaScriptu. Dodatkowo każdy przycisk musiałem utworzyć w nowym divie, aby nie kasować poprzednich. Rozwiązanie to nie jest zbyt eleganckie i ma nie wiele wspólnego z DOMem, ale działa w IE, Operze i Firefoxie, co bardzo mnie ucieszyło.

Podsumowanie

Moje początki z JavaScriptem i AJAXem są dosyć ciężkie. Na szczęście Damian Wielgosik udostępnia świetny kurs JavaScript. Ponieważ jednak nie mam zbyt wiele czasu aby wgłębiać się w JS, zastosuję w przyszłych projektach jeden z AJAXowych frameworków, na przykład mootools albo jQuery. Za jQuery przemiawiają dwa nowe kursy po polsku pisane przez Damiana Wielgosika i Piotra Petrusa.