There’s a quirk with the display of combobox values when XPages are in read mode. Instead of just displaying the value, it generates a table with one row and one cell. This can cause problems with your form alignment if your fields are aleady in a table (especially a OneUI form layout table). This post contains a few lines of dojo code that can be used to fix the problem.
If you have a one-row two-cell table that contains a label and a combobox, it looks like this in the page source in Domino Designer:
<table> <tr> <td> <xp:label value="Label" id="label1" for="comboBox1"></xp:label> </td> <td> <xp:comboBox id="comboBox1" value="#{document1.Field1}"> <xp:selectItem itemLabel="Value 1"></xp:selectItem> <xp:selectItem itemLabel="Value 2"></xp:selectItem> <xp:selectItem itemLabel="Value 3"></xp:selectItem> </xp:comboBox> </td> </tr> </table>
But this is the output in read mode:
<table> <tr> <td> <label id="view:_id1:label1" for="view:_id1:comboBox1" class="xspTextLabel">Label</label> </td> <td> <table id="view:_id1:comboBox1"> <tr> <td>Value 1</td> </tr> </table> </td> </tr> </table>
Instead of just writing out the value of the combobox, it wraps it in a table.
(A regular field value is generally written out within a span tag that has the id of the control.)
When the combobox doesn’t have a value, then an empty table is inserted (no rows or cells):
<table id="view:_id1:comboBox1"></table>
This code, when run onClientLoad of the page, will fix this issue by replacing the table with just the value of the combobox.
if("#{javascript:document1.isEditable()}" == "false"){ // Search for all nested tables with ids dojo.query('table td table[id]').forEach(function(node) { var value = ''; // Locate the first table cell, which contains the value dojo.query('td:first-child', node).forEach(function(innerNode) { value = innerNode.innerHTML; }); // Replace the table with only the value (or a blank) node.outerHTML = value; }); }
Line 1 tells it to only run in read mode. (Update the name of the document data source variable if you need to.)
Line 3 gets a handle on tables with ids that are nested inside of table cells.
Lines 7-9 search for the first cell within the table and retrieve it’s innerHTML, which is the value of the combobox. If there is no value, then there won’t be a table cell and it will replace the table with an empty string.
Line 12 replaces the original combobox table with just the value that needs to be displayed.
And now the output from the example shown above looks like this, as it should:
<table> <tr> <td> <label id="view:_id1:label1" for="view:_id1:comboBox1" class="xspTextLabel">Label</label> </td> <td> Value 1 </td> </tr> </table>
If you run into conflicts with this affecting other tables in your page, you may need to refine the selector in line 3.
If you need to preserve the of the element and/or wrap it in a span tag like other field values, you can tweak the code accordingly.
