[RESOLVIDO] Problema com menu em abas e mensagens

2 respostas
J

Olá pessoal.

Eu tinha um tela com um formulário único, resolvi dividir o conteúdo do form, então criei abas para isso.
Com o formulário sem divisão por abas as mensagens de validação e growl do primefaces apareciam corretamente, porém com as abas essas mensagens não aparecem mais.

O primeiro erro que tive foi que existia um update dentro dos botões de submit que referenciavam o id do form, mas com as abas no momento do submit eu perdia(some) o conteúdo, então resolvi tirar esse update e no momento do submit eu não perco mais esse conteúdo das abas.

Alguém poderia me ajudar nesse problema?
Tentei fazer o update do botão apontar para o div que envolve o conteúdo, porém não consegui.
Também tentei mudar a posição do growl para dentro desse div que abriga os divs do conteúdo, mas sem resultados.

Segue a minha tela.

<ui:composition 
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:c="http://java.sun.com/jsp/jstl/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.prime.com.tr/ui" 
	xmlns:ui="http://java.sun.com/jsf/facelets"
	template="comuns/template.xhtml">

	<ui:define name="title"></ui:define>
	
	<ui:define name="conteudo" style="vertical-align: top;">
		<script language="javascript" type="text/javascript" src="#{facesContext.externalContext.requestContextPath}/js/menuAbas.js" ></script>
		<link rel="stylesheet" media="all" href="#{facesContext.externalContext.requestContextPath}/css/menuAbas/menuAbas.css" />
		<link rel="stylesheet" media="all" href="#{facesContext.externalContext.requestContextPath}/css/configuracaoGlobal/configuracaoGlobal.css" />
			
		<f:view>
			<p:dialog modal="true" widgetVar="statusDialog" header="#{msg['processando']}" draggable="false" closable="false" resizable="false">  
				<p:ajaxStatus style="width:16px;height:16px; position: center;">  
					<p:graphicImage value="/images/timesheet/ajaxloadingbar.gif" style="position: center;"/>
				</p:ajaxStatus>
			</p:dialog>
			
			<h:form styleClass="cadastro" id="formulario" style="min-height:0px; vertical-align: top;" prependId="false">
				<h:inputHidden id="onLoad" value="#{configuracaoGlobalController.onload}" />
				<div class="linhaSecaoDados" />
				<div class="secaoDados">
					<h:outputLabel value="&#160;#{msg['menu.cadastro']} / #{msg['menu.configuracaoGlobal']}" />
				</div>

				<div class="blankLine"></div>
				<div class="container" >
				<p:growl id="messagens" showDetail="false" globalOnly="true" />				
					<div class="simpleTabs">
					    <ul class="simpleTabsNavigation">
					        <li><a href="#"><span>Configurações Gerais</span></a></li>
					        <li><a href="#"><span>Timesheet</span></a></li>
					        <li><a href="#"><span>Robo Email</span></a></li>
					        <li><a href="#"><span>Robo Timesheet</span></a></li>
					        <li><a href="#"><span>Robo Bloqueio</span></a></li>
					    </ul>
						
					    <div class="simpleTabsContent">
					    	<table class="dadosBackground">
								<tr>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.contextPathAplicacao']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.pathUploadArquivo']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.auditarSistema']}"/></th>
								</tr>
								<tr>
									<td>
										<h:inputText
											id="urlContextPath"
											value="#{configuracaoGlobalController.model.urlContextPath}"
											size="80" 
											maxlength="60"
											tabindex="1" >
										
											<p:ajax event="blur" update="msgUrlContextPath"/>
										</h:inputText>
										<p:message id="msgUrlContextPath" for="urlContextPath" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="pathUploadArquivo"
											value="#{configuracaoGlobalController.model.pathUploadArquivos}"
											size="80" 
											maxlength="60"
											tabindex="2" >
										
											<p:ajax event="blur" update="msgPathUploadArquivo"/>
										</h:inputText>
										<p:message id="msgPathUploadArquivo" for="pathUploadArquivo" showDetail="true"/>
									</td>
									<td>
										<h:selectOneMenu
											id="auditoriaSistema"
			   								value="#{configuracaoGlobalController.model.auditarOperacoes}"
											immediate="true"
											tabindex="3"
											style="width: 150px" >
															
											<f:selectItems value="#{configuracaoGlobalController.selectItemSimNao}" />
											<p:ajax event="change" update="msgAuditoriaSistema"/>
										</h:selectOneMenu>
										<p:message id="msgAuditoriaSistema" for="auditoriaSistema" showDetail="true"/>
									</td>
								</tr>
							</table>
		
							<table class="dadosBackground">
								<tr>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.tipoAutenticacao']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.qtdeTentativaLogin']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.senhaDefaultImportacao']}"/></th>
								</tr>
								<tr>
									<td>
										<h:selectOneMenu
											id="tipoAutenticacao"
			   								value="#{configuracaoGlobalController.model.tipoAutenticacaoEnum}"
											immediate="true"
											tabindex="4"
											style="width: 220px" >
															
											<f:selectItems value="#{configuracaoGlobalController.selectItemTipoAutenticacao}" />
											<p:ajax event="change" update="msgTipoAutenticacao"/>
										</h:selectOneMenu>
										<p:message id="msgTipoAutenticacao" for="tipoAutenticacao" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="qtdeTentativaLogin"
											value="#{configuracaoGlobalController.model.qtdeTentativaLogin}"
											size="20" 
											maxlength="3"
											tabindex="5"  
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
											
											<p:ajax event="blur" update="msgQtdeTentativaLogin"/>
										</h:inputText>
										<p:message id="msgQtdeTentativaLogin" for="qtdeTentativaLogin" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="senhaDefault"
											value="#{configuracaoGlobalController.model.senhaDefault}"
											size="30" 
											maxlength="16"
											tabindex="6" >
										
											<p:ajax event="blur" update="msgSenhaDefault"/>
										</h:inputText>
										<p:message id="msgSenhaDefault" for="senhaDefault" showDetail="true"/>
									</td>
								</tr>
								<tr>
									<td colspan="4">
										<p:panel styleClass="prime-no-border">
											<h:panelGroup styleClass="btpeq">
												<p:commandLink 
													value="#{msg['gravar']}"
													tabindex="" 
													action="#{configuracaoGlobalController.gravar}"
													onstart="statusDialog.show();" 
													onsuccess="statusDialog.hide();" />
											</h:panelGroup>
										</p:panel>
									</td>
								</tr>
							</table>						
					    </div>
					    
					    <div class="simpleTabsContent">
					    	<table class="dadosBackground">
								<tr>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.qtdeMaximoHoras']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.qtdeDiasMininimoHora']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.diaLimite']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.horaLimite']}"/></th>
								</tr>
								<tr>
									<td>
										<h:inputText
											id="qtdeMaximoHoras"
											value="#{configuracaoGlobalController.model.qtdeMaximoHoras}"
											size="15" 
											maxlength="2"
											tabindex="11" 
											onkeypress="mascara_0007(this,mascaraNumero_0014)" >
										
											<p:ajax event="blur" update="msgQtdeMaximoHoras"/>
										</h:inputText>
										<p:message id="msgQtdeMaximoHoras" for="qtdeMaximoHoras" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="qtdeDiasMininimoHora"
											value="#{configuracaoGlobalController.model.qtdeDiasMininimoHora}"
											size="15" 
											maxlength="1"
											tabindex="12" 
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
										
											<p:ajax event="blur" update="msgQtdeDiasMininimoHora"/>
										</h:inputText>
										<p:message id="msgQtdeDiasMininimoHora" for="qtdeDiasMininimoHora" showDetail="true"/>
									</td>
									<td>
										<h:selectOneMenu
											id="diaLimiteLancamentoHoras"
											value="#{configuracaoGlobalController.model.diaLimiteLancamentoHoras}"
											immediate="true"
											tabindex="13" >
															
											<f:selectItems value="#{configuracaoGlobalController.selectDiaSemana}" />
											<p:ajax event="change" update="msgDiaLimiteLancamentoHoras" />
										</h:selectOneMenu>	
										<p:message id="msgDiaLimiteLancamentoHoras" for="diaLimiteLancamentoHoras" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="horarioLimiteLancamentoHoras"
											value="#{configuracaoGlobalController.model.horarioLimiteLancamentoHoras}"
											size="15" 
											maxlength="5"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraHoraMinuto_0015)">
										
											<p:ajax event="blur" update="msgHorarioLimiteLancamentoHoras"/>
										</h:inputText>
										<p:message id="msgHorarioLimiteLancamentoHoras" for="horarioLimiteLancamentoHoras" showDetail="true"/>
									</td>
								</tr>
								<tr>
									<td colspan="4">
										<p:panel styleClass="prime-no-border">
											<h:panelGroup styleClass="btpeq">
												<p:commandLink 
													value="#{msg['gravar']}"
													tabindex="" 
													action="#{configuracaoGlobalController.gravar}"
													onstart="statusDialog.show();" 
													onsuccess="statusDialog.hide();" />
											</h:panelGroup>
										</p:panel>
									</td>
								</tr>
							</table>
					    </div>
					    
				    	<div class="simpleTabsContent">
				    		<table class="dadosBackground">
								<tr>
									<th colspan="4"><h:outputLabel value="#{msg['configuracaoGlobal.emailAdministrador']}"/></th>
								</tr>
								<tr>
									<td colspan="4">
										<h:inputText
											id="emailAdministrador"
											size="80"
											maxlength="200" 
											tabindex="7"
											value="#{configuracaoGlobalController.model.emailAdministrador}">
											
											<p:ajax event="blur" update="msgEmailAdministrador"/>
										</h:inputText>
										<p:message id="msgEmailAdministrador" for="emailAdministrador" showDetail="true"/>
									</td>									
								</tr>
		
								<tr>								
									<th><h:outputLabel value="#{msg['configuracaoGlobal.qtdeTentativasRoboEmail']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.horaInicioRoboEmail']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.tempoTimerRoboEmail']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.ativarRoboEmail']}"/> </th>
								</tr>
								<tr>
									<td>
										<h:inputText
											id="qtdeTentativasRoboEmail"
											size="20"
											maxlength="2" 
											tabindex="8"
											value="#{configuracaoGlobalController.model.qtdeTentativasRoboEmail}"
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
											
											<p:ajax event="blur" update="msgQtdeTentativasRoboEmail"/>
										</h:inputText>
										<p:message id="msgQtdeTentativasRoboEmail" for="qtdeTentativasRoboEmail" showDetail="true"/>
									</td>	
									<td>
										<h:inputText
											id="horaInicioRoboEmail"
											size="20"
											maxlength="5"
											tabindex="9" 
											value="#{configuracaoGlobalController.model.horaInicioRoboEmail}"
											onkeypress="mascara_0007(this,mascaraHoraMinuto_0015)">
										
											<p:ajax event="blur" update="msgHoraInicioRoboEmail"/>
										</h:inputText>
										<p:message id="msgHoraInicioRoboEmail" for="horaInicioRoboEmail" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="timerRoboEmail"
											size="20"
											maxlength="3"
											tabindex="10" 
											value="#{configuracaoGlobalController.model.timerRoboEmail}"
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
										
											<p:ajax event="blur" update="msgTimerRoboEmail"/>
										</h:inputText>
										<p:message id="msgTimerRoboEmail" for="timerRoboEmail" showDetail="true"/>
									</td>
									<td>
										<p:selectBooleanCheckbox  value="#{configuracaoGlobalController.model.ativarRoboEmail}" immediate="true"/>
									</td>
								</tr>
								<tr>
									<td colspan="4">
										<p:panel styleClass="prime-no-border">
											<h:panelGroup styleClass="btpeq">
												<p:commandLink 
													value="#{msg['gravar']}"
													tabindex="" 
													action="#{configuracaoGlobalController.gravar}"
													onstart="statusDialog.show();" 
													onsuccess="statusDialog.hide();" />
											</h:panelGroup>
										</p:panel>
									</td>
								</tr>
							</table>
				    	</div>
					    <div class="simpleTabsContent">
							<table class="dadosBackground">
								<tr>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.qtdeTentativasRoboTimesheet']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.horaInicioRoboTimesheet']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.tempoTimerRoboTimesheet']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.ativarRoboTimesheet']}"/></th>
								</tr>
								<tr>
									<td>
										<h:inputText
											id="qtdeTentativasRoboTimesheet"
											value="#{configuracaoGlobalController.model.qtdeTentativasRoboTimesheet}"
											size="15" 
											maxlength="2"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
										
											<p:ajax event="blur" update="msgQtdeTentativasRoboTimesheet"/>
										</h:inputText>
										<p:message id="msgQtdeTentativasRoboTimesheet" for="qtdeTentativasRoboTimesheet" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="horaInicioRoboTimesheet"
											value="#{configuracaoGlobalController.model.horaInicioRoboTimesheet}"
											size="15" 
											maxlength="5"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraHoraMinuto_0015)">
										
											<p:ajax event="blur" update="msgHoraInicioRoboTimesheet"/>
										</h:inputText>
										<p:message id="msgHoraInicioRoboTimesheet" for="horaInicioRoboTimesheet" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="timerRoboTimesheet"
											value="#{configuracaoGlobalController.model.timerRoboTimesheet}"
											size="15" 
											maxlength="3"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
										
											<p:ajax event="blur" update="msgTimerRoboTimesheet"/>
										</h:inputText>
										<p:message id="msgTimerRoboTimesheet" for="timerRoboTimesheet" showDetail="true"/>
									</td>
									<td>
										<p:selectBooleanCheckbox  value="#{configuracaoGlobalController.model.ativarRoboTimesheet}" immediate="true"/>
									</td>
								</tr>
								<tr>
									<td colspan="4">
										<p:panel styleClass="prime-no-border">
											<h:panelGroup styleClass="btpeq">
												<p:commandLink 
													value="#{msg['gravar']}"
													tabindex="" 
													action="#{configuracaoGlobalController.gravar}"
													onstart="statusDialog.show();" 
													onsuccess="statusDialog.hide();" />
											</h:panelGroup>
										</p:panel>
									</td>
								</tr>
							</table>					
					    </div>
					    <div class="simpleTabsContent">
					    	<table class="dadosBackground">
								<tr>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.qtdeTentativasRoboBloqueio']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.horaInicioRoboBloqueio']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.tempoTimerRoboBloqueio']}"/></th>
									<th><h:outputLabel value="#{msg['configuracaoGlobal.ativarRoboBloqueio']}"/></th>
								</tr>
								<tr>
									<td>
										<h:inputText
											id="qtdeTentativasRoboBloqueio"
											value="#{configuracaoGlobalController.model.qtdeTentativasRoboBloqueio}"
											size="15" 
											maxlength="2"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
										
											<p:ajax event="blur" update="msgQtdeTentativasRoboBloqueio"/>
										</h:inputText>
										<p:message id="msgQtdeTentativasRoboBloqueio" for="qtdeTentativasRoboBloqueio" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="horaInicioRoboBloqueio"
											value="#{configuracaoGlobalController.model.horaInicioRoboBloqueio}"
											size="15" 
											maxlength="5"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraHoraMinuto_0015)">
										
											<p:ajax event="blur" update="msgHoraInicioRoboBloqueio"/>
										</h:inputText>
										<p:message id="msgHoraInicioRoboBloqueio" for="horaInicioRoboBloqueio" showDetail="true"/>
									</td>
									<td>
										<h:inputText
											id="timerRoboBloqueio"
											value="#{configuracaoGlobalController.model.timerRoboBloqueio}"
											size="15" 
											maxlength="3"
											tabindex="14" 
											onkeypress="mascara_0007(this,mascaraNumero_0014)">
										
											<p:ajax event="blur" update="msgTimerRoboBloqueio"/>
										</h:inputText>
										<p:message id="msgTimerRoboBloqueio" for="timerRoboBloqueio" showDetail="true"/>
									</td>
									<td>
										<p:selectBooleanCheckbox  value="#{configuracaoGlobalController.model.ativarRoboBloqueio}" immediate="true"/>
									</td>
								</tr>
								<tr>
							<td colspan="4">
								<p:panel styleClass="prime-no-border">
									<h:panelGroup styleClass="btpeq">
										<p:commandLink 
											value="#{msg['gravar']}"
											tabindex="" 
											action="#{configuracaoGlobalController.gravar}"
											onstart="statusDialog.show();" 
											onsuccess="statusDialog.hide();" />
									</h:panelGroup>
								</p:panel>
							</td>
						</tr>
							</table>	
					    </div>
					</div>
				</div>	
	    	</h:form>
		</f:view>

	</ui:define>
</ui:composition>

Obrigado.

2 Respostas

J

Olá pessoal,

Para resolver o problema do growl eu adicionei dentro da tag autoUpdate=“true” e agora aparecem as mensagens do growl.

Agora só estou com o problema das mensagens de validação dos campos.

Criei uma classe validator e adicionei o validator no campo.

<tr>
										<td>
											<h:inputText
												id="urlContextPath"
												value="#{configuracaoGlobalController.model.urlContextPath}"
												size="80" 
												maxlength="60"
												tabindex="1" >
												<f:validator validatorId="AQUI ESTÁ O NOME DECLARADO NA ANOTAÇÃO DO FACESVALIDATOR" />
												
												<p:ajax event="blur" update="msgUrlContextPath"/>
											</h:inputText>
											<p:message id="msgUrlContextPath" for="urlContextPath" showDetail="true"/>
										</td>
									</tr>

Essa classe de validação implementa Validator e nela coloquei a seguinte condição no método validate:

if(StringUtils.isEmpty(value.toString())){
			FacesMessage msg = new FacesMessage("Campo não pode ser nulo");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(msg);
		}

Quando o campo tem algum valor, ele chama normalmente esse método de validação, porém se está vazio não chama o método.

Alguém consegue me dar uma luz nesse problema?
Obrigado.

J

Pessoal,

Quebrei bastante a cabeça, dei várias voltas e encontrei o problema, que era bem simples.
Como vi poucos casos na internet, acho que a solução pode ajudar alguém.

Pelo que eu entendi o JSF 2.0 por padrão não valida campos “empty”, tanto é que somente entrava na classe de validação se estivesse algo inserido no campo.

Então coloquei a seguinte configuração no meu web.xml:

<context-param>
 <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
 <param-value>true</param-value>
 </context-param>

Só ficou obscuro o por quê do JSF adotar esse comportamento de não validar campos empty somente quando esses campos estão dentro de uma tab, mas pelo menos resolvi o problema aqui.

Abraços.

Criado 21 de novembro de 2011
Ultima resposta 22 de nov. de 2011
Respostas 2
Participantes 1