JSF, parâmetros, grid e alterar

16 respostas
C

Boa tarde a todos. Pessoal consegui um estágio em J2EE/JSF e sou novato nesse tema de frameworks. Estou desenvolvendo uma aplicação onde há uma regra de pesquisa e logo abaixo é exibido um grid com os resultados. Está funcionando. Em cada linha do resultado tem um link - alterar, e outro link - excluir. (Por enquanto só vou mexer com a alteração, pra não confundir)
O fato é que quando clico em alterar tenho que pegar os dados da linha correspondente da tabela e mandar para outra página onde será feita a alteração. Abrirão novos campos com os dados da linha que eu cliquei no grid pro usuário alterar.
O fato é que estou meio confuso pq me disseram aqui no estágio que eu teria que fazer através de passagem de parâmetros.
Segue o código para a coluna alterar:

<t:column sortable="false" id="alterar" columnId="alterar">
  <f:facet name="header">
	<h:outputText id="labelAlterar" value="Alterar" />
  </f:facet>
               <h:commandLink value="Alterar" action="#{vTipoMotivoBean.alterarTipoMotivo}" />
               <f:param id="alteratpmv" name="alteratpmv" value="#{vTipoMotivoBean.tpmv}" ></f:param>
</t:column>

Esse f:param que está me deixando confuso. Preciso pegar todo o TipoMotivo (que é um objeto) e injetá-lo no bean pra por sua vez mandar para a página de alteração, mas parece que não consigo injetar um objeto diretamente até pq como o jsf vai saber que aquela linha do grid corresponde a um objeto.
Então pensei em passar o id do TipoMotivo para uma função no bean que fizesse uma pesquisa e lá no bean construisse um objeto que seria por sua vez resgatado na página de alteração. Só que não estou entendendo a aplicação do param nesse caso e como eu passaria esse param para a página sequinte, como referenciá-lo lá. Alguém pode me explicar?

16 Respostas

D

Então, como você está em uma h:dataTable, você estará de posse de um objeto, referenciado pelo atributo var, certo?
É esta var que deve ser passada como parâmetro

///bla, bla, bla
<... var="tpmv">
<f:param id="alteratpmv" name="alteratpmv" value="#{tpmv}" >

Sacou?

C

acho que sim…mas deixa eu entender melhor, mas é associado cada objeto da tabela a esta respectiva variável? Ou seja ele vai saber qdo eu clicar por exemplo na quarta coluna que estou referenciando justamente ao objeto da 4. coluna?

A

Não lembro bem de cabeça mas acredito que dê para fazer isso sem passar parâmetros, pegando apenas pela Iteração.

Quando chegar em casa dou uma olhada.

D

Então, basicamente, em jsf 2, a dataTable funciona assim

<h:dataTable value="#{meuBean.listaDeObj}" var="obj" id="dtt">
  <h:column>
    <f:facet name="header"><h:outputLabel value="Nome"/></f:facet>
    #{obj.nome}
  </h:column>
  <h:column>
    <f:facet name="header"><h:outputLabel value="Ação"/></f:facet>
    <h:commandLink value="Alterar" action="#{vTipoMotivoBean.alterarTipoMotivo}" />  
               <f:param id="alteratpmv" name="alteratpmv" value="#{obj}" ></f:param>
  </h:column>
</h:dataTable>

Você só precisa adaptar para as tags que está utilizando.

C

tá…vou testar aqui…nem o pessoal daqui sabia…kk
Já posto se a exclusão deu certo (me confundi, a alteração que é mais complicada vou deixar pra depois, pois nela precisarei desse parâmetro porque vou usar a mesma page para inclusão e alteração e por isso vou precisar desses parâmetros, pq se for alteração é onde vou precisar do objeto construído pelo bean)

C

Bom…lá vou eu…

<f:param id="excluitpmv" name="excluitpmv" value="#{row}" ></f:param>

No bean eu preciso do objeto tipo Motivo e fiz essa lógica

FacesContext facesContext = FacesContext.getCurrentInstance();
		
Map param = facesContext.getExternalContext().getRequestParameterMap();
tpmv = (TipoMotivo) param.get("excluitpmv");

A pergunta é: com isso consigo associar o objeto vindo por parâmetro? Pq estourou uma exceção :
Descrição: #{vTipoMotivoBean.confirmarAcoesTipoMotivo}: java.lang.ClassCastException: java.lang.String cannot be cast to br.gov.dataprev.sgir.entity.TipoMotivo
Ao que parece o no parâmetro vem uma String?

D

Posta o trecho todo do código referente ao grid.

C
<dtp:dataTable id="gridSelecTipoMotivo" var="row" value="#{vTipoMotivoBean.dataModel}"
				rows="#{vTipoMotivoBean.pageSize}" rowClasses="even center,odd center"
				headerClass="cabecalhoPrincipal" renderedIfEmpty="true">

				<t:column sortable="false" id="nome" columnId="nmNome" width="20%">
					<f:facet name="header">
						<h:outputText id="labelNome" value="Nome" />
					</f:facet>
					<h:outputText value="#{row.nmTipoMotivo}" />
					
				</t:column>

				<t:column sortable="false" id="ativo" columnId="inAtivo">
					<f:facet name="header">
						<h:outputText id="labelAtivo" value="Ativo" />
					</f:facet>
					<h:outputText value="#{row.inAtivo}" />
				</t:column>

                <t:column sortable="false" id="csTpMotivo" columnId="csTipoMotivo" width="20%">
					<f:facet name="header">
						<h:outputText id="labelTipo" value="Classificador do Tipo Motivo" />
					</f:facet>
					<h:outputText value="#{row.csTipoMotivo}" />
				</t:column>


                <t:column sortable="false" id="descricao" columnId="teDescricao" width="20%">
					<f:facet name="header">
						<h:outputText id="labeldesc" value="Descrição" />
					</f:facet>
					<h:outputText value="#{row.teDescricao}" />
				</t:column>

				<t:column sortable="false" id="alterar" columnId="alterar">
					<f:facet name="header">
						<h:outputText id="labelAlterar" value="Alterar" />
					</f:facet>
					<h:commandLink value="Alterar" action="#{vTipoMotivoBean.alterarTipoMotivo}" />
				    <f:param id="alteratpmv" name="alteratpmv" value="#{row}" ></f:param>
				</t:column>


				<t:column sortable="false" id="excluir" columnId="excluir">
					<f:facet name="header">
						<h:outputText id="labelExcluir" value="Excluir" />
					</f:facet>
					<h:commandLink value="Excluir" action="#{vTipoMotivoBean.confirmarAcoesTipoMotivo}">
				    <f:param id="excluitpmv" name="excluitpmv" value="#{row}" ></f:param>
				</h:commandLink>
				</t:column>

			</dtp:dataTable>
C

E esse confirmarAcoesTipoMotivo pega o parâmetro no bean recupera o objeto e manda pra view de exclusão.

D

Vamos por partes
Ao declarar

var="row" value="#{vTipoMotivoBean.dataModel}"

Você diz que os objetos que estão em dataModel serão representados pelo alias row, certo?
Assim sendo, quando você coloca como argumento do f:param um row

<f:param id="excluitpmv" name="excluitpmv" value="#{row}" ></f:param>

Você tem um objeto do tipo row (aquele que preenche a dataModel).
Portanto, ele não poderia ser uma String (a não ser que você tenha colocado apenas Strings no dataModel…

C

tá…mas cada row continua trazendo pra mim um objeto TipoMotivo?
Pq no grid tenho que acessar cada item vindo do row para preenche-lo então no row de fato estaria um objeto?

D

Não sei qual o tipo de objeto que você possui na lista… Você apenas colocou as partes do dataTable e de como pretende recuperar os parâmetros…

Há um método gambiarra way, mas a IDE irá acusar inconsistência

<h:commandLink value="Excluir" action="#{vTipoMotivoBean.confirmarAcoesTipoMotivo(row)}"/>

Mas sei que funciona e você nem precisa do f:param, apenas mudar a assinatura do método confirmaAcoesTipoMotivo() para confirmaAcoesTipoMotivo(TipoMotivo tp)

C

pq eu acho que seria interessante atribuir ao parâmetro um objeto…e todos os exemplos que tenho aqui são com retorno de String, ou seja o f:param retorna Strings
Acredito que por isso dê o erro de cast.

D

Ok man, então vai precisar alterar determinados pontos.
Retornando uma String, precisa determinar a qual valor do objeto procurado ela se refere. A partir daí, você poderá percorrer a lista e encontrá-lo.

D

Opa, então, encontrei uma alternativa para isto.
Altere o f:param para f:attribute name=“bla” e de action para actionListener

<h:commandLink value="Excluir" actionListener="#{vTipoMotivoBean.confirmarAcoesTipoMotivo}">
<f:attribute id="excluitpmv" name="excluitpmv" value="#{row}" ></f:param>

E, no managedBean

/*assinatura do metodo */ confirmaAcoesTipoMotivo(javax.faces.event.ActionEvent event){
 TipoMotivo tm = (TipoMotivo) event.getComponent().getAttributes().get("excluirtpmv");
}

Assim você terá teu parâmetro e poderá fazer tanto o delete quanto o update.

C

Obrigado…entretanto mudaram o negócio aqui, querem um bean para cada tipo de tarefa do CRUD e uma view pra cada uma…to quebrando cabeça pra entender como passar os dados pra recuperar de um bean no outro…pq não tenho nem idéia como se faz isso. Ouvi falar que tem que mexer inclusive no faces config.

Mesmo assim obrigado.

Criado 29 de junho de 2011
Ultima resposta 30 de jun. de 2011
Respostas 16
Participantes 3