Skip to content


Why JSTL tags doesn’t work

The JSTL (c: ) tags are problematic. I have had problems with, for instance c:if and c:foreach not doing what I thought they should. Here is why!

The JSTL library does not contain components. They are tag handlers, which is placeholders for components. This means that they are responsible for building the component tree instead of being a part of it. The building of the component tree is done in the render response phase of teh JSF life cycle. So the thing with c: tags is that they are only evaluated once during each response. They are not reevaluated during an ajax-request.
So if you have a c:foreach that should be iterating trough a set every time a user selects something from a drop-down box (which is supported with a a4j:support, it will not happen. It will only happen the first time during a response.
What happens is that the c:foreach will be evaluated to place holders where actual components will be inserted. These place holders will not be recreated with less than a new page navigation to the same page.
The solution to this problem is to use ui:repeat instead.

<ui:composition template="/view/layout.xhtml"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:a4j="http://richfaces.org/a4j"
	xmlns:s="http://jboss.com/products/seam/taglib"
	xmlns:rich="http://richfaces.org/rich"
	xmlns:c="http://java.sun.com/jstl/core">
	
	<ui:define name="main">  				
		<h:form id="MgmtForm">
			<s:decorate id="routerField" template="/view/c_edit.xhtml">
				<ui:define name="label">Router</ui:define>
				<h:selectonemenu id="routerSelection" 
					style="width:160px;"
					disabled="false"
					value="#{managementVlanAction.selectedRouter}">
					<s:selectitems value="#{routerList.resultList}" 
						var="router"
						label="#{router.name}"
						itemValue="#{router}"
						noSelectionLabel="Please select router ... " />
					 <s:convertentity />
					<a4j:support event="onchange" 
						reRender="routerDivId, serviceFieldId" 
						eventsQueue="#{request.requestURI}"
						action="#{managementVlanAction.setSelectedRouterInterface(null)}"
						ajaxSingle="false" />
				</h:selectonemenu>
			</s:decorate>

			<s:div id="routerDivId" styleClass="routerdiv">
  				 <ui:repeat var="routerCard" value="#{managementVlanAction.selectedRouter.getCRouterCards().toArray()}" > 
					<div id="routercarddiv" >
						<div id="routercardtype" style="float:left; width: 190px; margin: 2px;">
							<h:outputtext value="Slot #{routerCard.slotNo}" style="font-weight: bold; float:left; clear:both;" />
							<h:outputtext value="#{routerCard.CRouterCardType.name}" style="font-weight: normal; width: 100px; float:left; clear:both;" />
						</div>
						<div id="routerinterfaces" style="width: 600px; margin-left: 200px; background-color: blue;" >
							 <ui:repeat var="routerInterface" value="#{routerCard.CRouterInterfaces.toArray()}">  
								<h:panelgrid columns="1" border="0" cellspacing="0" cellpadding="0" 
									style="float: left; background-color: #{routerInterface eq managementVlanAction.selectedRouterInterface ? '#B9E3FA':'#EBECE4'};" >
									<a4j:support event="onclick" 
												 action="#{managementVlanAction.setSelectedRouterInterface(routerInterface)}"
								                 immediate="true" 
								                 onsubmit="this.bgColor='#B9E3FA'" 
								                 eventsQueue="#{request.requestURI}" 
												 ignoreDupResponses="true" 
												 reRender="routerDivId, routerPortSpan"/>
									<h:graphicimage value="/images/icons/#{empty routerInterface.CL3InterfaceConfig ? 'lightbulb_off.png' : 'lightbulb.png'}"
											style="margin-right: 6px;"/>
									<h:panelgroup>
									<div class="routerinterfacediv" > 
										<h:outputtext value="#{routerInterface.getShortName()}" style="float:left; margin-top:3px" />
									</div>
									</h:panelgroup>
								</h:panelgrid>
							</ui:repeat> 
						</div>
					</div>
				</ui:repeat>
			</s:div>

The same problem exists with c:if. You should use the render property of a tag if you want change in an ajax request.
I learned this information from this blog post.

Posted in JSF, Programming.

Tagged with , , .


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.