About This Code
Brief Description:
Unread marks for a web based intranet using JavaScript with ActiveX
Contributor:
Michael Glenn
Category:
Javascript, Lotusscript
Last Modified:
07 Sep 2005
OpenNTF Disclaimer
All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.
Code / Description
I needed a simple way to implement read / unread marks for a bulletin board view on a corporate intranet accessed via a browser.
After much trial and error, I came up with the following approach :
1) Use the ActiveX Scripting.FileSystemObject object to create a local text file that contains all UNIDs of documents that have been read
2) When opening the view on the web, load an ActiveX Scripting.Dictionary object with the contents of the local text file and use the Exists method to test if a document has been read or not.
Perfomance is very good up to 6000 read documents (haven't tested more...but seems pretty linear. At 6000 documents, it takes 0.2 sec to open a view and 0.1 sec to open a document (marking it read).
I've also written a LotusScript cleanup agent that will remove UNIDs of documents that no longer appear in the view.
Feel free to modify and use...
Michael Glenn
Usage / Example
***** Here's the pass-thru HTML code to put at the top of the form
<SCRIPT language=JavaScript>
// This script adds the UNID of the current document to a text file
// named "readmarks.txt" on the users local hard drive.
// Author : Michael Glenn
// Feel free to modify...
function AddReadMark()
{
// Initialize variables
var fso, tf, readmarks, data, exists;
fso = new ActiveXObject("Scripting.FileSystemObject");
readmarks = "c://readmarks.txt";
exists = false;
// Test if readmarks file exists
if (fso.FileExists(readmarks))
{
// Open readmarks file for reading
tf = fso.OpenTextFile(readmarks, 1, false);
// Check to see if current document's UNID is already in the readmarks file
while (! tf.AtEndOfStream && ! exists)
{
data = tf.ReadLine(); // Read a UNID from readmarks file
if (data == '"<Computed Value>"') // Computed value is @Text(@DocumentUniqueID)
exists = true;
}
tf.Close( );
if (! exists)
{
// Document hasn't been read before. Append it to readmarks file.
tf = fso.OpenTextFile(readmarks, 8, false);
tf.WriteLine('"<Computed Value>"'); //Computed Value : @Text(@DocumentUniqueID
tf.Close();
}
}
else
{
// Readmarks file does not exist. Create it and add current document's UNID
tf = fso.OpenTextFile(readmarks, 2, true);
tf.WriteLine('"<Computed Value>"'); // Computed value is @Text(@DocumentUniqueID)
tf.Close();
}
}
AddReadMark();
</SCRIPT>
***** This pass-thru HTML goes at the top of the $$ViewTemplate
<SCRIPT language=JavaScript>
// Initialize an AcitveX Dictionary object that will be used by InitRead and WasRead functions
var d;
d = new ActiveXObject("Scripting.Dictionary");
function InitRead()
{
// This function reads the contents of the readmarks file into the dictionary object
var fso, tf, readmarks, data;
fso = new ActiveXObject("Scripting.FileSystemObject");
readmarks = "c://readmarks.txt";
if (fso.FileExists(readmarks))
{
tf = fso.OpenTextFile(readmarks, 1, false);
while (! tf.AtEndOfStream)
{
data = tf.ReadLine();
d.add (data, "Data"); // Note: the second argument can be anything...
}
tf.Close( );
}
}
function WasRead(docUNID)
{
// This function returns true if the UNID is found in the dictionary
// The function is called from code in a view column
var n
n = '"'+docUNID+'"'
if (d.Exists(docUNID))
return true;
else
return false;
}
InitRead();
</SCRIPT>
***** This code goes in a view column to display "(Read)" if a document has been read
***** (Note view is set to "Treat view contents as HTML")
<SCRIPT language=JavaScript>if (WasRead('"+@Char(34)+@Text(@DocumentUniqueID)+@Char(34)+"')) document.write(' (Read)')</SCRIPT>
***** Here is the code for the cleanup agent:
Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
Set db=s.CurrentDatabase
Dim fileNum1 As Integer, fileNum2 As Integer
Dim txtUNID As String
fileNum1% = Freefile
Open "C:\readmarks.txt" For Input As fileNum1%
fileNum2% = Freefile
Open "c:\readmarks_new.txt" For Output As fileNum2%
On Error Goto ProcessError
While Not Eof(fileNum1%) ' Read until end of file.
Input #fileNum1%, txtUNID
db.GetDocumentByUNID(Cstr(txtUNID))
Write #fileNum2%, txtUNID
ProcessError:
Resume Skip
Skip:
Wend
Close fileNum1%
Close fileNum2%
Filecopy "c:\readmarks_new.txt","c:\readmarks.txt"
Kill "c:\readmarks_new.txt"
End Sub