PermaLinkDomino Facelift: How the javascript calls get attached to the form05:26:11 AM
Written By : Lance SpellmanCategory : Lotusphere
This is the 3rd article in the introduction to the Domino Facelift. The first article's here if you need to start from the beginning.

Let's recap:
  • we can get the DXL for a form and find more properties to reveal to the browser.
  • we can turn that DXL information into a series of javascript calls
  • we can create a javascript library of functions that provide implementations for those calls (such as a date picker)
But how do we get the function calls we create from steps 1 and 2 to the browser so that they can execute the implementations of step 3? That's what we'll talk about now.

There are lots of ways to skin this cat. Let's list them:
  • Trigger some code when the Form is saved in the Designer client and add the calls directly to the form itself
  • Trigger some code when the Form is saved in the Designer client and create a custom JS library containing those function calls
  • When the form is rendered in the browser, go examine the DXL and dynamically add the function calls to the page
  • Write an nsfhook so that the Domino rendering engine finds the additional function calls and dynamically adds them to the page
Number 1 sounds like a great idea, but there are some negatives. When Domino renders a form to the browser, it only shows those design elements meant to be seen by the browser. Without that rendering, the code would have to figure out every design element on the page, evaluate hide/whens, figure out which subforms are to be included and under what circumstances. That would be tough. Also, the form design would now have these additional calls embedded into the form.

Number 2 has the same issues as number 1, but with the calls now extracted out into a JS library script.

Number 3 is what we've done with this version of the Facelift. It eliminates the complexity of figuring out which items Domino's actually going to render to the page because Domino's already completed that task. Now, given the elements actually present in the browser, we can call back to the server for the additional design information about those elements. This is accomplished via the script tag added to the bottom of the form.
<script language=javascript src='/facelift/facelift.nsf/dfl_StaticForm.js' /></script>
That .js file is in Script Libraries in the Facelift database. When it executes, it sets a timer event on the web page that waits for the page to finish loading. Then, it grabs the form name, does a little housekeeping and creates a url for calling a LS agent back on the server. Here's that code from the fl_onLoad function of the dfl_StaticForm.js script library.
var src = "/" +g_faceliftDB + "/dfl_dynamicForm.js?OpenAgent&form=" + formName
var fieldsNames = "&"
var EachElement
for (var Count=0; Count      EachElement = frm.elements[Count]
     if(fieldsNames.indexOf("," + EachElement.name +":" + EachElement.type + ",")==-1) {
          if(EachElement.type!="hidden"){
               fieldsNames += EachElement.name +":" + EachElement.type + ","
          }
     }
}
src += "&Fields=" + escape(fieldsNames.slice(1))
var CustomScript = document.createElement('script');
CustomScript.setAttribute('src', src);
CustomScript.setAttribute("LANGUAGE", "javascript");
CustomScript.setAttribute("type","text/javascript")
document.body.appendChild(CustomScript);
That is a holy hack my friends...using an included js file to create another call for a javascript file on the fly. This is what Dwight calls "dynamic js" and his way around using AJAX. When the last line of that code runs, it will have created a new script tag in the body of the page that will immediately execute and call a LotusScript agent.

The agent will read the query string for the form to get the form name to examine. It checks to see if a valid cached document has been created for that form that contains all the DXL to JS conversions. If it has, and the date on the cached doc is more recent than the last time the form design was modified, it sends the contents of the document to the browser. The document contents are the JS calls that add behavior to the design elements (e.g. a date picker). Here's the content of the GetCacheDoc function in the dfl_DynamicForm.js agent in the Facelift database:
Set FormLookupView = gcmn_CurrDB.GetView("FormLookup")
Set g_CacheDoc = FormLookupView.GetDocumentByKey( DBPath & "~" & FormName)
If g_CacheDoc Is Nothing Then
     Set g_CacheDoc = New notesdocument( gcmn_CurrDB)
     g_CacheDoc.Form = "fl_Form"
     g_CacheDoc.DBPath = DBPath
     g_CacheDoc.FormName = FormName
End If
g_CacheDoc.warnings= ""
Set targetdb = New NotesDatabase( gcmn_currdb.Server, DBPath)
If Not targetdb.IsOpen Then
     Call ReportFATALERROR("Unable To Open Database")
End If
Set nc = targetdb.CreateNoteCollection(False)
nc.SelectForms = True
nc.SelectionFormula = |$TITLE = "| & FormName & |"|
Call nc.BuildCollection
If nc.Count = 0 Then
     Call ReportFATALERROR("Unable To Find Form")
Elseif nc.count > 1 Then
     Call ReportFATALERROR("Found More than one Form")
End If
formNoteid = nc.GetFirstNoteId()
Set FormDoc = TargetDB.GetDocumentByID( FormNoteID)
If FormDoc Is Nothing Then
     Call ReportFATALERROR("Unable to retrieve form by noteid")
End If
If Len(g_CacheDoc.SavedXML(0)) = 0 Then
     Call ParseNC(NC)
Elseif Getparameter( gcmn_CTXDoc.http_referer(0), "deletecache") = "yes" Then
     Call ParseNC(NC)
Elseif isnewer( formdoc, g_CacheDoc) Then
     Call ParseNC(NC)
End If
If the cache doc has not been created or is not valid (form design has been updated), then it examines the DXL for the form, performs the DXL to JS convesions, stores them in a cache doc and sends the contents to the browser. This is how the JS calls for additional functionality get attached to the page. Is it a hack, yes. Would it be a problem to call agents in large scale environments? Potentially. How often do users call for forms in edit/open mode?

For those who want to avoid the agent call, the dynamic script can be eliminated. After you've put this code in place and previewed the form, the cache doc has all the function calls required. Simply remove the call to the dfl_StaticForm.js script on the form. Put the function calls in the JSHeader, and add an onLoad to the body to execute them.

Next articles:
  • Dwight puts a wizard around "facelifting a form"
  • Series on how the View facelift works
  • Examining the nsfhooks approach to adding behavior directly through the Domino Web Engine
Comments :v

1. Kary Forth02/13/2006 08:01:03 AM
Homepage: http://www.projectedge.com


Keep the articles coming...




2. Glenn Kohner03/01/2006 09:32:25 AM
Homepage: http://www.vintara.com


I would love to see this important project succeed. Why not use AJAX ? Is there a hosted version of the facelift database ? Are you looking at dojotoolkit?




3. William beh05/19/2006 02:17:34 AM
Homepage: http://notesweb2.blogspot.com/


Can't wait for any prototype of the facelift db.
Any update recently?




4. a11/26/2006 11:25:52 PM
Homepage: http://a





5. 11/26/2006 11:26:16 PM





6. Dwight Wilbanks05/28/2008 01:10:23 PM
Homepage: http://www.dwightwilbanks.org


test




Enter Comments^


Email addresses provided are not made available on this site.





You can use UUB Code in your posts.

[b]bold[/b]  [i]italic[/i]  [u]underline[/u]  [s]strikethrough[/s]

URL's will be automatically converted to Links


:grin: :-) :angry: ;-) :emb: :cry: :lips: :-x :laugh: :cool: :-\ :rolleyes: :huh: :-p :-D :-o :-(
bold italic underline Strikethrough





Remember me    

Add Manual Trackback
Please enter the details of the trackback post. Your trackback will not appear on the site until it has been verified. This won't be immediate, as trackbacks are validated on a scheduled basis. Be patient.











Powered By :

BlogSphere

Join The WebLog Revolution at BlogSphere.net

DFL Project
Links
RSS News Feed RSS Comments Feed Podcast Feed Blog Admin OpenNTF BlogSphere