CFORMS: Dinamically display radio buttons on a table

  • TARGET-AUDIENCE: *advanced*
  • COCOON-RELEASES: 2.1.7
  • DOCUMENT-STATUS: *draft* reviewed released

What you will get from this page

A piece of code that can dramatically ease the use of radio buttons on a cforms page.

Your basic skills

Take a while to understand how cforms various actions example work. XSL knowledge is also necessary to understand the code i wrote.

Technical prerequisites

All the xsl files under cocoon\samples\blocks\forms\resources.

At least the following xml files under cocoon\samples\blocks\forms\

form1.xml

form1_template_action.xml

If you bother to check dependencies you can reduce the number of xsl files needed.


As you might have noticed the current xsl provided with the cforms example is quite limited. I needed to display something like this:

radiobutton1

radiobutton2

radiobutton3

radiobutton4

radiobutton5

radiobutton6

To achieve this efect follow these steps:

  1. Edit forms-field-styling.xsl

1.1 Inside this file look for this line

<xsl:template match="fi:field[fi:selection-list][fi:styling/@list-type='radio']" priority="2">

1.2 Add the following variable line

<xsl:variable name="column" select="number(fi:styling/@column)"/>

1.3 Look for the <xsl:otherwise>. Replace this hole section with this code

<xsl:otherwise>
<xsl:call-template name="produceColumns">
  <xsl:with-param name="nos" select="fi:selection-list/fi:item"/>
  <xsl:with-param name="id" select="$id"/>
  <xsl:with-param name="value" select="$value"/>
  <xsl:with-param name="column" select="$column"/>
</xsl:call-template>
</xsl:otherwise>

1.4 Create the template produceColumns with the following code

<xsl:template name="produceColumns">
	
 <xsl:param name="nodes"/>	
 <xsl:param name="id"/>
 <xsl:param name="value"/>
 <xsl:param name="column"/>
 <xsl:variable name="elements" select="count($nodes)"/>
 
 <tr>
      <xsl:for-each select="$nodes">
      <xsl:variable name="temp" select="($elements)-(count(following-sibling::*))"/>
      <td>
            <input type="radio" id="{generate-id()}" name="{$id}" value="{@value}">
            <xsl:if test="@value = $value">
	       <xsl:attribute name="checked">checked</xsl:attribute>
	    </xsl:if>  	

	    <xsl:apply-templates select="../.." mode="styling"/>
	    </input>

	    <xsl:apply-templates select="." mode="label">
	    <xsl:with-param name="id" select="generate-id()"/>
	    </xsl:apply-templates>		
      </td>

	    <xsl:if test="($temp mod $column)=0">			
            <xsl:call-template name="produceColumns">
	        <xsl:with-param name="nos" select="descendant::fi:item"/>
		<xsl:with-param name="id" select="$id"/>
		<xsl:with-param name="value" select="$value"/>
		<xsl:with-param name="column" select="$column"/>
	    </xsl:call-template>
	    </xsl:if>
      </xsl:for-each>
			
</tr>
</xsl:template>

2. Edit form1.xml declare the following widget:

<fd:field id="test">
 <fd:label>
  this is a test
 </fd:label>
 
 <fd:datatype base="string"/>
  <fd:selection-list>
   <fd:item value="radiobutton1"/>
   <fd:item value="radiobutton2"/>
   <fd:item value="radiobutton3"/>
   <fd:item value="radiobutton4"/>
   <fd:item value="radiobutton5"/>
   <fd:item value="radiobutton6"/>
   </fd:selection-list>
  </fd:field> 

3. Edit form1_template_action.xml declare the use of the previous widget where you think is more convenient for you:

<table border="0">
  <ft:widget id="test">
  <fi:styling list-type="radio" list-orientation="horizontal" column="3"/>
  </ft:widget> 
</table>

4. Voilá! This should now produce a table with 3 columns. As you have 6 radiobuttons, the number of lines will be determined by (6 items/3 columns) = 2 lines.

radiobutton1

radiobutton2

radiobutton3

radiobutton4

radiobutton5

radiobutton6

I would like to thanks to Aaron Bock for his precious xsl help, without which this wiki wouldn't be possible. Also would like to help to Mark Lundquist for his patience and help posting this wiki.

page metadata

  • AUTHOR-CONTACT: cmsbn<at>student.dei.uc.pt
  • REVIEWED-BY:BR
  • REVIEWER-CONTACT:BR
  • No labels