Posts Tagged With: Linking

Creating one-to-many linking in Xpages

As I noted in my prior post, our new XPages application will need links from Requisitions to all Purchase Orders that are created from that Requisition. Now, in regular old Notes, I’d handle this just by plopping down a single-category embedded view, using the Requisition’s ID to find just the right Purchase Orders. Since embedded views already allow you to open the document underneath, my work would be done.

Fortunately, having found that Server Side Javascript is not frightfully different from LotusScript. You already have the basic understanding of the document object model from doing LotusScript, so it’s just a matter of figuring out the syntax, right?

Since I want to display a set of links to the associated Purchase Orders, I decided the cleanest way to do that was using a Repeat Control. Unfortunately, knowing the tool I needed didn’t resolve the problem by itself.

First, I had to build the values that would go into my Repeat Control. I thought about binding the view here, but our data doesn’t reside in the same database as the XPage designs. That means I’d have to compute which database I needed and, so far, that felt beyond my talents. Fortunately, the wonderful folks over at Teamwork Solutions provided us with a quick way to get a handle to the database, a getDb function. So, rather than trying to figure out how to squeeze that into a binding, I stuck to my LotusScript roots and got a NotesDocumentCollection from the view.

	<xp:this.value><![CDATA[#{javascript:
 		var db:NotesDatabase = getDb("tamisDb");
 		var poView = db.getView("PObyProcReqDocID");
 		var docCollection = poView.getAllDocumentsByKey(getComponent("docID1").getValue());
 		return docCollection;}]]>
 	</xp:this.value>

So, then, in my repeat, I can just refer to each document, pulling the values I want.

I always try to give my objects names that identify them clearly. My very first paid programming assignment was when I was pursuing my degree in Political Science, studying the Soviet Union. I worked at the National Superconducting Cyclotron Lab. It was a great place to work. Now, they don’t normally hire social studies majors to write code, but I hired in as a receptionist, then started working for the guys in Operations, walking around recording numbers on dials and checking on things. My boss knew I’d been a computer science major, so he guided me into re-writing their help document database. Every module in the database was named after a woman in his life. They were suitable names for him, because he knew the woman and the module names fit their personalities. I didn’t and I knew the next guy wouldn’t either, so I gave them all nice, functional names.

Why do I digress? Well, XPages is so eager to write code for you, that it assigns object names with object type and a number. I think a lot of people leave it that way, but when I’m in there, I need to assign names that fit. Sadly, I always end up with rowData as the object name for my repeats. I don’t know if changing from that had doomed my early repeats or if it’s just superstitious, but I leave it as rowData.

So, back to the completed code. Our ‘value’ section is there, identifying the NotesDocumentCollection we need, of all Purchase Orders documents that belong to the Requisition. For each one, we establish a link, labelling it by grabbing a field value, then using a Simple Action to open the pro_purchaseOrder XPage that displays Purchase Orders and using the UNID from the document selected as our rowData.

	<xp:repeat id="purchaseOrderLinkRepeat" rows="30" var="rowData" repeatControls="false" removeRepeat="true">
		<xp:this.value><![CDATA[#{javascript:
			var db:NotesDatabase = getDb("tamisDb");
			var poView = db.getView("PObyProcReqDocID")
			var docCollection = poView.getAllDocumentsByKey(getComponent("docID1").getValue());
			return docCollection;}]]>
		</xp:this.value>
		<xp:link id="poLink">
			<xp:this.text><![CDATA[#{javascript:"Purchase record: " + rowData.getItemValueString("TSWFNumber");}]]>
			</xp:this.text>
			<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
				<xp:this.action>
					<xp:openPage name="/pro_purchaseOrder.xsp" target="openDocument"
						documentId="#{javascript:rowData.getUniversalID();}">
					</xp:openPage>
				</xp:this.action>
			</xp:eventHandler>
		</xp:link>
	</xp:repeat>

Honestly, that little slice of code took me several days to get my head around. I wasn’t staring at the screen the whole time, but the stops-and-starts of trying one approach and then another were tremendous. Those hurdles truly point out that a seasoned developer might well accomplish in an hour what it takes a new developer (or one new to the language) an entire week to do. Now that I have it under my belt, my team and I will be reusing this all over the place. I hope you can as well.

Advertisements
Categories: Server-Side Javascript | Tags: , , , , | 1 Comment

Creating a one-to-one linking in XPages

In our current project, we create Requisitions with one XPage and then create Purchase Orders with another. Each Requisition may result in many Purchase Orders, but a Purchase Order can only contain line items from a single Requisition. Naturally, the customer wants to be able to move seamlessly from the Requisition to any of the corresponding Purchase Orders and vice-versa.

I wasn’t sure how I’d do this in XPages, but knew I could do it for Notes users without a lot of coding and I could even make it look like web link.

One-to-One In Notes

In regular old Notes, this was very simple. On the Purchase Order form, where I wanted my link I typed Open Procurement Request, then highlighted it and clicked from the top-line menu, Create – Hotspot – Action Hotspot. I made two formatting changes (underline and deselecting the border around the hotspot) 1 and switched the action to run LotusScript. Nice, simple code makes that hotspot open the Requisition:

Sub Click(Source As Button)
	Dim session As New NotesSession
	Dim ws As New NotesUIWorkspace
	Dim thisdb As NotesDatabase
	Dim view As NotesView
	Dim uidoc As NotesUIDocument
	Dim thisdoc As NotesDocument
	Dim reqdoc As NotesDocument
	Dim luvalue As Variant

	Set uidoc = ws.CurrentDocument
	Set thisdoc = uidoc.Document
	luvalue = thisdoc.GetItemValue ( "ProcReqDocID" )

	Set thisdb = session.CurrentDatabase
	Set view = thisdb.GetView ( "LUProcByDocID" )
	Set reqdoc = view.GetDocumentByKey ( luvalue(0) )

	Print luvalue (0)
	If Not reqdoc Is Nothing Then
		Call ws.editDocument ( False, reqdoc )
	End If

End Sub

One-to-One In XPages

Having done it in Notes, I had some guidelines for how I wanted to do it in XPages, rather than just shooting in the dark. I also added display of the requisition number, which turned out to take a few lines of code as well.

	<xp:link escape="true" id="requisitionLink" target="_blank">
		<xp:this.rendered><![CDATA[#{javascript:poDoc.getItemValueString("ProcReqDocID") != "";}]]>
		</xp:this.rendered>
		<xp:this.text><![CDATA[#{javascript:
			var reqID = poDoc.getItemValueString("ProcReqDocID");
			var db:NotesDatabase = getDb("tamisDb");
			var reqView:NotesView = db.getView("LUProcByDocID");
			var reqDoc:NotesDocument = reqView.getDocumentByKey(reqID);
			var reqNumber = reqDoc.getItemValueString("TSWFNumber");
			return "Requisition: " + reqNumber; }]]>
		</xp:this.text>
		<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
			<xp:this.action>
				<xp:openPage name="/pro_procurementRequest.xsp" target="openDocument">
					<xp:this.documentId><![CDATA[#{javascript:
						var reqID = poDoc.getItemValueString("ProcReqDocID");;
						var db:NotesDatabase = getDb("tamisDb");
						var reqView:NotesView = db.getView("LUProcByDocID");
						var reqDoc:NotesDocument = reqView.getDocumentByKey(reqID);
						return reqDoc.getUniversalID();}]]>
					</xp:this.documentId>
				</xp:openPage>
			</xp:this.action>
		</xp:eventHandler>
	</xp:link>

While this was somewhat intimidating, it ended up being not that hard. I will admit that it did take me a whole day to figure out, but it gave me the courage to try tackling linking in the opposite direction, our one-to-many link. For that, I had to expand my recently gained knowledge of repeats. More on that later.

My recent knowledge gain for repeats is thanks to TeamStudio’s webinar on mobile applications. Go figure. As I implement the mobile application that the webinar guided me through building, I’ll blog about that as well. For now, go check out the video.

1) Does anyone use those borders around the hotspot anymore? Since it looks so hideously and is therefor unusable shouldn’t it no longer be the default? Shouldn’t it instead default to underlined?

Categories: Server-Side Javascript | Tags: , , | 1 Comment

Create a free website or blog at WordPress.com.

%d bloggers like this: