User Application Approval Forms with Dynamically Generated MV CheckboxPicklists or Text Picklists

wschreiber

By: wschreiber

February 12, 2010 6:16 am

Reads: 530

Comments:7

Rating:0

It is quite straightforward to use Designer and create IDM request/approval forms that have statically defined checkbox or picklist options:

  • Add an multi-valued CheckboxPicklist or Picklist field to both, request and approval forms
  • Store the user-requested choices into flowdata by adding a request “Post activity” mapping item
  • Use the approval “Pre activity” mapping to retrieve the requested choices into the approval form with flowdata.getObject

In this approach, you’re hard-coding the choices into the CheckboxPicklist field, while the requested choices are transported through flowdata.

So far, so good.

Things become trickier, when you do not have a static list of choices that can be hard-coded in Designer.
Assume, your checkbox or picklist choices need to be dynamically generated through a DAL list or query.

Doing this in the request form isn’t a big problem, since you can simply use the “Pre Activity” mapping activity to load the list, or you create a little onload() event script with a line like


// field:onload()
IDVault.globalList( field.getName(), "myDalGlobalList" );

//

The dynamic options are displayed when the form loads and the users can happily make their choices

Now, for the approval form you need to differentiate two cases:

  • a) the approver just needs to see the requester’s choice, then approve/deny the request.
  • b) the approver needs to be able to modify the selected options before approving/denying the request.

Case a) still is simple: you do not need to load the whole set of available options, you just need to show what was selected by the requester.
To retrieve this selection and display it on the form, you can use a read-only MV form field like a Picklist or a TextArea, and fill the field during a “Pre Activity” mapping activity
You could, for example, have used a Request checkbox list field “myChoices”, then saved the user input during a Request Post Activity Mapping into “flowdata.start/request_form/myChoices”. Then the Approval Pre Activity Mapping could retrieve the data with flowdata.getObject(‘start/request_form/myChoices’). Easy enough.

Case b) Now, this outlined approach will not work, when you want to allow the approver to edit the requester’s selection. You could still load the available options from a global list during onload() and try to get the requestor’s input in the Approval Pre Activity; This will fail, since loading the valid options with onload() happens after trying to set the requester’s selection in the Pre Mapping. The selected options are lost, since they cannot be validated.

However, you could create some ECMAScript code that allows you to dynamically load the available options in request and approval forms, while still being able to transport the requested options to the approval form.

Here’s the way to proceed:

  • Use identical field names for the picklists in request and approval forms
  • Load the available checkbox/picklist options in request and approval forms during a field:onload() event according to your needs, e.g., by adding code like

    // field:onload()
    IDVault.globalList( field.getName(), "myDalGlobalList" );
    
    //
  • Add one hidden text area field to both, the request and approval form. This field is used to transport the choices of all other checkbox/picklist fields via flowdata. You only need one such hidden field, and it can take care of one or multiple list fields.
    During testing you may want to set it to visible, but in production it should be hidden.
    In this example we create a field named “hiddenTextArea”

    The Request Post Activity Mapping for this field stores the contents into “flowdata.start/request_form/hiddenTextArea”;
    The Approval Pre Activity Mapping for this field retrieves the contents with “flowdata.getObject(‘start/request_form/hiddenTextArea’)”

  • Now we need some ECMAscript logic to store the user input from all selected checkbox/picklists into that hidden field, then to restore the selection on the approval form.

    For this purpose we create a script that stores and extracts MV choices into a transportable text. Here’s one way to do achieve this:

    In designer, use the “scripts” tab of both, request and approval form, create an inline script and copy this scriptlet into both (those of you who are more familiar with scripting will know better places to store the scripts):

    // form:inline script
    
    var delimFields = "|";
    var delimFieldname = ":";
    var delimValues = ";";
    
    /** stored a field selection to hidden helper field
         call during onchange of the MV list
         e.g., storeSelection( form, field, "hiddenTextArea" );
    **/
    function storeSelection( form, field, targetFieldName )
    {
       try
       {
          var newVal = field.getName() + delimFieldname + field.getValues().join( delimValues );
    
          // extract packed string into object
          var current = new Object();
          var varAll = form.getValue( targetFieldName );
          var varFlds = varAll.split( delimFields );
          for ( var i = 0; i < varFlds.length; i++ )
          {
             var valFld = varFlds[i].split( delimFieldname );
             if ( valFld.length < 2 ) continue;
             current[ valFld[0] ]	= varFlds[i];
          }
          current[ field.getName() ] =  newVal; // update or overwrite
    
          // create new packed string
          var newObj = "";
          for ( var fldId in current )
          {
             newObj += ( newObj.length>0 ? delimFields : '' ) + current[ fldId ];
          }
          form.setValues( targetFieldName, newObj )
       }
       catch ( e )
       {
          form.showDebugMsg( e.toString() );
       }
    }
    
    /** extract a stored selection from hidden helper field
         call during onload of the MV list
         after dynamically loading the options
         e.g., retrieveSelection( form, field, "hiddenTextArea" );
    **/
    function retrieveSelection( form, field, targetFieldName )
    {
       try
       {
          var varAll = form.getValue( targetFieldName );
          var varFlds = varAll.split( delimFields );
          for ( var i = 0; i < varFlds.length; i++ )
          {
             var valFld = varFlds[i].split( delimFieldname );
             if ( valFld.length < 2 ) continue;
             // identify the relevant field
             if ( valFld[0] != field.getName() ) continue;
             // extract the field choices
             var newVals = valFld[1].split( delimValues );
             field.select( newVals );
             break;
          }
       }
       catch ( e )
       {
          form.showDebugMsg( e.toString() );
       }
    }
    
    //

    Now we’re nearly done.

  • On the request form, we need to call the script to save the users’ selection.
    For each relevant MV checkbox or picklist on the request form, add a field:onchange() event with this code

    // onchange()
    storeSelection( form, field, "hiddenTextArea" );
    
    //
  • On the approval form, we need to call the script to restore the users’ selection.
    For each relevant MV checkbox or picklist on the approval form, add an field:onload() event with this code

    // onload()
    
    // first load your dynamic options - modify with the respective call to load your option list
    IDVault.globalList( field.getName(), "myDalGlobalList" );
    
    // now restore the users' selection from the request form
    retrieveSelection( form, field, "hiddenTextArea" );
    
    //

Versions:
IDM / RBPM 3.5 / 3.6 / 3.7
IDM Designer 3.5

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

Tags:
Categories: Identity Manager, IDM Designer, Technical Solutions

Disclaimer: As with everything else at NetIQ Cool Solutions, this content is definitely not supported by NetIQ, so Customer Support will not be able to help you if it has any adverse effect on your environment.  It just worked for at least one person, and perhaps it will be useful for you too.  Be sure to test in a non-production environment.

7 Comments

  1. By:boz

    Hi,

    Thanks for sharing info, but I feel that the function:
    —-snip
    function retrieveSelection( form, field, targetFieldName )
    {
    try
    {
    var varAll = form.getValue( targetFieldName );
    var varFlds = varAll.split( delimFields );
    for ( var i = 0; i

    —– snip end

    is missing some info?

  2. By:ee0001

    Hello,

    Thanks for posting it, this was very helpful!
    However I get it to work in Firefox, IE6 and Chrome but the results don’t show up on IE8. My flow data displays in all my approval forms in Firefox , IE6 and Chrome but not IE8. What can I do to fix this? Is this a browser issue?

    Thanks,

    ee0001

  3. By:ee0001

    Wolfgang,

    I created a test form, copied the exact same code and made the hiddenTextArea visible. I tested the form in IE8, Firefox 3.6.13, IE6.

    Results:
    Firefox and IE6 works just fine. The selection displays on the picklist and it shows on the hiddenTextArea.
    IE8 – The hiddenTextArea shows the selections; however; they don’t display on the picklist as selected.

    At this point I’m not sure what I’m looking for. I tried renaming the hiddenTextArea, Adding the site to Trusted sites in

    Any help will be appreciated.

    Thanks,
    ee0001

  4. By:anja98

    Just to share another solution, we used a hidden MVEditor to contain the selected values in the PickList. That way, the selected values can still be stored as an array and passed between various forms in the flowdata object.

    • By:wschreiber

      Anja98, basically it doesn’t matter if you choose a text field or MVEditor.

      However, my outlined solution does not require one hidden field for each and every picklist, but can use a single hidden field for any number of picklists that need to be transported.

      Wolfgang

Comment