Pana azi, lista de colectii online de pattern-uri pentru interfete utilizator pe care as fi recomandat-o cuiva interesat de subiect ar fi fost destul de scurta si compusa din Yahoo! Design Pattern Library si UI-Patterns (iar offline Designing interfaces si Designing Web Navigation ).
La aceasta lista tocmai s-a mai adaugat inca o colectie online foarte utila, bine organizata si cu cea mai frumusica interfata (merita sa imi instalez Silverlight special pentru asta :) ) - Quince, cea mai noua productie Infragistics (de care am aflat prin intermediul blogului lui Chris).
Imi place foarte mult navigatia care permite gasirea unui pattern fie prin cautare dupa cuvinte cheie sau explorarea patternurilor in functie de ce incearca utilizatorul sa obtina (User tasks), dupa tag-uri ( cu o interfata foarte sugestiva) sau dupa schita (wireframe).![]()


Mult mai multe detalii si explicatii pe blogul Infragistics.
Via Design vs Art blog am aflat de Balsamiq,o aplicatie AIR foarte utila celor care lucreaza in web.
Intotdeauna pentru orice site sau orice aplicatie care necesita o interfata, va fi nevoie de o modalitate cat mai usoara pentru a arata clientilor o schita a acesteia si a ilustra vizual componentele principale alea acesteia.
Din cate aplicatii am incercat pana acum in acest sens, am constatat ca PowerPoint si Word sunt destul de rudimentare in timp ce Visio si Photoshop au dezavantajul ca necesita destul de mult timp si munca atat pentru a invata cat si pentru a obtine rezultatul dorit.
Balsamiq in schimb pare solutia ideala :
- usor de invatat
- usor de folosit
- dedicata domeniului web, cu o multitudine de componente specifice
- ieftina
Exemple realizate cu Balsamiq (mai multe pe pagina lor de exemple)

Aspectul nefinisat este intentionat, pentru ca atentia sa se concentreze asupra functionalitatii si nu a graficii.
Balsamiq va scuti ore intregi de munca si modificari ale designului , va clarifica de la inceput un numar suficient de mare de dileme si intrebari; in plus imi pare a fi solutia ideala si pentru teste de utilizabilitate.
Mai multe detalii in articolul original si pe pagina oficiala (demo disponibil cu toate optiunile activate cu exceptia celei de salvare).
Me likey.
Scrisa cu mult simt al umorului, Don't Make Me Think este o carte concisa, antrenanta care condenseaza in 224 de pagini ideile de baza ale uzabilitatii si acesibilitatii site-urilor.Scopul declarat al cartii este sa poata fi citita integral in timpul unei calatorii cu avionul (la mine a durat un pic mai mult - sa zicem cat echivalentul unei calatorii dus-intors cu avionul pana in Spania) ; motto-ul "It's not rocket surgery" si citatele de la inceputul fiecarui capitol ca si notele de subsol demonstreaza ca se poate scrie o carte serioasa si fara sa iti pierzi simtul umorului :) .
Mi-a placut abordarea practica si constructiva (de exemplu ideea de a nu da exemple de site-uri cu multe greseli, ci de site-uri care ar putea fi usor imbunatatite )
Un review mai inspirat aici
AJAX reprezinta probabil cea mai folosita tehnologie in momentul de fata pentru crearea de interfete web cat mai user friendly. Cum cunostintele proprii in aceasta directie inca nu-mi permit sa creez de la zero decat scripturi foarte basic, am descoperit cu bucurie MiniAjax, o colectie de scripturi gratuite, pe cat de utile, pe atat de simplu de implementat.
Mi-au placut ClickHeat, Bubble Tooltips si Carousel.
Design pattern-urile din dezvoltarea software sunt cunoscute de majoritatea programatorilor (de fapt de orice programator care este peste nivelul junior).
Am avut recent placuta surpriza sa dau peste un site de patternuri pentru interfete utilizator : UI Patterns
Cum Stef si Adi isi bat capul de cam 1 an sa ma invete design pattern-urile clasice (si recunosc ca sunt un elev groaznic, cum nu i-as dori nimanui), imi propun sa ma opresc pe viitor si asupra acestor patternuri UI ;)
Acum 2 zile s-a terminat in mod oficial proiectul din care facea parte acest blog, si anume proiectul la Interfete Evoluate (unde am fost premianti :) )
Cu toate acestea, blogul a fost un exercitiu placut pentru mine si il voi continua si in viitor, schimband un pic titlul.
Am inceput 2 posturi, unul pe tema Mac Air, altul cu topul 25 din Infoworld, am primit o sugestie foarte buna de la un prieten pentru un al treilea...material exista, acum nu ramane decat sa gasesc timp.
But I will be back :)
Din categoria pareri personale :)
In timpul facultatii am intalnit printre colegii mei diverse tipologii de oameni - unii mai pasionati de programare, altii mai putin, viitori topcoders, testeri sau arhitecti seniori precum si viitorii consultanti si IT project manageri .
Unul din principalele motive ale alegerii UPB A&C a fost mediul si factorul uman - cred ca este mult mai important sa iti constientizezi valoarea avand ca etalon pe cei mai buni decat sa iti gadili oarecum orgoliul fiind bun printre cei mai slabi.
Una din marile uimiri ale acestui an (vorbind de scoala si colegi) a fost atitudinea refractara la nou a unora (genul care nu sunt dispusi sa faca altceva decat stiu ei la servici..."eu fac java, de ce sa invat javascript, ca nu s-a zis de la inceput" si impresia de superioritate ("cum sa fac o tema cu X ca ala nu ia bursa")...mi se pare extrem de uimitor in continuare, mai ales in conditiile in care am intalnit aceleasi atitudini si la unii colegi de la servici.
Asa ca, insipirandu-ma de pe forumul de la IE m-am gandit ca e o idee buna sa postez urmatorul filmulet
precum si acest link (recomandarile sunt universale, nu doar pentru developerii web).
Think nice positive thoughts guys!
Si pentru ca tot am vorbit de pagini web interactive contruite cu AJAX, DOM si Javascript sa vedem si o aplicatie practica la aceste tehnologii. Ca exemplu o sa folosesc tema de casa 3, care consta dintr-un calendar care afiseaza colorat fiecare zi in care a fost postat un aricol pe acest blog. Un click pe acea data va va trimitie chiar la pagina cu articolul respectiv. Pentru a putea rula aceste scripturi este nevoie de un server web care sa ruleze php, si de Yahoo User Interface Librari (YUI) care poate fi downloadat de aici
calendar.html:
<>
<>
< equiv="Content-Type" content="text/html; charset=ISO-8859-1">
< type="text/css">
/*margin and padding on body element
can introduce errors in determining
element position and are not recommended;
we turn them off as a foundation for YUI
CSS treatments. */
body {
margin:0;
padding:0;
}
< /style>
< rel="stylesheet" type="text/css" href="build/fonts/fonts-min.css">
< type="text/css" rel="stylesheet" href="build/calendar/assets/skins/sam/calendar.css">
< type="text/javascript" src="build/yahoo-dom-event/yahoo-dom-event.js">< /script>
< type="text/javascript" src="build/calendar/calendar.js">< /script>
< type="text/javascript" src="getDates.js">< /script>
< /head>
< class="yui-skin-sam" onload="getDates()">
< id="cal1Container">< /div>
< /body>
< /html>
getDates.js:
var dates;
var xmlHttp;
var calendar;
function createXMLHttp()
{
var xmlHttp;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
return xmlHttp;
}
function getDates()
{
xmlHttp = createXMLHttp();
if (xmlHttp.readyState==4 xmlHttp.readyState==0)
{
var connString="http://localhost/getDates.php";
xmlHttp.onreadystatechange=readDates;
xmlHttp.open("GET",connString,true);
xmlHttp.send(null);
}
}
function readDates()
{
if (xmlHttp.readyState == 4)
{
if(xmlHttp.status == 200)
{
var response = xmlHttp.responseXML;
//alert("avem raspuns!zzz");
dates = response.getElementsByTagName("Date");
var i;
/*
for(i = 0; i < calendar =" new" i =" 0;" selected =" args[0];" i =" 0;" nodevalue ="=" xmlhttp =" createXMLHttp();" readystate="=" readystate="=" connstring="http://localhost/getUrl.php?date=" onreadystatechange="openDocument;" readystate ="=" status ="=" response =" xmlHttp.responseXML;" url =" response.getElementsByTagName(" i =" 0;" dom="new">load('http://interfeteevoluate.blogspot.com/feeds/posts/default',LIBXML_DTDLOAD);
$entries = $dom->getElementsByTagName('entry');
createLinkDocument($entries);
function createLinkDocument($entries)
{
$db = new DOMDocument('1.0', 'iso-8859-1');
$root = $db->createElement('root');
$db->appendChild($root);
foreach($entries as $entry)
{
$date = date_parse($entry->getElementsByTagName('published')->item(0)->nodeValue);
#print $date->item(0)->nodeValue . "\n";
#print_r(date_parse($date->item(0)->nodeValue));
$links = $entry->getElementsByTagName('link');
foreach($links as $link)
{
if(strcmp($link->getAttribute('rel'), 'alternate') == 0)
{
$url = $link->getAttribute('href');
#print $url . "\n";
}
}
$dbEntry = $db->createElement('entry');
$root->appendChild($dbEntry);
$dbEntryDate = $db->createElement('Date', $date['month'].'/'.$date['day'].'/'.$date['year']);
$dbEntry->appendChild($dbEntryDate);
$dbEntryURL = $db->createElement('URL', $url);
$dbEntry->appendChild($dbEntryURL);
}
$db->save("db.xml");
}
?>
getDates.php, folosit la incarcarea paginii pentru a determina zilele in care s-au postat articole:
< ?php $dom=new DOMDocument(); $dom->load('db.xml',LIBXML_DTDLOAD);
$entries = $dom->getElementsByTagName('entry');
$result = createDateDocument($entries);
header('Content-Type: text/xml');
echo $result->saveXML();
function createDateDocument($entries)
{
$db = new DOMDocument('1.0', 'iso-8859-1');
$root = $db->createElement('root');
$db->appendChild($root);
$lastDate = '';
foreach($entries as $entry)
{
$date = $entry->getElementsByTagName('Date')->item(0)->nodeValue;
if(strcmp($date, $lastDate) != 0)
{
$dbEntryDate = $db->createElement('Date', $date);
$root->appendChild($dbEntryDate);
$lastDate = $date;
}
}
return $db;
}
?>
getUrl.php, folosit pentru a afla link-ul catre ultimul articol postat in ziua selectata:
< ?php $dom=new DOMDocument(); $dom->load('db.xml',LIBXML_DTDLOAD);
$entries = $dom->getElementsByTagName('entry');
$date = $_GET['date'];
#$date='12/9/2007';
$result = createDateDocument($entries, $date);
header('Content-Type: text/xml');
echo $result->saveXML();
function createDateDocument($entries, $searchDate)
{
$db = new DOMDocument('1.0', 'iso-8859-1');
$root = $db->createElement('root');
$db->appendChild($root);
foreach($entries as $entry)
{
$date = $entry->getElementsByTagName('Date')->item(0)->nodeValue;
$url = $entry->getElementsByTagName('URL')->item(0)->nodeValue;
if(strcmp($date, $searchDate) == 0)
{
$dbEntryDate = $db->createElement('URL', $url);
$root->appendChild($dbEntryDate);
$lastDate = $date;
}
}
return $db;
}
?>
Tema 2 a fost implementata in Python 2.5 si s-a folosit pentru baze de date sqlite3 (incluse in pachetul standard Python).
Site-ul analizat este www.photosig.com. Programul pleaca de la un user si creeaza lista prietenilor sau a dusmanilor acestuia prin analiza comentariilor de pe ultima poza isncrisa pe site. Procesul se repeta pentru fiecare user.
Iata codul in Python:
#Ionescu Radu-Dragos 351 C2
import urllib, sqlite3
def cautarePoza(id):
#accesez pagina cu toate pozele userului ID si intorc linkul primei poze
aux="http://www.photosig.com/go/users/userphotos?id="+str(id)
fisierHtml = urllib.urlopen(aux)
s = fisierHtml.read()
index = s.find("/go/photos/view;jsessionid")
indexI=s.find("?id=",index+27)
aux=""
idPoza = ""
indexI=indexI+4
while s[indexI]!="&":
idPoza = idPoza + s[indexI]
indexI=indexI+1
return idPoza
def analizaPoza(idPoza):
global db
global userB
aux="http://www.photosig.com/go/photos/view?id="+idPoza+"&forward=user"
fisierHtml = urllib.urlopen(aux)
s = fisierHtml.read()
filename = "test.dat"
FILE = open(filename,"w")
FILE.writelines(s)
FILE.close()
i = s.find("alt=\"Thumb")
if i==-1:
print "Fara comentarii"
return -1
i1 = s.find("alt=\"Thumb", i+9)
while i1!=-1:
iaux = i1 + 11
if s[iaux]=="u":
relatie="prieten"
if s[iaux]=="d":
relatie="dusman"
indexI = s.find("/go/users/view;jsessioniddas",i1)
indexI = s.find("?id=", idUser+ 25)
indexI = indexI+4
idUser = ""
while s[indexI]!="\"":
idUser = idUser + s[idUser]
indexI=indexI+1
print "Iduser = "+idUser
aux = indexI + 2
numeUser=""
while s[aux]!="<": numeUser = numeUser + s[aux] aux = aux+1 # introducere in baza de date url = "http://www.photosig.com/go/users/view?id="+idUser t1 = (idUser,url,numeUser) e = 0 c = db.cursor() c.execute("SELECT oid FROM utilizator") for row in c: if str(row[0])==idUser: e=1 if e==0: c.execute("INSERT INTO utilizator(oid, url_profil, username) VALUES(?,?,?)",t1) f=0 t2 = (idUser, userB, relatie) c.execute("SELECT oid1, oid2 FROM colaborare") for row in c: if str(row[0])==str(idUser): if str(row[1])==str(userB): f=1 if f==0: c.execute("INSERT INTO colaborare(oid1, oid2, detalii_colaborare) VALUES(?,?,?)",t2) t3 = (idUser, url, numeUser) g = 0 c.execute("SELECT username from useri") for row in c: if str(row[0])==numeUser: g=1 if g==0: c.execute("INSERT INTO useri(oid, url_profil, username) VALUES(?,?,?)",t3) i1 = s.find("alt=\"Thumb", aux) #Program principal db = sqlite3.connect('ie.db') cd = db.cursor() limita = 3 userB = "245246" s = cautarePoza(userB) analizaPoza(s) #ne conectam la useri si alegem cate un user #stergem userul dupa i = 0 while i
analizaPoza(s)
print "Tabela utilizator:"
cd.execute("SELECT oid FROM utilizator")
for row in cd:
print row[0]
print "Tabela colaborare:"
cd.execute("SELECT oid1,oid2,detalii_colaborare FROM colaborare")
for row in cd:
print str(row[0])+"-"+str(row[1])+": "+row[2]
print "Tabela useri[neparcursi]:"
cd.execute("SELECT oid FROM useri")
for row in cd:
print row[0]
db.close()
Hello World!
Acest blog face parte din proiectul pentru Interfete Evoluate si va contine articole despre Interfete Evoluate, Interfete Utilizator, Interactiunea om-calculator,XML, DTD, Scripting si programare Web (Javascript, PHP etc), Servicii Web, Web 2.0 samd precum si temele noastre la Interfete Evoluate.
Cine suntem noi?
4 studenti in anul 5 la Facultatea de Automatica si Calculatoare, cu joburi si preocupari diferite, care si-au unit "fortele" pentru proiectul la Interfete Evoluate.
Mai multe despre fiecare, mai jos.
Monica Ionita
Grupa 351 C2
Project Manager pentru acest proiect, in restul timpului student si Junior Project Manager la HP.
Puncte de interes: scripting (Javascript), programare Web.
Sper ca acest proiect sa ma ajute in a invata notiunile de baza de optimizare pentru motoarele de cautare (SEO).
Gabrovschi Catalin
Grupa 354 C3
Student la "Facultatea de Automatica si Calulatoare" si developer la I-Play Romania.
Puncte de interes: Programare paralela, translatoare, sisteme de operare.
In legatura cu proiectul nostru sunt interesat de WAP si voi incerca sa tratez cat mai bine acest subiect.Ionescu Radu-Dragos
Grupa 351 C2
Student la A&C si consultant SAP-SD in cadrul SBSOL Group.
Puncte de interes: modul in care noile tehnologii web influenteaza prezenta anumitor produse pe piata, ultimele moduri de a face reclama
Stiu ca acest proiect ma va ajuta sa imi formez o imagine generala cat mai clara despre rolul promovarii produselor pe Internet, impulsurile utilizatorilor aflati in fata unei decizii, cat si metode de promovare a unui site.
Ionita Daniel
Grupa 353 C2
Student la Facultatea de Automatica si Calculatoare, programator la Capital Software Romania
Puncte de interes - baze de date, OOP
De la proiect sper sa ma lase cu o intelegere mai buna a asa-numitului web 2.0