How I can to export a chart, when charts are in a datatable? Primefaces 3.4 - jsf

What is idea?
Save the graphics in images.
Pass the binary to a String on the server.
Identify the graph from the binary (ready).
Create a pdf with data and graphics (ready, use itex).
View the pdf (ready).
But I can not export any graphics. This is because I can not detect them.
When I include a graphic in a datatable, widgetvar are repeated, so I can not use the solution of the showcase.
$('#output').empty().append(chartWidgetvar.exportAsImage());
This is part of my code.
<h:form id="reportePro">
<p:dataTable value="#{listas.reporteSeccionPro}" var="p"
selection="#{listas.reporteSeleccionadoSeccionPro}"
selectionMode="single" rowKey="#{p.idFila}"
emptyMessage="No existen coincidencias" id="reporteGeneral">
<p:column headerText="Chart">
<p:commandButton id="chartBtn" value="Gráficos" type="button" />
<p:overlayPanel id="chartPanel" for="chartBtn" hideEffect="fade"
showEffect="fade" appendToBody="true"
style="width:900px;height:450px;">
<p:pieChart id="pie"
styleClass="jqplot-table-legend jqplot-target"
value="#{p.pieModel}" extender="ext"
title="#{p.nomProSeccionPro}"
style="width:400px;height:450px;font-size:15px;"
showDataLabels="true" sliceMargin="5"
seriesColors="DB4C14, C0E9ED, A8CCED, C7B47F, F7F28F, 4DB0C4" />
</p:overlayPanel>
</p:column>
</p:dataTable>
</h:form>
I thought use dynamic id ,
<p:pieChart id="#{chart.idPie}" />
but can not be set.
I thought use dynamic widgetvar,
<p:pieChart widgetvar="#{chart.idPie}" />
but can not be set.
I thought of using only the id of the graphics,
#{p:widgetVar ('ComponentId')}
but remember that you can not use dynamic id
Another solution might be to use the canvas.toDataURL, for that, I need the id of the first canvas, but does not generate primefaces ID.
So I can not use this solution.
After spending hours and did not find the solution, I ask me.
It is possible to export a chart to an image, when they are in a datatable?

Related

PrimeFaces Chips addItem(value) to the component

I have a chips component and I want to add a button beside it and use this button to add values to this component.
My draft code is:
<p:outputPanel>
<p:chips id="TextToChips" value="#{myBean.myList}" unique="true" />
<p:button id="addButton">
<p:ajax event="click" process="TextToChips" update="chips" delay="300" listener="#{myBean.method}" />
</p:button>
</p:outputPanel>
I want to use the method addItem(value), which is listed in the documentation. So how can I use that if my principle is possible?

Dynamically adding components in multiple columns & legend creation [duplicate]

I'm working on dashboard application where I have to retrieve a set of records and display in dynamic tables boxes. Page frame length is fixed. now of columns and rows can be initialized. It should look like this sample:
Currently I'm using data table to display but it prints all the data in one column. How would I change my code to above pattern?
<o:dataTable id="tabBlSearch" var="item"
onkeyup="handleLeftRightArrowOnDataTable('frmDashBoard:tabBlSearch')"
value="#{bLDashBoardAction.listBondLoc}">
<o:column style="width: 20px;">
<h:outputText value="#{item.awb}" />
</o:column>
</o:dataTable>
You can achieve this with standard JSF components using a <h:panelGrid> wherein <c:forEach> is been used to generate the cells during the view build time. The <ui:repeat> won't work as that runs during view render time.
<h:panelGrid columns="5">
<c:forEach items="#{bean.items}" var="item">
<h:panelGroup>
<h:outputText value="#{item.value}" />
</h:panelGroup>
</c:forEach>
</h:panelGrid>
As to component libraries, I don't see anything in OpenFaces' showcase, but PrimeFaces has a <p:dataGrid> for exactly this purpose, even with pagination support.
<p:dataGrid columns="5" value="#{bean.items}" var="item">
<p:column>
<h:outputText value="#{item.value}" />
</p:column>
</p:dataGrid>

Primefaces form is not updating from within dialog

I have a view like so:
<h:form id="productForm">
<p:messages
id="productFormMessages"
autoUpdate="true"
redisplay="true"
globalOnly="true" />
<p:panelGrid
id="detailsGrid">
<p:row>
...
<p:column>
...
<p:outputLabel
id="fieldToUpdateId"
value="XYZ" />
<p:commandButton
action="#{bean.prepareDialog}"
update="dialogFormId"
oncomplete="PF('dialogModal').show();" />
</p:column>
</p:row>
</p:panelGrid>
</h:form>
<ui:include src="/../.../dialog.xhtml" />
And this is what dialog.xhtml looks like:
<p:dialog
id="dialogId"
widgetvar="dialogModal"
appendTo="#(body)"
modal="true"
dynamic="true">
<h:form
id="dialogFormId">
...a selectOneMenu...
<p:commandButton
id="saveButtonId"
value="Save"
actionListener="#{bean.save}"
oncomplete="PF('dialogModal').hide();"
process="#form"
update=":productForm" />
</h:form>
But the save button just refuses to update the productForm. It does update productFormMessages (which I'm guessing is because of the autoUpdate) but the form just doesn't update. I need to do a page reload from the browser in order for it to reflect the latest data. I have tried many different ways of doing this.
1. Using p:component to directly refer to the outputLabel in the update attribute.
2. (1) also using the form ID and the panelGrid ID.
3. Using the full client ID (with and without the preceeding ':') in the update attribute. Similarly using the form ID and the panelGrid ID.
4. Adding the client ID to the render IDs in the bean and then calling the partialViewContext#update method on that.
4. Setting partialViewContext#setRenderAll to true.
4. And as a last ditch attempt, as demonstrated by the code, updating the entire productForm. Which isn't so bad, because fieldToUpdateId is just one of the fields that I need to update in the form. But either way, it's not working.
Clearly, the data is being saved on the back end, because a page reload gives me the latest data. But I just can't get the dialog to update the form where it's being called from. I'm out of ideas. What am I doing wrong?
Theoretically this should work, But please inspect the button in the Html source, to make sure which part of the html it refresh. it should have something like this.
onclick="PrimeFaces.ab({s:'dialogFormId:saveButtonId1',u:'productForm',onco:function(xhr,status,args){PF('dialogModal').hide();;}});return false;"

PrimeFaces DataExporter to XLS for multiple tables

Am trying to Export XLS format from multiple tables. I have browsed and used some code, But its not working. Using primefaces extensions code is there but complete code is not there it seems in this
link.
I need solution for this.
Code i have used :
Tbl1, Tbl2, Tbl3 are table widgetVar's.
<p:commandLink id="xls" ajax="false" >
<p:graphicImage value="/images/excel.png" />
<pe:exporter type="xlsx" target="Tbl1, Tbl2, Tbl3" fileName="tables"/>
</p:commandLink>
You should not address them by widgetVar. From the PrimeFaces Extensions Exporter (emphasis mine):
Here we can export multiple tables by providing multiple datatable server ids with the delimiter as "comma"(or ",").
I work with primefaces 6.2 and this works for me (I’m not sure about other versions) without use primefaces extension
<p:dataTable id="tbl1" value="#{ManagedBean.listValues}" var="vt">
<p:column headerText="LabelPrint">
<h:outputText value="#{vt.id}"/>
</p:column>
</p:dataTable>
<p:dataTable id="tbl2" value="#{ManagedBean.otherList}" var="vt2">
<p:column headerText="Name Field Print">
<h:outputText value="#{vt2.name}"/>
</p:column>
</p:dataTable>
<h:commandLink>
<p:graphicImage url="#{resource['/images/icons/table-xls.png']}"/>
<p:dataExporter type="xls" target="tbl1, tbl2" fileName="My Data" pageOnly="true" />
</h:commandLink>
You separate your "id" of tables for export with (,) in attribute target of p:dataexporter object.

<p:overlayPanel> shows blank white after updating via command link/button

I am looking for solution that p:overlayPanel content should update it self while clicking commendButton or commendLink. But its showing blank white p:overlayPanel when i click the button. The updating with the p:overlayPanel id in that button or link. I have tried many ways nothing worked out. Is my code wrong?
Please suggest some solution.
Here is my code :
<ui:repeat id="profiles" value="#{items.lstProfiles}" var="profile">
<p:commandLink id="profileLink" value="show" update="moviePanel"
actionListener="#{dashBoardController.showProfileOverlay}"/>
<p:overlayPanel id="moviePanel" for="profileLink" hideEffect="fade"
dynamic="true" style="width:300px; height: 150px;">
<h:panelGrid columns="2">
<h:outputText value="Name : "/>
<h:outputText value="#{dashBoardController.selectedProfile.name}"/>
</h:panelGrid>
</p:overlayPanel>
</ui:repeat>
Usually dynamic="true" should do the job but some times it fails.So to update the contents inside the Overlay.
There are many ways to do this by tweaking Jquery.
Simplest one I can think of is:
Since ui:repeat generates dynamic ID for p:overlayPanels you can update by providing unique css class name from every iteration.
In Primefaces you can select a component using css class also using: #(.myclass).
And so you can update that component also:- update="#(.mystyle)"
Example:
<h:form>
<ui:repeat var="patient" value="#{dataCenter.patientList}">
<p:commandLink value="#{patient.firstName}" id="patientNameLnk" update="#(.overlay-class-#{patient.patientId})"/><br/>
<p:overlayPanel for="patientNameLnk">
<h:panelGroup styleClass="overlay-class-#{patient.patientId}">
#{patient.firstName}
#{patient.lastName}
#{patient.dob}
</h:panelGroup>
</p:overlayPanel>
</ui:repeat>
</h:form>
In the above example css class name for every h:panelGroup will be generated as overlay-class-<PATIENT_ID> so every h:panelGroup will have unique class name(if patientId is unique).
Note: Note that I'm updating h:panelGroup inside p:overlayPanel because if you update p:overlayPanel then it might start flickering(it happened to me while executing above example).

Resources