W Dojo Toolkit jest cały zestaw widgetów pozwalających budować bardzo nowoczesne aplikacje webowe. W ty wpisie zajmę się dwoma (spokrewnionymi) kontrolkami:

  • dijit.form.FilteringSelect
  • dijit.form.ComboBox

autouzupełnianie dijit.form.FilteringSelect

Co one robią?

Co z nimi nie tak, skoro mam zamiar im poświęcić cały wpis? Kolejno – są to komponenty zastępujące zwykły HTML-owy znacznik <select />. Są bardzo przyjazne dla oka, pozwalają nie tylko na wybór pozycji z listy dostępnych, ale także na wpisywanie własnych (mechanizm podpowiedzi), dodatkowo bardzo dobrze współdziałają z data store. Słowem – używać, nie umierać ;).

Jednak posiadają jedną dużą wadę funkcjonalną – aby rozwinąć listę trzeba kliknąć dokładnie,tylko i wyłącznie w strzałeczkę sugerującą rozwijanie.

demo online

Continue reading

Dojo posiada pokaźny zbiór widgetów (dijit – Dojo widget). W tym wpisie zajmiemy się kontrolką `dijit.Dialog’ oraz (nieistniejącym domyślnie) zdarzeniem `onMove’. Owe zdarzenie zostanie utworzone z wykorzystaniem istniejących mechanizmów dojo.

Proste okienko

Na początek pokażę kod prostego okienka `dijit.Dialog’:

dojo.require("dijit.Dialog");
dojo.ready(function(){
    var dialog = new dijit.Dialog({
        title: "Okienko",
        style: "width: 200px; height: 200px;",
        content : "Witaj świecie"
    });
    dialog.startup();
    dialog.show();
});
dojo.require("dijit.Dialog");
dojo.ready(function(){
	var dialog = new dijit.Dialog({
		title: "Okienko",
		style: "width: 200px; height: 200px;",
		content : "Witaj świecie"
	});
	dialog.startup();
	dialog.show();
});

demo online

Do konstruktora przekazałem tylko kilka parametrów. Aby zapoznać się z pozostałymi zapraszam do dokumentacji*. W kodzie zamieszczonym powyżej oczywiście nie ma jeszcze obsługi zdarzenia `onMove’. Aby je dodać wykorzystam mechanizm `dojo.subscribe‘.

Wykorzystanie `dojo.subscribe’ do przechwycenia przesunięcia

Skoro mamy okno, przechwyćmy moment, w którym zostanie przesunięte. Kontrolka okienka publikuje informacje o swoim przemieszczeniu w kanale ‘/dnd/move/stop‘. Wystarczy zatem zasubskrybować ten kanał:

dojo.require("dijit.Dialog");
dojo.ready(function()
{
    var dialog = new dijit.Dialog({
        title: "Okienko",
        style: "width: 200px; height: 200px;",
        content : "Witaj świecie"
    });
    dojo.subscribe('/dnd/move/stop', function(mover)
    {
        alert('Poruszyłeś mnie!');
    });
    dialog.startup();
    dialog.show();
});

demo online

OK, już mamy prymitywną obsługę “zdarzenia” `onMove’. Jakie są główne problemy:

  • na ten sam kanał publikują wszystkie wigety, a więc nie mamy obsługi konkretnie `onMove’ tego okienka,
  • nie jest to zbyt piękne rozwiązanie, raczej proteza.

Dodanie metody `onMove’

Aby ulepszyć poprzednie rozwiązanie musimy po pierwsze rozpoznawać konkretne okno. Po drugie musimy po rozpoznaniu wywołać metodę `onMove’. Kod jest dużo prostszy niż by się to wydawało:

dojo.require("dijit.Dialog");
dojo.ready(function()
{
    function createDijitDialogWithOnMoveEvent(title, content)
    {
        var dialog = new dijit.Dialog({
            title: title,
            style: "width: 200px; height: 200px;",
            content : content,
            onMove : function() {}
        });
       dojo.subscribe('/dnd/move/stop', function(mover)
       {
           // rozpoznanie okna
           if (mover.node.id === dialog.id)
           {
               dialog.onMove();
           }
       });
       dialog.startup();
       dialog.show();

       return dialog;
    }
    var x = createDijitDialogWithOnMoveEvent("dijit.Dialog.onMove", "Witaj świecie!");
    dojo.connect(x, 'onMove', function()
    {
        alert('poruszyłeś mnie!');
    });
});

demo online

Każdy widget dojo posiada swój unikalny id. Pozwala to podczas odczytywania z kanału sprawdzić, czy mamy do czynienia z tym oknem, o które aktualnie nam chodzi.

Następnie przypisanie odpowiedniej funkcji obsługi zdarzenia jest już formalnością. Opis mechanizmy dojo.connect/disconnect można znaleźć w jednym z wcześniejszych wpisów:

*A niech będzie – tu się wyżyję. Dojo Toolkit do wersji 1.6 posiadał bardzo przyjemną i ułatwiającą życie dokumentację (linkowany przykład `dijit.Menu’) w postaci opis-przykład-kod do skopiowania. W 1.7 stwierdzono chyba, że życie programisty nie może być takie piękne i zdecydowanie zepsuto IMVHO bardzo przydatne zasoby – dla kontrastu ten sam dijit, dokumentacja w wersji 1.7 – spróbuj uruchomić przykład lokalnie.

EDIT (2013-02-06): W wersji 1.8 naprawiono wyżej opisane błędy.

W poprzednim wpisie pokazałem jak zbudować drzewo oparte o `dojox.data.JsonRestStore’. W tym wpisie pokażę, jak odświeżać wybraną gałąź tego drzewa.

Scenariusz

Załóżmy, że mamy drzewo, które może być edytowane przez kilka osób równolegle lub też może zmieniać się automatycznie. Jako, że korzystamy z data store’a pozwalającego na lazy loading (ang. późne ładowanie) może się okazać, że dane na serwerze będą inne od tych, jakie przechowujemy lokalnie. Wteyd warto byłoby odświeżyć wybraną gałąź drzewa.

O dziwo nie ma prostej metody `dijit.Tree.refresh(gałąź)’ :/. Można jednak napisać krótki kawałek kodu pozwalający uzyskać oczekiwany efekt.Continue reading

Lazy loading (z ang. późne ładowanie danych – w wolnym tłumaczeniu) pozwala na pobranie do aplikacji z serwera tylko tych danych, które są nam aktualnie niezbędne. Takie podejście oszczędza pamięć i łącze (rzadko kiedy potrzebujemy wczytać cały zbiór danych). Niestety jednocześnie sprawia, że mamy więcej połączeń do serwera – każde zwraca kolejną małą porcję danych.

Chciałbym zaprezentować możliwości lazy loadingu w Dojo Toolkit.

Na początek

Continue reading

Widget dijit.Menu jest bardzo przydatny w wielu przypadkach. Można za jego pomocą zbudować rozwijane menu (opierając całość o dijit.MenuBar), można też zrobić menu kontekstowe, pojawiające się, gdy użytkownik kliknie PPM na jakimś węźle DOM (przykładowe zastowanie tego widgetu jako menu kontekstowego pokazałem we wpisie o menu kontekstowym na drzewie).

W tym wpisie pokażę, jak umieścić w takim menu fragment formularza.

Na początek

Continue reading