I am trying to toggle between a simple "click the row to select" table and a "multi-select Checkbox in the first column table". I have a check box outside the table to change the state of the table. For the simple table (no check boxes in the first column) a selectionMode must be set in the p:datatable tag; either to "single" or "multiple". In this state everything works fine.
If the state is changed so that the multi-select column is rendered, the click event seems to be consumed by selecting the selecting the row. In general when using this multi-select check box table the selectionMode would not be set; hence the mouse event would change the state of the check box.
How do I "unset" the selectionMode. Here are the things that did not work:
table.setSelectionMode(null) - this breaks the selection (so does setting to "")
table.getAttributes().get("javax.faces.component.UIComponentBase.attributesThatAreSet") then removing the selectionMode (it isn't in the set attributes).
My xhtml looks like:
<h:form id="addForm">
<p:panel toggleable="false" closable="false" widgetVar="remarksPanel"
id="remarksPanel" style="margin-bottom:5px; overflow:auto;">
<p:selectBooleanCheckbox value="#{multipleSelectBean.bulkEdit}">
<p:ajax update="addForm:remarksTable"
listener="#{multipleSelectBean.editModeChanged}" />
</p:selectBooleanCheckbox>
<h:outputText value=" Bulk Edit" />
<p:dataTable var="remark" id="remarksTable" rowIndexVar="rowNum"
value="#{multipleSelectBean.remarkList}" rowKey="#{remark.id}"
selectionMode="multiple"
selection="#{multipleSelectBean.selectedRemarks}">
<p:column rendered="#{multipleSelectBean.bulkEdit}"
selectionMode="multiple" style="width:18px" />
<p:column headerText="Remark">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{remark.remark}" />
</f:facet>
<f:facet name="input">
<p:inputText style="width:98%" id="remark"
value="#{remark.remark}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
My Bean Looks Like:
package gov.gsa.krichards.sandbox;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.event.SelectEvent;
#ManagedBean
#SessionScoped
public class MultipleSelectBean implements Serializable {
private static final long serialVersionUID = 1L;
private final static String[] categoryList;
private List<Remark> remarkList = new ArrayList<Remark>();
private Remark[] selectedRemarks = null;
private String words = "Mauris interdum, turpis nec euismod c aliquet fermentum nisl, in tristique arcu tincidunt nec.";
private boolean bulkEdit = false;
private boolean initialized = false;
static {
categoryList = new String[4];
categoryList[0] = "Cat5";
categoryList[1] = "Cat4";
categoryList[2] = "Cat3-UTP";
categoryList[3] = "BNC";
}
public MultipleSelectBean() {
Random r = new Random();
for (int i = 0; i < 10; i++) {
String cat = categoryList[r.nextInt(4)];
int len = words.length();
int begIndex = r.nextInt(len / 2);
int endIndex = begIndex + r.nextInt(len - begIndex);
Remark rem = new Remark(i, cat, words.substring(begIndex, endIndex));
remarkList.add(rem);
}
}
public void editModeChanged() {
System.out.println("changed to " + bulkEdit);
}
public void setBulkEdit(boolean arg) {
DataTable table = (DataTable) FacesContext.getCurrentInstance()
.getViewRoot().findComponent("addForm:remarksTable");
bulkEdit = arg;
if (bulkEdit) {
table.setSelectionMode("single");
} else {
table.setSelectionMode("multiple");
}
}
public boolean isBulkEdit() {
return bulkEdit;
}
public List<Remark> getRemarkList() {
return remarkList;
}
public void setRemarkList(List<Remark> remarkList) {
this.remarkList = remarkList;
}
public String[] getCategoryList() {
return categoryList;
}
public Remark[] getSelectedRemarks() {
if (selectedRemarks == null || selectedRemarks.length == 0)
return null;
return selectedRemarks;
}
public void setSelectedRemarks(Remark[] selectedRemarks) {
this.selectedRemarks = selectedRemarks;
}
}
Related
primeFaces select oneMenu Show Cases has select advance .and it has one attribute ( converter ) .
primeFaces Code:
<p:selectOneMenu id="advanced" value="#{selectOneMenuView.theme}" converter="#{themeConverter}" panelStyle="width:180px"
effect="fade" var="t" style="width:160px" filter="true" filterMatchMode="startsWith">
<f:selectItems value="#{selectOneMenuView.themes}" var="theme" itemLabel="#{theme.displayName}" itemValue="#{theme}" />
<p:column style="width:10%">
<h:graphicImage name="showcase/images/themeswitcher/themeswitcher-#{t.name}.png" alt="#{t.name}" styleClass="ui-theme" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{t.displayName}" />
</p:column>
<f:facet name="footer">
<p:separator />
<h:outputText value="#{selectOneMenuView.themes.size()} themes" style="font-weight:bold;"/>
</f:facet>
</p:selectOneMenu>
i'm looking for where's converter="#{themeConverter}" in the code (page.xhtml and manage Bean , class) i don't find it . they don't mention it(themeConverter) in other class whether annotation or class name or variable.
anybody has idea how use it ?
with example
thank you
ThemeConverter source code is right here:
https://github.com/primefaces/primefaces-showcase/blob/master/src/main/java/org/primefaces/showcase/convert/ThemeConverter.java
package org.primefaces.showcase.convert;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;
import org.primefaces.showcase.domain.Theme;
import org.primefaces.showcase.service.ThemeService;
#Named
#FacesConverter(value = "themeConverter", managed = true)
public class ThemeConverter implements Converter<Theme> {
#Inject private ThemeService themeService;
#Override
public Theme getAsObject(FacesContext context, UIComponent component, String value) {
if(value != null && value.trim().length() > 0) {
try {
return themeService.getThemes().get(Integer.parseInt(value));
} catch(NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid theme."));
}
}
else {
return null;
}
}
#Override
public String getAsString(FacesContext context, UIComponent component, Theme value) {
if(value != null) {
return String.valueOf(value.getId());
}
else {
return null;
}
}
}
i have a Java EE setup with JSF and primefaces and i'm trying to generate a selection, based on the chosen entry in a <selectOneMenu>.
My problem is that the selectManyCheckbox (or any other similar ui element) has all items filled in correctly and the items are selectable, but if a selection was made, the action of the commandButton doesn't get called.
I've set a breakpoint on the method. If I don't choose any item, the breakpoint gets hit, if I choose any amount of items greater than zero, the breakpoint doesn't get hit.
I read that one solution could be to define a converter. I tried that and if I set a breakpoint, it correctly converts the items, I chose, but nevertheless the method, defined as action, doesn't get called.
Btw: Sorry for german code, i'm a german and naming the methods and variables in german was set by guideline
The xhtml File:
<h:form>
<p:panelGrid columns="2">
<p:outputLabel for="kennzeichenInput">Kennzeichen: </p:outputLabel>
<p:inputText id="kennzeichenInput"></p:inputText>
<p:outputLabel for="studiengang">Studiengang: </p:outputLabel>
<p:selectOneMenu id="studiengang" value="#{registrationsController.gewaehlterStudiengang}">
<f:selectItem itemValue="#{null}" itemLabel="--Studiengang aussuchen--"/>
<f:selectItems value="#{registrationsController.getAlleStudiengaenge()}"/>
<p:ajax value="valueChange" update="vorlesungenInStudiengang" listener="#{registrationsController.onStudiengangGeaendert}"/>
</p:selectOneMenu>
</p:panelGrid>
<h:selectManyCheckbox id="vorlesungenInStudiengang"
value="#{registrationsController.gewaehlteVorlesungen}"
label="Vorlesungen" converter="de.phwt.parkhwt.domain.converter.vorlesung_converter">
<f:selectItems value="#{registrationsController.vorlesungen}"/>
</h:selectManyCheckbox >
<p:commandButton value="Registrieren" type="submit" action="#{registrationsController.registriereKennzeichen()}"/>
</h:form>
The Bean:
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.enterprise.context.RequestScoped;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Inject;
import javax.inject.Named;
import de.phwt.parkhwt.domain.CollectionKonverter;
import de.phwt.parkhwt.domain.KennzeichenRepository;
import de.phwt.parkhwt.domain.Studiengang;
import de.phwt.parkhwt.domain.Vorlesung;
#RequestScoped
#Named
public class RegistrationsController
{
#Inject
private KennzeichenRepository repository;
private String gewaehlterStudiengang;
private List<Vorlesung> vorlesungen;
private List<Vorlesung> gewaehlteVorlesungen;
public String getGewaehlterStudiengang()
{
return gewaehlterStudiengang;
}
public void setGewaehlterStudiengang(String gewaehlterStudiengang)
{
this.gewaehlterStudiengang = gewaehlterStudiengang;
}
public List<Vorlesung> getVorlesungen()
{
return vorlesungen;
}
public void setVorlesungen(List<Vorlesung> vorlesungen)
{
this.vorlesungen = vorlesungen;
}
public Vorlesung getVorlesung(String name)
{
return this.repository.sucheVorlesung(name);
}
public List<Vorlesung> getGewaehlteVorlesungen()
{
return gewaehlteVorlesungen;
}
public void setGewaehlteVorlesungen(List<Vorlesung> gewählteVorlesungen)
{
this.gewaehlteVorlesungen = gewählteVorlesungen;
}
public Set<Studiengang> getAlleStudiengaenge()
{
return repository.getAlleStudiengaenge();
}
public List<Vorlesung> getVorlesungenDesStudiengangs(String gewaehlterStudiengang)
{
Studiengang studiengang = repository.sucheStudiengang(gewaehlterStudiengang);
return CollectionKonverter.toList(studiengang.getVorlesungen());
}
public String registriereKennzeichen()
{
return "";
}
public void onStudiengangGeaendert(AjaxBehaviorEvent event)
{
if (getGewaehlterStudiengang() != null)
{
setVorlesungen(getVorlesungenDesStudiengangs(getGewaehlterStudiengang()));
}
else
{
setVorlesungen(new ArrayList<Vorlesung>());
}
}
}
The Converter:
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import de.phwt.parkhwt.controller.RegistrationsController;
#FacesConverter("de.phwt.parkhwt.domain.converter.vorlesung_converter")
public class VorlesungConverter implements Converter
{
#Inject
KennzeichenRepository repository;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
ValueExpression vex =
context.getApplication()
.getExpressionFactory()
.createValueExpression(context.getELContext(),
"#{registrationsController}", RegistrationsController.class);
RegistrationsController reg = (RegistrationsController) vex.getValue(context.getELContext());
Vorlesung vorlesung = reg.getVorlesung(value);
return vorlesung;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
if (value.getClass() == new Vorlesung().getClass())
{
Vorlesung v = (Vorlesung) value;
return v.getName();
}
return null;
}
}
Thanks to Mike Balthasar for his comment!
The solution was to add ajax="false" to my commandButton.
For more information, see his comment.
It's easy to show the selected row value in a dialog from a p:contextMenu. However, is there an easy way to show the column value (e.g. "2:b") or to get the column index on which the right-click happend?
<p:dataTable id="dt" value="#{['a','b','c']}" var="x" selection="#{bean.x}"
widgetVar="dtv" selectionMode="single" rowKey="#{x}">
<p:column>1:#{x}</p:column>
<p:column>2:#{x}</p:column>
</p:dataTable>
<p:contextMenu for="dt">
<p:menuitem value="Show" update="di" oncomplete="PF('wv').show()" />
</p:contextMenu>
<p:dialog id="di" widgetVar="wv">X=#{bean.x}</p:dialog>
Using: PF6.0 on JavaEE 7
Just idea...
Xhtml
I added two <h:inputHidden/> components and JavaScript function applySelectedCell which is called before context menu is shown.
<h:form prependId="false">
<script type="text/javascript">
function applySelectedCell(event) {
var cell = $(event.target);
if (!cell.is('td')) {
cell = cell.closest('td');
}
var row = cell.closest('tr');
var selectedCell = row.children().index(cell);
$('#selectedCell').val(selectedCell);
$('#selectedHtmlValue').val(cell.text());
}
</script>
<h:inputHidden id="selectedCell" value="#{bean.selectedCell}"/>
<h:inputHidden id="selectedHtmlValue" value="#{bean.selectedHtmlValue}"/>
<p:dataTable id="dt" value="#{['a','b','c']}" var="x" selection="#{bean.x}"
widgetVar="dtv" selectionMode="single" rowKey="#{x}">
<p:column>1:<div style="background: yellow;">#{x}</div></p:column>
<p:column>2:#{x}</p:column>
</p:dataTable>
<p:contextMenu for="dt" beforeShow="applySelectedCell(event);">
<p:menuitem value="Show" update="di" oncomplete="PF('wv').show()" />
</p:contextMenu>
<p:dialog id="di" widgetVar="wv">
<div>Cell value (Bean) = #{bean.selectedBeanValue}</div>
<div>Cell value (HTML) = #{bean.selectedHtmlValue}</div>
</p:dialog>
</h:form>
Backing bean
#ViewScoped
#Named
public class Bean implements Serializable {
private String x = "a";
private Integer selectedCell;
private String selectedHtmlValue;
public String getX() {
return x;
}
public void setX(String x) {
this.x = x;
}
public Integer getSelectedCell() {
return selectedCell;
}
public void setSelectedCell(Integer selectedCell) {
this.selectedCell = selectedCell;
}
public String getSelectedHtmlValue() {
return selectedHtmlValue;
}
public void setSelectedHtmlValue(String selectedHtmlValue) {
this.selectedHtmlValue = selectedHtmlValue;
}
public String getSelectedBeanValue() {
if (selectedCell != null) {
return (selectedCell + 1) + ":" + x;
} else {
return x;
}
}
}
I have a report in JasperReports, it works fine. However, i'm passing just one parameter of type cliente to the report, and what i do want now is to pass more than one. The page is like in the picture bellow, a basic idea was to have a button (maybe) that would send the content of <p:selectOneMenu that is of the type cliente each time its clicked to the map of parameters, than it would be sent to the report. I wasn't able to do that yet, so i'm asking for a help.
Bean:
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import org.hibernate.Session;
import com.rodrigo.controleacidentes.model.Cliente;
import com.rodrigo.controleacidentes.model.StatusEntrada;
import com.rodrigo.controleacidentes.util.jsf.FacesUtil;
import com.rodrigo.controleacidentes.util.report.ExecutorRelatorioPdf;
import com.rodrigo.controleacidentes.util.report.ExecutorRelatorioXls;
#Named
#RequestScoped
public class RelatorioEntradasBean implements Serializable {
private static final long serialVersionUID = 1L;
private Date dataInicio;
private Date dataFim;
private Cliente cliente;
private StatusEntrada statusEntrada;
public StatusEntrada getStatusEntrada() {
return statusEntrada;
}
public void setStatusEntrada(StatusEntrada statusEntrada) {
this.statusEntrada = statusEntrada;
}
public void teste(StatusEntrada st) {
// StatusEntrada entrada = StatusEntrada.valueOf(st);
System.out.println("TESTE: " + st);
}
#Inject
private FacesContext facesContext;
#Inject
private HttpServletResponse response;
#Inject
private EntityManager manager;
public void emitirXls() {
Map<String, Object> parametros = new HashMap<>();
parametros.put("data_inicio", this.dataInicio);
parametros.put("data_fim", this.dataFim);
if (cliente != null) {
System.out.println("TESTE: " + cliente.getNome());
parametros.put("nome_cliente", cliente.getNome());
}
if (statusEntrada != null) {
System.out.println("TESTE :" + statusEntrada.getDescricao());
parametros.put("status_entrada", statusEntrada.getDescricao());
}
ExecutorRelatorioXls executor = new ExecutorRelatorioXls("/relatorios/RelatorioEntradasNome.jasper",
this.response, parametros, "Relatório Entradas.xls");
Session session = manager.unwrap(Session.class);
session.doWork(executor);
if (executor.isRelatorioGerado()) {
facesContext.responseComplete();
} else {
FacesUtil.addErrorMessage("A execução do relatório não retornou dados.");
}
}
public void emitirPdf() {
Map<String, Object> parametros = new HashMap<>();
parametros.put("data_inicio", this.dataInicio);
parametros.put("data_fim", this.dataFim);
parametros.put("nome_cliente", this.cliente);
ExecutorRelatorioPdf executor = new ExecutorRelatorioPdf("/relatorios/RelatorioEntradasNome.jasper",
this.response, parametros, "Relatório Entradas.pdf");
Session session = manager.unwrap(Session.class);
session.doWork(executor);
if (executor.isRelatorioGerado()) {
facesContext.responseComplete();
} else {
FacesUtil.addErrorMessage("A execução do relatório não retornou dados.");
}
}
#NotNull
public Date getDataInicio() {
return dataInicio;
}
public void setDataInicio(Date dataInicio) {
this.dataInicio = dataInicio;
}
#NotNull
public Date getDataFim() {
return dataFim;
}
public void setDataFim(Date dataFim) {
this.dataFim = dataFim;
}
#NotNull
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
}
Executor:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.jdbc.Work;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
public class ExecutorRelatorioXls implements Work {
private String caminhoRelatorio;
private HttpServletResponse response;
private Map<String, Object> parametros;
private String nomeArquivoSaida;
private boolean relatorioGerado;
public ExecutorRelatorioXls(String caminhoRelatorio, HttpServletResponse response, Map<String, Object> parametros,
String nomeArquivoSaida) {
this.caminhoRelatorio = caminhoRelatorio;
this.response = response;
this.parametros = parametros;
this.nomeArquivoSaida = nomeArquivoSaida;
this.parametros.put(JRParameter.REPORT_LOCALE, new Locale("pt", "BR"));
}
#Override
public void execute(Connection connection) throws SQLException {
try {
InputStream relatorioStream = this.getClass().getResourceAsStream(this.caminhoRelatorio);
JasperPrint print = JasperFillManager.fillReport(relatorioStream, this.parametros, connection);
this.relatorioGerado = print.getPages().size() > 0;
if (this.relatorioGerado) {
JRXlsExporter exportador = new JRXlsExporter();
exportador.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, response.getOutputStream());
exportador.setParameter(JRXlsExporterParameter.JASPER_PRINT, print);
exportador.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exportador.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exportador.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
response.setHeader("Content-Transfer-Encoding", "Cp1256");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=\"" + this.nomeArquivoSaida + "\"");
exportador.exportReport();
}
} catch (Exception e) {
throw new SQLException("Erro ao executar relatório " + this.caminhoRelatorio, e);
}
}
public boolean isRelatorioGerado() {
return relatorioGerado;
}
}
Query in the report:
SELECT DISTINCT
ocorrencia.`id` AS ocorrencia_id,
ocorrencia.`descricao` AS ocorrencia_descricao,
ocorrencia.`condicao_tempo` AS ocorrencia_condicao_tempo,
ocorrencia.`data_ocorrencia` AS ocorrencia_data_ocorrencia,
ocorrencia.`periodo_ocorrencia` AS ocorrencia_periodo_ocorrencia,
ocorrencia.`condutor_id` AS ocorrencia_condutor_id,
condutor.`id` AS condutor_id,
condutor.`codigo` AS condutor_codigo,
condutor.`nome` AS condutor_nome,
entrada_acidente.`id` AS entrada_acidente_id,
entrada_acidente.`data_criacao` AS entrada_acidente_data_criacao,
entrada_acidente.`ocorrencia_id` AS entrada_acidente_ocorrencia_id,
entrada_acidente.`valor_unitario` AS entrada_acidente_valor_unitario,
cliente.`id` AS cliente_id,
cliente.`nome` AS cliente_nome,
entrada_acidente.`status` AS entrada_acidente_status
FROM
`condutor` condutor INNER JOIN `ocorrencia` ocorrencia ON condutor.`id` = ocorrencia.`condutor_id`
INNER JOIN `entrada_acidente` entrada_acidente ON ocorrencia.`id` = entrada_acidente.`ocorrencia_id`
INNER JOIN `cliente` cliente ON entrada_acidente.`cliente_id` = cliente.`id`
WHERE
entrada_acidente.`data_criacao` BETWEEN $P{data_inicio} AND $P{data_fim}
AND cliente.`nome` = $P{nome_cliente}
AND entrada_acidente.`status` = $P{status_entrada}
xhtml:
<ui:composition template="/WEB-INF/template/LayoutPadrao.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="titulo">Relatório de entradas emitidas</ui:define>
<ui:define name="corpo">
<h:form id="frm">
<h1>Relatório de entradas emitidas</h1>
<p:messages autoUpdate="true" closable="true" />
<p:toolbar style="margin-top: 20px">
<p:toolbarGroup>
<p:commandButton value="EmitirPdf"
action="#{relatorioEntradasBean.emitirPdf}" ajax="false" />
<p:commandButton value="EmitirXls"
action="#{relatorioEntradasBean.emitirXls}" ajax="false" />
</p:toolbarGroup>
</p:toolbar>
<p:panelGrid columns="7" id="painel"
style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo">
<p:outputLabel value="Data de criação" />
<h:panelGroup>
<p:calendar value="#{relatorioEntradasBean.dataInicio}"
label="Data inicial" pattern="dd/MM/yyyy" size="8" />
<p:spacer width="8" />
<h:outputText value="a" />
<p:spacer width="8" />
<p:calendar value="#{relatorioEntradasBean.dataFim}"
label="Data final" pattern="dd/MM/yyyy" size="8" />
</h:panelGroup>
<h:panelGroup>
<p:outputLabel value="Cliente" for="cliente" />
<p:autoComplete id="cliente" size="40" dropdown="true"
value="#{relatorioEntradasBean.cliente}"
completeMethod="#{cadastroEntradaBean.completarCliente}"
var="cliente" itemLabel="#{cliente.nome}" itemValue="#{cliente}"
forceSelection="true" />
</h:panelGroup>
<p:outputLabel value="Status" />
<h:panelGroup>
<p:selectOneMenu id="statusEntrada"
value="#{relatorioEntradasBean.statusEntrada}">
<f:selectItem itemLabel="Selecione" />
<f:selectItems value="#{enumProviderStatus.statusEntradas}"
var="statusEntrada" itemValue="#{statusEntrada}"
itemLabel="#{statusEntrada.descricao}" />
</p:selectOneMenu>
</h:panelGroup>
</p:panelGrid>
</h:form>
</ui:define>
</ui:composition>
I´m a begginer in Primefaces.... And I tried to make the example DragDrop - Native Primefaces
I´ll posted all the clases and xhtml files involved for this example.
I can drag any columns but it´s not working the droping property....
You can see an image showing the trouble in this link https://lh3.googleusercontent.com/clMOtntqI99ltjXGYpzUGt-8yg4N8ahtQQIBT5leNA=w314-h207-p-no
The fist file is dndColumns.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>dndColumns</title>
</h:head>
<body>
<h:form id="form">
<p:remoteCommand name="updateColumns" actionListener="#{tableBean.onColumnDrop}"
update="cars" oncomplete="initDND()"/>
<p:tree id="tree" value="#{tableBean.availableColumns}" var="column">
<p:treeNode>
<h:outputText value="#{column}" />
</p:treeNode>
<p:treeNode type="column" icon="ui-icon-grip-dotted-vertical">
<h:outputText value="#{column.property}" />
</p:treeNode>
</p:tree>
<p:dataTable id="cars" var="car" value="#{tableBean.carsSmall}">
<p:columns value="#{tableBean.columns}" var="column">
<f:facet name="header">
<h:outputText style="float:left;display:block;height:12px;width:10px;border:0 none;"
styleClass="droppoint dropleft" />
<h:outputText style="float:right;display:block;height:12px;width:10px;border:0 none;"
styleClass="droppoint dropright" />
<h:outputText value="#{column.header}" />
</f:facet>
<h:outputText value="#{car[column.property]}" />
</p:columns>
</p:dataTable>
<script type="text/javascript">
function initDND() {
$('.ui-treenode-leaf').draggable({
helper: 'clone',
scope: 'treetotable',
zIndex: ++PrimeFaces.zindex
});
$('.ui-datatable .droppoint').droppable({
activeClass: 'ui-state-active',
hoverClass: 'ui-state-highlight',
tolerance: 'pointer',
scope: 'treetotable',
drop: function(event, ui) {
var property = ui.draggable.find('.ui-treenode-label').text(),
droppedColumnId = $(this).parents('th:first').attr('id'),
dropPos = $(this).hasClass('dropleft') ? 0 : 1;
treeToTable([
{name: 'property', value: property}
,{name: 'droppedColumnId', value: droppedColumnId}
,{name: 'dropPos', value: dropPos}
]);
}
});
$('.ui-datatable th').draggable({
helper: 'clone',
scope: 'tabletotree',
helper: function() {
var th = $(this);
return th.clone().css('width', th.width());
}
});
$('.ui-tree').droppable({
helper: 'clone',
scope: 'tabletotree',
activeClass: 'ui-state-active',
hoverClass: 'ui-state-highlight',
tolerance: 'touch',
drop: function(event, ui) {
tableToTree([
{name: 'colIndex', value: ui.draggable.index()}
]);
}
});
}
$(function() {
initDND();
});
</script>
<hr/>
<p:menu>
<p:submenu label="Resources">
<p:menuitem value="Demo" url="http://www.primefaces.org/showcase-labs/ui/dndColumns.jsf" />
</p:submenu>
</p:menu>
</h:form>
</body>
</html>
The second file is TableBean.java
package org.sagarpa.src.managedBean;
import java.io.Serializable;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
// import org.primefaces.examples.domain.Car;
import org.sagarpa.src.bean.Car;
#ManagedBean
#SessionScoped
public class TableBean implements Serializable {
private final static List<String> VALID_COLUMN_KEYS = Arrays.asList("model", "manufacturer", "year", "color");
private final static String[] colors;
private final static String[] manufacturers;
private String columnTemplate = "model manufacturer year";
static {
colors = new String[10];
colors[0] = "Black";
colors[1] = "White";
colors[2] = "Green";
colors[3] = "Red";
colors[4] = "Blue";
colors[5] = "Orange";
colors[6] = "Silver";
colors[7] = "Yellow";
colors[8] = "Brown";
colors[9] = "Maroon";
manufacturers = new String[10];
manufacturers[0] = "Mercedes";
manufacturers[1] = "BMW";
manufacturers[2] = "Volvo";
manufacturers[3] = "Audi";
manufacturers[4] = "Renault";
manufacturers[5] = "Opel";
manufacturers[6] = "Volkswagen";
manufacturers[7] = "Chrysler";
manufacturers[8] = "Ferrari";
manufacturers[9] = "Ford";
}
private List<Car> carsSmall;
private List<Car> carsLarge;
private List<ColumnModel> columns = new ArrayList<ColumnModel>();
private TreeNode availableColumns;
public TableBean() {
carsSmall = new ArrayList<Car>();
populateRandomCars(carsSmall, 9);
createDynamicColumns();
createAvailableColumns();
}
private void populateRandomCars(List<Car> list, int size) {
for(int i = 0 ; i < size ; i++)
list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));
}
public List<Car> getCarsSmall() {
return carsSmall;
}
private int getRandomYear() {
return (int) (Math.random() * 50 + 1960);
}
private String getRandomColor() {
return colors[(int) (Math.random() * 10)];
}
private String getRandomManufacturer() {
return manufacturers[(int) (Math.random() * 10)];
}
private String getRandomModel() {
return UUID.randomUUID().toString().substring(0, 8);
}
public List<ColumnModel> getColumns() {
return columns;
}
private void createAvailableColumns() {
availableColumns = new DefaultTreeNode("Root", null);
TreeNode root = new DefaultTreeNode("Columns", availableColumns);
root.setExpanded(true);
TreeNode model = new DefaultTreeNode("column", new ColumnModel("Model", "model"), root);
TreeNode year = new DefaultTreeNode("column", new ColumnModel("Year", "year"), root);
TreeNode manufacturer = new DefaultTreeNode("column", new ColumnModel("Manufacturer", "manufacturer"), root);
TreeNode color = new DefaultTreeNode("column", new ColumnModel("Color", "color"), root);
}
public TreeNode getAvailableColumns() {
return availableColumns;
}
public void createDynamicColumns() {
String[] columnKeys = columnTemplate.split(" ");
columns.clear();
for(String columnKey : columnKeys) {
String key = columnKey.trim();
if(VALID_COLUMN_KEYS.contains(key)) {
columns.add(new ColumnModel(columnKey.toUpperCase(), columnKey));
}
}
}
public void treeToTable() {
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String property = params.get("property");
String droppedColumnId = params.get("droppedColumnId");
String dropPos = params.get("dropPos");
String[] droppedColumnTokens = droppedColumnId.split(":");
int draggedColumnIndex = Integer.parseInt(droppedColumnTokens[droppedColumnTokens.length - 1]);
int dropColumnIndex = draggedColumnIndex + Integer.parseInt(dropPos);
//add to columns
this.columns.add(dropColumnIndex, new ColumnModel(property.toUpperCase(), property));
//remove from nodes
TreeNode root = availableColumns.getChildren().get(0);
for(TreeNode node : root.getChildren()) {
ColumnModel model = (ColumnModel) node.getData();
if(model.getProperty().equals(property)) {
root.getChildren().remove(node);
break;
}
}
}
public void tableToTree() {
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
int colIndex = Integer.parseInt(params.get("colIndex"));
//remove from table
ColumnModel model = this.columns.remove(colIndex);
//add to nodes
TreeNode property = new DefaultTreeNode("column", model, availableColumns.getChildren().get(0));
}
static public class ColumnModel implements Serializable {
private String header;
private String property;
public ColumnModel(String header, String property) {
this.header = header;
this.property = property;
}
public String getHeader() {
return header;
}
public String getProperty() {
return property;
}
}
}
And the third and last file is Car.java
package org.sagarpa.src.bean;
// import java.util.Date;
public class Car {
private String model;
private int year;
private String manufacturer;
private String color;
public Car(String model, int year, String manufacturer, String color) {
this.model = model;
this.year = year;
this.manufacturer = manufacturer;
this.color = color;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
The problem exists when I want to drag any component because its can´t drop on the table or on the Columns area rectangle.
Please.... Could you help me to complete the code ??? Any sugestion ???
Regards...
I YET solved my problem....
Only make a change into the fist file is dndColumns.xhtml
We need to replace this line:
<p:remoteCommand name="updateColumns" actionListener="#{tableBean.onColumnDrop}" update="cars" oncomplete="initDND()"/>
for other these two lines:
<p:remoteCommand name="treeToTable" actionListener="#{tableBean.treeToTable}" update="tree cars" oncomplete="initDND()"/>
<p:remoteCommand name="tableToTree" actionListener="#{tableBean.tableToTree}" update="tree cars" oncomplete="initDND()"/>
And test it again.....
WONDERFUL....!!!!!!
I'll post the complete dndColumns.xhtml file.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>dndColumns</title>
</h:head>
<body>
<h1 class="title ui-widget-header ui-corner-all">DragDrop - Native</h1>
<p>This sample demonstrates how to integrate low level jquery apis with PrimeFaces. Tree component displays the available
columns which are draggable. Column headers have drop targets and dropping a treenode onto one of these adds the related property column to the datatable.
Column headers can also be moved back to the tree.</p>
<h:form id="form">
<p:remoteCommand name="treeToTable" actionListener="#{tableBean.treeToTable}" update="tree cars" oncomplete="initDND()"/>
<p:remoteCommand name="tableToTree" actionListener="#{tableBean.tableToTree}" update="tree cars" oncomplete="initDND()"/>
<p:tree id="tree" value="#{tableBean.availableColumns}" var="column">
<p:treeNode>
<h:outputText value="#{column}" />
</p:treeNode>
<p:treeNode type="column" icon="ui-icon-grip-dotted-vertical">
<h:outputText value="#{column.property}" />
</p:treeNode>
</p:tree>
<br />
<p:dataTable id="cars" var="car" value="#{tableBean.carsSmall}">
<p:columns value="#{tableBean.columns}" var="column">
<f:facet name="header">
<h:outputText style="float:left;display:block;height:20px;width:10px;border:0 none;" styleClass="droppoint dropleft" />
<h:outputText style="float:right;display:block;height:20px;width:10px;border:0 none;" styleClass="droppoint dropright" />
<h:outputText value="#{column.header}" />
</f:facet>
<h:outputText value="#{car[column.property]}" />
</p:columns>
</p:dataTable>
<script type="text/javascript">
function initDND() {
$('.ui-treenode-leaf').draggable({
helper: 'clone',
scope: 'treetotable',
zIndex: ++PrimeFaces.zindex
});
$('.ui-datatable .droppoint').droppable({
activeClass: 'ui-state-active',
hoverClass: 'ui-state-highlight',
tolerance: 'pointer',
scope: 'treetotable',
drop: function(event, ui) {
var property = ui.draggable.find('.ui-treenode-label').text(),
droppedColumnId = $(this).parents('th:first').attr('id'),
dropPos = $(this).hasClass('dropleft') ? 0 : 1;
treeToTable([
{name: 'property', value: property}
,{name: 'droppedColumnId', value: droppedColumnId}
,{name: 'dropPos', value: dropPos}
]);
}
});
$('.ui-datatable th').draggable({
helper: 'clone',
scope: 'tabletotree',
helper: function() {
var th = $(this);
return th.clone().css('width', th.width());
}
});
$('.ui-tree').droppable({
helper: 'clone',
scope: 'tabletotree',
activeClass: 'ui-state-active',
hoverClass: 'ui-state-highlight',
tolerance: 'touch',
drop: function(event, ui) {
tableToTree([
{name: 'colIndex', value: ui.draggable.index()}
]);
}
});
}
$(function() {
initDND();
});
</script>
<hr/>
<p:menu>
<p:submenu label="Resources">
<p:menuitem value="Demo" url="http://www.primefaces.org/showcase-labs/ui/dndColumns.jsf" />
</p:submenu>
</p:menu>
</h:form>
</body>
</html>