Source code for /src/cookie1.jsp.txt

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
//=====================================================================//
//Author: Mark Qian <markqian@hotmail.com>                             //
//WWW: http://www.coolshare.com/                                       //
//Copyright (c) 2006, Mark Qian                                        //
//                                                                     //
//You must contact Mark Qian to get a permission of use                //
//in case you want to make any use of the codes except viewing it     //
//on Mark's site.                                                      //
//=====================================================================//
%>
<html>
<META http-equiv="Page-Enter" CONTENT="RevealTrans(Duration=4,Transition=23)">
<HEAD>
	<TITLE>Auto-Complete with AJAX using Mark's Communicator</TITLE>
<script language="javascript" src="/RemoteScriptGuru/js/rslite.js"></script>
<script language="javascript" src="/RemoteScriptGuru/js/CManager.js"></script>
<script language="javascript" src="/RemoteScriptGuru/js/communicator.js"></script>
<script language="javascript" src="/RemoteScriptGuru/js/CookieCommunicator.js"></script>
<script language="javascript" src="/RemoteScriptGuru/js/autocomplete.js"></script>	
<script>
var cm = new CManager("Cookie", 2);

function doKeyUp(c, d, kc) {
  //Local var comm
  var comm = cm.getCommunicator();
  
  //////////////////////////// Closure 1 /////////////////////////////////
  //
  // Forming a closure to preserve comm, c, d and kc. We need them when
  // the callback is invoked otherwise they may be garbag collocted
  // when doKeyUp is exited.
  //
  ///////////////////////////////////////////////////////////////
  var handler = (function() {
    function updateDiv() {
	    /***********************************************************************/
	    /*  The task in the concrete handler, updateDiv, is so simple:         */
	    /*                                                                     */
	    /*  1. get the server return from comm.res (Note: this is the          */
	    /*     same over all the Concrete Communicators and all the            */
	    /*     details about how to obtain the res, such as onload in          */
	    /*     the hidden iframe, is transparnt)                               */
	    /*  2. assign it to the div holding the select                         */
	    /*  3. call auto-complete                                              */
	    /***********************************************************************/
	    d.innerHTML = comm.res;         
	    autoComplete(c,c.form.state,'value',true, kc);      
    }
    return updateDiv;
  })();

  //////////////////////////////////////////////////////////////////////////////
  //
  // Separate init and send to make pooling of Communicator
  // easier. So there is a state, "ready (1)",  between "avaiable (0)" and "running (2)"
  //
  /////////////////////////////////////////////////////////////////////////////////
  comm.init(window, "/RemoteScriptGuru/remote_script.issue_1_comm.common.select3.do", c.value, handler);
  comm.send();
}

</script>
</HEAD>
<body background="/RemoteScriptGuru/images/rulebk.jpg">
 <table><tr><td><table width=150><tr><td></td></tr></table></td><td><table><tr><td>

<h2>Auto-Complete with Cookies using Mark's Communicator</h2>
<pre>
<form Action="#_demo"><input type=submit value="Run Demo Here"></form>
<b>What is this?</b>

This is a demo of autocomplete. Initially, the dropdown box at the right is filled up with
50 states. After you type a character, say "c", "California" the first item in the subset
starting with "c" (ignoring cases) will be selected in the select box and the content of 
text box will be changed to the first item, "California", too. <b>If you look inside the 
dropdown box now</b>, you will see only the subset (3 states) instead of 50 states. This 
demo not only shows how the remote scripting is done but also describe how <b>Mark's 
Communicator</b> is built.

<b>Compatibility</b>: IE (6.x, 7.x), FireFox (1.5.0.4), Mozilla/Netscape(7.2), Opera(9.0)
                      were fully tested and worked in XP (v2002. sp2).
                      
<b>Design goal of Mark's Communicator:</b> 

          the goal of Mark's Communicator is to wrap the implementation details to provide 
          its users a easily and clean remote scripting environment. It won't be necessary 
          for its user to learn what meant is used (they have their control if they want to) 
          and the Communicator will detect the maximum available environment and pick the 
          best one. Only thing they need to do for the communication is getting the result 
          return by server from Communicator in the handler they provide.

<b>Design Issues of Mark's Communicator</b>: the of Mark's Communicator is to wrap the 

          implementation details to provide its users a easily and clean remote scripting
          environment. It won't be necessary for its user to learn what meant is used
          (they have their control if they want to) and the Communicator will detect
          the maximum available environment and pick the best one.
          
<ul><li>Encapsulation</li>

      I wrapped all the communication details into a single js object, Communicator
      In this way, detail implementation of Cookies is transparent to programmers using
      Communicator. See <a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/communicator.js.txt">communicator.js</a> for details.      
      
  <li>Inheritance</li> 
  
      Pattern "Template Method" is used so that the implementation of "sending" is
      postpone to the subclass of Communicator such as CookieCommunicator. In this way,
      all the concrete Communicators only have their send method different to maximize
      code sharing and consistency. See <a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/CookieCommunicator.js.txt">CookieCommunicator.js</a> for details.      
      
  <li>Preserving objects crossing the gap between sending and receiving</li>
  
     There are two chanllenges in this example:
       1). preserve the reference of callback handler, "handler", so that we
           can still access it when the callback wrapping method, "process", is
           invoked in "process's" execution context. See details in <a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/CookieCommunicator.txt" target=_blank>CookieCommunicator.js</a>.
       2). the method "autocomplete" needs to be invoked in "hanlder" after the
           response arrives so that we can select from the updated list but 
           all the parameters "autocomplete" needs are only available before sending.
           
       So there are two <b>closures</b> formed to preserve them. See <a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/cookie1.jsp.txt">cookie1.jsp</a>(closure 1) and <a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/CookieCommunicator.txt">CookieCommunicator.js</a>(closure 2).       
       
   <li>Communicator pooling</li>
   
       The CookieCommunicator is pooled and managed by CCManager.
       
       The reason I used a callback wrapper, "process", as onreadystatechange, instead
       of the real callback function, "handler", is that I can do some preprocess and 
       clear up around "handler". This will give me a chance to maintain pool related
       states used by my CookieCommunicator. 
          
</ul>
<A NAME="_demo"></A>
<hr>
</pre>
<h3>Running page:</h3>
<form><br><table bgcolor="#CCFFFF"><tr><td>
<INPUT TYPE="text" NAME="input1" VALUE="" ONKEYUP="doKeyUp(this, document.getElementById('stateDiv'), event.keyCode)">
</td><td>
<div id=stateDiv>
<%@ include file = "/jsp/remote_script/issue_1_comm/common/issue_1_select.jsp" %>
</div></td></tr></table>
</form>

 
<hr>
 <pre>
<A NAME="_src"></A>
 <b>Source Codes</b>
 <ul>
 <li>Mark Qian's codes:</li><ul>
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/cookie1.jsp.txt" target=_blank>cookie1.jsp</a></li>
    
        The main page of this demo (this page).
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/issue_1_select3.jsp.txt" target=_blank>issue_1_select3.jsp</a></li>
    
        The tile jsp containing the select component that is "silently" update by 
        Cookie.        
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/CookieCommunicator.js.txt" target=_blank>CookieCommunicator.js</a></li>
    
        The concreate Cookies Communicator js file.
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/communicator.js.txt" target=_blank>communicator.js</a></li>
    
        The super class of Communicator
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/LoadStateAction.java.txt" target=_blank>LoadStateAction.java</a></li>
    
        The Struts action that support the search.
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/CManager.js.txt" target=_blank>CManager.js</a></li>
    
        The basic class of Communicator Manager.        

    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/cross_browser.js.txt" target=_blank>cross_browser.js</a></li>
    
        Browser detection.        
        </ul>
        <li>Third Party's codes:</li><ul>
    <li><a href="http://remotescriptguru.com/RemoteScriptGuru/jsp/common/showSource.jsp?name=/src/autocomplete.js.txt" target=_blank>autocomplete.js</a></li>
    
        A third party js API from Matt Kruse matt@mattkruse.com        
        </ul>
        
</ul>
 </pre>
<script language="javascript" src="/RemoteScriptGuru/html/coolshare/html/js/cross_browser.js"></script>
<script language="javascript" src="/RemoteScriptGuru/html/coolshare/html/js/include_ajax.js"></script>
<script id="__include__">
  include.load("/RemoteScriptGuru/html/coolshare/html/common/contact.htm");
</script>
</body>
</html>