(User) Profile documents & mandatory fields

It has been a while since I wrote here something so I will just write something I did today. Right now I am doing some prototyping for a demo-application (web) which generally will be an ordering system.

The application uses currently (user) profile documents. It was a bit hard to find code to copy & paste, because most examples where not so detailed (just words, no code) or they used actual Notes documents, not profile documents.

So how does it work? When opening the form via an url (form_name?OpenForm) a WebQueryOpen Agent is initiated which runs the following simplified code:

Sub Initialize
 Dim s As New NotesSession
 Dim db As NotesDatabase
 Dim profiledoc As NotesDocument
 Set db = s.CurrentDatabase
 Set profiledoc = db.GetProfileDocument(“UserProfile”, s.UserName) 
 Dim currentdoc As NotesDocument
 Set currentdoc = s.documentcontext 
 currentdoc.Tx_UserLanguage = profiledoc.Tx_UserLanguage(0)
 currentdoc.Tx_UserCostCenter = profiledoc.Tx_UserCostCenter(0)
 currentdoc.Tx_UserGLAccount = profiledoc.Tx_UserGLAccount(0) 
 currentdoc.Tx_UserTechName = profiledoc.Tx_UserTechName(0)
 currentdoc.Tx_UserTechPhone = profiledoc.Tx_UserTechPhone(0)
 currentdoc.Tx_UserDeliveryStation = profiledoc.Tx_UserDeliveryStation(0) 
End Sub

So basically it picks (when available) the profiledoc and copies values from it to the opened form. I could have used IsProfile to check if we actually working with a profile document…

In the WebQuerySave event I run a different code which writes away information entered in the form to the profile document:

Sub Initialize
 Dim s As New NotesSession
 Dim db As NotesDatabase
 Dim profiledoc As NotesDocument
 Set db = s.CurrentDatabase
 Set profiledoc = db.GetProfileDocument(“UserProfile”, s.UserName) 
 Dim currentdoc As NotesDocument
 Set currentdoc = s.documentcontext 
 profiledoc.Tx_UserLanguage = currentdoc.Tx_UserLanguage(0)
 profiledoc.Tx_UserCostCenter = currentdoc.Tx_UserCostCenter(0)
 profiledoc.Tx_UserGLAccount = currentdoc.Tx_UserGLAccount(0) 
 profiledoc.Tx_UserTechName = currentdoc.Tx_UserTechName(0)
 profiledoc.Tx_UserTechPhone = currentdoc.Tx_UserTechPhone(0)
 profiledoc.Tx_UserDeliveryStation = currentdoc.Tx_UserDeliveryStation(0) 
 Call profiledoc.Save( True, False )
End Sub

Later I think will use a similar functionality to write information back to the profile document, that hasn’t been entered before in the user profile, from any sensible point in the application (like in a final order form)…

The first ‘problem’ i faced was that a ‘normal’ JavaScript submit would give me a ‘form processed’ message.  Since I had a nice ‘update’ button in mind so the user should stay in the form opened I was ‘forced’ to use a common known Domino ‘work around’.

updatebuttons

The reference under the ‘Save Setting’ link inititates a JS function which actually initiates the function under a Notes button, that is being stored in a hidden <div>

function submitForm(){
 document.all.MySaveButton.onclick();
}

hidebutton

So the JS function initiates the @Command([FileSave]) function which initiates the WebQuerySave event and thereby the user profile is being updated on the background.

Since the document will be re-opened due to a refresh (don’t ask me why what forces this) the WebQueryOpen events initiates again and the saved information is being re-placed on the refreshed form…

So far so good, where is the news?

I wanted to make visible which fields are supposed to be mandatory and highlight them like in the next example:

mandatory empty

Here you have ‘normal’ fields with a gray border, and ‘normal’ entry fields that are supposed to be also ‘mandatory’. So for these fields I add both classnames.

field properties

On the JS onload event I initiate the following function:

checkISValid();

The code for this function is pretty basic and contains (in this example) no actualy validation, just a check if the field is empty or not:

function checkISValid(){
 var checkFields = new Array();
 checkFields = getElementsByClassName(document, “input”, “mandatoryField”)
 for (x in checkFields){  
  if (checkFields[x].value != “” ){
   checkFields[x].className = “entryField”; 
  }
 }
}

So if the field with classname mandatoryField is empty it will get the mandatoryField class ‘removed’ (overwritten) and it will look like this:

mandatory field entered

I think in this way it is pretty clear for the user which information is still missing…

Here is the ‘getElementsByClassName’ function borrowed from this site:

function getElementsByClassName(node,tag,searchClass) {
 var classElements = new Array();
 if ( node == null )
  node = document;
 if ( tag == null )
  tag = ‘*’;
 var els = node.getElementsByTagName(tag);
 var elsLen = els.length;
 var pattern = new RegExp(“(^|\\s)”+searchClass+”(\\s|$)”);
 for (i = 0, j = 0; i < elsLen; i++) {
  if ( pattern.test(els[i].className) ) {
   classElements[j] = els[i];
   j++;
  }
 }
 return classElements;
}

Ps. for some nice JS onFocus effect like this:

on focus effect

You could add something like this:

on focus JS code

Don’t forget to reset coloring on the onBlur event 😉

9 thoughts on “(User) Profile documents & mandatory fields

  1. Thomas Bahn 2007-August-30 / 9:28 pm

    Hi Patrick,

    I like the border to signal mandatory fields. I had just some ideas about your implementation:

    You could use a computed for display $$Return field with a formula that calculates the EditDocument url for the current document and places it in double (?) square brackets. Something like :
    “[[” + currentDB_URL + “/0/” + currentDoc_UNID + “?EditDocument]]”
    This will redirect the browser to the document in edit mode. Or use OpenDocument url command to open it in display mode. Or make a more complex formula….

    Second thought: Why do you use a hidden button? You could use CSS to “format” the button to look like your example.

    Third: I would not use document.all.MySaveButton without need, since this is IE only. You could use document.getElementById(“MySaveButton”) instead.

    Fourth point: Your checkISValid() function overwrites the CSS class. This way, you don’t know that a field is mandatory after the user has filled in some data. The problem is that the user could empty the field afterwards. I think, you could apply a black border to the elements (input) style attribute. If the user empties the input, remove the direct border style, thus the class border is used again.

    And finally: If this is a web-only solution, why do you want to use user profile documents instead of normal documents?

    Ciao
    Thomas
    http://www.assono.de/blog.nsf/

  2. quintessens 2007-August-31 / 8:19 am

    Hej Thomas,

    you are right on some points, as I stated I was prototyping for a demo and in the progress I did not care so much about correctness.

    Concerning the user profiles; we decided to switch back to normal Notes documents, because the advantage of real profile documents and caching options does not seem to be an advantage for Web users. Also after reviewing the customer wants to be able to do some administration on the profiles so normal documents are more obvious.

    About the ‘Save’ button; I overlooked the document.all, that’s ofcourse not compliant for most browsers. I hide the button because I wanted to present a more noticable, graphic element with a submit function…

    I did not enter the onBlur event for an entryField, there I check if the mandatory fields is according the validation rules…

    But thanks for your advice!

  3. Thomas Bahn 2007-August-31 / 11:09 am

    Hi Patrick,

    “I hide the button because I wanted to present a more noticable, graphic element with a submit function”
    This could be done with some CSS for the button. Change border, colors, set background graphic…

    “I did not enter the onBlur event for an entryField, there I check if the mandatory fields is according the validation rules”
    But you remove the red border. Do you restore it, after the user has emptied the field?

    Ciao
    Thomas
    http://www.assono.de/blog.nsf/

  4. quintessens 2007-August-31 / 11:47 am

    You could use something like:

    this.value = trim(this.value);

    if (this.value != “”) {
    this.className = “entryField”;
    }
    else {
    this.className = “entryField mandatoryField”;
    }

    better would be to capture it initial classname when you enter the field so you can restore it after you have left the field…

  5. Tommy Valand 2007-August-31 / 3:50 pm

    @quintessens: There is no native trim-function in the current version of JavaScript (ECMAScript 3), but this workas a trim (removes leading and trailing white-spaces):

    [String].replace(/^\s*|\s*$/g, “”)

    e.g.
    var str = ” aa “;
    str = str.replace(/^\s*|\s*$/g, “”) -> “aa”

  6. quintessens 2007-August-31 / 7:37 pm

    indeed, the trim is a JS function I forgot to post…

  7. Nooruddin N Khamgaonwala 2007-September-8 / 11:58 am

    Hi,

    Pls send me how to sort the second column in web application where is opened as embeded view.
    so pls suggest the solutiom.

    Regards,
    Nooruddin N Khamgaonwala

  8. sasikanth 2007-September-10 / 3:49 pm

    hai,
    i want to know more about this lotus notes in detail can u send me details,
    recently icame to know about this , so anybody intrested pls send me.
    bye,
    sasi

  9. Tanny O'Haley 2008-May-6 / 7:58 pm

    You can add a trim function to the string object with the following code

    // If the String object doesn’t have a trim method add one.
    if(typeof “”.trim == “undefined”){
    // Trim leading and trailing spaces from a string.
    String.prototype.trim = function(str) {
    str = this != window? this : str;
    return str.replace(/^\s+/g, ”).replace(/\s+$/g, ”);
    }
    }

Leave a reply to Tommy Valand Cancel reply