Changeset 2c8e84c in github


Ignore:
Timestamp:
Nov 23, 2008 7:38:44 AM (5 years ago)
Author:
thomascube <thomas@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
69ad1e8
Parents:
b4b31d62
Message:

Do serverside addressbook queries for autocompletion (#1485531) + make autocompletion list clickable

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    rd59aaa1 r2c8e84c  
    11CHANGELOG RoundCube Webmail 
    22--------------------------- 
     3 
     42008/11/23 (thomasb) 
     5---------- 
     6- Do serverside addressbook queries for autocompletion (#1485531) 
    37 
    482008/11/23 (alec) 
  • config/main.inc.php.dist

    rd59aaa1 r2c8e84c  
    280280 *  'scope'         => 'sub',   // search mode: sub|base|list 
    281281 *  'filter'        => '',      // used for basic listing (if not empty) and will be &'d with search queries. example: status=act 
    282  *  'global_search' => true,    // perform a global search for address auto-completion on compose 
    283282 *  'fuzzy_search'  => true);   // server allows wildcard search 
    284283 */ 
     284 
     285// An ordered array of the ids of the addressbooks that should be searched 
     286// when populating address autocomplete fields server-side. ex: array('sql','Verisign'); 
     287$rcmail_config['autocomplete_addressbooks'] = array('sql'); 
    285288 
    286289// don't allow these settings to be overriden by the user 
  • program/js/app.js

    rd59aaa1 r2c8e84c  
    459459    { 
    460460    var handler = function(e){ return ref.ksearch_keypress(e,this); }; 
    461     var handler2 = function(e){ return ref.ksearch_blur(e,this); }; 
    462461     
    463462    if (obj.addEventListener) 
    464     { 
    465463      obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false); 
    466       obj.addEventListener('blur', handler2, false); 
    467     } 
    468464    else 
    469     { 
    470465      obj.onkeydown = handler; 
    471       obj.onblur = handler2; 
    472     } 
    473  
    474     obj.setAttribute('autocomplete', 'off');        
     466 
     467    obj.setAttribute('autocomplete', 'off'); 
    475468    }; 
    476469 
     
    11741167      model = this.env.address_sources; 
    11751168    } 
     1169    else if (this.ksearch_value) { 
     1170      this.ksearch_blur(); 
     1171    } 
    11761172     
    11771173    // handle mouse release when dragging 
     
    23142310 
    23152311      if (this.gui_objects.search_filter) 
    2316         addurl = '&_filter=' + this.gui_objects.search_filter.value; 
     2312      addurl = '&_filter=' + this.gui_objects.search_filter.value; 
    23172313 
    23182314      // reset vars 
     
    23202316      this.set_busy(true, 'searching'); 
    23212317      this.http_request('search', '_q='+urlencode(value) 
    2322             +(this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '') 
    2323             +(this.env.source ? '&_source='+urlencode(this.env.source) : '') 
    2324             +(addurl ? addurl : ''), true); 
     2318        + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '') 
     2319        + (this.env.source ? '&_source='+urlencode(this.env.source) : '') 
     2320        + (addurl ? addurl : ''), true); 
    23252321      } 
    23262322    return true; 
     
    23502346  // handler for keyboard events on address-fields 
    23512347  this.ksearch_keypress = function(e, obj) 
    2352     { 
    2353     if (typeof(this.env.contacts)!='object' || !this.env.contacts.length) 
    2354       return true; 
    2355  
     2348  { 
    23562349    if (this.ksearch_timer) 
    23572350      clearTimeout(this.ksearch_timer); 
     
    23692362           
    23702363        var dir = key==38 ? 1 : 0; 
    2371         var next; 
    23722364         
    23732365        highlight = document.getElementById('rcmksearchSelected'); 
     
    23752367          highlight = this.ksearch_pane.ul.firstChild; 
    23762368         
    2377         if (highlight && (next = dir ? highlight.previousSibling : highlight.nextSibling)) 
    2378           { 
    2379           highlight.removeAttribute('id'); 
    2380           this.set_classname(highlight, 'selected', false); 
    2381           } 
    2382  
    2383         if (next) 
    2384           { 
    2385           next.setAttribute('id', 'rcmksearchSelected'); 
    2386           this.set_classname(next, 'selected', true); 
    2387           this.ksearch_selected = next._rcm_id; 
    2388           } 
     2369        if (highlight) 
     2370          this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling); 
    23892371 
    23902372        return rcube_event.cancel(e); 
     
    23942376          break; 
    23952377 
    2396       case 13:  // enter      
     2378      case 13:  // enter 
    23972379        if (this.ksearch_selected===null || !this.ksearch_input || !this.ksearch_value) 
    23982380          break; 
     
    24152397     
    24162398    return true; 
    2417     }; 
     2399  }; 
     2400   
     2401  this.ksearch_select = function(node) 
     2402  { 
     2403    var current = document.getElementById('rcmksearchSelected'); 
     2404    if (current && node) { 
     2405      current.removeAttribute('id'); 
     2406      this.set_classname(current, 'selected', false); 
     2407    } 
     2408 
     2409    if (node) { 
     2410      node.setAttribute('id', 'rcmksearchSelected'); 
     2411      this.set_classname(node, 'selected', true); 
     2412      this.ksearch_selected = node._rcm_id; 
     2413    } 
     2414  }; 
    24182415 
    24192416  this.insert_recipient = function(id) 
     
    24412438  // address search processor 
    24422439  this.ksearch_get_results = function() 
    2443     { 
     2440  { 
    24442441    var inp_value = this.ksearch_input ? this.ksearch_input.value : null; 
    2445     if (inp_value===null) 
     2442    if (inp_value === null) 
    24462443      return; 
     2444       
     2445    if (this.ksearch_pane && this.ksearch_pane.visible) 
     2446      this.ksearch_pane.show(0); 
    24472447 
    24482448    // get string from current cursor pos to last comma 
     
    24542454    q = q.replace(/(^\s+|\s+$)/g, '').toLowerCase(); 
    24552455 
    2456     if (!q.length || q==this.ksearch_value) 
    2457       { 
    2458       if (!q.length && this.ksearch_pane && this.ksearch_pane.visible) 
    2459         this.ksearch_pane.show(0); 
    2460  
    2461       return; 
    2462       } 
     2456    // Don't (re-)search if string is empty or if the last results are still active 
     2457    if (!q.length || q == this.ksearch_value) 
     2458        return; 
    24632459 
    24642460    this.ksearch_value = q; 
    24652461     
    2466     // start searching the contact list 
    2467     var a_results = new Array(); 
    2468     var a_result_ids = new Array(); 
     2462    this.display_message('searching', 'loading', true); 
     2463    this.http_post('autocomplete', '_search='+q); 
     2464  }; 
     2465 
     2466  this.ksearch_query_results = function(results) 
     2467  { 
     2468    this.hide_message(); 
     2469    this.env.contacts = results ? results : []; 
     2470 
     2471    var result_ids = new Array(); 
    24692472    var c=0; 
    2470     for (var i=0; i<this.env.contacts.length; i++) 
    2471       { 
    2472       if (this.env.contacts[i].toLowerCase().indexOf(q)>=0) 
    2473         { 
    2474         a_results[c] = this.env.contacts[i]; 
    2475         a_result_ids[c++] = i; 
    2476          
    2477         if (c==15)  // limit search results 
    2478           break; 
    2479         } 
    2480       } 
    2481  
     2473    for (var i=0; i < this.env.contacts.length; i++) { 
     2474      result_ids[c++] = i; 
     2475      if (c == 15)  // limit search results 
     2476        break; 
     2477    } 
     2478     
     2479    this.ksearch_display_results(this.env.contacts, result_ids, c); 
     2480  }; 
     2481 
     2482  this.ksearch_display_results = function (a_results, a_result_ids, c) 
     2483  { 
    24822484    // display search results 
    2483     if (c && a_results.length) 
    2484       { 
     2485    if (c && a_results.length) { 
    24852486      var p, ul, li; 
    24862487       
    24872488      // create results pane if not present 
    2488       if (!this.ksearch_pane) 
    2489         { 
     2489      if (!this.ksearch_pane) { 
    24902490        ul = document.createElement('UL'); 
    24912491        this.ksearch_pane = new rcube_layer('rcmKSearchpane', {vis:0, zindex:30000}); 
    24922492        this.ksearch_pane.elm.appendChild(ul); 
    24932493        this.ksearch_pane.ul = ul; 
    2494         } 
     2494      } 
    24952495      else 
    24962496        ul = this.ksearch_pane.ul; 
     
    25002500             
    25012501      // add each result line to list 
    2502       for (i=0; i<a_results.length; i++) 
    2503         { 
     2502      for (i=0; i<a_results.length; i++) { 
    25042503        li = document.createElement('LI'); 
    2505         li.innerHTML = a_results[i].replace(/</, '&lt;').replace(/>/, '&gt;'); 
     2504        li.innerHTML = a_results[i].replace(/</, '&lt;').replace(/>/, '&gt;').replace(new RegExp('('+this.ksearch_value+')', 'ig'), '<b>$1</b>'); 
     2505        li.onmouseover = function(){ ref.ksearch_select(this); }; 
     2506        li.onclick = function(){ ref.ksearch_click(this) }; 
    25062507        li._rcm_id = a_result_ids[i]; 
    25072508        ul.appendChild(li); 
    2508         } 
     2509      } 
    25092510 
    25102511      // check if last selected item is still in result list 
    2511       if (this.ksearch_selected!==null) 
    2512         { 
     2512      if (this.ksearch_selected !== null) { 
    25132513        p = find_in_array(this.ksearch_selected, a_result_ids); 
    2514         if (p>=0 && ul.childNodes) 
    2515           { 
     2514        if (p >= 0 && ul.childNodes) { 
    25162515          ul.childNodes[p].setAttribute('id', 'rcmksearchSelected'); 
    25172516          this.set_classname(ul.childNodes[p], 'selected', true); 
    2518           } 
     2517        } 
    25192518        else 
    25202519          this.ksearch_selected = null; 
    2521         } 
     2520      } 
    25222521       
    25232522      // if no item selected, select the first one 
    2524       if (this.ksearch_selected===null) 
    2525         { 
     2523      if (this.ksearch_selected === null) { 
    25262524        ul.firstChild.setAttribute('id', 'rcmksearchSelected'); 
    25272525        this.set_classname(ul.firstChild, 'selected', true); 
    25282526        this.ksearch_selected = a_result_ids[0]; 
    2529         } 
     2527      } 
    25302528 
    25312529      // move the results pane right under the input box and make it visible 
    25322530      var pos = rcube_get_object_pos(this.ksearch_input); 
    25332531      this.ksearch_pane.move(pos.x, pos.y+this.ksearch_input.offsetHeight); 
    2534       this.ksearch_pane.show(1);  
    2535       } 
     2532      this.ksearch_pane.show(1); 
     2533    } 
    25362534    // hide results pane 
    25372535    else 
    25382536      this.ksearch_hide(); 
    2539     }; 
    2540  
    2541   this.ksearch_blur = function(e, obj) 
     2537  }; 
     2538   
     2539  this.ksearch_click = function(node) 
     2540  { 
     2541    this.insert_recipient(node._rcm_id); 
     2542    this.ksearch_hide(); 
     2543     
     2544    if (ref.ksearch_input) 
     2545      this.ksearch_input.focus(); 
     2546  }; 
     2547 
     2548  this.ksearch_blur = function() 
    25422549    { 
    25432550    if (this.ksearch_timer) 
    25442551      clearTimeout(this.ksearch_timer); 
    25452552 
    2546     this.ksearch_value = '';       
     2553    this.ksearch_value = ''; 
    25472554    this.ksearch_input = null; 
    25482555     
     
    25562563     
    25572564    if (this.ksearch_pane) 
    2558       this.ksearch_pane.show(0);     
     2565      this.ksearch_pane.show(0); 
    25592566    }; 
    25602567 
  • program/steps/mail/compose.inc

    r300fc65 r2c8e84c  
    8484$OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 
    8585    'nobodywarning', 'notsentwarning', 'savingmessage', 'sendingmessage', 'messagesaved', 
    86     'converting', 'editorwarning'); 
     86    'converting', 'editorwarning', 'searching'); 
    8787 
    8888// add config parameters to client script 
     
    914914)); 
    915915 
    916 /****** get contacts for this user and add them to client scripts ********/ 
    917  
    918 $CONTACTS = new rcube_contacts($DB, $USER->ID); 
    919 $CONTACTS->set_pagesize(1000); 
    920  
    921 $a_contacts = array();  
    922                                     
    923 if ($result = $CONTACTS->list_records()) 
    924   { 
    925   while ($sql_arr = $result->iterate()) 
    926     if ($sql_arr['email']) 
    927       $a_contacts[] = format_email_recipient($sql_arr['email'], $sql_arr['name']); 
    928   } 
    929 if (!empty($CONFIG['ldap_public']) && is_array($CONFIG['ldap_public'])) 
    930   { 
    931   /* LDAP autocompletion */  
    932   foreach ($CONFIG['ldap_public'] as $ldapserv_config)  
    933     {  
    934     if ($ldapserv_config['fuzzy_search'] != 1 ||  
    935         $ldapserv_config['global_search'] != 1) 
    936       {  
    937       continue;  
    938       } 
    939           
    940     $LDAP = new rcube_ldap($ldapserv_config);  
    941     $LDAP->connect();  
    942     $LDAP->set_pagesize(1000); 
    943    
    944     $results = $LDAP->search($ldapserv_config['mail_field'], "");  
    945   
    946     for ($i = 0; $i < $results->count; $i++)  
    947           {  
    948           if ($results->records[$i]['email'] != '')  
    949             {  
    950             $email = $results->records[$i]['email'];  
    951             $name = $results->records[$i]['name'];  
    952                   
    953             $a_contacts[] = format_email_recipient($email, $name); 
    954             }  
    955           } 
    956     $LDAP->close();  
    957     } 
    958   } 
    959 if ($a_contacts)  
    960   {  
    961         $OUTPUT->set_env('contacts', $a_contacts);  
    962   } 
    963  
    964916$OUTPUT->send('compose'); 
    965917 
  • skins/default/common.css

    re538b3d r2c8e84c  
    432432#rcmKSearchpane ul li 
    433433{ 
     434  display: block; 
    434435  height: 16px; 
    435436  font-size: 11px; 
    436   padding-left: 8px; 
     437  padding-left: 6px; 
    437438  padding-top: 2px; 
    438   padding-right: 8px; 
    439   white-space: nowrap;   
     439  padding-right: 6px; 
     440  white-space: nowrap; 
     441  cursor: pointer; 
    440442} 
    441443 
Note: See TracChangeset for help on using the changeset viewer.