Aide - Recherche - Membres - Calendrier
Version complète : mise en page style google suggest
Forum Développeur - Administration serveur, programmation et base de données > Programmation > Javascript et AJAX
qwix
Bonjour smile.gif

Voilà pour les besoins d'une appli, j'ai décidé de créer un mini moteur de requête en utilisant les XHR, mais je voudrais que l'afficha se fasse comme dans google suggest, seulement je n'ai aucune idée de comment ils arrivent à faire afficher la liste des résultats comme ils le font.

Pour préciser ma question est au niveau des CSS, côté serveur je m'en charge icon_mrgreen.gif mais le coup de l'affchage de la liste toute propre, ça, ça me bluffe, si jamais quelqu'un à une idée wink.gif

smile.gif
jep
Ben... d'un point de vu strictement CSS, ce n'est pas bien sorcier ! C'est juste une liste (vraissemblablement un tableau) stylisé et c'est tout !

Ce qui est bien bluffant, c'est la gestion de l'affichage... et là, pas de surprise non plus, il y a une grosse utilisation de Javascript. Si j'ai a peu près compris ce qu'ils font, il passe par l'intermediaire d'un iframe (!? solution lourde et inutile !) qu'ils remplisse à grand coup de JS et dans laquel on peut naviguer à la souris ou au clavier (un petite gestion d'evenement pour savoir ce qu'on utilise et où).
qwix
Ha ok, j'avais même pas pensé à ça...

<Boulet inside>

smile.gif
qwix
he he, et hop

Javascript
// Copyright 2004 and onwards Google Inc.
//
// uncompressed / commented / renamed by Chris...
//
 
var w="";
var pa=false;
var _oldInputFieldValue=""; // inputField value (set during call to google...)...(was ta)
var da=false;
var _currentInputFieldValue=""; // also inputField value (was g)
var G="";
var _eventKeycode=""; // event keycode... (was m)
var _highlightedSuggestionIndex=-1; // currently hightlighted suggestion index (was j)
var _highlightedSuggestionDiv=null; // currently highlisted suggestion div... (was h)
var _completeDivRows=-1; // completeDiv rows at time of keypress... (was Z)
var _completeDivDivList=null; // completeDiv div list at time of keypress (was za)
var _completeDivRows2=5; // was Ca... initially 5? not sure difference between this and _completeDivRows...
var q="";
var _divTag="div"; // Was Lb
var _spanTag="span"; // Was Bb
var _documentForm=null; // Form on html page... (was la...)
var _inputField=null; // Input field on form... (was a)
var _completeDiv=null; // document.completeDiv (was b)
var _submitButton=null; // submit button (was Xa)
var mb=null;
var X=null;
var _enString=null; // This becomes the string "en" (was ha)
var _cursorUpDownPressed=false; // Was ra...
var kc=null;
var hc=null;
var _resultCache=new Object(); // This is a cache of results from google... (was Ua)
var ca=1;
var Aa=1;
var Y=false;
var _lastKeyCode=-1; // Gets set on keyDown... Was na...
var Va=(new Date()).getTime();
var _hasXMLHTTP=false; // Gets set to true if XMLHTTP Supported (was Q)
var _xmlHttp=null; // This is the XMLHttp Object... (was k)
var _completeSearchEnString=null; // Gets set to "/complete/search/?hl=en" (was sa)
var _completeSearchString=null; // Gets set to "/complete/search" ... (was E)
var B=null;
var aa=null;
var Ba=false;
var Ka=false;
var p=60;
var _searchString=null; // Gets set to "search" in installAC (was ia)
var ya=null;
var _timeoutAdjustment=0; // timeout adjustment... (was W)... gets adjusted over time...
 
// This is the function that get's called from the google html page...
// Line from page:
// InstallAC(document.f,document.f.q,document.f.btnG,"search","en");
// document.f is the name of the form on the page...
// document.f.q is the input text box on the page...
// -> <input autocomplete="off" maxLength=256 size=55 name=q value="">
// document.f.btnG Google Search button
InstallAC=function(frm,fld,sb,pn,rl,hd,sm,ufn){
_documentForm=frm;
_inputField=fld;
_submitButton=sb;
if(!pn) {
pn="search";
}
_searchString=pn;
var Kb="en|";
var Jb="zh-CN|zh-TW|ja|ko|vi|";
if(!rl||Kb.indexOf(rl+"|")==-1) {
rl="en";
}
_enString=escapeURI(rl);
if(Jb.indexOf(_enString+"|")==-1){
// We won't pass through here...
X=true;
Y=false;
Ba=false
}else{
// but will come through here...
X=false;
if(_enString.indexOf("zh")==0) {
// not here...
Y=false;
} else {
// but here...
Y=true;
}
Ba=true
}
// hd is not defined, so becomes false...
if(!hd) {
hd=false;
}
ya=hd;
 
// sm not defined, so becomes the string "query"
if(!sm) {
sm="query";
}
w=sm;
 
// ufn is not defined...
mb=ufn;
 
installACPartTwo()
}
;
 
// blurs focus, then sets focus again...
// This is getting aclled when we press cursor up / cursor down...
// Was Yb...
function blurThenGetFocus(){
_cursorUpDownPressed=true;
_inputField.blur();
setTimeout("setInputFieldFocus();",10);
return
}
 
// setup a keydown event...
// Was Fb...
function setupKeydown1(){
if(document.createEventObject) {
var y=document.createEventObject();
y.ctrlKey=true;
y.keyCode=70;
document.fireEvent("onkeydown",y)
}
}
 
// setup a keydown event...
// I can't figure out what calls this...
// was nc...
function setupKeydown2(vb){
var y=document.createEventObject();
y.ctrlKey=true;
y.keyCode=vb;
document.fireEvent("onkeydown",y)
}
 
function gc(event){}
function ic(event){}
 
// Was Pb
function keyDownHandler(event){
if(!event&&window.event) {
event=window.event;
}
if(event) {
_lastKeyCode=event.keyCode;
}
 
// We are backspacing here...
if(event&&event.keyCode==8){
if(X&&(_inputField.createTextRange&&(event.srcElement==a&&(bb(_inputField)==0&&lb(_inputField)==0)))){
cc(_inputField);
event.cancelBubble=true;
event.returnValue=false;
return false
}
}
}
 
function mc(){}
 
// Was Db..
function resizeHandler(){
if(w=="url"){
setInputFieldSize()
}
setCompleteDivSize()
}
 
// was ba...
function setCompleteDivSize(){
if(_completeDiv){
_completeDiv.style.left=calculateOffsetLeft(_inputField)+"px";
_completeDiv.style.top=calculateOffsetTop(_inputField)+_inputField.offsetHeight-1+"px";
_completeDiv.style.width=calculateWidth()+"px"
}
}
 
// calculate width of inputField... Note browser specific adjustments...
// Was Ja()
function calculateWidth(){
if(navigator&&navigator.userAgent.toLowerCase().indexOf("msie")==-1){
return _inputField.offsetWidth-ca*2
}else{
return _inputField.offsetWidth
}
}
 
 
// Called from InstallAC...
// was ac()
function installACPartTwo(){
if(getXMLHTTP()){
_hasXMLHTTP=true
}else{
_hasXMLHTTP=false
}
 
// pa init'd to false at the top of this file...
if(pa) {
_completeSearchString="complete";
} else {
_completeSearchString="/complete/"+_searchString;
}
 
_completeSearchEnString=_completeSearchString+"?hl="+_enString;
 
if(!_hasXMLHTTP){
setCookie("qu","",0,_completeSearchString,null,null)
}
 
_documentForm.onsubmit=Fa;
_inputField.autocomplete="off";
_inputField.onblur=onBlurHandler;
if(_inputField.createTextRange) {
_inputField.onkeyup=new Function("return okuh(event);");
} else {
_inputField.onkeyup=okuh;
}
_inputField.onsubmit=Fa;
_currentInputFieldValue=_inputField.value;
_oldInputFieldValue=_currentInputFieldValue;
_completeDiv=document.createElement("DIV");
_completeDiv.id="completeDiv";
ca=1;
Aa=1;
_completeDiv.style.borderRight="black "+ca+"px solid";
_completeDiv.style.borderLeft="black "+ca+"px solid";
_completeDiv.style.borderTop="black "+Aa+"px solid";
_completeDiv.style.borderBottom="black "+Aa+"px solid";
_completeDiv.style.zIndex="1";
_completeDiv.style.paddingRight="0";
_completeDiv.style.paddingLeft="0";
_completeDiv.style.paddingTop="0";
_completeDiv.style.paddingBottom="0";
setCompleteDivSize();
_completeDiv.style.visibility="hidden";
_completeDiv.style.position="absolute";
_completeDiv.style.backgroundColor="white";
document.body.appendChild(_completeDiv);
cacheResults("",new Array(),new Array());
Gb(_completeDiv);
var s=document.createElement("DIV");
s.style.visibility="hidden";
s.style.position="absolute";
s.style.left="-10000";
s.style.top="-10000";
s.style.width="0";
s.style.height="0";
var M=document.createElement("IFRAME");
M.completeDiv=_completeDiv;
M.name="completionFrame";
M.id="completionFrame";
M.src=_completeSearchEnString;
s.appendChild(M);
document.body.appendChild(s);
if(frames&&(frames["completionFrame"]&&frames["completionFrame"].frameElement)) {
B=frames["completionFrame"].frameElement;
} else {
B=document.getElementById("completionFrame");
}
if(w=="url"){
setInputFieldSize();
setCompleteDivSize()
}
window.onresize=resizeHandler;
document.onkeydown=keyDownHandler;
setupKeydown1()
}
 
// Was Ob
function onBlurHandler(event){
if(!event&&window.event) {
event=window.event;
}
if(!_cursorUpDownPressed){
hideCompleteDiv();
// check if tab pressed...
if(_lastKeyCode==9){
setSubmitButtonFocus();
_lastKeyCode=-1
}
}
_cursorUpDownPressed=false
}
 
okuh=function(e){
_eventKeycode=e.keyCode;
aa=_inputField.value;
Oa()
}
;
// Was Xb...
function setSubmitButtonFocus(){
_submitButton.focus()
}
 
// Was sfi..
setInputFieldFocus=function(){
_inputField.focus()
}
;
 
// strip CR from string...
// was Wb
function stripCRFromString(va){
for(var f=0,oa="",zb=" "; f<va.length; f++) {
if (zb.indexOf(va.charAt(f))==-1) {
oa+=va.charAt(f);
} else {
oa+=" ";
}
}
return oa
}
 
// Find span value with className = dc...
// Was Qa
function findSpanValueForClass(i,dc){
var ga=i.getElementsByTagName(_spanTag);
if(ga){
for(var f=0; f<ga.length; ++f){
if(ga[f].className==dc){
var value=ga[f].innerHTML;
if(value=="&nbsp;") {
return"";
} else{
var z=stripCRFromString(value);
return z
}
}
}
}else{
return""
}
}
 
// Return null if i undefined...
// otherwise return value of span cAutoComplete...
// was U
function valueOfCAutoComplete(i){
if(!i) {
return null;
}
return findSpanValueForClass(i,"cAutoComplete")
}
 
// Return null if i undefined...
// otherwise return value of span dAutoComplete...
// was wa
function valueOfDAutoComplete(i){
if(!i) {
return null;
}
return findSpanValueForClass(i,"dAutoComplete")
}
 
// Was F
function hideCompleteDiv(){
document.getElementById("completeDiv").style.visibility="hidden"
}
// Was cb
function showCompleteDiv(){
document.getElementById("completeDiv").style.visibility="visible";
setCompleteDivSize()
}
 
// This is a result caching mechanism...
// was Ma
function cacheResults(is,cs,ds){
_resultCache[is]=new Array(cs,ds)
}
 
// We get the following javascript code dynamically returned from google:
// sendRPCDone(frameElement, "fast bug", new Array("fast bug track", "fast bugs", "fast bug", "fast bugtrack"), new Array("793,000 results", "2,040,000 results", "6,000,000 results", "7,910 results"), new Array(""));
sendRPCDone=function(fr,is,cs,ds,pr){
if(_timeoutAdjustment>0) {
_timeoutAdjustment--;
}
var lc=(new Date()).getTime();
if(!fr) {
fr=B;
}
cacheResults(is,cs,ds);
var b=fr.completeDiv;
b.completeStrings=cs;
b.displayStrings=ds;
b.prefixStrings=pr;
displaySuggestedList(b,b.completeStrings,b.displayStrings);
Pa(b,valueOfCAutoComplete);
if(_completeDivRows2>0) {
b.height=16*_completeDivRows2+4;
} else {
hideCompleteDiv();
}
}
 
function Oa(){
// 38 is up cursor key, 40 is down cursor key...
if(_eventKeycode==40||_eventKeycode==38) {
blurThenGetFocus();
}
var N=lb(_inputField);
var v=bb(_inputField);
var V=_inputField.value;
if(X&&_eventKeycode!=0){
if(N>0&&v!=-1) {
V=V.substring(0,v);
}
if(_eventKeycode==13||_eventKeycode==3){
var d=_inputField;
if(d.createTextRange){
var t=d.createTextRange();
t.moveStart("character",d.value.length);
t.select()
} else if (d.setSelectionRange){
d.setSelectionRange(d.value.length,d.value.length)
}
} else {
if(_inputField.value!=V) {
selectEntry(V)
}
}
}
_currentInputFieldValue=V;
if(handleCursorUpDownEnter(_eventKeycode)&&_eventKeycode!=0) {
Pa(_completeDiv,valueOfCAutoComplete)
}
}
 
function Fa(){
return xb(w)
}
 
function xb(eb) {
da=true;
if(!_hasXMLHTTP){
setCookie("qu","",0,_completeSearchString,null,null)
}
hideCompleteDiv();
if(eb=="url"){
var R="";
if(_highlightedSuggestionIndex!=-1&&h) {
R=valueOfCAutoComplete(_highlightedSuggestionDiv);
}
if(R=="") {
R=_inputField.value;
}
if(q=="") {
document.title=R;
} else {
document.title=q;
}
var Tb="window.frames['"+mb+"'].location = ""+R+'";';
setTimeout(Tb,10);
return false
} else if(eb=="query"){
_documentForm.submit();
return true
}
}
 
newwin=function(){
window.open(_inputField.value);
hideCompleteDiv();
return false
}
;
 
idkc=function(e){
if(Ba){
var Ta=_inputField.value;
if(Ta!=aa){
_eventKeycode=0;
Oa()
}
aa=Ta;
setTimeout("idkc()",10)
}
}
;
setTimeout("idkc()",10
qwix
Encore mieux:
http://ajax.zervaas.com.au/examples/GoogleSuggestCloneJax/

smile.gif
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'informations, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2009 Invision Power Services, Inc.