JSF: Problema no botão cancelar com ajax [RESOLVIDO]

O usuário digita um valor inválido no campo inpFilterValue e clica no botão Salve, o que vai disparar a validação e a mensagem de validação será exibida.
Então o usuário clica no botão Cancelar para descartar as alterações, o comportamento desejado é que os valores voltem ao estado original (ou em branco no caso de inclusão).
Porém devido a validação previamente executada, o valor incorreto é mantido no campo que estava inválido.
Vejam que o botão Cancelar foi configurado para não processar outros componentes. Isto funciona, desde que o usuário não tenha clicado no botão salvar previamente.

<p:dataTable id="tblFilters"
	value="#{targetBean.filterEditor.dataModel}"
	var="filter">

	<f:facet name="header">

		<h:panelGroup>

			<p:toolbar id="filtersToolbar">

				<p:toolbarGroup align="left">

					<p:commandButton id="btnAddNew" icon="ui-icon ui-icon-plus"
						value="New"
						disabled="#{targetBean.filterEditor.buttonDisabled['btnAdd']}"
						action="#{targetBean.filterEditor.addNew}"
						process="@form" update="@form" title="#{msg['action.add']}" />

					<p:commandButton id="btnEdit" icon="ui-icon ui-icon-plus"
						value="Edit"
						disabled="#{targetBean.filterEditor.buttonDisabled['btnEdit']}"
						action="#{targetBean.filterEditor.edit}"
						process="@form" update="@form" title="#{msg['action.edit']}" />

					<p:commandButton id="btnRemove" icon="ui-icon ui-icon-minus"
						value="Remove"
						disabled="#{targetBean.filterEditor.buttonDisabled['btnRemove']}"
						action="#{targetBean.filterEditor.delete}"
						process="@this" update="@form" title="#{msg['action.remove']}"
						immediate="true">

					</p:commandButton>

					<p:commandButton id="btnSave" process="@form" update="@form"
						value="Save"
						disabled="#{targetBean.filterEditor.buttonDisabled['btnSave']}"
						icon="ui-icon ui-icon-circle-check" title="Salvar"
						action="#{targetBean.filterEditor.save}">

					</p:commandButton>

					<p:commandButton id="btnCancel" value="Cancel" process="@this"
						update="@form" immediate="true"
						disabled="#{targetBean.filterEditor.buttonDisabled['btnCancel']}"
						icon="ui-icon ui-icon-circle-check" title="Cancelar"
						action="#{targetBean.filterEditor.cancel}">

					</p:commandButton>

				</p:toolbarGroup>

			</p:toolbar>

		</h:panelGroup>

	</f:facet>

	<p:column style="width: 2.0em;">

		<p:panelGrid columns="2">

			<p:commandButton id="btnSelect" process="@this" update="@form"
				disabled="#{targetBean.filterEditor.buttonDisabled['btnSelect']}"
				style="width: 1.5em!important; height: 1.5em !important;"
				icon="ui-icon ui-icon-pencil" 
				actionListener="#{targetBean.filterEditor.selectRow}">

				<f:attribute name="selectedValue" value="#{filter}" />

			</p:commandButton>

		</p:panelGrid>

	</p:column>

	<p:column id="colFilterOperating"
		headerText="#{msg['search.filterfield']}">

		<p:selectOneMenu id="inpFilterOperating"
			value="#{filter.operating}" effect="fade" style="width: 100%"
			valueChangeListener="#{targetBean.filterEditor.onChangeOperating}"
			validator="#{targetBean.filterEditor.validateOperating}"
			required="true"
			requiredMessage="Campo de preenchimento obrigatório não preenchido!"
			disabled="#{filter.fieldState['operating'].disabled}">

			<f:selectItem itemLabel="#{msg['action.select']}..." itemValue="" />

			<f:selectItems
				value="#{targetBean.filterEditor.availableFilters}" />

			<p:ajax event="change" process="@this"
				update="msgFilterOperating inpFilterValue msgFilterValue btnAddNew btnRemove btnSelect" />

			<p:message id="msgFilterOperating" for="inpFilterOperating"
				showSummary="true" showDetail="true" />

		</p:selectOneMenu>

	</p:column>

	<p:column id="colFilterOperator"
		headerText="#{msg['search.filtertype']}">

		<p:selectOneMenu id="inpFilterOperator" value="#{filter.operator}"
			effect="fade" style="width: 100%" converter="#{operatorConverter}"
			valueChangeListener="#{targetBean.filterEditor.onChangeOperator}"
			validator="#{targetBean.filterEditor.validateOperator}"
			required="true"
			requiredMessage="Campo de preenchimento obrigatório não preenchido!"
			disabled="#{filter.fieldState['operator'].disabled}">

			<f:selectItem itemLabel="#{msg['action.select']}..." itemValue="" />

			<f:selectItems
				value="#{targetBean.filterEditor.availableOperators}" />

			<p:ajax event="change" process="@this"
				update="msgFilterOperator btnAddNew btnRemove btnSelect" />

			<p:message id="msgFilterOperator" for="inpFilterOperator"
				showSummary="true" showDetail="true" />

		</p:selectOneMenu>

	</p:column>

	<p:column id="colFilterValue"
		headerText="#{msg['search.filtervalue']}">

		<p:inputText id="inpFilterValue" value="#{filter.value}"
			style="width: 100%;"
			valueChangeListener="#{targetBean.filterEditor.onChangeValue}"
			validator="#{targetBean.filterEditor.validateValue}"
			required="true"
			requiredMessage="Campo de preenchimento obrigatório não preenchido!"
			disabled="#{filter.fieldState['value'].disabled}">

			<p:message id="msgFilterValue" for="inpFilterValue"
				showSummary="true" showDetail="true" />

		</p:inputText>

	</p:column>

</p:dataTable>

Coloca o ajax

ajax="false" 

Já passei por situação similar.
No meu caso eu validava na própria página com campos requeridos (required=“true”).

Então ao editar o formulário, clicar em Salvar e reprovar na validação, mesmo que eu quisesse cancelar a operação posteriormente o objeto parecia não sair daquele estado de validação. A página ficava trancada, o load e nem o new no objeto não funcionavam.

“Resolvi” dando refresh na página (submit) para forçar a saída daquele estado.

Ola amigo

Tente por o immediate=“true” no seu botao cancelar

Olá Diego,

Vlw, mas o problema persiste com a alteração abaixo. Desta forma, mesmo com o estado válido ao cancelar os dados são mantidos no componente.

<p:commandButton id="btnCancel" value="Cancel" process="@this"
	update="@form" immediate="true" ajax="false"
	disabled="#{targetBean.filterEditor.buttonDisabled['btnCancel']}"
	icon="ui-icon ui-icon-circle-check" title="Cancelar"
	action="#{targetBean.filterEditor.cancel}">

</p:commandButton>

e nem assim:

<p:commandButton id="btnCancel" value="Cancel" immediate="true" ajax="false"
	disabled="#{targetBean.filterEditor.buttonDisabled['btnCancel']}"
	icon="ui-icon ui-icon-circle-check" title="Cancelar"
	action="#{targetBean.filterEditor.cancel}">

</p:commandButton>

também não assim:

<p:commandButton id="btnCancel" value="Cancel" process="@this"
	update="@form" 
	disabled="#{targetBean.filterEditor.buttonDisabled['btnCancel']}"
	icon="ui-icon ui-icon-circle-check" title="Cancelar"
	action="#{targetBean.filterEditor.cancel}">

</p:commandButton>

Ainda, eu prefiria fazer isso usando ajax para não precisar renderizar toda a view.

[quote=DarthCego]Ola amigo

Tente por o immediate=“true” no seu botao cancelar[/quote]

Vlw colega, mas já está desta forma.

[quote=mrbbm]Já passei por situação similar.
No meu caso eu validava na própria página com campos requeridos (required=“true”).

Então ao editar o formulário, clicar em Salvar e reprovar na validação, mesmo que eu quisesse cancelar a operação posteriormente o objeto parecia não sair daquele estado de validação. A página ficava trancada, o load e nem o new no objeto não funcionavam.

“Resolvi” dando refresh na página (submit) para forçar a saída daquele estado.[/quote]

Pode ser uma solução, mas aí também encontrei uma solução alternativa, que vou adotar caso não solucione de outra forma: retornar uma mensagem FacesMessage.SEVERITY_WARN ao invés FacesMessage.SEVERITY_ERROR e controlar a validação do campo no bean, inclusive o required. Desta forma não deixou a view em estado inválido.

Mesmo assim aceito sugestões para corrigir de uma menos “alternativa”.

só o process="@this" update="@form" já é suficiente pra fazer funcionar… eu uso e funciona perfeito, use actionListener em vez de action, tira esse disabled por enquanto e testa…

[color=blue]<p:commandButton id=“btnCancel” value=“Cancel”
process="@this" update="@form"
icon=“ui-icon ui-icon-circle-check” title=“Cancelar”
actionListener="#{targetBean.filterEditor.cancel}" />
[/color]

tente assim…

mas verifica tb se as tags tão certas…

[color=blue] <h:body>
<f:view>
<h:form prependId=“false” >

        </h:form>
    </f:view>
</h:body>[/color]

[quote=lordaj]só o process="@this" update="@form" já é suficiente pra fazer funcionar… eu uso e funciona perfeito, use actionListener em vez de action, tira esse disabled por enquanto e testa…

[color=blue]<p:commandButton id=“btnCancel” value=“Cancel”
process="@this" update="@form"
icon=“ui-icon ui-icon-circle-check” title=“Cancelar”
actionListener="#{targetBean.filterEditor.cancel}" />
[/color]

tente assim…

mas verifica tb se as tags tão certas…

[color=blue] <h:body>
<f:view>
<h:form prependId=“false” >

        </h:form>
    </f:view>
</h:body>[/color][/quote]

Acredito que tem razão sobre os atributos process e update, BalusC explica aqui:
http://stackoverflow.com/questions/7708041/jsf-immediate-true-for-cancel-button-doesnt-work

Com relação ao disabled, não é o problema. E as tags estão corretas. Vlw lordaj.

Bem, acho que vou “resolver” com a solução “alternativa”, que comentei antes, que está com gerando o comportamento que desejo.

[quote=valdair.mts][quote=mrbbm]Já passei por situação similar.
No meu caso eu validava na própria página com campos requeridos (required=“true”).

Então ao editar o formulário, clicar em Salvar e reprovar na validação, mesmo que eu quisesse cancelar a operação posteriormente o objeto parecia não sair daquele estado de validação. A página ficava trancada, o load e nem o new no objeto não funcionavam.

“Resolvi” dando refresh na página (submit) para forçar a saída daquele estado.[/quote]

Pode ser uma solução, mas aí também encontrei uma solução alternativa, que vou adotar caso não solucione de outra forma: retornar uma mensagem FacesMessage.SEVERITY_WARN ao invés FacesMessage.SEVERITY_ERROR e controlar a validação do campo no bean, inclusive o required. Desta forma não deixou a view em estado inválido.

Mesmo assim aceito sugestões para corrigir de uma menos “alternativa”.[/quote]

Eu resolvi assim, tratando no Bean, inclusive os required. E em conjunto com Ajax nem é preciso dar refresh na página.
Funciona perfeitamente.

Estou com o mesmo problema, mas não queria resolver com a validação no bean e sim na própria página.
Já tentei com imediate=“true” e tbm com process="@this" update="@form" mas nenhum funcionou.
Se alguém souber alguma outra maneira ficarei grato.

Resolvi criando um método no Bean para atualizar a página.

Bean:

public void atualizaPaginaAtual() { FacesContext context = FacesContext.getCurrentInstance(); Application application = context.getApplication(); ViewHandler viewHandler = application.getViewHandler(); UIViewRoot viewRoot = viewHandler.createView(context, context.getViewRoot().getViewId()); context.setViewRoot(viewRoot); context.renderResponse(); }

Página:

&lt;p:commandButton value="Cancelar" actionListener="#{nomeDoBean.atualizaPaginaAtual}" update=":frm" immediate="true" icon="ui-icon-close"/&gt;