Link to home
Start Free TrialLog in
Avatar of gs_kanata
gs_kanataFlag for Canada

asked on

Javascript multiple cookies do not work

I have written a javascript to save cookies for customized settings for multiple users. When the HTML page is loaded, it prompts for a user name. Then it checks whether the user has associated cookie. If it does, then it retrieve that cookie string and load the user's settings from previous session.  

Lets say my HTML page has user John and Jessica. John is the first user and he saved the selections/settings when he left. The cookie string will be:

"John=ColorSel%3A1%3FLoadPage%3Ared_rose.html;"

If John revisted the page, the page will be loaded with his previous selections/settings. He can change it in the current session and the cookie string will be updated correctly. No issue here for a single user.

However, if Jesscia visits the HTML page. She looks and around and tries to save her selections/settings. Then for somehow the cookie string does not extend. I tried to assign the following new cookie string to doucument.cookie,

"John=ColorSel%3A1%3FLoadPage%3Ared_rose.html;
;Jessica=ColorSel%3A2%3FLoadPage%3Ayellow_rose.html"

But after assignment, when I print the document.cookie value, it only returns John's setting. So when Jesscia come back, the HTML load javascript could not find her cookie.

BTW, when I uploaded the HTML page to school website and launch it from there, it is stuck in the checkCookie() getUserName() function. The labtop vista task manager shows 50% CPU usage and finally the IE pop up an warning message saying that the page cause slow web response and should close.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
  <head>
    <title>Assign2 bottom left frame</title>
    <script type="text/javascript"> <!--
      var g_username;
      var g_load_page;
      var g_is_new_cookie;
      
      /*
       * This function marks the current opened page in frame P3.
       */
      function markLoadPage( page_url )
      {
	    g_load_page = page_url;
      }
      
      /*
       * This function prompts user name when the page is re-loaded
       */       
	  function getUserName()
      {
	    do
	    {
          var username=prompt( 'Please enter your name:',"" );
        }       
        while( username == null || username =="" )
        
        return username;
      }
 
      /*
       * This is general function to get the cookie string for the specified cookie name
       */      
      function getCookie( c_name )
      {
        if( document.cookie.length>0 )
        {
          var c_start = document.cookie.indexOf( c_name + "=" );
          if( c_start!=-1 )
          { 
            c_start=c_start + c_name.length+1; 
            c_end=document.cookie.indexOf( ";",c_start );
            if( c_end==-1 ) c_end=document.cookie.length;
            return unescape( document.cookie.substring( c_start,c_end ));
          } 
        }
              
        return "";
      }
 
      /*
       * This function update the cookie. The cookie string contains the user 
       * preferenced selections on the HTML form.
       */      
      function setCookie()
      {	
	    var c_name = g_username;    
	    var c_value = "ColorSel:" + document.getElementById( "color_list" ).selectedIndex + "?" +
	                  "LoadPage:" + g_load_page;
	              	   
	    if( g_is_new_cookie )
	    {          
          tmp_cookie_str = document.cookie;
          if( document.cookie.length>0 )
          {
	        tmp_cookie_str = document.cookie;
	        
	        alert( "tmp_cookie_str = " + tmp_cookie_str );
	        
	        alert( "Assigned value =\n" +  tmp_cookie_str + ";" + c_name + "=" + escape( c_value ));
	        document.cookie = tmp_cookie_str + ";" + c_name + "=" + escape( c_value );
	        // document.cookie += ";" + c_name + "=" + escape( c_value );
          }
          else
          {
	        document.cookie = c_name + "=" + escape( c_value );
          }
        }
        else
        {
	      var newCookies = "";
	      var cookieArr = document.cookie.split( ";" );
	      
	      for( i=0; i<cookieArr.length; i++ )
	      {
		    var name_start = 0;
		    var name_end = cookieArr[ i ].indexOf( "=", 0 );
		    if( name_end == -1 )
		    {
			  alert( "Cookie String is corrupted at\n" + cookieArr[ i ] );
			  
			  continue;
		    }
		    
		    newCookies += ( newCookies.length > 0 )? ";" : "";
		    
		    var another_c_name = unescape( cookieArr[ i ].substring( 0, name_end ));
		    if( another_c_name == c_name )
		    {
			  newCookies += c_name + "=" + escape( c_value );
		    }
		    else
		    {
			  newCookies += cookieArr[ i ];
		    }
		  } // end of for    
 
	      
	      alert( "newCookies ==>\n" + newCookies );
	      
	      document.cookie = newCookies;
        }
        
        alert( "Saved cookies ==>\n" + document.cookie );    
      }
 
      /*
       * This function restores the user saved preference settings as the initial input
       * value to the HTML form fields.
       */      
      function restorePreference( cookieStr )
      { 
	    var fldArr = cookieStr.split( "?" );
	    
        for ( i=0; i<fldArr.length; i++) 
        {
          fldPair = fldArr[ i ];
          var broken_info = fldPair.split(":");
          var fld_name = broken_info[ 0 ];
          var fld_value = broken_info[ 1 ];
          
          switch( fld_name )
          {
	        case "ColorSel":
	        {
	          var idx = parseInt( fld_value );
	          document.getElementById( "color_list" ).selectedIndex = idx;
	          if( idx > 0 )
	          {
	            document.bgColor = document.getElementById( "color_list" ).options[ idx ].value;
              }
            }
            case "LoadPage":
            {
	          parent.P3.location.href = fld_value;
            }
          } // end of switch
        }
      }
 
      /*
       * This function check the existing cookie for the user of previous session. It assums that there is
       * one and only one user for this HTML form. In another word, second user preference settings will 
       * overwrite the one of first user.
       */   
      function checkCookie()
      { 
	    g_username = getUserName();
	    
	    var cookieStr = getCookie( g_username );
	    
	    if( cookieStr!=null && cookieStr!="" )
        {
            restorePreference( unescape( cookieStr )); 
            g_is_new_cookie = false;
        }
        else
        {
          g_is_new_cookie = true;
        }
      }
      
      /*
       * This function set the background color of the P2 page
       */
  	  function setColor()
  	  {
	    var idx = document.getElementById( "color_list" ).selectedIndex;
	    if( idx > 0 )
	    {
	      document.bgColor = document.getElementById( "color_list" ).options[ idx ].value;
        }
      }
//--></script>
  <style type="text/css"> <!--
    dl
    {
	  font-size:       medium;
	  test-decoration: underline;
	  margin-bottom:   0px;
	  padding:         0px;
    }
    select
    {
	  width:    5cm;
	  hight:    1cm;
    }
    table
    {
	  border:           1px;
	  border-spacing:   1px;
	  caption-side:     bottom;
	  border-collapse:  separate;
	  table-layout:     auto;
	  width:			100%;
	  empty-cells:		show;
    }
    option
    {
	  font-weight:  700;
    }
    .bt-style
    {
      border-color: efefef; 
      color: black; 
      font-family: arial, verdana, ms sans serif; 
      font-weight: bold; 
      font-size: 	 10pt; 
      width: 		 100px;
      height:		 25px
    }	  
//--></style>
  </head>
  <body onload="checkCookie()">
   <h2>Categories</h2>
   <dl><dt><a href="red_rose.html" target="P3" onclick="markLoadPage( 'red_rose.html' )">Red rose</a></dt></dl>
   <dl><dt><a href="pink_rose.html" target="P3" onclick="markLoadPage( 'pink_rose.html' )">Pink rose</a></dt></dl>
   <dl><dt><a href="yellow_rose.html" target="P3" onclick="markLoadPage( 'yellow_rose.html' )">Yellow rose</a></dt></dl>
   <dl><dt><a href="white_rose.html" target="P3" onclick="markLoadPage( 'white_rose.html' )">White rose</a></dt></dl>
   <dl><dt><a href="orange_rose.html" target="P3" onclick="markLoadPage( 'orange_rose.html' )">Orange rose</a></dt></dl>
   <dl><dt><a href="lavender_rose.html" target="P3" onclick="markLoadPage( 'lavender_rose.html' )">Lavender rose</a></dt></dl>
   <br/><br/><br/><br/>
   <form action="">
     <select name="color_list" id="color_list" onchange="setColor()">
       <option value="prompt">Choose a colour</option>
       <option value="red">red</option>
       <option value="pink">pink</option>
       <option value="yellow">yellow</option>
       <option value="white">white</option>
       <option value="orange">orange</option>
       <option value="lavender">lavender</option>
     </select>
     <br/><br/>
     <input type="button" class="bt_style" value="Save Selection" name="b_save" onclick="setCookie()" />
   </form>
  </body>
</html>

Open in new window

SOLUTION
Avatar of webwyzsystems
webwyzsystems

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gs_kanata

ASKER

Does the prompt( .. ) function act like request and wait? I am not sure as it behave like that in local machine if I enter the empty user name. However, if the HTML page is run in a web server, then the prompt simply not display. I really don't know what the local labtop CPU is busy with.

As for the cookie implementation, I appreciate and will try your suggestion. But that does not solve the issue to append more cookie to the document.cookie. For each windows login account, there is only one cookie file for one domain, right? And the cookie file has only one line having multiple cookies concatenated. The issue is that I can not append more cookie to that line. One it could, I have no issue to separate and extract properties and values.
BTW, another strange thing the John's cookie string can be still retrieved even after I tried to delete all the cookies from control panel.

Attached are 2 screen capture files. One for Windows error message and another is the Control panel cookie deletion selection...
Alert.doc
delete-cookie.doc
I have figured out some issues:

(1) I have overkilled the multiple cookies. The javascript or the system has taken good care of it. So if one needs to update one cookie, then just write as
   
   document.cookie = c_name + "=" + c_value;

It won't overwrite the other cookie, only update the cooke has the same name if it exists. Otherwise, it just append a new cookie. So if it re-build the whole cookie line with multiple cookies separated with ";", then it will take the first one, as it can only update one cookie at a time.

(2) HTML webpage stuck duing the lauching from the remote website is because the security issue set in my IE. If I add that remote website as the truested site, then prompt will be display and stop there for user input.

However, back to cookie again, it saved cookie string seem can not survive from closing and starting the web page. Here is my testing step:

(1) Launch the HTML page, and enter a user name "user1".
(2) Navigate through pages and save the selection.
(3) Refresh the HTML main frame, and enter another user name say "user2".
(4) Repeat step 2 to save the customized selection
(5) Refresh the HTML main frame, and enter the first user name "user1". The user1's settings will be restored.
(6) Refresh the HTML main frame, and enter the second user name "user2". The user2's settings will be restored.

Everything seems to be fine so far until the HTML page is closed. Then when re-opening, the cookie string becomes empty and no user customized preference is restored.

Attached is the updated code




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
  <head>
    <title>Assign2 bottom left frame</title>
    <script type="text/javascript"> <!--
      var g_username;
 
 
      /*
       * This function prompts user name for first load. So it assumes that only one
       * user uses this form
       */       
	  function getUserName()
      {
	    do
	    {
          var username=prompt( 'Please enter your name:',"" );
        }       
        while( username == null || username =="" )
        
        return username;
      }
 
      /*
       * This is general function to get the cookie string for the specified cookie name
       */      
      function getCookie( c_name )
      {
	    alert( "Retrieved cookies ==>\n" + document.cookie ); 
	    
        if( document.cookie.length>0 )
        {
          var c_start = document.cookie.indexOf( c_name + "=" );
          if( c_start!=-1 )
          { 
            c_start=c_start + c_name.length+1; 
            c_end=document.cookie.indexOf( ";",c_start );
            if( c_end==-1 ) c_end=document.cookie.length;
            return unescape( document.cookie.substring( c_start,c_end ));
          } 
        }
              
        return "";
      }
 
      /*
       * This function sets the cookie for the current exclusive user. The cookie string
       * contains the user preferenced selections on the HTML form.
       */      
      function setCookie()
      {	
	    var c_name = g_username;    
	    var c_value = "ColorSel&" + document.bgColor + "?" + "LoadPage&" + parent.P3.location.href;
	    
	    document.cookie = c_name + "=" + escape( c_value );
 
        alert( "Saved cookies ==>\n" + document.cookie );    
      }
 
      /*
       * This function restores the user saved preference settings as the initial input
       * value to the HTML form fields.
       */      
      function restorePreference( cookieStr )
      { 
	    var fldArr = cookieStr.split( "?" );
	    
        for ( i=0; i<fldArr.length; i++) 
        {
          fldPair = fldArr[ i ];
          var broken_info = fldPair.split("&");
          var fld_name = broken_info[ 0 ];
          var fld_value = broken_info[ 1 ];
          
          switch( fld_name )
          {
	        case "ColorSel":
	        {
		      document.bgColor = fld_value;
 
              break;
            }
            case "LoadPage":
            {	          
	          if( fld_value != "undefined" )
	          {
	            parent.P3.location.href = fld_value;
              }
              break;
            }
            default:
            {
	          alert( "Internal error: unsupported property name <" + fld_name + ">" );
            }
          } // end of switch
        }
      }
 
      /*
       * This function check the existing cookie for the user of previous session. It assums that there is
       * one and only one user for this HTML form. In another word, second user preference settings will 
       * overwrite the one of first user.
       */   
      function checkCookie()
      { 
	    g_username = getUserName();
	    
	    var cookieStr = getCookie( g_username );
	    
	    if( cookieStr!=null && cookieStr!="" )
        {
            restorePreference( unescape( cookieStr )); 
        }
      }
      
  	  function setColor()
  	  {
	    var idx = document.getElementById( "color_list" ).selectedIndex;
	    if( idx > 0 )
	    {
	      document.bgColor = document.getElementById( "color_list" ).options[ idx ].value;
        }
      }
//--></script>
  <style type="text/css"> <!--
    dl
    {
	  font-size:       medium;
	  test-decoration: underline;
	  margin-bottom:   0px;
	  padding:         0px;
    }
    select
    {
	  width:    5cm;
	  hight:    1cm;
    }
    table
    {
	  border:           1px;
	  border-spacing:   1px;
	  caption-side:     bottom;
	  border-collapse:  separate;
	  table-layout:     auto;
	  width:			100%;
	  empty-cells:		show;
    }
    option
    {
	  font-weight:  700;
    }
    .td_1
    {
	  font-style:  italic; 
	  font-size:   small;
	  font-weight: 700;
    }
    .td_2
    {
	  font-style:  italic; 
	  height:	   1cm;
    }
    .bt-style
    {
      border-color: efefef; 
      color: black; 
      font-family: arial, verdana, ms sans serif; 
      font-weight: bold; 
      font-size: 	 10pt; 
      width: 		 100px;
      height:		 25px
    }	  
//--></style>
  </head>
  <body onload="checkCookie()">
   <h2>Categories</h2>
   <dl><dt><a href="red_rose.html" target="P3">Red rose</a></dt></dl>
   <dl><dt><a href="pink_rose.html" target="P3">Pink rose</a></dt></dl>
   <dl><dt><a href="yellow_rose.html" target="P3">Yellow rose</a></dt></dl>
   <dl><dt><a href="white_rose.html" target="P3">White rose</a></dt></dl>
   <dl><dt><a href="orange_rose.html" target="P3">Orange rose</a></dt></dl>
   <dl><dt><a href="lavender_rose.html" target="P3">Lavender rose</a></dt></dl>
   <br/><br/><br/><br/>
   <form action="">
     <select name="color_list" id="color_list" onchange="setColor()">
       <option value="prompt">Choose a colour</option>
       <option value="red">red</option>
       <option value="pink">pink</option>
       <option value="yellow">yellow</option>
       <option value="white">white</option>
       <option value="orange">orange</option>
       <option value="lavender">lavender</option>
     </select>
     <br/><br/>
     <input type="button" class="bt_style" value="Save Selection" name="b_save" onclick="setCookie()" />
   </form>
  </body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of b0lsc0tt
b0lsc0tt
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'm glad I could help.  Thanks for the grade, the points and the fun question.
bol