preciso criar dois selectOneMenu, sendo que um é dependente de outro. Por exemplo, um selectOneMenu em que é selecionado ESTADO, e dinamicamente, o outro selectOneMenu de MUNICIPIO é carregado.
Pois bem, consigo fazer com que ambos sejam sincronizados, logo, a alteração em um implica na alteração do outro. Contudo, tenho problemas no momento da submissão em que me deparo com erros no último selectOneMenu.
Alguém tem algum código pronto, ou sugestão de como contornar este problema?
Dá uma olhada na tag <t:saveState/> do MyFaces Tomahawk.
Ele salva o estados dos objetos, tenta colocas 2 tags que salvam os estados das 2 collections q populam a suas combos.
Eu estava com exatamente o mesmo cenario e o mesmo problema, essa tag resolveu meus problemas =)
WARNING: executePhase(PROCESS_VALIDATIONS 3,com.sun.faces.context.FacesContextImpl@cc0e01) threw exception
javax.faces.FacesException
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:108 )
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:248 )
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at sso.DominoLoginFilter.doFilter(DominoLoginFilter.java:84)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228 )
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128 )
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:212)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:818 )
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:624)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
at java.lang.Thread.run(Unknown Source)
Caused by: java.util.NoSuchElementException
at javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:117)
at javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:141)
at javax.faces.component.SelectItemsIterator.next(SelectItemsIterator.java:49)
at javax.faces.component.UISelectOne.matchValue(UISelectOne.java:165)
at javax.faces.component.UISelectOne.validateValue(UISelectOne.java:137)
at javax.faces.component.UIInput.validate(UIInput.java:868 )
at javax.faces.component.UIInput.executeValidate(UIInput.java:1071)
at javax.faces.component.UIInput.processValidators(UIInput.java:663)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1021)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1021)
at javax.faces.component.UIForm.processValidators(UIForm.java:229)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1021)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:662)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:100)
cara, como o André falou, a solução para o teu problema pode ser o uso da tag t:saveState. Só para não duplicar a explicação do porque isso deve estar acontecendo, dá uma olhada nesse post http://www.guj.com.br/posts/list/48462.java
Espero que ajude.
falow.
Só para constar nos autos, é possível usar o atributo actionListener do primeiro selectOneMenu, sem nenhum componente ou controle adicional na jsp para tanto.
Basta um método no seu bean (void e que recebe como argumento um ValueChangeEvent) para filtrar o segundo selectOneMenu de acordo com a opção selecionada no primeiro.
Agradeço a ajuda de todos, mas o uso dessa tag só ocorrerá em último caso, porque aqui no trabalho temos um ambiente fechado muito burocrático, e atualmente não temos muita flexibilidade na escolha das ferramentas a serem usadas.
Enfim, é algo estranho que no momento que eu clico no botão de Submit ocorre o estranho erro que já mandei em anexo. Não existe nenhuma forma de fazer isso usando apenas JSF?
Bom, se nao tem como usar outras coisas então complica. Pela minha esperiência eu indico você dar uma conversada com o pessoal da tua empresa e considerar fortemente o uso daquela tag (t:saveState).
Apesar deu nao ter olhado certinho como você está atualizando o segundo combo :oops: , pelo erro já imagino que seja aquilo que eu comentei no post que mandei o link. Pelo fato do JSF facilitar algumas coisas, a gente acaba esquecendo que por baixo dos panos é tudo request e response, e então a gente estressa mesmo. A solução seria jogar tudo na session :shock: , ou então usar esse componente que é bem inteligente e resolve esse problema.
Para não usar nenhuma dessas alternativas realmente você vai ter dorzinha de cabeça :twisted:
bom, essa é apenas a MINHA opinião, baseada na esperiência que eu tenho.
Relaxem, se esse for o problema de vocês, fiquem contentes! :wink:
Como já foi comentado, existem algumas formas diferentes de fazer essa implementação.
Gilliard citou uma que utiliza um componente do tomahawk. Não sei como funciona pois nunca usei, mas deve resolver com certeza. Temos um detalhe da dependência que isso agrega, conforme comentado pelo criador deste tópico.
Uma segunda forma de resolver, usando apenas faces, é a que eu sugerí. Para tanto, usa-se normalmente os dois selectOneMenu. Estes selects encapsulam sim, f:selectItems que apontam pra listas do seu bean. O primeiro selectOneMenu terá 3 particularidades: os atributos "onchange", valueChangeListener (peço desculpas pelo post que fiz antes, havia dito actionListener, está errado) e por fim, o "immediate".
Esse valueChangeListener é o mais importante, integra a renderização faces com a sua lógica de negócios. Ou seja, o MethodBinding usado nesse atributo precisa ser capaz de buscar a sua lista de Municípios de acordo com o Estado selecionado. O "onchange" é "requisito não funcional", precisa ser usado para que a jsp seja renderizada novamente com os valores das listas atualizadas. E pra terminar, o immediante precisa ser igual a "true", pois é possível que vc tenha outros campos na sua jsp e vc não deseja validá-los (ou preenchê-los caso sejam obrigatórios) para capturar Estados/Municípios.
Se ainda restarem dúvidas, mandem uma MP.
Bom, só justificando a minha resposta… é que eu tenho o costume de deixar para os gets resolverem os valores, pois uso ajax e assim, no meu caso, da forma como uso, acredito que fica mais fácil. Mas com certeza da pra fazer de outro jeito. E sobre usar ou não o tomahawk, a dependencia dele é muito pequena (voce pode usar com RI, e é esse o meu caso). Uma das vantagens do JSF é esse “mundaréu” de coisas/componentes que você encontra na net, então podar isso é deixar de usar muita coisa. Mas como é algo da sua organização eu não me meto, foi só um comentário.
Como pra tudo tem várias formas de fazer, escolha uma e bom trabalho
Só complementando… pra essa situação, eu uso a tag saveState e populo as combox com ajax usando Ajax4JSF.
Mto bom viu, rápido, simples e sem refresh na página
Se conseguir implementar o Ajajax4JSF vai te poupar um teabalho tbm
Cada caso é diferente, projetos com requisitos ou necessidades específicas.
Eu fiz um mega comentário sobre como fazer o que na prática se traduz em poucas linhas, simples mesmo. Entretanto, usar uma biblioteca com a do tomahawk é muito interessante, as funcionalidades suportadas são muitas e as vezes, em situações delicadas são quase "obrigatórias".
Eu por exemplo brigo até hoje com dateTables do faces quando preciso renderizar galerias em colunas e linhas. Aí apelo!. =)
O esquema é simples… vc faz dois array’s. Um com os estados e outro com as UF’s.Ai tu joga num for e manda os ifs pra comparar…
depois tu cria outra function pra chamar isso tudo aew…
vlw