Breadcrumbs using JQuery

Embed Size (px)

Citation preview

Breadcrumbs using JQuery2010-February-27 at 9:14 pm Filed under UI, View Tagged Agent, breadcrumbs, domino, jquery, View Bob Balfe asked some time ago who is using JQuery for their Domino development projects. I hoped it was gonna rain with examples of implementation of JQuery plugins in Lotus Notes but so far it remains a bit quiet. So why not describe an example myself?

Figure: Screenshot from the website. xBreadcrumbs is a nice plugin to JQuery to provide horizontal navigation. It uses an unordered list (UL) as source so when you provide that data dynamically with Notes data it becomes interesting. In my case the customer wanted to have breadcrumbs on top of documents that are stored in a Notes view. Documents are categorized in a parent-response hierarchy so for each document I have to calculate the complete path from the opened document to its uber-parent (some points on that u) aka as Home.

Figure: Document location in Notes view.

Figure: Document location in breadcrumb. Implementation Download the zip file, extract it and upload the files in your Notes application. Create a subform that you will embed on the form of your document. Add the following code to the subform:

$(document).ready(function(){ $(#breadcrumbs-2).xBreadcrumbs({ collapsible: true }); }); .xbreadcrumbs { background:#FFF none repeat scroll 0 0; } .xbreadcrumbs LI { border-right: none; background: url(../img/frmwrk/breadcrumb/separator.gif) no-repeat right center; padding-right: 15px; } .xbreadcrumbs LI.current { background: none; } .xbreadcrumbs LI UL LI { background: none; } .xbreadcrumbs LI A.home { background: url(../img/frmwrk/breadcrumb/home.gif) no-repeat left center; padding-left: 20px; } /* Custom styles for breadcrums (#breadcrumbs-3) */ .xbreadcrumbs#breadcrumbs-3 { background: none; } .xbreadcrumbs#breadcrumbs-3 LI A { text-decoration: underline; color: #0A8ECC; } .xbreadcrumbs#breadcrumbs-3 LI A:HOVER, .xbreadcrumbs#breadcrumbs-3 LI.hover A { text-decoration: none; } .xbreadcrumbs#breadcrumbs-3 LI.current A { color: #333333; text-decoration: none; } .xbreadcrumbs#breadcrumbs-3 LI { border-right: none; background: url(../img/frmwrk/breadcrumb/separator.gif) no-repeat right center; padding-right: 15px; padding-left:0px; } .xbreadcrumbs#breadcrumbs-3 LI.current { background: none; } .xbreadcrumbs#breadcrumbs-3 LI UL LI { background: none; padding: 0; }

The source for my unordered list is the agent $a-get-bread-crumb. The formula for the computed value is as followed: @Text(@DocumentUniqueID) The agent will use the Notes view $v-treeview, find the document by its document UNID and navigates via each parent all the way up in the Notes view. While doing so the required information to build the unordered list is collected. By the way, the code for this agent was co-written by my collegue Tomas Ekstrm 20100104T135525,47+01 20100118T105706,77+01 20100118T105706,65+01 20100118T105706,74+01 20100111T083443,65+01 CN=Patrick KwintenPatrick Kwinten Patrick Kwinten%REM Library class:WebGetTreeFromView Created Sep 1, 2009 by Tomas Ekstrm Description: Comments for Library %END REM Option Public Option Declare %REM Class ULTreeFromView Description: Comments for Class %END REM Class ULTreeFromView Private hasChild As Boolean Private childNodes() As ChildNode Private nview As NotesView Private vnav As NotesViewNavigator Private ve As NotesViewEntry Private session As NotesSession Private contentSource As String

'

Private liClass As String Private id As String Private className As String Private activeCrumbClass As String Private currentLevel As Integer Private levelsToReturn As Integer Private fromPosition As String Public Property Get getContentSource As String getContentSource = contentSource End Property

%REM Property Set setContentSource Value: field:[fieldname] or column:# or universalID:%%UNID%% Description: Comments for Property Get. In column:# the first column is 0. Example: ULTreeFromView.setContentSource = "field:Tx_Title" Result "Home" if the field Tx_Title contains "Home" ULTreeFromView.setContentSource = "column:1" Result "Home" if the column in the view contains "Home" (first column is 0) ULTreeFromView.setContentSource = "universalID:field:Tx_Title%%CONTENT%%" Result "Home a>" if the documents universal id is CEA6C8D38AC6E216C1257678006CE1BA %END REM Public Property Set setFromPosition As String Me.fromPosition = setFromPosition End Property Public Property Set setLevelsToReturn As String Me.levelsToReturn = setLevelsToReturn End Property Public Property Set setContentSource As String contentSource = setContentSource End Property Public Property Get getLiClass As String getLiClass = liClass End Property Public Property Set setLiClass As String liClass = setLiClass

End Property Public Property Get getID As String getID = id End Property Public Property Set setID As String id = setID End Property Public Property Get getClass As String getClass = className End Property Public Property Set setClass As String className = setClass End Property Public Property Get getActiveCrumbClass As String getActiveCrumbClass = activeCrumbClass End Property Public Property Set setActiveCrumbClass As String activeCrumbClass = setActiveCrumbClass End Property %REM Sub New Parameter: Notes View as [NotesView] or Name of view as [String] Description: Comments for Sub %END REM Sub New( nviw As Variant) Set session = New NotesSession ' 'Set nview = session.Currentdatabase.Getview("$v-treeview") Me.currentLevel = 0 Me.levelsToReturn = -1 Select Case Typename(nviw) Case "STRING" Set nview = session.Currentdatabase.Getview(nviw) Case "NOTESVIEW" Set nview = nviw Case Else Error 1123, "Error: Wrong parameter type in constructor! Expects either String or NotesView" End Select

Me.id = "tree" Me.className = "treeclass" Me.activeCrumbClass = "ActiveCrumb" If nview Is Nothing Then Error 1023, "Error View does not exist!" Else Set vnav = nview.Createviewnav() Set ve = vnav.Getfirst() End If hasChild = False End Sub %REM Function getULBreadCrumb Parameter: currentID as String current id for document either universalid or position in view (11.2.4) Return: [String] UL formated bread crumb list Description: Comments for Property Get %END REM Public Function getULBreadCrumb(currentID As String) As String Dim breadCrumbList As String Dim n As Integer ' Me.currentLevel = 0 nview.Autoupdate = False Call Me.rebuildNodes()

If Me.HasChild Then For n=0 To Ubound(Me.childNodes) breadCrumbList = Me.childNodes(n).getBreadCrumbLI(currentID) If breadCrumbList "" Then Exit For End If Next getULBreadCrumb = |

  • | & breadCrumbList & |

| Else getULBreadCrumb = |

| End If %REM disabled auto update because of performance nview.Autoupdate = True %END REM End Function %REM Property Get getUL

Return: [String] UL formated interpretation of the view Description: Comments for Property Get %END REM Public Property Get getUL As String getUL = |

  • | & Me.getLI & |

| End Property %REM Property Get getLI Return: [String] LI formated interpretation of the view Description: Comments for Property Get %END REM Public Property Get getLI As String Dim n As Integer Dim childItemArray() As String %REM Call nview.Refresh() %END REM nview.Autoupdate = False ' Me.currentLevel = 0 Call Me.rebuildNodes() Redim childItemArray(Ubound(Me.childNodes)) As String If Me.HasChild Then For n=0 To Ubound(Me.childNodes) childItemArray(n) = Me.childNodes(n).getLI Next getLI = Join(childItemArray,"") Else getLI = "" End If %REM 'nview.Autoupdate = True %END REM End Property %REM Property Get getULAttributes Description: Comments for Property Get %END REM Private Property Get getULAttributes As String Dim headerData List As String Dim headerDataSize As Integer Dim headerDataArray() As String Dim tmpHeaderDataArray As Variant Dim cnt As Integer

headerData("id") = Me.getID headerData("class") = Me.getClass headerDataSize = 1 Redim headerDataArray(headerDataSize) As String cnt = 0 Forall itm In headerData If itm "" Then headerDataArray(cnt) = Listtag(itm) & |='| & itm & |'| End If cnt = cnt + 1 End Forall tmpHeaderDataArray = Fulltrim(headerDataArray) getULAttributes = Join(tmpHeaderDataArray, " ") End Property %REM Function addNode Description: Comments for Function %END REM Private Function addNode(cn As ChildNode) If Not cn Is Nothing Then If Not hasChild Then Redim childNodes(0) As ChildNode hasChild = True Else Redim Preserve childNodes(Ubound(childNodes) + 1) As ChildNode End If Set childNodes(Ubound(childNodes)) = cn End If End Function %REM Sub reBuildNodes Description: Comments for Sub %END REM Private Sub rebuildNodes Dim tmpNode As ChildNode Dim currVe As NotesViewEntry While Not Me.getViewEntry() Is Nothing Set tmpNode = New ChildNode(Me) Me.addNode tmpNode ' This will work since the constructor walks the child nodes and returns here when indent level is 0

Wend End Sub %REM Function getNextViewEntry Description: Comments for Function %END REM Public Function getNextViewEntry As NotesViewEntry If Not Me.ve Is Nothing Then Set Me.ve = Me.vnav.Getnext(Me.ve) End If Set getNextViewEntry = Me.getViewEntry() End Function %REM Function getViewEntry Description: Comments for Function %END REM Public Function getViewEntry As NotesViewEntry Set getViewEntry = Me.ve End Function Sub Delete If Not nview Is Nothing Then %REM 'nview.Autoupdate = True %END REM End If End Sub End Class %REM Class TreeRow Description: Comments for Class %END REM Private Class ChildNode Private itemData List As String Private pHasChild As Boolean Private childNodes() As childNode Private parentNode As childNode Private myIndent As Integer Private itemDataSize As Integer Private root As ULTreeFromView Private UniversalID As String Private position As String

%REM Sub New Description: Comments for Sub %END REM Sub New(myroot As ULTreeFromView) Dim ve As NotesViewEntry Dim content As String Set root = myroot Set ve = root.getViewEntry() Me.UniversalID = ve.UniversalID Me.position = ve.Getposition(".") myIndent = root.getViewEntry().Indentlevel Me.pHasChild = False itemData("attribute:id") = Me.position itemData("attribute:universalid") = Me.UniversalID itemDataSize = 0 If root.getLiClass "" Then itemData("attribute:class") = root.getLiClass itemDataSize = itemDataSize + 1 End If Select Case Strleft(Lcase(root.getContentSource),":") Case "field" itemData("content") = ve.Document.GetItemValue(Strright( Lcase(root.getContentSource),":")) itemDataSize = itemDataSize + 1 Case "column" itemData("content") = ve.Columnvalues( Cint( Strright( Lcase(root.getContentSource),":") ) ) itemDataSize = itemDataSize + 1 Case "universalid" Select Case Strtoken(Lcase(root.getContentSource),":",2) Case "field" content = ve.Document.GetItemValue( Strtoken(root.getContentSource,":",3) ) Case "column" content = ve.Columnvalues( Cint( Strtoken(root.getContentSource,":",3) ) ) End Select content = Replace(Strright(Strright(Strright(root.getContentSource,":"),":"),":"), "%%CONTENT%%", content) itemData("content") = Replace(content, "%%UNID%%", Me.UniversalID) itemDataSize = itemDataSize + 1 Case Else

itemData("content") = ve.Columnvalues( 1 ) End Select Me.addChildNodes End Sub Public Property Set setParentNode As ChildNode Set Me.parentNode = setParentNode End Property Public Property Get getParentNode As ChildNode Set getParentNode = Me.parentNode End Property %REM Sub walkNodes Description: Comments for Sub %END REM Private Sub addChildNodes Dim tmpNode As ChildNode Dim exitWhile As Boolean 'Dim currVe As NotesViewEntry 'Set currVe = root.getNextViewEntry() exitWhile = False Call root.getNextViewEntry() While Not root.getViewEntry() Is Nothing And Not exitWhile If root.getViewEntry().Columnindentlevel = myIndent + 1 Then ' Walkthrough all childs indented one level from my on level Set tmpNode = New ChildNode(Me.root) Call Me.addNode(tmpNode) 'Set currVe = root.getNextViewEntry() Else ' Set currVe = Nothing exitWhile = True If root.getViewEntry().Columnindentlevel myIndent Then 'Call root.getNextViewEntry() 'Stop End If End If Wend End Sub %REM Function addNode Description: Comments for Function

%END REM Private Function addNode(cn As ChildNode) If Not cn Is Nothing Then If Not Me.pHasChild Then Redim childNodes(0) As ChildNode pHasChild = True Else Redim Preserve childNodes(Ubound(childNodes) + 1) As ChildNode End If Set childNodes(Ubound(childNodes)) = cn Set childNodes(Ubound(childNodes)).setParentNode = Me End If End Function %REM Property Get getLI Description: Comments for Property Get %END REM Public Property Get getLI As String Dim childTree As ChildNode 'Dim itemData List As String Dim strLI As String 'Dim itemDataSize As Integer Dim itemDataArray() As String Dim attributes() As String Dim tmpAttributes As Variant ' Dim endTag As String Dim cnt As Integer Dim content As String Redim itemDataArray(itemDataSize) As String Redim attributes(itemDataSize) As String cnt = 0 Forall itm In itemData Select Case Lcase(Strleft(Listtag(itm),":")) Case "attribute" attributes(cnt) = Strright(Listtag(itm),":") & "='" & itm & "'" Case Else ' So it's not attribute so its content! content = itm End Select cnt = cnt + 1 End Forall tmpAttributes = Fulltrim(attributes) If Me.root.fromPosition = "" Then

strLI= "" & content & Me.getULFromChildren & "" If Me.getLevel