Boa tarde a todos!
Estou tentando criar os botões com uns checkbox em tempo de execução e não estou conseguindo.
O que gostaria e como esta imagem:
No qual este boneco são as imagens e loga abaixo deles quero colocar os checkbox.
Segue também o código que fiz até agora para este:
<p:wizard flowListener="#{solicitacaoAtendimentoBean.onFlowProcess}" backLabel="Voltar" nextLabel="Proxímo">
<p:tab id="dtAreaAtendimento" title="Área de atendimento" >
<p:panel header="Escolha qual área de atendimento">
<p:outputPanel>
<p:panelGrid id="pnlAreaAtendimento" columns="3" styleClass="ui-panelgrid-blank" layout="grid" style="text-align: center">
<h:commandButton image="/resources/images/saude.jpg" disabled="true"/>
<h:commandButton image="/resources/images/educacao.jpg" disabled="true"/>
<h:commandButton image="/resources/images/emprego.jpg" disabled="true"/>
<p:selectBooleanCheckbox value="#{solicitacaoAtendimentoBean.saude}">
<p:ajax update="pnlAreaAtendimento" listener="#{solicitacaoAtendimentoBean.changeValueAreaAtendimento}" />
</p:selectBooleanCheckbox>
<p:selectBooleanCheckbox value="#{solicitacaoAtendimentoBean.educacao}">
<p:ajax update="pnlAreaAtendimento" listener="#{solicitacaoAtendimentoBean.changeValueAreaAtendimento}" />
</p:selectBooleanCheckbox>
<p:selectBooleanCheckbox value="#{solicitacaoAtendimentoBean.emprego}">
<p:ajax update="pnlAreaAtendimento" listener="#{solicitacaoAtendimentoBean.changeValueAreaAtendimento}" />
</p:selectBooleanCheckbox>
</p:panelGrid>
</p:outputPanel>
</p:panel>
</p:tab>
<\p:wizard>
Em resumo eu deveria ter dentro deste panelGrid apena um commandButton e um Checkbox. Já tentei colocar o ui:repeat e também o c:forEach, mas nenhum funcionou ele fica totalmente desorganizado. Então preciso ver uma forma de coloca-los de forma que se inclusive eu adicionar mais um botão (imagem) e um checkbox ele fique organizado na tela.
Alguém teria alguma ideia para me dar para fazer isto?
Olá pessoal, bom dia!
Consegui resolver o problema, segue a baixo a solução para aqueles que necessitarem de algo parecido.
<p:wizard flowListener="#{solicitarAtendimentoBean.onFlowProcess}" backLabel="Voltar" nextLabel="Proxímo">
<p:tab id="dtAreaAtendimento" title="Área de atendimento" >
<p:panel header="Escolha qual área de atendimento">
<p:messages id="msgAreaAtendimento" autoUpdate="true" closable="true" showSummary="false" showDetail="true" escape="false"/>
<p:outputPanel>
<p:panelGrid id="pnlAreaAtendimento" columns="3" styleClass="ui-panelgrid-blank" layout="grid" style="text-align: center;padding-left: 150px;">
<c:forEach items="#{solicitarAtendimentoBean.lstAreaAtendimentos}" var="area">
<h:dataTable value="#{solicitarAtendimentoBean.lstAreaAtendimentos}" rows="1" style="padding-bottom: 30px">
<h:column>
<h:commandButton image="#{area.imagem}" disabled="true"/> <br/>
<p:selectBooleanCheckbox value="#{solicitarAtendimentoBean.checkMapAreaAtendimento[area]}">
<p:ajax update=":frmSolicitacao:pnlAreaAtendimento" listener="#{solicitarAtendimentoBean.changeValueAreaAtendimento(area)}"/>
</p:selectBooleanCheckbox>
</h:column>
</h:dataTable>
</c:forEach>
</p:panelGrid>
</p:outputPanel>
</p:panel>
</p:tab>
</p:wizard>
Bem, a ideia é colocar um panelGrid, depois coloca-se o laço (forEach) e dentro deste laço coloca-se um dataTable com as colunas. Uma coisa importante que percebi é que a dataTable deve ter o atributo rows setado com 1, pois se não informar ele irá duplicar a quantidade de linhas.
Outra questão, foi que queria que os selectBooleanCheckbox fosse marcado somente um e além disto queria obter a informação (valor) de quando eu clicasse, pois se decidisse também optar por aceitar escolher mais de um precisar saber quais foram marcado.
Para isto usei a ideia deste link: Binding Dynamic Multi-select Checkbox
Ficando o meu Bean assim:
public class SolicitarAtendimentoBean extends implements Serializable {
private Map<AreaAtendimento, Boolean> checkMapAreaAtendimento;
public String inicializar() { //Este metodo é chamando quando clico no menu
try {
clear();//Metodo somente para limpar as variaveis ao inicializar
findAreaAtendimento();//Metodo que ira mantar o menu da tela (veja abaixo)
} catch (Exception ex) {
logger.error("Falha ao inicializar as solicitacao de atendimento: " + ex.getMessage());
}
return UrlRedirectEnum.SOLICITARATENDIMENTO.getValue();//Url que será direcionada (a tela da imagem acima)
}
public void findAreaAtendimento() {
try {
checkMapAreaAtendimento = new HashMap<>(); //Este conterá a lista dos objetos que quero e a infomção booleana se ele foi marcado (clicado) ou não
lstAreaAtendimentos = areaAtendimentoService.selectAll();//Busco no banco a lista de objeto a serem mostrado na tela
//Aqui vou adiciona a lista
if (lstAreaAtendimentos != null) {
lstAreaAtendimentos.forEach((item) -> {
checkMapAreaAtendimento.put(item, Boolean.FALSE);// adiciono inicialmente cada componete como faço para serem mostrado desmarcado na tela.
});
}
} catch (Exception e) {
logger.error("Falha ao obter a lista de area de atendimentos: " + e.getMessage());
}
}
/*Este metodo será chamando pelo ajax que esta no componente selectBooleanCheckbox do codigo acima.*/
public void changeValueAreaAtendimento(AreaAtendimento area) {
//Uma laço que ira percorre todos os objetos que obtive no banco.
lstAreaAtendimentos.forEach((a) -> {
//Aqui está o "X" da questão.
//O metodo (ajax listener) irá passar como parametro um obejto que busquei no banco.
//Então percorro o laço em busca do objeto com mesmo ID e quando acho atribuo a ele TRUE
//Como pode ser visto abaixo, o demais ficam FALSE. Assim somente o que clicou irá ficar marcado.
//Lembrando que vc pode fazer outros tratamentos aqui, por exemplo, tirando o else para que todos que forem clicado sejam marcado, enfim vai da sua criatividade e necessidade.
if (area.getIdAreaAtendimento() == a.getIdAreaAtendimento()) {
checkMapAreaAtendimento.put(a, Boolean.TRUE);
areaAtendimento = a;
} else {
checkMapAreaAtendimento.put(a, Boolean.FALSE);
}
});
}
}
Bem, espero ajudar alguém com esta dica.
Qualquer dúvida estou à disposição.
Abraços e até a próxima.