Renderizar/Não renderizar uma tab, sem atualizar o form

Eu preciso fazer com que uma tab do tabview do primefaces, só seja exibida se eu obtiver uma lista não estiver vazia e fazer isso por ajax, eu até consegui fazer com que a tab seja renderizada ou não, porém eu utilizei desse jeito:

<f:ajax event="blur" render="@form" />

Só que desse jeito ao atualizar ele atualiza todas as páginas de todas as tab e eu perco tudo q havia preenchido na tab e o que eu queria era que só atualizasse somente a parte da tab.

Observação: também já tentei passar o id do tabView no render e obtive o mesmo resultado do @form.

1 curtida

Você esta utilizando PrimeFaces? Se sim, você pode trocar o f:ajax por p:ajax e utilizar o seletor abaixo

<p:ajax event="blur" update="@(.ui-tabs-panel:visible)" />

Qualquer coisa posta o código :+1:

1 curtida

Obrigado pela resposta @Mike, mas não funcionou.

Segue a minha tabView:
<p:tabView id=“tabView_estacao” prependId=“false” orientation="top"
widgetVar=“tabViewEstacaoWidget” dynamic=“true”>

			<p:ajax event="tabChange" />

				<p:tab id="tab_01_informacoesGerais" title="Informações Gerais">
					<ui:include
						src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab01InformacoesGerais.xhtml" />
				</p:tab>

				<p:tab id="tab_02_secao_reguas" title="Seção de réguas">
					<div class="ui-fluid ui-g">
						<p:outputPanel class="ui-g-12 no-padding">
							<ui:include
								src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab02SecaoReguas.xhtml" />
						</p:outputPanel>
					</div>
				</p:tab>

				<p:tab id="tab_03_secao_medicao" title="Seção Medição">
					<div class="ui-fluid ui-g">
						<p:outputPanel class="ui-g-12 no-padding">
							<ui:include
								src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab03SecaoMedicao.xhtml" />
						</p:outputPanel>
					</div>
				</p:tab>

				<p:tab id="tab_04_observador" title="Observador"
					rendered="#{not empty inspecaoFluController.inspecaoFluSelecao.estacao.estacaoObservadorAtivos}">
					<div class="ui-fluid ui-g">
						<p:outputPanel class="ui-g-12 no-padding">
							<ui:include
								src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab04Observador.xhtml" />
						</p:outputPanel>
					</div>
				</p:tab>

				<p:tab id="tab_05_responsaveis" title="Responsáveis">
					<div class="ui-fluid ui-g">
						<p:outputPanel class="ui-g-12 no-padding">
							<ui:include
								src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab05Responsaveis.xhtml" />
						</p:outputPanel>
					</div>
				</p:tab>

				<p:tab id="tab_06_despesas" title="Despesas">
					<div class="ui-fluid ui-g">
						<p:outputPanel class="ui-g-12 no-padding">
							<ui:include
								src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab06Despesas.xhtml" />
						</p:outputPanel>
					</div>
				</p:tab>

				<p:tab id="tab_07_anexos" title="Anexos">
					<div class="ui-fluid ui-g">
						<p:outputPanel class="ui-g-12 no-padding">
							<ui:include
								src="/pages/gestaodarede/inspecaoflu/abasCadastro/tab07Anexos.xhtml" />
						</p:outputPanel>
					</div>
				</p:tab>
		</p:tabView>

E esse é o meu input que tem o ajax que atualizará a tab:

<p:inputText id="autocompleteCodigoEstacao"
									placeholder="Entre com o código" maxlength="8" required="true"
									requiredMessage="Código da estação é um campo Obrigatório."
									disabled="#{inspecaoFluController.visualizarFormulario}"
									value="#{inspecaoFluController.codigoEstacaoParaCadastro}">
									<p:ajax event="blur"
										listener="#{inspecaoFluController.onInsertCode}"
										update="nomeEstacaoInspecaoFlu panelLanceRegua panelCotas observadorDataTable @(ui-tabs-panel:visible)" />
									<f:validateLength minimum="8" maximum="8" />

								</p:inputText>

Eu utilizei o render para esconder a tab, mas n necessariamente precisa ser dessa forma, pode ser o disable também ou qualquer outro modo em que o usuário não consiga acessar a tab

Repare que você esqueceu de colocar um ponto “.” antes de ui.-tabs-panel:visible

EDIT:

Quando você mexe com componentes/layouts dinâmicos, você pode utilizar alguns outros seletores que facilitam muito, como por exemplo: @parent, @child, @next, @previous, @composite, etc.

@parent -> pai do componente atual
@form:@child(0) -> primeiro filho do form
@next -> proximo componente
@previous -> componente anterior

Abaixo tem um uso do seletor @parent, no caso ele atualiza o outputPanel

<p:tab>
    <p:outputPanel >
        <p:datatable > 

       </p:datatable>

       <h:panelGrid>
            <p:commandButton value="Atualizar" update="@parent:@parent"/>
       </h:panelGrid>
    </p:outputPanel>
</tab>

O primeiro parent (pai) é o h:panelGrid e o segundo é o p:outputPanel

Você também pode fazer combinações de seletores:

@form:@child(0):@child(1):@(.ui-datatable):@next

No exemplo abaixo eu estaria atualizando todo o h:panelGrid

O seletor aponta o update para o form, depois pro primeiro filho do form(tabView), depois pro segundo filho da tabView (segundo p:tab), depois para a datatable e por fim aponta para o componente declarado logo depois da datatable (h:panelGrid)

<h:form>
    <p:tabView>
        <p:tab > 

        </p:tab>

        <p:tab>
            <p:outputPanel >
                <p:datatable > 

                </p:datatable>

                <h:panelGrid>
                    <p:commandButton value="Atualizar" 
                       update="@form:@child(0):@child(1):@(.ui-datatable):@next"/>
                </h:panelGrid>
            </p:outputPanel>
        </tab>
    </p:tabView>
</h:form>
1 curtida

Desculpe a demora a responder,

Do seu modo eu não consegui fazer, por isso fiz de uma outra forma:

utilizando o ajax do primeface eu dei update no @form e também coloquei o @form no process. Com isso os dados não da tela não foram perdidos.