não faz submit (JSF + Facelets)

Estou usando a dupla JSF+Facelets em um pequeno projeto para poder aprender mais sobre estes frameworks, mas não estou conseguindo fazer o submit na primeira tela que criei.

Depois de “apanhar” para entender como criar os templates e utilizá-los, consegui também usar o conceito de componentes, e criar fragmentos de código para poder reutilizá-los em outras páginas. A página “insereEquipamento.xhtml” utiliza os templates “default.xhtml” (esta utiliza o template do arquivo “menuSuperior.jspx”) e o componente gerado pelo arquivo “insereEquipamento.jspx”, como pode ser visto nos códigos abaixo:

insereEquipamento.xhtml (a tag my:insereEquipamento foi criada como componente pelo arquivo insereEquipamento.jspx, devidamente registrada no web.xml)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
					  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
					  
<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:f="http://java.sun.com/jsf/core"
	  xmlns:h="http://java.sun.com/jsf/html"
	  xmlns:ui="http://java.sun.com/jsf/facelets"
	  xmlns:a4j="http://richfaces.org/a4j"
	  xmlns:rich="http://richfaces.org/rich"
	  xmlns:my="http://w3.go.ibge.gov.br/jsf/facelets">

	<ui:composition template="/WEB-INF/templates/default.xhtml">
		<ui:define name="titulo">Informe os valores abaixo</ui:define>
		
		<ui:define name="corpoPagina">
			<h:panelGrid columns="3" cellpadding="3" cellspacing="3">
				<f:facet name="header">
					<h:outputText value="Informe os valores abaixo:" styleClass="tituloFormulario" />
				</f:facet>
		
				<f:verbatim>&nbsp;</f:verbatim>
				<f:verbatim>&nbsp;</f:verbatim>
				<f:verbatim>&nbsp;</f:verbatim>

				<my:insereEquipamento />
				
				<f:verbatim>&nbsp;</f:verbatim>
				<a4j:commandButton value="Confirmar" type="submit" actionListener="{ondeMB.inserirEquipamento}" />
				<f:verbatim>&nbsp;</f:verbatim>
		
				<f:verbatim>&nbsp;</f:verbatim>
				<a4j:outputPanel ajaxRendered="true">
					<h:messages id="mensagens" binding="#{ondeMB.mensagem}" globalOnly="true"
								layout="table" errorClass="mensagemErro"/>
				</a4j:outputPanel>
				<f:verbatim>&nbsp;</f:verbatim>
			</h:panelGrid>
		</ui:define>
	</ui:composition>
</html>

default.xhtml

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
					  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
					  
<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:f="http://java.sun.com/jsf/core"
	  xmlns:h="http://java.sun.com/jsf/html"
	  xmlns:ui="http://java.sun.com/jsf/facelets"
	  xmlns:a4j="http://richfaces.org/a4j"
	  xmlns:rich="http://richfaces.org/rich">

<head>
	<meta http-equiv="Content-Type" content="text/html, charset=iso-8859-1" />
	<link rel="stylesheet" type="text/css" href="scripts/estilo.css"/>
	<link rel="stylesheet" type="text/css" href="scripts/links.css"/>
<!-- <script language="JavaScript" src="scripts/appOndeEsta.js" /> -->

	<title><ui:insert name="titulo">Intranet UE/GO</ui:insert></title>
</head>
	<body>
	<a4j:form id="form1">
		<!-- cabecalho da pagina -->
		<div id="top">
			<ui:insert name="header">
				<div>
					<!-- banner aqui -->
				</div>
			</ui:insert>
		</div>
		
		<!-- menu superior -->  
		<div id="menuSuperior">  
    		<ui:insert name="menuSuperior">  
        		<ui:include src="/WEB-INF/templates/menuSuperior.jspx" />  
    		</ui:insert>  
		</div>  
  
		<!-- corpo da pagina -->  
		<div id="corpoPagina">  
    		<ui:insert name="corpoPagina">
    		** inserir aqui o conteúdo desejado **
    		</ui:insert>  
		</div>  
  
		<!-- rodape da pagina -->  
		<div id="rodape">  
    		<ui:insert name="rodape">  
        		<p style="text-align:center">UE-GO ©2010</p>  
    		</ui:insert>  
		</div>  
	</a4j:form>
	</body>
</html>

menuSuperior.jspx

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
					  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
					  
<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:f="http://java.sun.com/jsf/core"
	  xmlns:h="http://java.sun.com/jsf/html"
	  xmlns:ui="http://java.sun.com/jsf/facelets"
	  xmlns:a4j="http://richfaces.org/a4j"
	  xmlns:rich="http://richfaces.org/rich">

	<ui:composition>
		<rich:toolBar>
			<rich:dropDownMenu>
				<f:facet name="label">
					<h:outputText value="Início"/>
				</f:facet>
				<rich:menuItem value="Início" submitMode="ajax" onclick="document.location.href='index.jsf'"/>
			</rich:dropDownMenu>
			
			<rich:dropDownMenu>
				<f:facet name="label">
					<h:outputText value="Inserir"/>
				</f:facet>
				<rich:menuItem value="Equipamento" submitMode="ajax" onclick="document.location.href='insereEquipamento.jsf'"/>
			</rich:dropDownMenu>
		</rich:toolBar>
	</ui:composition>
</html>

insereEquipamento.jspx

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
					  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
					  
<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:f="http://java.sun.com/jsf/core"
	  xmlns:h="http://java.sun.com/jsf/html"
	  xmlns:ui="http://java.sun.com/jsf/facelets"
	  xmlns:a4j="http://richfaces.org/a4j"
	  xmlns:rich="http://richfaces.org/rich">

	<ui:composition>
				<h:outputLabel value="Tipo:" for="tipo" styleClass="label" />
				<h:selectOneMenu id="tipo" valueChangeListener="#{ondeMB.setTipoSelecionado}"
                                                                         validator="#{ondeMB.validaTipo}" styleClass="listbox">
					<f:selectItem itemLabel="-- selecione o tipo --"/>
					<f:selectItems value="#{ondeMB.tipos}" />
						<a4j:support event="onchange" focus="patrimoniosDigitados" />
				</h:selectOneMenu>
				<f:verbatim>&nbsp;</f:verbatim>

				<h:outputLabel value="Patrimônios:" for="patrimoniosDigitados" styleClass="label"/>
				<h:inputText id="patrimoniosDigitados" size="50" title="informe valores separados por vírgula" styleClass="textArea"/>
				<a4j:commandButton value="Adicionar" type="button" actionListener="#{ondeMB.transferePatrimonios}" />

				<f:verbatim>&nbsp;</f:verbatim>
				<h:panelGrid columns="2">
					<h:selectManyListbox id="patrimonios" size="10" required="true" requiredMessage="Infome os patrimônios"
										 title="use a tecla CTRL para marcar mais de um elemento" style="width:100px"
                                                                                 styleClass="listbox">
						<f:selectItem itemLabel="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"/>
						<f:selectItems value="#{ondeMB.patrimonios}" />
					</h:selectManyListbox>
					<h:panelGrid columns="1">
						<a4j:commandButton value="Remover" type="button" actionListener="#{ondeMB.removerItemLista}"/>
						<a4j:commandButton value="    Limpar   " type="button" actionListener="#{ondeMB.limparLista}"/>
					</h:panelGrid>
				</h:panelGrid>
				<f:verbatim>&nbsp;</f:verbatim>	
	</ui:composition>
</html>

O meu problema é que o botão de submit presente na página “insereEquipamento.xhtml” não faz nada, não chama o managed bean como deveria.
Pesquisando na web (inclusive aqui) encontrei algumas referências sobre problemas de encadeamento de e evitei o uso de vários componentes aninhados, e optei por inserir um único a4j:form no template “default.xhtml”, o que insere todos os componentes em um único (o que constatei no HTML gerado. Tentei também utilizar o par tr:form tr:subform oferecido pelo MyFaces Trinidad, mas também não funcionou.

Peço ajuda aos colegas para me ajudarem a descobrir o que estou fazendo errado.

Estou utilizando MyFaces 1.2.5, RichFaces 3.2.2 SR1 no Tomcat 6.0.16.

nos seus commandButtons coloque o atributo immediate=“true” algo assim:

<a4j:commandButton value="Adicionar" type="button" immediate="true" actionListener="#{ondeMB.transferePatrimonios}" />

Veja se isso funciona.

cara… vc colocou um commandButton mas nao vi nenhum form ( h:form ) nessa página insereEquipamento.

markin1,

nessa tela tem dois commandButton do tipo button (‘Remover’ e ‘Limpar’) e um para submeter o formulário (‘Adicionar’). Eu já havia tentado isso, mas não deu certo. O engraçado é que o formulário não faz nada, não exibe nem as mensagens de validação no h:messages .

deadlock,
realmente não tem h:form, pois foi o que eu disse no texto abaixo do código, por achar em fóruns sobre problemas de se ter mais de um form, e como estou usando Facelets, optei por colocar o a4j:form no default.xhtml, que é incluído na insereEquipamento.xhtml pelo ui:composition. O engraçado é que colocando ou não um a4j:form nessa página insereEquipamento.xhtml o comportamento é o mesmo.

Se tiverem novas sugestões, agradeço.

seguinte… vi a linha:

&lt;f:selectItems value="#{ondeMB.tipos}" /&gt;  

recomendo q vc coloque esse “ondeMB.tipos”, e qualquer outra coleção, em um saveState. Testa ai e diz o resultado.

Desculpe, mas não conheço a expressão ‘saveState’. É um managedBean? Se sim, é de lá que os elementos vem, após buscar no SGBD. Abaixo, o código do managedBean que cria os f:selectItens:

	public List<SelectItem> getTipos(){
		try{
			//busca os tipos no SGBD
                        tipos = tipoFacade.getTipos();
			List<SelectItem> itens = new ArrayList<SelectItem>();
			for(TipoEquipamento t : tipos)
				itens.add(new SelectItem(t.getDescricao()));
			return itens;
		} catch (Exception e) {
                     ...
		}
	}

Aliás, a tela está sendo montada corretamente, os itens do h:selectOneMenu estão sendo exibidos normalmente. Caso fique o primeiro item selecionado ("-- selecione o tipo --""), deveria aparecer uma mensagem de erro no h:messages, gerado pelo validador quando fizesse o submit.

[quote=rogerioag]Desculpe, mas não conheço a expressão ‘saveState’. É um managedBean? Se sim, é de lá que os elementos vem, após buscar no SGBD. Abaixo, o código do managedBean que cria os f:selectItens:
[/quote]

o saveState é uma tag do tomahawk que, na minha opinião, resolve “99,9%” dos problemas do JSF.
pelo q vi, sua página insereEquipamento.jspx não está declarando o namespace do tomahawk.

para usar o saveState, vc faz:

<t:saveState value="#{ondeMB.tipos}" />

logo após <ui:composition>

e quanto ao uso do tomahawk, fik como dever de casa… rsrsrsrsrs

Ok, já vi o saveState, depois estudarei-o com mais calma. Obrigado pela dica.

Só que o que quero persistir é o que o usuário vai digitar no campo ‘patrimonioDigitado’. E independente do que ele digitar, o validador do campo ‘tipo’ (que possui o #ondeMB.tipos) deveria ser validado no submit, e isso não ocorre. Ou seja, não acredito que seja por falta do saveState.

Aliás, eu já havia testado uma página básica, sem facelets, que submetia, era validada e exibia a mensagem de erro. Quando comecei a estudar o Facelets e alterar o código é que parou de funcionar.

Foi aí que resolvi “passar” por aqui. Se puder me ajudar… :))

Alguma sugestão???

Cara, vejo que você está utilizando a4j . Só por desencargo de consciência, você registrou ele corretamente no seu web.xml ?

Sim.

<?xml version='1.0' encoding='ISO-8859-1'?>

<!--
  Copyright 2006 The Apache Software Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         					http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
        <description>
            State saving method: "client" or "server" (= default)
            See JSF Specification 2.5.2
        </description>
    </context-param>
    
    <context-param>
    	<param-name>org.ajax4jsf.SKIN</param-name>
    	<param-value>classic</param-value>
    </context-param>
	
	<!-- Facelets -->
	<context-param>
    	<param-name>facelets.DEVELOPMENT</param-name>
    	<param-value>true</param-value>
    	<description>Special Debug Output for Development</description>
	</context-param>
	
	<!-- para evitar mensagens de erro em comentarios colocados em paginas XHTML -->
	<context-param>
  		<param-name>facelets.SKIP_COMMENTS</param-name>
  		<param-value>true</param-value>
	</context-param>
    
    <context-param>
    	<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    	<param-value>.xhtml</param-value>
    	<description>Por usar o Facelets, este parametro informa para a
    	implementacao do JSF que os arquivos agora terao a extensao
    	xhtml, e nao mais jsp</description>
    </context-param>
	
    <context-param>
    	<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
    	<param-value>com.sun.facelets.FaceletViewHandler</param-value>
    </context-param>
    
    <context-param>
		<param-name>facelets.LIBRARIES</param-name>
		<param-value>/WEB-INF/tags/insereEquipamento.taglib.xml</param-value>
	</context-param>
    

<!-- Extensions Filter -->
    <filter>
	<display-name>Ajax4jsf Filter</display-name>
		<filter-name>ajax4jsf</filter-name>
		<filter-class>org.ajax4jsf.Filter</filter-class>
    </filter>

<!-- mapeamento de filtros -->
    <filter-mapping>
		<filter-name>ajax4jsf</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    
<!-- listeners -->
    <listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

<!-- Servlets -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

<!-- mapeamento de servlets -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

<!-- outros -->
    <welcome-file-list>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
	
    <application>
        <message-bundle>messages</message-bundle>
    </application>

<!-- seguranca -->
	<security-constraint>
		<display-name>Restrict XHTML Documents</display-name>
		<web-resource-collection>
			<web-resource-name>XHTML</web-resource-name>
			<url-pattern>*.xhtml</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<description>Somente desenvolvedores terao acesso aos arquivos XHTML</description>
			<role-name>developer</role-name>
		</auth-constraint>
	</security-constraint>
</web-app>

Estou com um problema quero usar Richfaces e facelets.

coloquei no xhtml : xmlns:rich=“http://richfaces.org/rich

dentro do arquivo xhtml chamo o compomente richfaces: <rich:calendar></rich:calendar>

mais dentro dos componente richfaces não tenho acesso aos atributos, so tendo acesso ao atributo id, estou usando
facelets 1.1.14 e richfaces 3.3.0

Como esta :<rich:calendar></rich:calendar>

Como deveria esta <rich:calendar converter="" currentDate="" dayStyleClass=""> </rich:calendar>

Desde ja agradeco a todos.