save state of all form field types

Does anyone have a ready-made script for saving state (via cookies) of all form field types? I've found different scripts that will handle saving state for drop-downs and text inputs, but I haven't managed to cobble together a single script that will save state (via cookie-setting) for drop-downs and text inputs AS WELL AS checkboxes and radio buttons. Anyone have something that will do this? I need to save users' query form entries across all pages of a database site I've developed. I only need to save state for the session; don't need cookies to persist beyond the session end.

Thanks!
GessWurkerAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
ZvonkoConnect With a Mentor Systems architectCommented:
Ok, check this:

function returnState(){
  fVal = document.cookie.split("_ff=");
  if(fVal.length==2){
    theForm = document.forms[0];
    cVal = (fVal[1]+";").split(";")[0].split("$")
    for(i=1;i<cVal.length-1;i++){
      ePart = cVal[i].split(":");
      eVal = unescape(ePart[2]);
      elem = theForm[ePart[1]];
      if(elem.length){
        if(ePart[0]=="s"){
          opt=elem.options;
          for(j=0;j<opt.length;j++){
            if(opt[j].value==eVal)opt[j].selected=true;
          }
        } else
        for(j=0;j<elem.length;j++){
          if(elem[j].value==eVal) elem[j].checked=true;
        }
      } else {
        if(ePart[0]=="c") elem.checked = true;
        else elem.value = eVal;
      }
    }
  }
}

0
 
ZvonkoSystems architectCommented:
That is not good done by cookies.
If you already use server side scripting then why do not you use hidden fields for data storing?

The reasin is that you can have only twenty cookies with a total maximum size of 4096 bytes.
That is not very much for big forms and long values which also need to be escaped in the cookies.

0
 
GessWurkerAuthor Commented:
Zvonko:

Server-side scripting is not available to me in this case. Also, there aren't SO many fields in the form. There are just 3 drop-downs, 1 text input, and 1 checkbox. No more than that. I've got a SaveForm() script by J. Meyers that does very nicely for storing state w/the drop-downs and the text input (it autopopulates those fields onload, putting back the user's previous entries), but it doesn't work w/checkboxes and I don't know how to modify it as necessary.With the drop-downs, all I'd need to store is the selectedindex, w/the checkbox, just the checked/unchecked status, and then the text input. Doesn't seem like such a big cookie(s). Does it?
0
Easily Design & Build Your Next Website

Squarespace’s all-in-one platform gives you everything you need to express yourself creatively online, whether it is with a domain, website, or online store. Get started with your free trial today, and when ready, take 10% off your first purchase with offer code 'EXPERTS'.

 
ZvonkoSystems architectCommented:
You are right.

I just made one for another question:

<script>
function storeState(theBox){
  document.cookie="cb$"+theBox.name+"="+theBox.checked+";path=/;";
}
function returnState(){
  cBc = document.cookie.split("cb$");
  if(cBc.length>1){
    theForm = document.qbe_form;
    for(i=1;i<cBc.length;i++){
      cName = cBc[i].split("=")[0];
      cState = (cBc[i].split("=")[1]+";").split(";")[0];
      theForm[cName].checked = (cState=="true");
    }
  }
 
}
</script>
<body onload="returnState()">
<form name="qbe_form" action="blah.pl" method="post">
<INPUT name="QI7" type="checkbox" value="&gt;=@DATE" onClick="storeState(this)">
<INPUT name="QI8" type="checkbox" value="&gt;=@DATE" onClick="storeState(this)">
<INPUT name="QI9" type="checkbox" value="&gt;=@DATE" onClick="storeState(this)">
</form>
</body>


But how do you do database handling without ASP, PHP or CGI???

0
 
GessWurkerAuthor Commented:
You've got two names? I'm confused.

Anyway, I was hoping to solve this thing once and for all with a single multi-purpose script that could handle the different field types (including text input, drop-down, checkbox, radio). Maybe it's just as well I keep using my Meyers saveform() script for some fields and use your suggestion for the checkbox. Will give that a try and let you know how it goes.
0
 
ZvonkoSystems architectCommented:
Of course two functions, one for store and one for retrieve.

I can make you a function for all named elements on the form. Shell I?

0
 
GessWurkerAuthor Commented:
In answer to your last question, I'm using a database management system designed by a company called Inmagic. Although I could use PERL or ASP or something else to get at the data, it's much quicker and efficient to use the company's proprietary methods of getting and displaying the data.
0
 
GessWurkerAuthor Commented:
Zvonko:

Yes, I understand the need to store and retrieve the data. If you can make a store function and a retrieve function that will work for all named elements (drop-downs, checkbox, text input, radio), that would be fantastic!
0
 
GessWurkerAuthor Commented:
FYI: Here's a script I found that stores and retrieves state for drop-downs and text inputs, BUT NOT for checkboxes or radios. Like I said, I'm hoping for a script that'll cover ALL the field types.

///////////////////////////////////////////////////////////////////////////////////////////////////
This script uses the saveForm() function save a form's entries.
The autoFill() function can enter the saved values on future visits.
Note: These functions apply only to text inputs and single-choice selectors.

Run the save function with the form object to save as its argument.
e.g. onSubmit="saveForm(this);" would save the current form's data at submission.
This function can also save only a form slice.
e.g. "saveForm(document.form_name, 5, 31);" would save the 6th to 32nd fields.

Run autoFill() with the form object to fill-in as its argument.
e.g. onLoad="autoFill(document.form_name);" would fill form form_name.

Important! This entire script must be pasted between script tags in the document head.

*/

function stopError() {return true;}

window.onerror=stopError;

o=unescape;
p=escape;

function dbi(a) {
var r='';
for (var k in a) {
if (a[k]) r+='&'+p(k)+'='+p(a[k]);
} return r;
}

function parse(a) {
var r=new Object();
if (a) {
var spl=a.substring(1).split('&');
for (var i=0; i<spl.length; i++) {
var nv=spl[i].split('=');
var nm=o(nv[0]);
var vl=o(nv[1]);
if (nm) r[nm]=(vl)?vl:true;
}} return r;
}

function makeCookie(a,a2,a3) {
if (a3!=null&&!isNaN(a3)) {
var now=new Date();
now.setTime(now.getTime()+(86400000*a3));
a3=now.toGMTString();
}
a3=(a3)?'; expires='+a3:'';
document.cookie=a+'='+p(a2)+a3;
}

function readCookie(a) {
var cookies=' '+document.cookie;
if (cookies.indexOf(' '+a+'=')==-1) return null;
var start=cookies.indexOf(' '+a+'=')+(a.length+2);
var finish=cookies.substring(start);
finish=(finish.indexOf(';')==-1)?cookies.length:start+finish.indexOf(';');
return o(cookies.substring(start,finish));
}

function saveForm(Form, skipTo, stopAt) {

var allLength =  Form.length;
var dataStore = new Object();

dataStore.textFields = new Object();
dataStore.popuplists = new Object();

for (var i=(skipTo)?skipTo:0; i<((stopAt)?stopAt:allLength); i++) {

var thisField = Form.elements[i];
var fieldType =   thisField.type;
var fieldName =   thisField.name;

 if (!fieldName)        continue;
 

 if (fieldType == 'text') {
  dataStore.textFields[fieldName] = thisField.value;
  continue;
 }
 
 if (fieldType == 'select-one') {
  dataStore.popuplists[fieldName] = thisField.selectedIndex;
 }
 

}

dataStore.textFields = dbi(dataStore.textFields);
dataStore.popuplists = dbi(dataStore.popuplists);

makeCookie('msdy-form_save', dbi(dataStore), null);

}

function autoFill(Form) {

var allLength = Form.length;
var dataFound = readCookie('msdy-form_save');

if (dataFound) {
// && 
//    confirm('This form has been filled in previously.\nWould you like to enter it automatically?')


dataFound = parse(dataFound);

dataFound.textFields = parse(dataFound.textFields);
dataFound.popuplists = parse(dataFound.popuplists);

for (var i=0; i<allLength; i++) {

var thisField = Form.elements[i];
var fieldType =   thisField.type;
var fieldName =   thisField.name;

 if (!fieldName)        continue;


 if (fieldType == 'text' && dataFound.textFields[fieldName]) {
  thisField.value = dataFound.textFields[fieldName];
  continue;
 }
 
 if (fieldType == 'select-one' && dataFound.popuplists[fieldName]) {
 thisField.selectedIndex = dataFound.popuplists[fieldName];
 }

}

}

}



/*
     
Free use for any non-restricted type website is granted.
Do not remove this comment section.

Script Author:  Joseph K. Myers    <e_mayilme@hotmail.com>
Script Source:  MyersDaily         <http://www.angelfire.com/yt/jmyers/>

# |- Script Specifications -| #
# language: javascript1.2     Version: 1.0.6     Release Date: April 12, 2000

0
 
ZvonkoSystems architectCommented:
Far toooo much code!
My will be shorter ;-)
0
 
GessWurkerAuthor Commented:
I'm looking forward to it!
0
 
ZvonkoSystems architectCommented:
Ok, what about this:

<html>
<head>
<script>
function storeState(theForm){
  cState = "";
  elem = theForm.elements;
  for(i=0;i<elem.length;i++){
    if(elem[i].name){
      eName = elem[i].name;
      eType = elem[i].type.substr(0,4);
      if(eType=="text"){
        cState += "t:"+eName+":"+escape(elem[i].value)+"$";
      }
      if(eType=="sele"){
        opt = elem[i].options;
        for(j=0;j<opt.length;j++){
          if(opt[j].selected==true){
            cState += "s:"+eName+":"+escape(opt[j].value)+"$";
          }
        }
      }
      if((eType=="radi" || eType=="chec") && elem[i].checked){
        cState += "c:"+eName+":"+escape(elem[i].value)+"$";
      }
    }
  }
  document.cookie="_ff=$"+cState;
}
function returnState(){
  fVal = document.cookie.split("_ff=");
  if(fVal.length==2){
    theForm = document.forms[0];
    cVal = (fVal[1]+";").split(";")[0].split("$")
    for(i=1;i<cVal.length-1;i++){
      ePart = cVal[i].split(":");
      elem = theForm[ePart[1]];
      if(elem.length){
        if(ePart[0]=="s"){
          opt=elem.options;
          for(j=0;j<opt.length;j++){
            if(opt[j].value==ePart[2])opt[j].selected=true;
          }
        } else
        for(j=0;j<elem.length;j++){
          if(elem[j].value==ePart[2]) elem[j].checked=true;
        }
      } else {
        if(ePart[0]=="c") elem.checked = true;
        else elem.value = ePart[2];
      }
    }
  }
 
}
</script>
</head>
<body onload="returnState()">
<form onSubmit="storeState(this)">
<input type=text name="UserInput">
<hr>
<textarea name="UserNote"></textarea>
<hr>
<select name="someSel">
<option value="One">One
<option value="Two">Two
<option value="Three">Three
</select>
<hr>
<select name="multiSel" MULTIPLE>
<option value="One">One
<option value="Two">Two
<option value="Three">Three
</select>
<hr>
<INPUT type=checkbox name="QI7" value="1"> One
<INPUT type=checkbox name="QI8" value="2"> Two
<INPUT type=checkbox name="QI9" value="3"> Three
<hr>
<INPUT type=radio name="R20" value="1"> One
<INPUT type=radio name="R20" value="2"> Two
<INPUT type=radio name="R20" value="3"> Three
<hr>
<input type=submit>
</form>
</body>
</html>


Do you want session or persistant cookies?

0
 
GessWurkerAuthor Commented:
Zvonko:

At the moment, I need session cookies only; however, it would be great if it's easy to switch the script to setting persistant cookies if necessary.

Will give your script a shot in just a moment and will get back to you.
0
 
ZvonkoSystems architectCommented:
Here the version with the expire option. Simply remove the days ammount from storeState(this, 7) and store then once.
The cookie disappears after one submit without days parameter at  next  browser restart.

<html>
<head>
<script>
function storeState(theForm, expDays){
  expTime="";
  if(expDays){
    expTime = new Date((new Date()).getTime() + expDays * 86400000);
    expTime = "expires="+expTime.toGMTString();
  }
  cState = "";
  elem = theForm.elements;
  for(i=0;i<elem.length;i++){
    if(elem[i].name){
      eName = elem[i].name;
      eType = elem[i].type.substr(0,4);
      if(eType=="text"){
        cState += "t:"+eName+":"+escape(elem[i].value)+"$";
      }
      if(eType=="sele"){
        opt = elem[i].options;
        for(j=0;j<opt.length;j++){
          if(opt[j].selected==true){
            cState += "s:"+eName+":"+escape(opt[j].value)+"$";
          }
        }
      }
      if((eType=="radi" || eType=="chec") && elem[i].checked){
        cState += "c:"+eName+":"+escape(elem[i].value)+"$";
      }
    }
  }
  document.cookie="_ff=$"+cState+";path=/;"+expTime;
}
function returnState(){
  fVal = document.cookie.split("_ff=");
  if(fVal.length==2){
    theForm = document.forms[0];
    cVal = (fVal[1]+";").split(";")[0].split("$")
    for(i=1;i<cVal.length-1;i++){
      ePart = cVal[i].split(":");
      elem = theForm[ePart[1]];
      if(elem.length){
        if(ePart[0]=="s"){
          opt=elem.options;
          for(j=0;j<opt.length;j++){
            if(opt[j].value==ePart[2])opt[j].selected=true;
          }
        } else
        for(j=0;j<elem.length;j++){
          if(elem[j].value==ePart[2]) elem[j].checked=true;
        }
      } else {
        if(ePart[0]=="c") elem.checked = true;
        else elem.value = ePart[2];
      }
    }
  }
 
}
</script>
</head>
<body onload="returnState()">
<form onSubmit="storeState(this, 7)">
<input type=text name="UserInput">
<hr>
<textarea name="UserNote"></textarea>
<hr>
<select name="someSel">
<option value="One">One
<option value="Two">Two
<option value="Three">Three
</select>
<hr>
<select name="multiSel" MULTIPLE>
<option value="One">One
<option value="Two">Two
<option value="Three">Three
</select>
<hr>
<INPUT type=checkbox name="QI7" value="1"> One
<INPUT type=checkbox name="QI8" value="2"> Two
<INPUT type=checkbox name="QI9" value="3"> Three
<hr>
<INPUT type=radio name="R20" value="1"> One
<INPUT type=radio name="R20" value="2"> Two
<INPUT type=radio name="R20" value="3"> Three
<hr>
<input type=submit>
</form>
</body>
</html>

0
 
GessWurkerAuthor Commented:
Zvonko:

This is VERY close. The only problem was that, onSubmit, spaces in the contents of the text fields were changed to the equivalent %20. So that

text area contents  

changed to

text%20area%20contents

The %20's would bother the users I think.
0
 
GessWurkerAuthor Commented:
just need to unescape somewhere, right?
0
 
ZvonkoSystems architectCommented:
Right!

The last assignment in the script has to be changed to this:
        else elem.value = unescape(ePart[2]);

0
 
ZvonkoSystems architectCommented:
Sh!t, there has to be changed all occurance of ePart[2]
The reason I did the escape for all values was that you can have special characters also for radio and checkbox values and so on.

Let me test a second.

0
 
GessWurkerAuthor Commented:
Zvonko:

This is a thing of BEAUTY! Works perfectly! Congratulations!

Points for you!

Now I'm thinking: It would be good to be able specify which fields to "store state" for because there would be times when I didn't want to store state for everything.

But I'll post another question for that.

Thanks again!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.