piątek, 28 października 2011

Przekazywanie parametrów w kodzie HTML

Przekazywanie dodatkowych parametrów, które winny być uwzględnione w procesie tworzenia strony wydaje się trywialnym zagadnieniem. Takie dodatkowe parametry są potrzebne, gdy nie można (lub jest utrudnione) wstawienie odpowiedniej dane bezpośrednio do źródła HTML. Przykładem może strona główna z aplikacji invoicer, która do programu zadawana jest jako szablon, na której chcemy umieścić aktualny numer wersji programu. Jedno z rozwiązań polega na sparsowaniu pliku szablonu, odszukaniu słów kluczowych i na ich podstawie modyfikacji go w locie. Poniżej fragment kodu z ustawień bloggera.

body {
  font: $(body.font);
}


Zamiast opracować odpowiednią notację szablonu, umożliwiającą programowi sparsowanie szablonu i jej zaimplementowanie, znalezienie odpowiedniego miejsca i wstawienie numeru można zlecić przeglądarce.



tworzenie szablonu

Szablon strony głównej
W źródle szablonu tworzymy własny element wyświetlający nr wersji, jedynym elementem wyróżniającym jest id

<span id="md-version"><a href="http://www.invoicer.pl"><div > &nbsp;</div></a></span>




przygotowanie skryptów


Równolegle do szablonu tworzony jest funkcja w skrypcie, której celem przeniesienie parametru

function StartMain(){
..
try{
  var xUser=document.getElementById('idversion').innerHTML;
   document.getElementById('md-version').innerHTML=xUser;
} catch(ee) { };
..
}



Aby uniezależnić się od konstrukcji szablonu, który może zwyczajnie nie przewidywać miejsca na nr wersji dobrze jest wyłapać wyjątek. Wtedy nie będzie to miało wpływu na pozostałe części skryptu.


To co musi zrobić program:

Przed wysłaniem strony do szablonu doklejane są dodatkowe informacje konieczne do zbudowania poprawnej strony. Przyjęto konwencję że szablon zawiera sekcję body docelowej strony, a aplikacja jest odpowiedzialna za uzupełnienie kodu początkowego i końcowego. Ponieważ przyjęto również zasadę pomijania tagu body aplikacja może swobodnie uzupełnić kod o dodatkowe parametry.

'<body onload="StartMain();" oncontextmenu="return true;">'
....
'<div id="idversion" style="display:none;">Invoicer 248</div>';



Początkowo próbowałem przesyłać parametry w sekcji head jako elementy meta, niestety metoda ta nie jest akceptowana przez wszystkie przeglądarki. Dlatego pewniejsze jest wykorzystanie niewyświetlanych elementów div style="display:none"


Funkcja startMain jest wywoływana przez przeglądarkę po załadowaniu strony. Przyjąłem konwencję że jest ona definiowana w pliku o nazwie takiej samej jak nazwa pliku szablonu (tylko rozszerzenie zmienione na ".js").

Funkcja podpięta do onload w nagłówku body wywoływana jest jedynie przy pełnym wywołaniu strony konieczne jest również wywołanie jej przy aktualizacji asynchronicznej via XMLHttpRequest, ale to już należy wbudować w procedurę obsługi.


rezultat

portal Inbira

Technika ta została zastosowana również do przekazywania loginu, bazy danych, wersji językowej.

środa, 26 października 2011

XMLHttpRequest

W kolejnym poście zajmę się podstawowym elementem aplikacji internetowej, tym, dzięki któremu strony HTML ożyły. Chodzi o możliwość wykonywania asynchronicznych odwołań do serwera, inicjowanych przez skrypty w JavaScript. Bez takiej funkcji przeglądarka może jedynie prezentować strony, ładując kolejne wtedy i tylko wtedy gdy użytkownik nacisnął na odnośnik. Dodatkowo to program decyduje, co ma zrobić z otrzymaną odpowiedzią, jak ją zinterpretować. Odpowiedź nie musi już być pełną stroną HTML, nawet nie musi zawierać kodu HTML. Może być zakodowana w XML, JSON lub dowolnie innym formacie, byle tylko program był na to przygotowany.

var http = getHTTPObject();

function getHTTPObject() {
  var xmlhttp;
  /*@cc_on
  @if (@_jscript_version >= 5)
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
        xmlhttp = false;
      }
    }
  @else
  xmlhttp = false;
  @end @*/
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    try {
      xmlhttp = new XMLHttpRequest();
    } catch (e) {
      xmlhttp = false;
    }
  }
  return xmlhttp;
}

function httpget(aUrl){
 http.open("GET",aUrl,true);
 http.onreadystatechange = handleHttpResponse;
 http.send(null);
 return false;
}




Do realizacji zapytań należy utworzyć obiekt http;


Zapytania sekwencyjne


Zapytania wysyłane przez przeglądarkę nie są realizowane natychmiast. A dokładniej to wysyłając zapytanie program nie czeka na odpowiedź, ta przychodząc wywołuje wskazane zdarzenie. Pomiędzy tymi dwoma momentami upływa pewien okres czasu. Jeżeli czas ten jest stosunkowo długi (np. z powodu wolnej sieci albo przeciążonego serwera albo po prostu przetworzenie zajmuje czas) to może się zdarzyć że nastąpi kolejna inicjacja zapytania zanim poprzednie zostanie zakończone. Przeglądarka domyślnie porzuca (przerywa) poprzednie zapytanie i rozpoczyna realizację nowego. Jest to podyktowane naturalnym schematem przeglądania internetu. Jeżeli jakaś strona ładuje się zbyt długo albo została wywołana przez pomyłkę to naciśnięcie kolejnego odnośnika spowoduje rozpoczęcie kolejnego zapytania z jednoczesnym przerwaniem poprzedniego. Takie przerwanie nie powoduje większych problemów, gdyż odpowiedź zazwyczaj stanowi pełną całość i wystarcza do wygenerowania nowego obrazu.

O ile podczas przeglądania internetu ignorowanie niektórych zapytań nie powoduje skutków ubocznych, to w przypadku aplikacji internetowych sprawa ma się inaczej. Każde zapytanie, a dokładniej każda uzyskana odpowiedź ma wpływ na końcowy rezultat. Szczególnie to jest widoczne przy obsłudze klawiatury. Kolejne zdarzenia (tj. naciśnięcia klawiszy) mogą następować bardzo szybko po sobie, szybciej niż typowy czas odpowiedzi serwera. Kilkadziesiąt milisekund, dzielące kolejne uderzenia w klawisz jest niewystarczające na efektywne skomunikowanie się z serwerem, do którego przeciętny czas samego przesłania informacji (mierzony usługą ping) wynosi 100 i więcej milisekund. Wymuszenie kolejnego zapytania przerywa oczekiwanie na odpowiedź, co też wymaga poinformowania serwera o tym fakcie. Do analizy tego typu zjawisk przydatny jest firebug.com. Wszystkie przerwane zapytania są oznaczone statusem aborted.

Współbieżność

Ponieważ zablokowanie możliwości wysyłania zapytań przed powrotem poprzedniej odpowiedzi znacząco zmniejszyło by wygodę działania programu należało poszukać innych rozwiązań. Ponieważ do obsługi połączeń wykorzystywane jest opisany powyżej obiekt http oczywiste jest że ograniczenie leży w jego strukturze wewnętrznej. Ponieważ nie można zmusić go w prosty sposób do obsługi wielu połączeń jednocześnie to może można utworzyć wiele takich obiektów i w ten sposób uzyskać współbieżność. Okazało się to skutecznym rozwiązaniem (kod poniżej).


var http2 = getHTTPObject();
var http3 = getHTTPObject();


function httpswap(aUrl){
   httpswapid+=1;
 if ((httpswapid  %  3) == 0 )
   {return  httpget(aUrl);}
 else if ((httpswapid  %  3) == 1 )
   {return  httpget2(aUrl);}
 else
   {return  httpget3(aUrl);};
}



function httpget2(aUrl){
 http2.open("GET",wjakie_id,true);
 http2.onreadystatechange = handleHttpResponse2;
 http2.send(null);
 return false;
}

function handleHttpResponse() {
  if (http.readyState == 4) {    handleResponse(http.responseText);  }
}

function handleHttpResponse2() {
   if (http2.readyState == 4) {   handleResponse(https.responseText); }
 }

Zostały utworzone jeszcze dwa takie obiekty (łącznie 3),
funkcje wołania zapytań z httpget zamieniono na httpswap, która rozdzielała kolejno zapytania do poszczególnych obiektów. Każdy z nich samodzielnie czekał na odpowiedź, gdy ją otrzymał wywoływał funkcję przetwarzającą.

Rezultat



Uzyskano znacznie lepszą użyteczność programu. Mimo realnie istniejącego znacznego opóźnienia odpowiedzi (porównując aplikację webową do stacjonarnej, desktopowej) sposób obsługi znacząco się upodobnił. Prawdopodobnie wynika to z możliwości szybkiego wprowadzania poleceń bez oczekiwania na wynik, tzn. czas oczekiwania rzędu kilkuset milisekund, przy pewności że wszystkie wysłane w tym czasie polecenia zostały przetworzone jest akceptowalny. Natomiast pomyłki wynikające z pominięcia niektórych poleceń przez przeglądarkę przeszkadzają w intensywnej pracy na aplikacji

poniedziałek, 24 października 2011

Kontrolka wyboru wyboru z listy

Formularze aplikacji składają się z szeregu pól. Sam HTML ma wbudowany szereg elementów podstawowych takich jak pole tekstowe, wyboru czy też checkbox. W realnej aplikacji to nie wystarcza. Dlatego też większość programów posiada własne kontrolki, których wygląd i zachowanie jest dopasowane do charakteru całości. Jedną z takich kontrolek przedstawię poniżej. Jej zadaniem jest umożliwienie wybrania pozycji z listy (czyli tabelki lub gida, która jest wyświetlana w odrębnym oknie).

 Kontrolka jest stosunkowo prosta: składa się z dwu elementów. Ikony w kształcie strzałki, służącej do przejścia do okna z listą oraz tytułu aktualnie wybranej pozycji. Kod HTML dla powyższego przykładu, obramowanie, wyrównanie jest trywialny więc nie będę go omawiał.

zwiększanie funkcjonalności

Taką kontrolkę możemy wzbogacić o dodatkową funkcjonalność, podnoszącą ergonomię programu. Przykładowo częstym działaniem użytkownika jest potrzeba dopisania nowej pozycji i następnie wybrania jej.



Dodanie przycisku dodaj wydaje się oczywiste. Ale tak nie jest. Taki dodatkowy przycisk to strata cennego miejsca na ekranie oraz drobna utrata czytelności.
Natomiast możemy skonstruować kontrolkę dynamicznie zmieniającą się pod wpływem działania użytkownika. W tym przykładzie Przycisk DODAJ wraz z tytułem ukazuje się dopiero gdy użytkownik najedzie na na pole. Gdy myszka jest poza to kontrolna jest w swojej podstawowej, surowej formie. Taka zmienność naturalnie podkreśla i uwypukla dodatkową funkcjonalność.

kod css


.fieldpicksupp{
position: absolute;
right:0;
top:0;
height:100%;
width:60px;
background:url(mark16.png) no-repeat right top;
display:none;
}

.fieldpick:hover .fieldpicksupp{ display:block;}

Powyżej jest zawarty fragment kodu css. Nie jest to gotowy przykład, myślę jednak że taki fragment wystarczy do przekazanie podstawowej idei. Dość powiedzieć że fieldpick jest identyfikatorem klasy kontrolki, a fieldpicksupp identyfikatorem klasy przypisanej do fragmentu mającego się ujawnić gdy użytkownik najedzie na kontrolkę. Cała dynamika uzyskana jest poprzez wykorzystanie pseudo klasy :hover, dzięki której możemy przypisać różne atrybuty kontrolce w zależności od akcji użytkownika. Dzięki jej istnieniu całe zagadnienie sprowadza się do kilku deklaracji w CSS, nie musimy zupełnie zaprzęgać do tego języka skryptowego.


cieniowanie


Dodanie nowego elementu do kontrolki, który przykrywa (chociaż tylko czasami) tytuł zmniejsza użyteczność programu. Aby to ograniczyć można spowodować aby ten dodatkowy element stał się półprzeźroczysty. Przy odpowiednio dobranych parametrach widzimy i pełny tytuł i ukazujący się przycisk.


.fieldpicksupp span{
background: -moz-linear-gradient(left, rgba(159,210,204,0.9), rgba(235,255,255,0.3));
background: -webkit-gradient(linear,left top ,right top, from( rgba(159,210,204,0.8)), to(rgba(235,255,255,0.3)));
}

Aby podkreślić walory estetyczne wykorzystano gradientowe wypełnienie tła. Jest to jedno z możliwości wprowadzonych w HTML5, dostępnych w przeglądarkach opartych o Mozillę oraz WebKit. Niestety nie jest to jeszcze zatwierdzony standard, więc wpisy są oddzielne dla każdej z przeglądarek (każdy ma indywidualny prefix).

podsumowanie

Powyżej przedstawiono przykład rozbudowy kontrolki. Dokonano jej poprzez dodanie kilku deklaracji w CSS. Takie deklaratywne podejście ma szereg zalet. Po pierwsze jest czytelniejsze od analogicznego zapisu w Javascript. Po drugie Nie musimy się martwić o zgodność z przeglądarką, zgodnie z przyjętą regułą przeglądarka ignoruje wpisy których nie rozumie. Po drugie może być szybsze (teraz lub w przyszłości) gdyż przeglądarka może przeanalizować występujące deklaracje i przygotować wymagane elementy. Przy skryptach ogólnego przeznaczenia jest to utrudnione. Po trzecie mamy program naturalnie dopasowujący się do możliwości komputera. Gradienty, cieniowania itp mogą zostać pominięte na słabszych urządzeniach.

niedziela, 23 października 2011

Odnośniki w HTML

Odnośniki, czyli znaczniki HTML <a>, są jednym z podstawowych elementów języka HTML. W zasadzie stanowią one podstawę hipertekstu i umożliwiają poruszanie się w globalnej sieci. Ich działanie polega na tym, że po aktywacji następuje przeniesienie do innego miejsca w sieci określonego adresem URL. W przypadku aplikacji internetowych odnośniki mają kilka istotnych wad.

Przeładowanie strony

Standardowe działanie przeglądarki, polegające na prezentowaniu kolejnych stron HTML, wywoływanych poprzez naciśnięcie na odnośniku jest zupełnie rożne od działania zwyczajnego programu GUI. Aplikacje Windows (i nie tylko) są zorganizowane w okna, które pojawiają się, znikają lub tylko zmieniają swoją zawartość pod wpływem działań operatora. Rzadko następuje całkowita zmiana zawartości ekranu. Dlatego też należało zmienić sposób nawigowania po stronie HTML, która miała być aplikacją internetową. Z pomocą przyszła możliwość asynchronicznych wywoływać HTTP z JavaScriptu, chodzi o XMLHttpRequest ale o tym innym razem. Aby to jednak zadziałało należało zmienić sposób wołania odnośników.

<a href="#" onClick="validateLogin();">

Jak widać parametr href został niejako pominięty (ustawiony pusty) natomiast wykorzystano zdarzenie onCLick, które wywołuje wskazaną funkcję. Takie rozwiązanie jest bliższe aplikacyjnemu: w zależności od potrzeb możemy decydować co ma się zdarzyć po naciśnięciu odnośnika, wcale nie musi to być przejście do nowej strony (praktycznie nigdy nie jest).

Klawiatura

Klawiatura jest to jedno z narzędzi pośredniczące w komunikacji pomiędzy użytkownikiem a programem. Służy do wprowadzania informacji, szczególnie tekstowej, przez człowieka, oraz sterowania programem. Rozwój komputerów przyniósł inne urządzenia, takie jak myszka czy ekrany dotykowe, które przejęły część zadań klawiatury. Eksperymentalnie możliwe jest również sterowanie głosem czy gestami, ale do tej pory klawiatura jest istotnym, a w wielu przypadkach podstawowym interfejsem programu.

Klawiatura w przeglądarkach domyślnie jest podporządkowana przeglądaniu hipertekstu. Całe szczęście że w podstawowych aspektach nie różni się od zwykłych desktopowych programów. Zawiera pola <input> służące do wprowadzania danych, przyjmuje znaki wysyłane przez klawiaturę i wprowadza je w miejsce oznaczone kursorem na ekranie. Niestety kilka szczegółów działa inaczej. Oprócz pól tekstowych , które naturalnie przyjmują sterowanie z klawiatury są jeszcze odnośniki , które również mogą być kontrolowane klawiaturą. Przy normalnym używaniu przeglądarki do przeglądania stron internetowych takie działanie jest jak najbardziej pożądane. Natomiast w przypadku aplikacji internetowych sprawa ma się inaczej. Programy winne być ergonomiczne, dopracowane w każdym elemencie, w tym w sposobie nawigacji.

Nawigacja tabulatorem

Podstawowym sposobem przechodzenia pomiędzy polami <input> jest tabulator. Zazwyczaj jednak na ekranie oprócz takich pól znajduje się jeszcze szereg elementów takich jak klawisze, linki, menu, które służą do sterowania programem. Naturalnym podejściem jest wykorzystanie do ich utworzenia znacznika <a>, którego wywołanie spowoduje wykonanie określonej akcji. Niestety znaczniki te łamią oczekiwaną przez użytkownika zasadę, "chodzenia" kursorem wyłącznie po polach. Program jest wtedy wygodniejszy w obsłudze.

Rozwiązanie

<div id="dfaB73D7E80" class="buttonup klawisz">

<div onclick="return wlk('aB6CF4EB0.html?procedura=L;komenda=311);">

</div>

Rozwiązanie które przyjąłem jest dosyć drastyczne. Ponieważ nie mogłem zmienić zachowanie odnośników praktycznie wszystkie wyrzuciłem. Wystarcza używanie podstawowych elementów strony takich jak DIV i SPAN z podpiętymi zdarzeniami. Czasami tak trudno jest zmienić własności danego elementu, że prościej zbudować nowy, od podstaw. Oczywiście w pewnych miejscach nadal używam odnośników. Tam gdzie celem jest przejście do innej witryny są niezastąpione, gdyż programowe rozwiązania są zazwyczaj ułomne ze względu na ograniczenia narzucane przez reguły bezpieczeństwa obowiązujące przeglądarki. Wszędzie indziej rozwiązania programowe dają większą kontrolę nad działaniem programu

piątek, 21 października 2011

Powitanie

O mnie
W pierwszym poście wypada się przedstawić. Mam na imię Darek. Moją pasją jest programowanie i tego ma właśnie dotyczyć niniejszy blog. Długo się zastanawiałem o czym mógłbym pisać. Z uwagi na doświadczenie jest wiele obszarów, na temat których mógłbym się wypowiadać, tylko że wiele z nich jest bardzo specjalistycznych, co czyni je nieinteresującymi dla szerszego kręgu. Wiele technologii, które używałem, są już dzisiaj niepopularne. Ale w końcu pojawiła się nowa możliwość: tworzenie aplikacji internetowych i jest to obszar w którym ostatnio na świecie najwięcej się dzieje.

Aplikacje internetowe
Języki HTML, CSS i Javascript stały się powszechnym sposobem tworzenia, a przeglądarki - najszybciej rozwijającymi się programami. Nastąpiło niesamowite przeobrażenie Internetu jako globalnej sieci. Strony WWW przestały być folderami zawierającymi treści multimedialne. Stały się środowiskiem umożliwiającym działanie programów komputerowym niemal tak samo jak w układzie klasycznym - desktopowym.


Oczywiście nie nastąpiło to od razu. Aplikacje posiadające GUI, w większości napisane pod system Windows realizowały dosyć skomplikowaną interakcję z użytkownikiem. Do tego część zadań wykonywane było przez system operacyjny i inne oprogramowanie z nim zintegrowane. Przeniesienie tego wszystkiego do zupełnie innego ekosystemu (czyli na platformę WWW) kilka lat temu wydawało się nierealne. Internet był przeznaczony do innego celu - do komunikacji. Natomiast życie potoczyło się inaczej. Trudny do przecenienia potencjał internetu, jego niewątpliwe atuty związane z szybkością i łatwością przekazu dowolnej informacji do dowolnej osoby, spowodowały że pozostałe ograniczenia stały się jedynie wyzwaniem do pokonania. Krok po kroku, element po elemencie aplikacje internetowe są coraz lepsze, mają coraz mniej wad, a coraz więcej zalet, gdy je porównamy z aplikacjami desktopowymi.

Obecne aplikacje internetowe oferują niemal taką samą użyteczność
Porównując program invoicer w wersji desktop z wersją portalową na pierwszy rzut oka nie znajdziemy istotnych różnic w funkcjonalności. Samo ujednolicenie czy zmiana platformy nie jest celem ostatecznym tylko etapem rozwoju. Patrząc na rozwój Internetu, tempo zmian nie tylko sprzętu ale i społeczności, można postawić tezę że  aplikacje internetowe dopiero są w środku drogi rozwoju. O tym świadczą zarówno miliony aplikacji, tworzonych wyłącznie na platformę webową, jak i narastający ruch przenoszenia aplikacji klasycznych do internetu. Robią to nie tylko nowo powstałe firmy, popularnie zwane startup-ami, ale też wielkie korporacje, wyrosłe na klasycznych aplikacjach.

Nawet Microsoft, który jest niejako właścicielem obecnego największego ekosystemu obejmującego twórców i użytkowników programów pracujących w systemie Windows, ponosi znaczne wysiłki i inwestycje w celu wejścia do internetu.Należy tu wskazać dwa składniki. Pierwszy to przeglądarka: Internet Explorer, najnowsze jego wersje coraz lepiej spełniają wymagania otwartych standardów. Jest to olbrzymi sukces środowiska, które wymusiło na gigancie otwartość w miejsce tworzenia zamkniętych, niestandardowych rozwiązań w celu utrzymania kontroli nad przyszłymi użytkownikami. Równocześnie jest to dowód, że aplikacje internetowe stanowią w opinii Microsoftu bardzo ważny element, gdyż jak inaczej wytłumaczyć olbrzymie inwestycje w tworzenie programu, który następnie jest nieodpłatnie udostępniany?

Drugim dowodem na wzrost popularności aplikacji webowych jest uruchomienie serwisu office365. Najbardziej intratny składnik aktywów, program najbardziej związany z systemem Windows, czyli Microsoft Office zostaje przeniesiony do sieci. Mimo oporów, ujawniających się w postaci kpin słanych w kierunku alternatywnych serwisów udostępnianych przez konkurencje (takich jak Google Doc czy Zoho) korporacja dokonała zwrotu i udostępniła program nowej postaci: czyli z dostępem przez przeglądarkę.

I podsumowanie
To tylko kilka argumentów, dlaczego aplikacje internetowe. W następnych postach przedstawię już konkretne, techniczne elementy, które stosuję w tworzonych aplikacjach. Mam nadzieję że komuś się to przyda albo kogoś zainspiruję. To tyle wstępu.