Persisting Form Data

Using HTML to design forms comes with some drawbacks, namely the need for a server or client-side script to process the form data. The saveSnapshot behavior can be used to save a Web page and persist the form data directly within the page itself. This allows a larger audience to use Web forms for day-to-day activities without needing a special script to process and deliver the information.

An expense report can be created with HTML, persisted with the saveSnapshot behavior, and then sent in e-mail to an employee or employer with no specialized scripting.

Essential Persistence Preparations

The saveSnapshot behavior requires certain elements in order to function: a meta element, a style block, an ID attribute, and a CLASS attribute on the object to persist.

security note Security Alert  Using this behavior incorrectly can compromise the security of your application. This behavior persists data as plain text in a saved Web page. Text is not encrypted and therefore not secure. Any application that has access to the drive where the page is saved also has access to the data and can tamper with it. Therefore, it is recommended that you not persist sensitive data like credit card numbers. For more information, see Security Considerations: DHTML and Default Behaviors.

The META Tag and STYLE Block

The meta and style elements are used to inform the browser that the Web page is persistent.

<META NAME="save" CONTENT="snapshot">
<STYLE>
   .saveSnapshot {behavior:url(#default#savesnapshot);}
</STYLE>

The CLASS Attribute

The CLASS attribute identifies the type of persistence the element is using.

<ELEMENT CLASS=saveSnapshot ID=oPersistElement.. >

The STYLE Attribute Set Inline

The style can also be set inline with the element.

<ELEMENT
   CLASS="saveSnapshot"
   STYLE="behavior:url(#default#savesnapshot)"
   ID="oPersistElement"
>

Defining a Form to Persist

Persisting form data using the saveSnapshot behavior does not require additional scripting. Therefore, the entire form will appear almost like any other form except for the required CLASS and ID attributes. These attributes may either be placed on the form object, or on the individual form elements.

Persisting the Entire Form

The following form only needs a defined CLASS in order to persist.

<FORM ID=oPersistForm CLASS=saveSnapshot>
First Name: <INPUT TYPE=text>
Last Name:  <INPUT TYPE=text>
Exemptions: <INPUT TYPE=text>
</FORM>

By giving the form object an ID and a CLASS of saveSnapshot, the entire form will persist. If persisting only selected elements is desired, then the ID and CLASS attributes can be moved from the form object onto those elements.

In the following example, the First Name and Last Name text fields are persisted, but the Exemptions field is not. The entire Web page for this form would include the HTML form, the essential persistence information, and html, head and body elements.

<FORM>
First Name: <INPUT TYPE=text ID=oPersistInput1 CLASS=saveSnapshot>
Last Name:  <INPUT TYPE=text ID=oPersistInput2 CLASS=saveSnapshot>
Exemptions: <INPUT TYPE=text>
</FORM>

In the next example, a complete HTML file is shown where all text fields are persisted.

<HTML>
<HEAD>
<META NAME="save" CONTENT="snapshot">
<STYLE>
   .saveSnapshot {behavior:url(#default#savesnapshot);}
</STYLE>
</HEAD>
<BODY>
<FORM ID=oPersistForm CLASS=saveSnapshot>
First Name: <INPUT TYPE=text>
Last Name:  <INPUT TYPE=text>
Exemptions: <INPUT TYPE=text>
</FORM>
</BODY>
</HTML>

Code example: https://samples.msdn.microsoft.com/workshop/samples/author/persistence/saveSnapshot_ht1.htm

Persisting Form Data in a Script Block

The saveSnapshot behavior allows the script block to persist variables. Comments, functions, and script objects such as arrays will be automatically removed.

Persisting the script block is no different than for any other object, except that the information must be placed into the persistent block, which involves some scripting.

<SCRIPT CLASS=saveSnapshot ID=oPersistScript>
   var sPersistValue="";
</SCRIPT>
:
Enter some text: <INPUT TYPE=text ID=oInput>
Click to save:
<INPUT TYPE=button VALUE="Save" onclick="sPersistValue=oInput.value;">
Click to load:
<INPUT TYPE=button VALUE="Load" onclick="oInput.value=sPersistValue;">
:

Code example: https://samples.msdn.microsoft.com/workshop/samples/author/persistence/saveSnapshot_ht2.htm

Validating and Persisting A Trip Expense Report

Web applications, expense reports, and other forms that would benefit from using the saveSnapshot behavior often times need a means of validation. The ability to present information in several formats also may be required for whomever receives the completed form.

A combination of persistent form values and persistent script variables can be used to create a dynamic, persistent form. Such a form can provide different variations of format to easily import or export the information into other formats such as mailing lists, databases, and so on.

A trip expense report would need to fit the needs of at least two people: the person entering the information and the person reading the completed form. Depending on the needs of the company, the information would need to be transferred into another application for billing and logging procedures, such as a database, spreadsheet, or word processing file. Therefore, the Web page will need to have an original version and a completed version. This can be done dynamically.

First, the form needs to be added and set to persist. A persistent script block can be used to determine when the form was submitted, if the form was validated, and what format the information should take.

<SCRIPT CLASS=saveSnapshot ID=oPersistScript>
   var bIsValid=false;
   var bIsComplete=false;
   var sFormat="Edit";
</SCRIPT>

Two Boolean variables are used to determine the validation and completion state of the form, and a string is used to determine what format the form takes when the page is loaded. A function is added to validate the form and set the persistent variables.

/* The validate function determines:
   1) if everything is filled in, and
   2) what the form will look like when it is reloaded.
*/
function Validate(){
   var iAll=document.all.length;
   var bValid=true;
   for(var i=0;i<iAll;i++){
      window.status=i + " of " + iAll;
      var vForm=document.all[i];
      if(vForm.type=="text"){
         if(vForm.value.length==0){
/* Look through the entire document.
   If an empty form element is found that is not marked as extra ...
*/
            if((vForm.id!="oStub2")||
               (vForm.id!="oStub3")||
               (vForm.id!="oTCo2")||
               (vForm.id!="oTCo3")){
/* then set the Boolean to false.
   This is not the same Boolean as the persistent Boolean.
*/
               bValid=false;
            }
         }
      }
   }
   if(bValid==false){
// If the Boolean is false, alert the user that the form is invalid.
      alert("This form is invalid."
      + "Review the log and make the necessary corrections.");
   }
   if(bValid==true){
// If the Boolean is true, set the persistent Booleans to true.
      alert("This form has been validated." + 
          + "Save this page as Web Page, HTML Only."
          + "When it is reloaded, the new style will take effect.");
      bIsValid=true;
      bIsComplete=true;
      sFormat="Output";
   }
}

A second function is used to build the output from the form values after the form has been persisted.

function fnPopulateOutput(){
/* Since the form data is still in the fields,
   the form is hidden and a new display is made
   by using the persisting data.
*/
   oEdit.style.display="none";
   oOutput.style.display="block";
   var iAll=document.all.length;
   var bValid=false;
   for (var i=0;i<iAll;i++){
      window.status=i + " of " + iAll;
      var vForm=document.all[i];
      if(vForm.type=="text"){
         if(vForm.value.length!=0){
/* If the form does not contain empty entries,
   write the values to the output.
*/
            bValid=true;
            oOutput.innerHTML+=document.all[i-2].innerHTML + 
               ' ' + vForm.value + '<br>\n';
         }
      }
   }
   if(bValid==false){
/* If an empty value is discovered,
   then write an appropriate error message.
*/
      oOutput.innerHTML+='Error: The form contains no data.<br>\n';
   }
}

By keeping the form visible when the page starts, browsers that do not support persistence, Cascading Style Sheets (CSS), or Microsoft JScript are still able to view the completed form.

Code example: https://samples.msdn.microsoft.com/workshop/samples/author/persistence/saveSnapshot_ht3.htm