Your Development & Design Resource
Control the rendered HTML ID attribute of IBM Domino XPages Controls
03/30/2016 by Chris Toohey
The ID attribute of any HTML element is designed to be unique, and to it's credit IBM Domino XPages does a great job using DOM node tree placement to create completely unique IDs.
Those IDs are a horrible mess... but they are unique!
To qualify that statement, let's take a look at a simple example. Here's an
xp:panel Control with an ID:
-- and now, here's what you get in the rendered HTML:
The rendered HTML DIV element here has an ID that is created as a result of the node tree structure of the XPages XML. In other words, this
xp:panel was inside of oh-so-many
xp:form controls, and as a result we get a colon-joined string that's confirmed unique.
But what if you want to set the ID to something specific due to use of a 3rd-party plugin, framework, or other snippet that is looking specifically for a more "simplified" key? Well, we have a few options...
While you can absolutely use pass-thru HTML in the XML source of an XPage to address this, I wouldn't recommend it. In fact, I avoid pass-thru markup at all costs. And for those of you asking why?, I tend to do the majority of my HTML rendering either via Themes or Custom Render Kits vs. the actual markup on the XPage.
And while I'm a huge fan of you writing HTML so you understand exactly what you're sending to the screen, there are better - and more maintainable - ways.
Using inline Control Attributes
We asked for them, and boy did they deliver! When the IBM Domino XPages development team gave us the Attributes List in 8.5.3, they unlocked a pretty slick hack in
As mentioned in past features, an
xp:panel that has no properties - meaning no
styleClass, et al - will simply not render an HTML element. And when you add any of those non-required properties, the
xp:panel will default to rendering an HTML DIV. ... but that's just the default behavior. With the
tagName property, we can make it render as any HTML element we need.
-- but we'll get to that one later. For now, let's stick specifically with the rendered HTML element
Here's a simple example of how you can set the rendered HTML element
id of an
And here's the rendered HTML:
Pretty simple right? Well let's take this a step further with Themes!
Using Themes for Control Attributes
Let's create a themeId for our
xp:panel which will set the rendered HTML element ID attribute to "dnd":
And now, our Theme rule:
Now, just in case you don't speak Theme, we're not only forcing the
tagName property for our
xp:panel Control so it will render an HTML DIV element, but we're setting the element's
id attribute to "dnd" via the
xp:attrs or Attributes List via this Theme rule.
And you might now be asking "why?" as in:
- Why would I not use pass-thru HTML and be done with it?
- Why would I go through all of this trouble just for force the
idon a DIV?
- Why am I still reading this far into a feature for such a simple, basic function in XPages?!
And my answer to all of those is this:
Future Proofing and Code Maintenance
You need to think about the structure of your XPages, and how they can evolve over time, and how they can accomplish that with minimal to zero hands-on maintenance for individual applications as possible.
I recently had a need to create a drag and drop in-browser Microsoft Excel spreadsheet reader. Basically the user can "drag and drop" a spreadsheet onto an area, that spreadsheet is read locally via the HTML5 File API, spreadsheet data is extracted as JSON and rendered in a grid for on-screen management... all offline before submitting the final "imported" spreadsheet data to the server for further processing.
The result was a very slick and highly reusable component that will find its way into many of our applications, and I suspect will become a core function and way we do business in our XPages applications.
Now the libraries I'm using -- more on those in a future post -- require that your HTML have specific attributes, with one of them being an ID of "dnd" for the "Drag and Drop" area.
I could have used pass-thru markup or even used inline Attributes List declarations.
But I opted for a Theme rule... because what happens if the libraries and framework change and they require I use a SPAN vs. a DIV?
What happens if there is some day a native "Drag and Drop" handling element introduced to the HTML spec?
What happens is that I have to either keep the old libraries in production and use a now-antiquated solution or I have to manually change all of my applications to use the new hotness.
So instead I used a Theme rule.
A Theme rule that was added to our main "corporate" Theme, which exists on the Domino server.
A Theme rule which is now available to every single application in our environment.
So if I need to change the DIV to a SPAN (or perhaps one day DNDAREA) element, I only have to make a single Theme rule change and I'm done.
-- and note the
themeId name change, as you really shouldn't type your themes by their resulting output HTML element, as evident by how easily that can change!