SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : User Persistence Features of IE 5
By Kenneth Cox

This article will show you how to use XML data islands, the userData behavior, and DHTML to implement a custom user preferences application for your IE 5 web site users.

The sample lets a user drag an item (bookmark) complete with picture and link to an area setup on our web page to handle drop events. Inside of the page we also have an XML island that we will use to store newly added items for later saving to the userData object.

The code to implement this functionality does several things. First, we handle drag and drop operations by setting up our source IMG tags we want to drag and give them an event handler as shown below:
<IMG height=40 id=BK1 ondragstart=initDropInfo(this.id) 
     src="images/Files.gif" width=40 
     LINK="link1.htm">
    

At the style block we declare the userData behavior:
    
<STYLE>
  .userData { behavior:url(#default#userdata); }
</STYLE>
      

After declaring our userData we can assign any element we wish to save information to the userData class name.
    
<SPAN CLASS=userData 
      id=XMLPREF style="DISPLAY: none">
         Some arbitrary text
</SPAN>    
      

Next up, we add our XML island to the document that we will use to update with bookmark information
<XML id=PREFS>  
  <BOOKMARKS>
  </BOOKMARKS>
</XML>
    

To be able to accept a dragged item we set up an element to be a drop target:
<SPAN ID="DROPPOINT" STYLE="BACKGROUND-COLOR: 
      buttonface; HEIGHT: 145px; WIDTH: 414px" 
      ondragenter="fnCancelDefault();" 
      ondragover="fnCancelDefault();" 
      ondrop="getDropItem();"ondragstart='event.returnValue=false'>
</SPAN>
    

The event handlers for the SPAN tag "DROPPOINT" (above) handle our drag and drop operations and work as follows:
function fnCancelDefault() { 
  event.returnValue = false; 
}
      
function getDropItem() {
  var oText = window.event.dataTransfer.getData("TEXT");
  window.event.dataTransfer.dropEffect='copy';
  ...
}

Essentially, we use the dataTransfer object to get the data that was added when we started a drag operation on the Img tags (ondragstart).

Once we have this information, we copy it and and paste it into our the hidden span tag created earlier called "XMLPREF". We do this so we can verify whether the user has added this item before. This way we know whether or not to display it in the real display area called "DROPPOINT". Think of the SPAN tag "XMLPREF" as a temporary storage bin to keep dragged items until we verify them. The rest of the function "getDropItem" that is not shown verifies this when the user releases the item on the drop target.

Next, we want to store information about items being moved to the drop target in the userData in structured format, so we use an XML island on the client side to save added items to.

At first it may seem confusing to refer to an element we want to save to. This simply means that we are going to give our target element a new attribute, then in script code save information to that attribute, then use the userData behavior to save and store our attribute as an XML file.

How do we save XML to a SPAN tag using userData behavior?

Using the SPAN tag offers us a way to store data to it, and hide it at the same time.  Hiding the SPAN tag also gives us a way to store temporary information while we programmatically check the information and decide what to do with it. Additionally, we can create an Attribute on the SPAN tag and store userData as a value of that attribute. By declaring the class name as "userData" we ready our tag for persistence.

Because we want to store items in the DROPPOINT span tag  and access them later in a structured way, we save the xml data island with new bookmarks added to the userData behavior enabled SPAN tag attribute "USERPREF".

Saving the data in a structured format creates a file on the users computer that is named in our sample "USER_PREFS". In our example, we save the XML island to the Attribute "PREFERENCES" we create in code on the SPAN tag. We copy our XML Island including any bookmarks we may have added and put it in a global variable object called g_XMLDOC. Once we have this key piece of information we can save the XML as userData by setting the newly created PREFERENCES attributes value to our g_XMLDOC xml. The last step is to actually save the new attribute and give it a name for saving as a file using userData behavior. This code is shown below:
function checkLoad() {
  ...
  g_XMLDOC = document.all("PREF").XMLDocument; //xml data island
  XMLPREF.setAttribute("PREFERENCES",g_XMLDOC); //create  attribute 
  XMLPREF.save("USER_PREFS");  //save as file
  ...
}

Loading and accessing the userData "USER_PREFS" is easy:
function checkLoad() { 
  XMLPREF.load("USER_PREFS");
  XMLPREF.innerText=''
  var isValidXML = XMLPREF.getAttribute("PREFERENCES"); 
  ...  
}

Once we load the userData saved in USER_PREFS, we create an ActiveX object to implement the XMLDOM to access the xml stored within it.

So just where is this userData file stored?
For Windows machines, look in:

WINNT OR WINDOWS DIRECTORY
   |
   PROFILES
       |
       YOURPROFILENAME
              |
              APPLICATIONDATA
                     |
                     MICROSOFT
                         |
                         INTERNET EXPLORER
                                |
                                USERDATA
 

Under the USERDATA folder are folders that contain user data XML files. Double clicking one of the files will open it in your web browser and display it's contents.

Summary

Accessing and saving user preferences using XML gives you maximum flexibility and portability that other schemes can't offer, such as cookies or session variables. Using the userData allows you to store structured information and access it in a uniform way. Because it is structured you could port the xml to a file on the server or database and exploit it any way you see fit.

Allowing your users to customize your web pages provides a greater user experience that adds real benefits to your users and is sure to win return visits to your site.

Happy Coding!
Kenneth W. Cox

Page 1:User Persistence Features of IE 5
Page 2:User Persistence Demonstration