Preface
iNotes started using tabbed UI interface beginning 8.0.1 lite mode and 8.5 full mode. In lite mode, the form to read/edit mail as well as the form to read meeting notice has got a new architecture that fully exploits such tabbed UI interface. It efficiently shares JavaScript code with mail view, etc. It also shares JavaScript code as well as form HTML among different documents using the same form.
As the result, the only thing that's loaded for every single document is raw document data. It dramatically improves the client-side response time to open a document, by reducing the byte size required. Forms with such new architecture is called iNotes Lite forms. (Forms with older architecture is called iNotes Classic forms)
As shown above, the following contents are loaded for the first attempt of opening a document, with iNotes Lite forms:
1. Raw document data (Via XMLHttpRequest)
2. Form HTML (Via XMLHttpRequest)
3. JavaScript code to drive form (Via dynamic <script> tag insertion)
The second and third contents are reused for subsequence opening of documents with the same form. Form HTML works as a "template" - It's stored as a property in a JavaScript object, and put via DOM method for use. JavaScript code puts document data to the UI afterwards that completes the document form UI.
The new way to handle document form UI requires a slightly different way to customize it. This article shows how to customize iNotes Lite forms, by doing the same thing as what the earlier DeveloperWorks article does:
Manipulating Data in Domino Web Access
Many techniques described in this article use iNotes Lite framework, described in:
iNotes Lite Framework
It's recommended reading iNotes Lite framework's article before reading the rest of this article.
iNotes shortens most of function names and variable names to two or three characters, to keep the download size small. Such shortened names appear a lot in this article, too - We'll mention the original names with
[]. To find the original, more meaningful variable names, open the forms template (Forms85.nsf for 8.5), go to Shared Resources - Files in Domino Designer and open ObfuscationList.txt., or enter the following URL from a browser <url to forms file>/ObfuscationList.txt
Note - We recommend creating a backup of original forms template before making any changes. Also, if you copy and paste the sample code to Domino Designer, we recommend using Edit - Paste Special and select Text (instead of Ctrl-V or Edit - Paste) to make sure no formatting in this page is copied to Domino Designer.
Disclaimer - The specification of iNotes Lite framework, iNotes Lite forms, and/or how to write applications shown in this article, may be changed without notice to improve the iNotes product.
Scenes, subscenes and the Forms Map Table
iNotes Lite forms have the same concept of scenes, subscenes and the forms map table, as iNotes Classic forms. This concept is well described in the earlier DeveloperWorks article. There is a new column for iNotes Lite forms in Forms Map Table,
l_SubFormPrefix,
l_SetReadScene and
l_SetEditScene. They correspond to
s_SubFormPrefix,
h_SetReadScene and
h_SetEditScene used for iNotes Classic forms. Such concept is used in iNotes Lite forms, for the following four purposes:
1. To determine what subforms should be loaded as part of raw document data. It's used to define form-specific fields (data). Such subforms typically are:
s_MailMemoDictionary,
s_MeetingNoticeDictionary. You'll notice these subforms here begin with
s_ prefix. It's because these subforms are shared with iNotes Classic forms
2. To determine what subforms should be loaded as part of form HTML. Such subforms typically are:
l_MailMemoRead,
l_MailMemoEdit,
l_MeetingNoticeRead
3. To determine what subforms should be loaded as the JavaScript code to drive the form. Such subforms typically are:
l_MailMemoReadCode,
l_MailMemoEditCode,
l_MeetingNoticeReadCode
4. To determine what subforms should be loaded when saving a document, sending a memo, etc. Such subforms typically are:
s_MailMemoDictionary,
l_MailMemoEdit_Init,
l_MailMemoEdit
l_StdPageRead,
l_StdPageEdit,
l_StdPageReadCode and
l_StdPageEditCode are loaded along with "scene specific" subforms, in the similar manner as iNotes Classic forms.
Mail info widget
iNotes Lite form has a new UI to show series of information associated with memo. For example, subject, date, sender, recipients, etc. are shown for mail read scene. It's constructed by
EdT [
com_ibm_dwa_ui_mailinfo] iNotes Lite widget.
Below code (to be put into
Custom_JS_Lite subform) puts mail retention info set in the earlier article's example to such widget, by mangling the DOM inside:
1: function com_ibm_dwa_ui_mailinfo_setRetention(oMailInfo, oContent, fPropagateHeight){
2: var oMainDoc = AAA.EcK;
3: var fEditMode = oContent.oForm ? oContent.oForm.EDt : oContent.EDt;
4: var oForm = fEditMode ?
5: oMainDoc.getElementById('e-pageui-' + oContent.sId) :
6: {};
7: var sStartDate = !fEditMode ?
8: oContent.oNote.EHA('RETENTION_START_DATE', 0) :
9: oForm['RETENTION_START_DATE'].value;
10:
11: var oCalendar = (new EJw).Us(sStartDate);
12: oCalendar.Cep = true;
13:
14: var oRetentionContainer
15: = oMainDoc.getElementById(oMailInfo.sId + '-retention-container');
16: if (oRetentionContainer)
17: EJQ(oRetentionContainer, 's-nodisplay', oCalendar.rl());
18:
19: if (oCalendar.rl())
20: return;
21:
22: if (!oRetentionContainer) {
23: if (!fEditMode) {
24: var oReferenceContainer
25: = oMainDoc.getElementById(oMailInfo.sId + '-history-container-detail')
26: || oMainDoc.getElementById(oMailInfo.sId + '-history-container');
27: oRetentionContainer
28: = oReferenceContainer.parentNode.insertRow(oReferenceContainer.rowIndex + 1);
29: oRetentionContainer.id = oMailInfo.sId + '-retention-container';
30: var oTd = oRetentionContainer.insertCell(-1);
31: oTd.id = oMailInfo.sId + '-retention';
32: oTd.colSpan = 3;
33: oTd.className = 's-mailinfo-label';
34: } else {
35: oRetentionContainer = oMainDoc.createElement('div');
36: oRetentionContainer.id = oMailInfo.sId + '-retention-container';
37: var oDiv = oMainDoc.createElement('div');
38: oDiv.id = oMailInfo.sId + '-retention';
39: oDiv.className = 's-mailinfo-label';
40: oRetentionContainer.appendChild(oDiv);
41: var oMailInfoDiv = oMainDoc.getElementById(oMailInfo.sId + '');
42: oMailInfoDiv.appendChild(oRetentionContainer);
43: }
44: }
45:
46: var nDays = !fEditMode ?
47: oContent.oNote.EHA('RETENTION_PERIOD', 0) - 0 :
48: oForm['RETENTION_PERIOD'].value;
49: oCalendar.EJj(0, 0, nDays);
50:
51: oMainDoc.getElementById(oMailInfo.sId + '-retention').innerHTML
52: = 'This document is marked for rentention. Expires on: '
53: + (new EJw).format(oCalendar);
54:
55: if (fPropagateHeight) {
56: var oProperty = EPx.get('p-' + oMailInfo.sId + '-height');
57: oProperty.BRW(oMainDoc.getElementById(oMailInfo.sId).offsetHeight);
58: }
59: }
To explain things in above code:
- The HTML of EdT [com_ibm_dwa_ui_mailinfo] widget is constructed by <table> for read mode, by <div> for edit mode. Those two HTML elements requires a different way to mangle.
- oContent is a repository containing several different info in the panel.
- oContent.oNote is an instance of com_ibm_dwa_misc_note class that contains raw document data. It only contains item values having <NotesField> or <NotesVar> associated with them. Most of such <NotesField> or <NotesVar> should be defined in scene-specific subform, like l_MailMemoDictionary. EHA() method of that class returns the item value.
- EYB [com_ibm_dwa_misc_calendar] class allows us to do calendar arithmetics. For example, EJj() (adjustDays()) method adds years, months and days specified in calendar level. Cep [fDateOnly] property specifies that the calendar contains only date info, not time info.
- EJw [com_ibm_dwa_misc_dateFormatter] class allows us to format EYB [com_ibm_dwa_misc_calendar] visible for user.
- 'p-' + oMailInfo.sId + '-height' common property allows the entire form to react to the change in size of EdT [com_ibm_dwa_ui_mailinfo] widget.
Above code can be run right after
EdT [
com_ibm_dwa_ui_mailinfo] iNotes Lite widget is created, by adding below code to
Scene_PostLoad_Lite():
1: if ((s_SceneName || '').split(':')[1] == 'EdT') {
2: var oMailInfo = EKc.prototype.EYl[s_SceneName];
3: var oElem = AAA.EcK.getElementById(s_SceneName.split(':')[0]);
4: var sContentId = oElem.getAttribute('com_ibm_dwa_ui_mailinfo_contentid');
5: var oContent = AAA.Fkb().getContent(sContentId);
6: com_ibm_dwa_ui_mailinfo_setRetention(oMailInfo, oContent, true);
7: }
To explain things in above code:
- AAA.Fkb() [com_ibm_dwa_globals.getPanelManager()] returns the singleton panel manager object. It manages the content objects described before. Content object is keyed by "content ID" and can be obtained by getContent() method.
- EdT [com_ibm_dwa_ui_mailinfo] widget keeps its content ID in com_ibm_dwa_ui_mailinfo_contentid attribute of its root element.
The new UI in mail info widget will be like below:
iNotes Lite action
iNotes Lite action is a special kind of iNotes Lite widget. The difference is not having a UI. The following code is the simplest iNotes Lite action:
1: function com_ibm_dwa_ui_actionHello(sId){
2: var oContext = ELU.EJs[sId];
3: alert(oContext.sHello);
4: }
sId above is an ID of iNotes' internal data instead of HTML element ID. Such internal data is called "action context", which can be accessed via
ELU.EJs [
com_ibm_dwa_ui_invokeAction.oContext]. Some properties in it will automatically be set, like below:
|
|
|
|
|
The content object the action is invoked upon
|
|
|
The UNIDs of select documents in view, the UNID for document form
|
|
|
The view/folder name in view, the opened form for document form
|
iNotes Lite action can be lazy loaded with the same way as lazy loading iNotes Lite widget. iNotes Lite action can be launched by one of the following two ways:
1. From tool bar widget or drop down menu widget
2. Calling
ELU(event, sId, sClass, oContext) function. The parameters are below:
|
|
|
|
|
The event triggering the action (null if not applicable)
|
|
|
The ID of the element triggering the action (null if not applicable)
|
|
|
The class name of the action
|
|
|
User-defined action context
|
How to add a tool bar item or a drop down menu item is well described in the sample code seen in
Scene_Actions_Lite() function in
Custom_JS_Lite subform. To begin with, you'll need to enable the commented-out <InsertNotesSubForm Name=D_Custom_ActionsHelper_Subform_Lite>. The action is specified in a way like:
com_ibm_dwa_ui_actionHello {sHello: \'Hello!\'} In this case,
com_ibm_dwa_ui_actionHello is the class name of the action.
{sHello: \'Hello!\'} is evaluated as the user-defined action context.
Below is another example to add a tool bar item for mail retention, to be put in
Scene_Actions_Lite() function. It's used for the dialog shown in the next section:
1: if (/^e-actions-mail(read|edit)/.test(s_MenuID)) {
2: // Lazy loading table entry for date picker widget
3: EKc.prototype.EQj['EEF'] = [AAA.FzC];
4: // Lazy loading table entry for com_ibm_dwa_ui_actionMailRetention
5: EKc.prototype.EQj['com_ibm_dwa_ui_actionMailRetention'] = ['MailRetention'];
6: addActionsLite(s_MenuID, true, [
7: {
8: title: 'Mail Retention',
9: find_id: /mailread/.test(s_MenuID) ? 'print' : 'attach',
10: id: 'retention',
11: before: true,
12: action: 'com_ibm_dwa_ui_actionMailRetention',
13: help_text: 'Mail Retention'
14: }
15: ]);
16: }
Implement an iNotes Lite action to launch a dialog widget with a date picker widget inside
To get the new action lazy loaded, add following markups in
l_StdPageOperations,
l_StdPageOperations_Gecko,
l_StdPageOperations_Safari Notes forms at appropriate places. For the first one, the best place to put it is right before </NotesDictionary>. For the second one, the best place to put it is at the very end:
1: <NotesVar name=s_GetMailRetentionScript type=number initialvalue={0}>
1: <InsertNotesSubForm name=@{@If(s_GetMailRetentionScript != 0; "Custom_MailRetention"; "")}>
(Above code is for 8.5 release. For 8.5.1 release or later, use below)
1: <NotesVar name=s_MailRetention AllowPreset="yes">
1: <InsertNotesSubForm name=@{@If(s_MailRetention = "1"; "Custom_MailRetention"; "")}>
(To get the data loaded correctly, we need to define some fields, exactly the same way as the earlier DeveloperWorks article does. Please refer to
Custom_MailRetentionFields and
s_MailMemoDictionary things in Step 7 and Step 8 in readme.txt in the sample code in the earlier DeveloperWorks article)
Custom_MailRetention subform will have the following contents:
1: (com_ibm_dwa_ui_actionMailRetention implementation)
2: (com_ibm_dwa_io_mailRetentionListener implementation)
3: (com_ibm_dwa_io_mailRetentionApproversListener implementation)
4: EKc.prototype.FKd['mailretention'] = true;
This section introduces two iNotes Lite widgets:
- EeE [com_ibm_dwa_ui_dialog] - A dialog fully HTML/CSS based. Given that, it's totally free from pop-up blocker
- EEF [com_ibm_dwa_ui_dateInput] - A input box with date picker
The constructor of
com_ibm_dwa_ui_actionMailRetention will be like:
1: function com_ibm_dwa_ui_actionMailRetention(sId){
2: this.sId = sId;
3: var oMainDoc = AAA.EcK;
4: EKc.prototype.ESH['e-dialog-retention:EeE']
5: = this.dialogInited.EHq(this);
6: if (!oMainDoc.getElementById('e-dialog-retention')) {
7: var EPQ = 'AAA.DSq.EKc.prototype.EYl["'e-dialog-retention:EeE"']';
8: var sHtml = '<div id="e-dialog-retention" class="s-stack s-dialog"'
9: + ' com_ibm_dwa_ui_widget_class="EeE"'
10: + ' com_ibm_dwa_ui_dialog_title="Mail Retention"'
11: + ' com_ibm_dwa_ui_dialog_closeIndicator="8 7 40 20"'
12: + ' com_ibm_dwa_ui_dialog_consolidatedIcons="' + AAA.BYp('basicicons.gif') + '"'
13: + ' com_ibm_dwa_ui_dialog_width="18em" com_ibm_dwa_ui_dialog_height="14em">'
14: + '<table class="s-toppanel" border="0" cellspacing="4" cellpadding="0">'
15: + '<tbody>'
16: + '<tr>'
17: + '<td class="s-label-light" nowrap>Start Date:</td>'
18: + '<td id="e-dialog-retention-date" com_ibm_dwa_ui_widget_class="EEF"'
19: + ' com_ibm_dwa_ui_dateInput_optional="true"'
20: + ' com_ibm_dwa_ui_dateInput_updateOnChange="false"'
21: + ' com_ibm_dwa_ui_dateInput_dropdownMgr="dropdownmanager-e-dialog-retention-date"'
22: + ' com_ibm_dwa_misc_observes_input="p-e-dialog-retention-date-currentselected">'
23: + '</td>'
24: + '</tr>'
25: + '<tr>'
26: + '<td class="s-label-light" nowrap>Retention Period (days):</td>'
27: + '<td>'
28: + '<select id="e-dialog-retention-period" class="s-label-light" style="width:100%;"'
29: + ' onchange="' + EPQ + '.oAction.changePeriod();">'
30: + '<option value="30">30</option>'
31: + '<option value="60">60</option>'
32: + '<option value="90">90</option>'
33: + '</select>'
34: + '</td>'
35: + '</tr>'
36: + '<tr id="e-dialog-retention-approverarea" class="s-nodisplay">'
37: + '<td class="s-label-light" nowrap>Approver:</td>'
38: + '<td>'
39: + '<select id="e-dialog-retention-approver" class="s-label-light" style="width:100%;">'
40: + '</select>'
41: + '</td>'
42: + '</tr>'
43: + '<tr>'
44: + '<td class="s-label-light" nowrap>Business Justification:</td>'
45: + '<td>'
46: + '<textarea id="e-dialog-retention-justification" class="s-label-light"'
47: + ' style="width:100%;height:6em;">'
48: + '</textarea>'
49: + '</td>'
50: + '</tr>'
51: + '</tbody>'
52: + '</table>'
53: + '<div class="s-rightpanel" style="height:auto;bottom:0;">'
54: + '<input id="e-dialog-retention-ok" class="s-label-light" type="button" value="OK"'
55: + ' onclick="' + EPQ + '.oAction.dialogSelected();">'
56: + '<input id="e-dialog-retention-cancel" class="s-label-light"'
57: + ' type="button" value="Cancel" onclick="' + EPQ + '.close();">'
58: + '</div>}}}
59: + '</div>}}}
60: if (oMainDoc.body.insertAdjacentHTML) {
61: oMainDoc.body.insertAdjacentHTML('beforeEnd', sHtml);
62: } else {
63: var oRange = oMainDoc.createRange();
64: oRange.setStartBefore(oMainDoc.body);
65: var oFragment = oRange.createContextualFragment(sHtml);
66: oMainDoc.body.appendChild(oFragment);
67: }
68: EPl(oMainDoc.getElementById('e-dialog-retention'));
69: } else {
70: EKc.prototype.EYl['e-dialog-retention:EeE'].Fcs();
71: this.dialogInited();
72: }
73: }
To explain things in above code:
- The long string for HTML consists the dialog and the contents inside.
- s-nodisplay class hides the element without taking up its space.
- EKc.prototype.ESH is a repository for callback functions called when a widget is initialized.EHq() creates a function object to call the function as the method of the object specified as the first parameter - Useful to define callback functions, event handlers, etc.
- Fcs() [showResetDialog()] method of EeE [com_ibm_dwa_ui_dialog] widget shows an exiting dialog that has been hidden (closed).
The code to initialize the dialog with associated document data will be like:
1: com_ibm_dwa_ui_actionMailRetention.prototype.dialogInited
2: = function com_ibm_dwa_ui_actionMailRetention_dialogInited(){
3: var oContext = ELU.EJs[this.sId];
4: var oNote = oContext.EZN.oNote;
5:
6: var oCalendar = (new EJw).Us(oNote.EHA('RETENTION_START_DATE', 0));
7: oCalendar.Cep = true;
8: if (oCalendar.rl())
9: oCalendar.setDate(new Date);
10:
11: EPx.get('p-e-dialog-retention-date-currentselected').BRW('' + oCalendar);
12:
13: var oMainDoc = AAA.EcK;
14: oMainDoc.getElementById('e-dialog-retention-period').value
15: = oNote.EHA('RETENTION_PERIOD', 0) || '';
16: oMainDoc.getElementById('e-dialog-retention-approver').value
17: = oNote.EHA('RETENTION_APPROVER', 0) || '';
18: oMainDoc.getElementById('e-dialog-retention-justification').value
19: = oNote.EHA('RETENTION_JUSTIFICATION', 0) || '';
20:
21: this.changePeriod();
22:
23: EKc.prototype.EYl['e-dialog-retention:EeE'].oAction = this;
24: };
To explain things in above code:
- setDate() method of EYB [com_ibm_dwa_misc_calendar] class sets a JavaScript Date object's calendar values, like year, month, date, etc.
- When JavaScript engine does automatic type conversion from EYB [com_ibm_dwa_misc_calendar] class to a string, ISO8601 format of the calendar value will be generated.
- com_ibm_dwa_misc_observes_input attribute in the root element of EEF [com_ibm_dwa_ui_dateInput] widget specifies the common property the widget looks at. Such common property will be updated when user puts a new value to the input box, or when user selects a date in date picker.
- The last line sets the iNotes Lite action the dialog is launched upon, to associate it with button, etc. actions in the dialog.
The sample in the earlier DeveloperWorks article required an approver for long retention period. Below code would do the same.
com_ibm_dwa_io_mailRetentionApproversListener creates an XMLHttpRequest and put the list of approvers to the dialog once the data is ready. The implementation of
com_ibm_dwa_io_mailRetentionApproversListener as well as
Custom_ApproverLookup form will be shown after in this article.
1: com_ibm_dwa_ui_actionMailRetention.prototype.changePeriod
2: = function com_ibm_dwa_ui_actionMailRetention_changePeriod(){
3: var fApprover = AAA.EcK.getElementById('e-dialog-retention-period').value == '90';
4: EJQ(AAA.EcK.getElementById('e-dialog-retention-approverarea'),
5: 's-nodisplay', !fApprover);
6: var oApprover = AAA.EcK.getElementById('e-dialog-retention-approver');
7: if (!fApprover || oApprover.length)
8: return;
9: var sUrl = '../../iNotes/Proxy/?OpenDocument&Form=Custom_ApproverLookup';
10: (new com_ibm_dwa_io_mailRetentionApproversListener).load(sUrl);
11: };
Lastly, implement the code to save mail retention data. Like the earlier DeveloperWorks article does, it launches the HTTP request immediately for read mode, and mail retention data is saved along with saving the entire document for edit mode.
com_ibm_dwa_io_mailRetentionListener creates an XMLHttpRequest and updates the mail info widget once it completes saving the data. The implementation of
com_ibm_dwa_io_mailRetentionListener will be shown after in this article.
(We use the same agents as the earlier DeveloperWorks article here - Please refer to Step 2 and Step 3 in readme.txt in the sample code in the earlier DeveloperWorks article. Also, to save the data in edit mode requires the same @nowiki@11s as the earlier DeveloperWorks article - Create Custom_MailRetentionHTMLFields subform as described in Step 7. Refer to Step 8 to put the new subform to the edit scene, but where it should be put to is l_MailMemoEdit subform intead of s_MailMemoEdit subform)
1: com_ibm_dwa_ui_actionMailRetention.prototype.dialogSelected
2: = function com_ibm_dwa_ui_actionMailRetention_dialogSelected(){
3: var oMainDoc = AAA.EcK;
4: var oContext = ELU.EJs[this.sId];
5:
6: var oCalendar = new EYB;
7: oCalendar.EKN(EPx.get('p-e-dialog-retention-date-currentselected').BoB);
8:
9: var fEditMode = oContext.EZN.oForm ? oContext.EZN.oForm.EDt : oContext.EZN.EDt;
10: if (!fEditMode) {
11: var oData = {
12: StartDate: (new EJw('yyyy/MM/dd')).format(oCalendar),
13: Period: oMainDoc.getElementById('e-dialog-retention-period').value,
14: Approver: oMainDoc.getElementById('e-dialog-retention-approver').value,
15: Justification: oMainDoc.getElementById('e-dialog-retention-justification').value
16: };
17:
18: AAA.EVI.sr(2, '', 'Marking a memo for retention...');
19:
20: var sUrl = AAA.MO + '/0/' + oContext.EIX[0]
21: + '?EditDocument&Form=s_RunAgent&PresetFields=AgentName;ReadMailRtAgent';
22: var oListener = new com_ibm_dwa_io_mailRetentionListener;
23: oListener.oContent = oContext.EZN;
24: oListener.load(sUrl, '' + new ENj(oData, true));
25: } else {
26: var oForm = oMainDoc.getElementById('e-pageui-' + oContext.EZN.sId);
27: oForm['RETENTION_START_DATE'].value = oCalendar;
28: oForm['RETENTION_PERIOD'].value
29: = oMainDoc.getElementById('e-dialog-retention-period').value;
30: oForm['RETENTION_APPROVER'].value
31: = oMainDoc.getElementById('e-dialog-retention-approver').value;
32: oForm['RETENTION_JUSTIFICATION'].value
33: = oMainDoc.getElementById('e-dialog-retention-justification').value;
34:
35: var oWidget = EKc.prototype.EYl['e-' + oContext.EZN.sId + '-mailinfo:EdT'];
36: if (oWidget)
37: com_ibm_dwa_ui_mailinfo_setRetention(oWidget, oContext.EZN, true);
38: }
39:
40: EKc.prototype.EYl['e-dialog-retention:EeE'].close();
41: };
To explain things in above code:
- EKN() [setISO8601String()] method of EYB [com_ibm_dwa_misc_calendar] class sets an ISO8601-formatted string.
- AAA.MO [com_ibm_dwa_globals.sNsfPath] contains the URL of the mail database.
Here are some other contents that need to be created:
Custom_ApproverLookup form implementation
1: <NotesDictionary>
2: <NotesVar name={HTTP_USER_AGENT} value={HTTP_USER_AGENT}>
3: @{{
4: tmp := @DbLookup("":""; "":"apprv.nsf"; "LuApprovers"; @NameLookup([NoUpdate]; @UserName; "Department"); 2);
5: @Implode(@If(@IsError(tmp); "Error"; tmp); "||")
6: }; jsdata}
7: </NotesDictionary>
8: @{{
9: tmp := @DbLookup("":""; "":"apprv.nsf"; "LuApprovers"; @NameLookup([NoUpdate]; @UserName; "Department"); 2);
10: @Implode(@If(@IsError(tmp); "Error"; tmp); "||")
11: }; jsdata}
com_ibm_dwa_io_mailRetentionListener implementation
1: function com_ibm_dwa_io_mailRetentionListener(sKey){
2: EGe.call(this, sKey);
3: }
4: com_ibm_dwa_io_mailRetentionListener.prototype = new EGe('VOID');
5: com_ibm_dwa_io_mailRetentionListener.prototype.DlJ = com_ibm_dwa_io_mailRetentionListener.prototype.Dhe
6: = function com_ibm_dwa_io_mailRetentionListener_onDatasetComplete(){
7: if (this.EVW.readyState != 4)
8: return;
9: try {
10: this.EJS('text/html');
11: } catch (e) {
12: var sLog = EYX(AAA.EPT.sErrLoadFailure, e.message);
13: AAA.EVI.sr(0, '', sLog);
14: this.release();
15: return;
16: }
17:
18: AAA.EVI.sr(2, '', 'A memo has been marked for retention.');
19:
20: var oNoteListener = new EOc;
21: oNoteListener.oContent = this.oContent;
22: oNoteListener.DlJ = function(){
23: var oWidget = EKc.prototype.EYl['e-' + this.oContent.sId + '-mailinfo:EdT'];
24: if (oWidget)
25: com_ibm_dwa_ui_mailinfo_setRetention(oWidget, this.oContent, true);
26: this.release();
27: };
28:
29: this.oContent.oNote.load(oNoteListener, true);
30: this.release();
31: };
com_ibm_dwa_io_mailRetentionApproversListener implementation
1: function com_ibm_dwa_io_mailRetentionApproversListener(sKey){
2: EGe.call(this, sKey);
3: }
4: com_ibm_dwa_io_mailRetentionApproversListener.prototype = new EGe('VOID');
5: com_ibm_dwa_io_mailRetentionApproversListener.prototype.DlJ
6: = com_ibm_dwa_io_mailRetentionApproversListener.prototype.Dhe
7: = function com_ibm_dwa_io_mailRetentionApproversListener_onDatasetComplete(){
8: if (this.EVW.readyState != 4)
9: return;
10: var oApprover = AAA.EcK.getElementById('e-dialog-retention-approver');
11: var Cac = AAA.EcK.createElement('option');
12: Cac.text = '(Select One)';
13: Cac.value = '';
14: oApprover.options.add(Cac);
15: for (var asApprovers = this.EVW.responseText.split('||'), i = 0;
16: i < asApprovers.length; i++) {
17: var Cac = AAA.EcK.createElement('option');
18: Cac.text = Cac.value = asApprovers[i];
19: oApprover.options.add(Cac);
20: }
21: this.release();
22: };
Once everything is implemented, you'll get the new "Mail Retention" action which launches the following dialog:
Sample code
http://www.openntf.org/catalogs/a2cat.nsf/topicThread.xsp?action=openDocument&documentId=EB7E01E3BBCEF5F6852576D200205EBE