Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Blogs

photo

Patrick Picar...

62 Entries |  Patrick Picard
Updated 
RatingsRatings 2     CommentsComments 112
photo

Lotus Nut

111 Entries |  Chris Whisonant
Updated 
RatingsRatings 23     CommentsComments 157
photo

Uh Clem's Adm...

54 Entries |  Chris Mobley
Updated 
RatingsRatings 8     CommentsComments 55
photo

Life is too s...

33 Entries |  Barbara Skedel
Updated 
RatingsRatings 3     CommentsComments 56
photo

Yellow is the...

72 Entries |  Tim Tripcony
Updated 
RatingsRatings 2     CommentsComments 34

Jan Schulz

Blog Authors:  Jan Schulz  

All entries tagged with events

Fun with events

Jan Schulz  |     |  Tags:  events lotusscript  |  Comments (0)
After seeing how much fun everybody else had with events, I tried to get my own version together.

I tried my luck with delegating the actual event handling to EventHandlers, which do the actual job. So the called QueryOpen Method looks like this:

Sub delegate_Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant) Forall evhandler In listEventHandlers Call evHandler.Queryopen(Source , Mode, Isnewdoc , Continue ) If Not Continue Then Exit Sub End Forall End Sub


The actuall handlers extend a basic EventHandler (which does nothing in each object method) with the required functionality. The rest of the design is modeled after the MVC Pattern as described in this presentation/example DB.

Fun: binding object methods to an event and not having the object around at "call time" (like when you forget to declare your object in Declaration and just do a <code>dim controller as New BaseDocumentController(source)</code> on the PostOpen-Event of the Form) will do funny things in the debugger: after the QueryClose Event the client goes into a endless loop. Without debugger, just nothing happens.

This is the complete code for Tims example:
Private Const ERR_ABSTRACT_INSTANTIATION = 1000 Private Const MSG_ABSTRACT_INSTANTIATION = | Attempt to instantiate as an object instance the abstract class | Public Class BaseDocumentController %REM The Controller Part of MVC Binds to a UIDocument, delegates all events to the EventHandlers %END REM Private fUIDoc As NotesUIDocument Private fModel As BaseDocumentModel Private fIsInitialized As Boolean Private listEventHandlers List As AbstractDocumentEventHandler Sub new(uidoc As NotesUIDocument) If Not uidoc Is Nothing Then Call initializeWithUIDoc(uidoc) End If End Sub Public Function getUIDoc() As NotesUIDocument Set getUIDoc = fUIDoc End Function Public Function initializeWithUIDoc(uidoc As NotesUIDocument) If uiDoc Is Nothing Then Error 1111, "Need a UI Document" End If Set fUIDoc = uidoc Set fModel = New BaseDocumentModel( fUIDoc.Document) fIsInitialized = True Call bindEvents() Call setupEventHandler() End Function %REM adds the default EventHandler (Validation) the to eventhandler List Can be overwritten to extend the EventHandler List, needs to call BaseDocumentController..setupEventHandler() to get the basic EventHandler setup or you need to add validation yourself %END REM Function setupEventHandler() Dim evHandler As New ValidationHandler(fModel) Call Me.addEventHandler( "validation", evHandler) Dim evHandler2 As New AuditTrailHandler(fModel) Call Me.addEventHandler( "AuditTrail", evHandler2) End Function Public Function addEventHandler(evName As String, evHandler As AbstractDocumentEventHandler) Set listEventHandlers(evName) = evHandler End Function Private Function bindEvents() On Event Queryopen From fUIDoc Call delegate_Queryopen On Event Postopen From fUIDoc Call delegate_Postopen On Event Querymodechange From fUIDoc Call delegate_Querymodechange On Event Postmodechange From fUIDoc Call delegate_Postmodechange On Event Queryrecalc From fUIDoc Call delegate_Queryrecalc On Event Postrecalc From fUIDoc Call delegate_Postrecalc On Event Querysave From fUIDoc Call delegate_Querysave On Event Postsave From fUIDoc Call delegate_Postsave On Event Querysend From fUIDoc Call delegate_Querysend On Event Postsend From fUIDoc Call delegate_Postsend On Event Queryclose From fUIDoc Call delegate_Queryclose End Function Sub delegate_Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant) Forall evhandler In listEventHandlers Call evHandler.Queryopen(Source , Mode, Isnewdoc , Continue ) If Not Continue Then Exit Sub End Forall End Sub Sub delegate_Postopen(Source As Notesuidocument) Forall evhandler In listEventHandlers Call evHandler.PostOpen(Source) End Forall End Sub Private Sub delegate_Querymodechange(Source As Notesuidocument, Continue As Variant) Forall evhandler In listEventHandlers Call evHandler.Querymodechange(Source, Continue) If Not Continue Then Exit Sub End Forall End Sub Private Sub delegate_Postmodechange(Source As Notesuidocument) Forall evhandler In listEventHandlers Call evHandler.Postmodechange(Source) End Forall End Sub Private Sub delegate_Queryrecalc(Source As Notesuidocument, Continue As Variant) Forall evhandler In listEventHandlers Call evHandler.Queryrecalc(Source, Continue) If Not Continue Then Exit Sub End Forall End Sub Private Sub delegate_Postrecalc(Source As Notesuidocument) Forall evhandler In listEventHandlers Call evHandler.Postrecalc(Source) End Forall End Sub Private Sub delegate_Querysave(Source As Notesuidocument, Continue As Variant) Forall evhandler In listEventHandlers Call evHandler.Querysave(Source, Continue) If Not Continue Then Exit Sub End Forall End Sub Private Sub delegate_Postsave(Source As Notesuidocument) Forall evhandler In listEventHandlers Call evHandler.Postsave(Source) End Forall End Sub Private Sub delegate_Querysend(Source As Notesuidocument, Continue As Variant) Forall evhandler In listEventHandlers Call evHandler.Querysend(Source, Continue) If Not Continue Then Exit Sub End Forall End Sub Private Sub delegate_Postsend(Source As Notesuidocument) Forall evhandler In listEventHandlers Call evHandler.Postsend(Source) End Forall End Sub Private Sub delegate_Queryclose(Source As Notesuidocument, Continue As Variant) Forall evhandler In listEventHandlers Print "Calling eventhandler for QueryClose" Call evHandler.Queryclose(Source, Continue) If Not Continue Then Exit Sub End Forall Print "End QueryClose" End Sub End Class Class BaseDocumentModel %REM The model part of MVC Binds to the backend document and does validation (not implmented properly) and other stuff with the data %END REM Private fDoc As NotesDocument Private fIsInitialized As Boolean Sub new(doc As NotesDocument) If Not doc Is Nothing Then Call initializeWithDocument(doc) End If End Sub Function initializeWithDocument(doc As NotesDocument) If doc Is Nothing Then Error 1111, "Model needs a Document" End If Set fDoc = doc fIsInitialized = True End Function Public Function validate() As ValidationResult If Not fIsInitialized Then Error 11111, "Uninitialised Model!" ' Checks the model: something like a array of validation rules and the ValidationResult is passed to each rule to collect the result ' Just for show: Set validate = New ValidationResult() End Function End Class Class validationResult %REM Collects the result of a validation %END REM Sub new () ' Nothing to do End Sub Public Function addError(fieldname As String, Message As String) ' unimplemented End Function Public Function hasErrors() As Boolean ' unimplemented hasErrors = False End Function Public Function getFirstInvalidField() As String ' unimplemented getFirstInvalidField = "Subject" End Function Public Function getFormattedErrorMessage() As String 'unimplemented getFormattedErrorMessage = "Some Field: invalid" End Function End Class Public Class AbstractDocumentEventHandler %REM Handels the delegated events from the Controller Overwrite specific methods to let them do something %END REM Private fModel As BaseDocumentModel Public Sub New (model As BaseDocumentModel) Dim classname As String Let className = Typename(Me) If (className = "ABSTRACTDOCUMENTEVENTHANDLER") Then Error ERR_ABSTRACT_INSTANTIATION, MSG_ABSTRACT_INSTANTIATION & classname Exit Sub End If Set Me.fModel = model End Sub Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant) ' To be overwritten End Sub Sub Postopen(Source As Notesuidocument) ' To be overwritten End Sub Public Sub Querymodechange(Source As Notesuidocument, Continue As Variant) ' To be overwritten End Sub Public Sub Postmodechange(Source As Notesuidocument) ' To be overwritten End Sub Public Sub Queryrecalc(Source As Notesuidocument, Continue As Variant) ' To be overwritten End Sub Public Sub Postrecalc(Source As Notesuidocument) ' To be overwritten End Sub Public Sub Querysave(Source As Notesuidocument, Continue As Variant) ' To be overwritten End Sub Public Sub Postsave(Source As Notesuidocument) ' To be overwritten End Sub Public Sub Querysend(Source As Notesuidocument, Continue As Variant) ' To be overwritten End Sub Public Sub Postsend(Source As Notesuidocument) ' To be overwritten End Sub Public Sub Queryclose(Source As Notesuidocument, Continue As Variant) ' To be overwritten End Sub End Class Public Class ValidationHandler As AbstractDocumentEventHandler %REM Handels the validation of the model in the QuerySave Event, - stops saving when the model is not valid - jumps to the first invalid field, as returned by the ValidationResult %END REM Sub new(model As BaseDocumentModel), AbstractDocumentEventHandler(model) ' nothing to do, just pass the model on to parent class... End Sub Public Sub Querysave(Source As Notesuidocument, Continue As Variant) Print "doing validation" Dim oResult As ValidationResult Set oResult = fModel.validate() If oResult.hasErrors() Then Continue = Continue And False Msgbox oResult.getFormattedErrorMessage(), 0 , "Validation error" Call source.GoToField(oResult.getFirstInvalidField()) End If End Sub End Class Public Class AuditTrailHandler As AbstractDocumentEventHandler %REM Adds a comment to the backend document in the QuerySave Event, - This should better be done in an event in the Model: Controller -> QuerySave -> Everything validates, etc -> model.QuerySave(....) -> Calls a listener, which does the Trail or the model does it itself -> even when you use the model without a controller, it gets a Trail %END REM Sub new(model As BaseDocumentModel), AbstractDocumentEventHandler(model) ' nothing to do, just pass the model on to parent class... End Sub Private Sub Querysave(Source As Notesuidocument, Continue As Variant) Print "Doing Audit" Dim sess As New NotesSession Dim newEdit As String Dim editType As String If (Source.IsNewDoc) Then Let editType = "created" Else Let editType = "modified" End If Let newEdit = Cstr(Now) & " - Document2 " & editType & " by " & sess.commonUserName Call Source.Document.ReplaceItemValue("AuditTrail", Fulltrim(Split(newEdit & Chr(13) & Join(Source.Document.GetItemValue("AuditTrail"), Chr(13)), Chr(13)))) End Sub End Class
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.

Skip to main content link. Accesskey S
IBM Lotus Connections Help Tools About

Tags

A tag is a keyword that is used to categorize an entry. To view the entries with a particular tag, click a tag name or enter a tag in the box.
The tag cloud indicates the frequency of tag use. Popular tags appear darkest. The slider control adjusts how many tags are displayed in the tag cloud.