Yesterday I fought for quite some time trying to get Edit Boxes in a Form Table to go full width. It’s a starter database I’ve had for some time and converted from OneUI to Bootstrap. So I have some styles for setting the width of Edit Boxes, depending on whether I want small, medium or full-width. My CSS class for full width sets “width: 100%”. But this was being ignored.
Using Firebug I could see it wasn’t being overridden by something else. I could see that the Edit Box was being surrounded by a div with the class “pull-left”, which I suspected was the culprit. Googling the problem gave a host of standard web developers who had hit a similar issue and HTML-related solutions. But this is XPages (and I’ll come back to why that’s good, not bad).
So I jumped onto the XPages Slack chat, certain that I wasn’t the first to hit this problem and there must be a simple, smart solution. Yes, I found I wasn’t the only one. But the approaches other developers had taken was Custom Controls with raw HTML or custom renderers.
My Solution
So after over an hour of frustrated Googling and internal ranting at why no smart solution has been identified, interspersed with very brief dismissal of alternatives, I took the approach I’ve used for a number of years now, since I got involved in writing XPages Extension Library book (some time before Bootstrap was considered as a candidate, I hasten to add). I dug into the source code.
I blogged some years ago on OpenNTF about installing the source code of Extension Library, at the time IBM first started accepting pull requests and I first contributed fixes and enhancements that are now in the core with Feature Pack 8. I would encourage anyone with a modicum of Java knowledge to do so. It is good to learn how the functionality is built and – as in this case – provides a smart solution for problems where documentation would need to be too exhaustive and would not get used. (I say this based on questions I’ve answered on StackOverflow quoting XPages Extension Library book, which by no means could go into the kind of detail required – I wouldn’t have the time to write it and I am convinced developers wouldn’t bother reading the minutiae involved.)
This is bootstrap, so the relevant Java plugin was obviously going to be com.ibm.xsp.theme.bootstrap. This is a Form Table, and the answer was in the class that rendered the HTML, so I searched in Eclipse for “FormTableRenderer”, though “pull-left” would also work. This led to the FormTableRenderer class and the property “PROP_FLOATDATACLASS”. Highlighting that pointed to three other places it was used in the class. The One was in writeFormRowLabel method – my problem wasn’t where it was writing the label of the row, so easy to dismiss that one. The first of the others was in writeFormRowData method, here:
It’s set if the l(a)b(e)lWidth is not empty. Checking my code showed I had label width set via CSS to 20%, left over from when I used the OneUI style. Removing that width solved my problems immediately, with zero HTML coding and in a way that required no copying and pasting of content between applications if I want the same outcome in the future.
If you want a label width, my strong recommendation would be to look at submitting a pull request for a scalable, flexible, smart way to dynamically work out the width. Personally, my approach would be to expect the label width to be set via a Bootstrap class in the format “col-md-2”, then the Extension Library code could check for that format and work out the relevant width based on 12-column layout and whether or not the row has Help defined.
Component-Based Development FTW!
I said earlier that the fact this is XPages is good not bad. This is why. Hitting a problem, the solution can be managed server-wide with flexible output. No manual coding of HTML, which may force you to maintain legacy code because it cannot easily be upgraded to a newer Bootstrap framework. After all, this is why XPages developers have had minimal effort upgrading from Bootstrap 2.x to 3.x, whereas those developers manually coding HTML will have had to put in more effort. It also means no adding custom renderers which need copying from application to application (remembering to register them in faces-config, which is easily forgotten). The component-based approach that XPages has used since its launch in 2009 is, in my opinion, the smart choice.
And that’s not based on experience only of XPages. Vaadin uses the same component-based approach and has also made its components available to JavaScript developers as well as Java developers. Out of the two main JavaScript frameworks, I have no experience of Angular but I know React uses a component-based approach. The less code that needs changing as a framework matures, the better in my opinion. And the more centralised the component (OSGi plugins over Custom Controls, core Domino extension libraries over custom OSGi plugins), the smarter the approach.
Hopefully this will mean others don’t have to spend as long fighting for a solution. And if there is a feeling that the current code needs to be more flexible, hopefully people will embrace submitting a pull request. There is a degree of technical learning that may be required, but I am more than happy to help empower others to contribute to open source, and I know others involved in OpenNTF and chats would also be willing. All that is required is to ask, because the more who contribute to open source, the less time we have to spend solving the same problems and reinventing the wheel, and the better the outcome we can get. After all, this is why I blog and contribute to open source.