What is the facet "execution" order?

  • I have an XPage that uses a facet in a template custom control. That template contains the banner, application title bar, bread crumbs, and footer. The facet is the content.

  • That content may or may not employ one or more facets. For the particular issue I’m having, the content employs one facet called “Navigator”, with panes and custom controls for the actual content.

  • That “Navigator” facet is a custom control that, amongst other things, builds an ad-hoc list of links based on data and configuration documents. Because these links are built here, it also sets a session variable here to provide a “friendly” name for the last link clicked, which is supposed to appear as the first entry in the bread crumbs (on the template control). It’s a sessionScope variable to allow any page in the system, which all display the bread crumb, to consistently display this first link as dynamic text, instead of a generic “Home” label.

  • Unfortunately it doesn’t work that way. I’m thinking it’s a timing issue - because the template control has the bread crumb control in it, and the JS that sets the sessionScope value is “two levels down” (content facet is level one, navigator facet is level two), the bread crumb is using the sessionScope value before the navigator sets it.

  • I’d just like verification that is what’s happening. For instance, if it “executes” (renders, traverses, whatever) the facets first, in order to know how much window real estate they consume, then the navigator should always “run” before the bread crumbs, and what I describe can’t be happening.

  • If what I describe is happening, is there some way to tell the bread crumb control to repaint itself? If so I could simply “invalidate” the bread crumb after updating the value and all should be well.

Thanks for your time…

Subject: Use an event

You’re right, it is a timing issue, but it is not specific to facets.Facets are executed inline within the page at the location where they appear in the output HTML.

They are not specially processed before.

You can encounter the same issue if you have a single XPage with 2 different computed fields

  • the first computed field cannot see values that were computed in the 2nd computed field.

The final phase of processing on the server is the render phase, where it iterates through all the controls in the control tree, telling each to output itself as HTML. So a control that appears further up the page will be invoked before a control that is further down the page, and it cannot see the output of a computation in the later control.

The solution to this is to do the processing that produces the output before the render phase occurs.

To execute code before the render phase, you use events.

For example, each XPage or Custom Control has a beforeRenderResponse event, visible in the Events view, where you can set some script to be executed just before the page is output to HTML.

You could compute your list of links there, to be re-evaluated on every page display.

Another option is to save the new value during the event that changes the value, in your case when you click on the link.

Hope that helps.

Subject: Sadly beforeRenderResponse does not work…

  • I attempted to set a sessionScope value here, not even set up any UI stuff, and while there are no errors, the sessionScope value is never set.

  • If I use beforePageLoad the sessionScope value is set, but it’s “too late”, in that the timing issue remains.

  • Just for giggles and laughs I tried afterRenderResponse, but as expected it had no effect. In fact it had the exact same effect as beforeRenderResponse. I’m thinking both of these are server-side events, but the data binding doesn’t grok the link to the configuration document if I set the JS to run server-side. Or maybe I have them backwards. If I set the JS to run with a wakka (#) it finds the data binding but won’t update the sessionScope value. If I set the JS to run with a dollar ($) it doesn’t find the data binding and I get an exception. I thought a wakka was client side?

  • I’ll see about setting it on the link, but that’s going to require a lot of reworking. The link doesn’t have the data it needs to update the bread crumb, so I’ll have to vet that to store it with each link, so the link can use it to update the bread crumb. Assuming such is even possible. It’s looking like a mess at this point. If it weren’t standard to put the bread crumb at the top I’d put it at the bottom and have no worries. (grin)

  • Otherwise I’ll kludge up a control that doesn’t render, it simply manages the data for the links and bread crumb, but sits before everything else. I don’t like that, but there it is. Or I could look up how to reference JS across controls. Then I could keep the existing code and have the navigator update the bread crumb directly.

  • Hmmm. I’m going to look into that. Seems simplest if the system will let me do it.

Thanks again…

Subject: Of course!

(slaps forehead) It’s always the obvious that’s missed right off! It’s bound to help a great deal. Thanks!!!..