wtorek, 2 grudnia 2014

Checkbox na raporcie i paginacja

W trakcie realizacji projektu zaszła potrzeba stworzenia funkcjonalności, umożliwiającej usuwanie rekordów z raportu, które zostały zaznaczone za pomocą Checkboxa.
Natomiast kluczowym wymaganiem jest, aby funkcjonalność zapamiętywała zaznaczone Checkboxy na różnych stronach raportu (przechodząc poprzez paginację).

W ramach wyjaśnienia:
Użytkownik zaznacza na raporcie wiersze od 1-5 -> przechodzi do kolejnej strony raportu (wyświetlają się wiersze 6-10) i nic nie zaznacza -> powraca do wierszy 1-5 i te powinny być nadal zaznaczone.

Co potrzebujemy?

Raport w którym dodamy kolumnę z Checkbox za pomocą (APEX_ITEM.CHECKBOX2)

Funkcja JavaScript -> uruchamia Proces Aplikacyjny.

Proces Aplikacyjny -> zarządza wpisami w kolekcji.


Idea działania jest następująca:
1. Zaznaczamy lub odznaczamy Checkbox na raporcie.
2. Po zaznaczeniu wywoływana jest funkcja JavaScript, do której przekazujemy ID zaznaczonego rekordu.
3. Funkcja JavaScript uruchamia Proces Aplikacyjny, który będzie dodawać lub usuwać wpis w kolekcji.
4. Podpinamy tabelę APEX_COLLECTIONS do naszego raportu przez co wiemy, który Checkbox jest zaznaczony.

1. Tworzymy raport

SELECT
APEX_ITEM.CHECKBOX2(p_idx => 5,
                    p_value => empno,
                    p_attributes => 'onchange="checkboxCollection(this);"',
                    p_item_id => empno) checkbox_row,
empno,
ename,
job,
mgr,
hiredate,
sal,
comm,
deptno
FROM emp



APEX_ITEM.CHECKBOX2 generuje kod HTML na podstawie podanych parametrów

p_idx => numer zmiennej globalnej. 5 oznaczna, że będzie to F05.

p_value => wartość, która będzie ustawiana na checkboxie.

p_attributes => dopisanie atrybutu onchange, który uruchomi odpowiedni kod JavaScript.

p_item_id => nadanie elementowi HTML unikalnego id.


efekt:



2. Tworzymy Proces Aplikacyjny

APEX_COLLECTION


DECLARE
l_checkbox_val  number;
l_seq_id   number := 0;

BEGIN
-- utwórz kolekcję jeżeli nie istnieje
IF apex_collection.collection_exists('CHECKBOX_COLLECTION') = FALSE
    THEN
        apex_collection.create_collection('CHECKBOX_COLLECTION');
END IF;
-- przypisz do zmiennej przekazaną wartość x01
l_checkbox_val := apex_application.g_x01;
-- przeszukaj kolekcję czy jest zaznaczony checkbox o wartosci x01
FOR c1 IN (SELECT seq_id
    FROM apex_collections
    WHERE collection_name = 'CHECKBOX_COLLECTION'
    and n001 = l_checkbox_val)
LOOP
-- przypisz do zmiennej znalezione seq_id 
-- jak nie znaleziono rekordu w kolekcji to wartosc l_seq_id wynosi 0

    l_seq_id := c1.seq_id;
END LOOP;
-- checkbox nie istnieje w kolekcji wiec dodaj wpis do kolekcji
IF nvl(l_seq_id,0) = 0 THEN
    APEX_COLLECTION.ADD_MEMBER(
    p_collection_name => 'CHECKBOX_COLLECTION',
    p_n001 => l_checkbox_val
    );
ELSE
-- Checkbox istnieje w kolekcji, więc usuń
    APEX_COLLECTION.DELETE_MEMBER(
    p_collection_name => 'CHECKBOX_COLLECTION',
    p_seq => l_seq_id
    );
END IF;

COMMIT;

END;

3. Tworzymy funkcje JavaScript
apex.server.process
inne wpisy z wykorzystaniem apex.server.process
-> parametry w apex.server.process
-> zapisywanie wartości do sesji



function checkboxCollection(id) {
    apex.server.process("UpdateCheckboxCollection", {
    x01: id.value
},{
    dataType: 'text',
    success: function( pData ) { }
});
}


4. Modyfikujemy wcześniejszego Selecta.
Celem jest dołączenie tabeli z kolekcją i wykorzystanie parametru p_checked_values, który zaznacza Checkbox.

SELECT
    APEX_ITEM.CHECKBOX2(p_idx => 5,
                        p_value => empno,
                        p_attributes => 'onchange="checkboxCollection(this);"'
                       ,p_item_id => empno
                       ,p_checked_values => acol.n001 ) checkbox_row,
empno,
ename,
job,
mgr,
hiredate,
sal,
comm,
deptno
from EMP e 
LEFT JOIN APEX_COLLECTIONS acol
ON (e.empno = acol.n001)
AND acol.collection_name = 'CHECKBOX_COLLECTION'

Aby usunąć zaznaczone wiersze będziemy musieli dodatkowo stworzyć proces odwołujący się do kolekcji. Głównym celem wpisu było pokazanie jak zapisać zaznaczone Checkboxy do kolekcji, dlatego dalsze procesowanie danych z kolekcji pozostawiam w inicjatywie własnej.
Działanie przetestować możemy np: wybierając z paska developerskiego "Sessions" a następnie View -> Collections.
Jeżeli ktoś posiada inne rozwiązanie, zachęcam do podzielenia się w komentarzu.

Brak komentarzy:

Prześlij komentarz