Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; PDOXpander has a deprecated constructor in /usr/home/void/domains/programowo.net/public_html/core/PDOXpander.class.php on line 11
Selektory typu $('#id')
lub $('div.klasa')
są bardzo wygodne - to fakt. Jednak co zrobić kiedy nie spełniają naszych wymagań, bo są zbyt ogólne, bo nie damy rady wyłuskać tego, czego potrzebujemy?
Na przykładzie formsetów Django pokażę, jak stosować bardziej szczegółową metodę dobierania elementów z dokumentu.
Załóżmy, że mamy w adminie Django model (nazwijmy fo Element), do którego przypięty mamy inny model (nazwijmy go Block) relacją many to many
i wyświetlamy go w inlineowym formsecie.
Mockupowy kod modeli wygląda mniej więcej tak:
class Block(models.Model): text = models.CharField(max_length=40) order = models.SmallIntegerField() active = models.BooleanField() class Element(models.Model): blocks = models.ManyToMany(Block)
Jeśli podejrzymy źródło htmla to zobaczymy przykładowe id dla danego formsetu:
id_blocks_set-TOTAL_FORMS id_blocks_set-INITIAL_FORMS id_blocks_set-MIN_NUM_FORMS id_blocks_set-MAX_NUM_FORMS id_blocks_set-0-text id_blocks_set-0-active id_blocks_set-0-order id_blocks_set-1-text id_blocks_set-1-active id_blocks_set-1-order id_blocks_set-2-text id_blocks_set-2-active id_blocks_set-2-order id_blocks_set-__prefix__-text id_blocks_set-__prefix__-active id_blocks_set-__prefix__-order
Id kończące się wielkimi literami to dane formsetu potrzebne wewnętrznym mechanizmom Django, id mające w środku __prefix__
to szablon używany przez javascript Django do dodawania pustego formularza. Natomiast id mające numer (w naszym przypadku 0, 1, 2) to nasze konkretne formularze. I to do nich chcielibyśmy się dobrać.
Załóżmy, że chcemy wybrać wszystkie pola z formularzy dotczące pól text oraz order.
Zastosujemy wtedy taki selektor:
$.each($('input, textarea, select').filter( function() { return this.id.match(/id_blocks_set\-[0-9]+\-(text|order)/); }), function(index, element) { console.log($(element)); } );
Wstępnie dobieramy sobie elementy typu input, textarea, select. Na nich dopiero wywołujemy metodę filter, która ma za zadanie wyszukać dokładnie interesujące nas elementy: zaczynające się od id_blocks_set-
mające w środku jedną lub więcej cyfr i kończące się na -text
lub -order
.
Oczywiście zamiast wstępnych selektorów można zastosować zwykłe body. Ale ja wolę dobrać sobie konkretne elementy na wypadek, gdyby gdzieś indziej występowały takie same bądź podobne id.
Metodę .filter()
stosujemy tu na zasadzie sprawdzenia, czy którekolwiek ze znalezionych id pasuje do zadanego wyrażenia regularnego, jeśli tak, to zwracamy element.
Zamiast id możemy sprawdzać klasy. Wtedy zamiast this.id.
można zastosować this.className
(nazwy klas w stringu) lub this.classList
(poszczególne klasy jako stringi na liście). W zasadzie znając mechanizm metody .filter()
mamy pełną dowolność i swobodę dobierania konkretnych elementów.