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 Nietrywialne selektory w jQuery na przykładzie Django i formsetów - Programowo.net

Nietrywialne selektory w jQuery na przykładzie Django i formsetów

Data publikacji: 2016-02-02 | Tagi:

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.


Oceń ten post:
Podziel się:

comments powered by Disqus

IT w obrazkach: