How to get the selected image from <p:galleria - jsf

In this code,
<p:galleria value="#{Bean.images}" var="image" panelWidth="500" panelHeight="313" showCaption="true"
<p:graphicImage value="/images/galleria/#{image}" alt="Image Description for #{image}" title="#{image}"/
</p:galleria>
how do you get selectedImage? as expressed in
<p:carousel id="carousel" value="#{tableBean.carsSmall}" var="car" itemStyleClass="carItem" headerText="Cars">
<p:graphicImage id="image" value="/images/cars/#{car.manufacturer}.jpg"/>
<h:panelGrid columns="2" style="width:100%" cellpadding="5">
<h:outputText value="Model: " /><h:outputText id="model" value="#{car.model}" />
</h:panelGrid>
<p:commandLink id="view" update=":form:carDetail" oncomplete="carDialog.show()" title="View Detail">
<h:outputText styleClass="ui-icon ui-icon-search" style="margin:0 auto;" />
<f:setPropertyActionListener value="#{car}"
target="#{tableBean.selectedCar}" />
</p:commandLink>
</p:carousel>

Supposing you have a details button on each current displayed picture
(with alt attribute set to image filename)
<p:galleria value="#{Bean.images}" var="image">
<p:graphicImage value="/images/galleria/#{image}"/>
<f:facet name="content">
<p:graphicImage value="/images/galleria/#{image}" alt="#{image}" />
<span style="position:absolute;right:0;top:0;">
<p:commandButton styleClass="ui-icon ui-icon-search" onclick="jsCallRemote(this);" />
</span>
</f:facet>
</p:galleria>
Search button could call a js function passing the button himself as a hint to find the current image filename, and then call a remote command passing it the filename as a request parameter:
<script>
function jsCallRemote(btn) {
var imageFileName = btn.parentNode.parentNode.getElementsByTagName('img')[0].alt;
selectImage([{name:'imageFileName', value:imageFileName}]);
}
</script>
<p:remoteCommand name="selectImage" actionListener="#{tableBean.selectImage}" />
And the bean's method makes the actual selection through the request parameter imageFileName:
public void selectImage() {
String fileName = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("imageFileName");
// find image by filename...
}

In case you do not intend to have a button for each image you can take advantage of the galleria caption to catch the selected image title. This solution is based on the answer of andreea m.
<p:commandButton action="#{controller.preview}" value="Preview" onclick="checkSelectedImage();" oncomplete="PF('previewDialog').show();"/>
JS function
function checkSelectedImage() {
var caption = document.getElementsByClassName("ui-galleria-caption");
selectImage([{name:'imageFileName', value:caption[0].getElementsByTagName("h4")[0].innerHTML}]);
}
Remote command
<p:remoteCommand name="selectImage" actionListener="#{controller.selectImage}"/>

Related

primefaces BlockUI not blocking panel

I have a Primefaces 11 page where I want to make a mass change on the database. Reading the data works fine and the updateprocess works also. But because it takes some time I wanted to block the page and show an statusbar so the user knows that something is happening and he sees how long it will approximatly take to finish. But the BlockUI doesn't show up. I have a page that is almost the same and there it is working. But I can't see where the difference is to this page.
The xhtml looks like this:
<h:form id="abbauForm">
<div class="card">
<p:growl id="messages" sticky="false" showDetail="true" />
<p:panel id="quelldaten" header="Quelldaten">
<h:panelGrid columns="2" columnClasses="label, value">
<h:outputText value="Auswahl" />
<p:fileUpload label="Datei auswahl" mode="simple" multiple="false" auto="true" allowTypes="/(\.|\/)(xlsx?m?|csv)$/"
invalidFileMessage="nur xls | xlsx | csv | erlaubt" update="messages quelldaten"
listener="#{massenabbauhandler.handleFileUpload}" skinSimple="true" />
<h:outputText value="Ticketnummer" />
<p:inputText value="#{massenabbauhandler.massenabbau.ticket}" required="true" label="Ticketnummer" />
<h:outputText value="Abbaudatum" />
<p:datePicker id="date" value="#{massenabbauhandler.massenabbau.abbaudatum}" required="true" />
<h:outputText value="Abbau Objekt" />
<p:selectOneMenu id="selObject" value="#{massenabbauhandler.massenabbau.abbauObject}" required="true">
<f:selectItems value="#{massenabbauhandler.abbauObjects}" />
</p:selectOneMenu>
<h:outputText value="Spalte mit Hostnamen" />
<p:selectOneMenu id="hostCol" value="#{massenabbauhandler.massenabbau.hostCol}" required="true">
<f:selectItems value="#{massenabbauhandler.posCols}" />
</p:selectOneMenu>
<p:commandButton id="abbauBtn" value="Abbau" icon="pi pi-caret-right" actionListener="#{massenabbauhandler.startAbbau}"
disabled="#{massenabbauhandler.notUploaded}" />
</h:panelGrid>
</p:panel>
<p:panel header="Importdaten" id="dataPanel">
<p:staticMessage severity="info" summary="INFO" detail="#{massenabbauhandler.abbauStep}" style="width: 100%" />
</p:panel>
<p:blockUI block="abbauForm:quelldaten" trigger="abbauForm:abbauBtn" />
</div>
</h:form>
I have minimalized the BlockUI to a minimum because it didn't work. The startAbbau() function looks like this:
public void startAbbau() throws InterruptedException {
FacesMessage msg = new FacesMessage("Abbau läuft");
FacesContext.getCurrentInstance().addMessage(null, msg);
setStartBlocked(true);
PrimeFaces.current().ajax().update("abbauForm:quelldaten");
setInProgress(0);
MassenabbauDbHandler madh = new MassenabbauDbHandler(massenabbau);
Thread t = new Thread(madh);
t.start();
do {
Thread.sleep(3000);
setInProgress(madh.getStatus());
} while (t.isAlive());
setInProgress(100);
abbauStep = madh.getReturnMsg();
msg = new FacesMessage("Erfolgreich abgebaut.");
FacesContext.getCurrentInstance().addMessage(null, msg);
PrimeFaces.current().ajax().update("abbauForm:dataPanel");
}
I've noticed that the first and the last message of the function are shown at the end of the function.
I can't see why the blockUI isn't shown.

Primefaces Mobile commandButton not working with ActionListener

I presented the following problem.
when done click the button located in the dialog (pop -up ), the actionListener attribute does not work , ie not call the Backingbean.
The strange thing is that in the version PrimeFaces showcase this code works perfectly , only mobile fails.
Another curiosity is that the javascript function button is successful, what makes me think it's a problem of ajax for mobile version
Here the code
<pm:content>
<h:form id="productForm">
<p:dataList value="#{productoMB.productList}" var="pro"
paginator="true" id="productDL">
<f:facet name="header">Menu de comidas</f:facet>
<p:panel header="#{pro.name}" style="text-align:center">
<h:panelGrid columns="1" style="width:100%">
<p:commandLink update=":homeFirst:productForm:productDetail"
oncomplete="PF('productDialog').show()" title="Ver Detalles">
<h:graphicImage library="images" name="#{pro.path}" width="320px"
height="120px" />
<f:setPropertyActionListener value="#{pro}"
target="#{productoMB.productSelect}" />
</p:commandLink>
</h:panelGrid>
</p:panel>
</p:dataList>
<p:dialog header="Detalle Plato" widgetVar="productDialog"
modal="true" showEffect="fade" hideEffect="fade" resizable="false">
<p:outputPanel style="text-align:center;">
<p:panelGrid id="productDetail" columns="2"
rendered="#{not empty productoMB.productSelect}"
columnClasses="label,value">
<f:facet name="header">
<p:graphicImage library="images"
name="#{productoMB.productSelect.path}.jpg" width="100px"
height="100px" />
</f:facet>
<h:outputText value="Nombre:" />
<h:outputText value="#{productMB.productSelect.name}" />
<h:outputText value="Precio" />
<h:outputText value="#{productoMB.productSelect.price}" />
<h:outputText value="Detalles:" />
<h:outputText value="#{productoMB.productSelect.description}" />
<h:outputText value="Cantidad:" />
<h:inputText value="#{productoMB.quantity}" required="true">
<!-- <p:ajax update="costo" listener="#{empMB.calcularPrecioTotal}" /> -->
<!-- <f:validateDoubleRange minimum="0" maximum="200" /> -->
</h:inputText>
<h:outputText value="Total a Pagar:" />
<!-- <h:outputText id="costo" value="#{empMB.precioTotal}" /> -->
<p:commandButton value="Volver"
onclick="PF('productDialog').hide()"></p:commandButton>
<h:form>
<p:commandButton value="Agregar al carrito"
onclick="PF('carDialog').hide()" icon="ui-icon-cart" actionListener="#{productoMB.addCart}">
</p:commandButton>
</h:form>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
</pm:content>
This is a backingbean
package ar.com.as.presentation.mb;
import java.util.ArrayList;
import java.util.List;
import ar.com.as.business.bo.interfaces.GenericBO;
import ar.com.as.business.bo.patterns.FactoryFacade;
import ar.com.as.model.Cart;
import ar.com.as.model.Product;
public class ProductMB {
private List<Product> productList;
private Product productSelect;
private int quantity;
private List<Cart> cartList;
public ProductMB() {
productList = new ArrayList<Product>();
cartList = new ArrayList<Cart>();
findAllProduct();
}
public void findAllProduct() {
GenericBO<Product> productBO = FactoryFacade.createFacade("facade")
.getInstance().create("product");
productList = productBO.findAll();
}
public void addCart() {
System.out.println("se agrego al carrito");
}
// Getters+setters.
}
Any idea Como esta Problem solved .Or How to run the method addcart without ajax .
From already thank you very much .
Regards, Santiago
You have a nested h:form. Correct that, since it will very often (~always) lead to unexpected behaviour. Working in one environment and not in another is one of them.
Related Stackoverflow posts
I share the solution I found to my particular problem is:
<p:commandButton value="add" onclick="addC()"
icon="ui-icon-plus"
style="margin-left:20%; margin- rigth:15%" >
</p:commandButton >
In the onclick call javascript function addC:
<p:remoteCommand name="addC"
actionListener="#{productoMB.addCart}"
update="#widgetVar(cart)" />
RemoteCommand provides a simple way to execute backing bean methods with javascript.
Apparently mobile PrimeFaces has some bugs and does not work correctly with ajax.
Regards, Santiago

PrimeFaces print doesn't work with p:chart

I'm using primeface print just like below
<ui:define name="content" id="content">
<h:form id="common_chart_form" prependId="flase">
<p:growl id="growl" showDetail="true" autoUpdate="true"
sticky="false" />
<p:outputLabel id="labelvalue" value="aaaaaaaaaa"/>
<p:chart id="chart" type="bar"
model="#{commonChartController.barModel}" style="height:300px" />
<p:commandButton value="Print" type="button" icon="ui-icon-print">
<p:printer target="chart" />
</p:commandButton>
<p:commandButton value="Back" action="admin_sales_reports" />
</h:form>
</ui:define>
i need to print the chart but unfortunately it cannot print. then to test the print target i tried to print the "labelvalue" it printed what is the wrong thing that im doing in this code
this is the screen shot of the page
You can do it in a more elegant way, without the need of the outputPanel declared in the page:
Javascript function:
function print(component){
var out = document.createElement('div');
out.appendChild(PF(component).exportAsImage());
var innerHTML = out.innerHTML;
var openWindow = window.open('', 'Report', '');
openWindow.document.write(innerHTML);
openWindow.document.close();
openWindow.focus();
openWindow.print();
openWindow.close();
}
Define widgetVar for chart:
<p:chart widgetVar="chart2" type="bar" model="#{chartsBean.barModel2}" />
Call the print function:
<p:commandLink id="lnk" onclick="print('chart2')"/>
Here is how you do it - found a thread from Brazil that showed it:
1 - Create a dialog like this:
<p:dialog widgetVar="outputDialog" showEffect="fade" modal="true" header="Header Name">
<p:outputPanel id="output" layout="block" style="width:860px;height:540px"/>
</p:dialog>
2 - Create your charts with a widgetVar like this:
<p:chart widgetVar="chart1" type="bar" model="#{chartsBean.barModel1}" style="height:300px;width:800px;"/>
<p:spacer height="40px"/>
<p:chart widgetVar="chart2" type="bar" model="#{chartsBean.barModel2}" style="height:300px;width:800px;"/>
<p:spacer height="40px"/>
<p:chart widgetVar="chart3" type="bar" model="#{chartsBean.barModel3}" style="height:300px;width:800px;"/>
<p:spacer height="40px"/>
<p:chart widgetVar="chart4" type="line" model="#{chartsBean.lineModel1}" style="height:300px;width:800px;"/>
<p:spacer height="40px"/>
<p:chart widgetVar="chart5" type="line" model="#{chartsBean.lineModel2}" style="height:300px;width:800px;"/>
<p:spacer height="40px"/>
<p:chart widgetVar="chart6" type="line" model="#{chartsBean.lineModel3}" style="height:300px;width:800px;"/>
3 - Create a javascript function like this:
function print() {
$('#output').empty().append(PF('chart1').exportAsImage());
$('#output').append(PF('chart2').exportAsImage());
$('#output').append(PF('chart3').exportAsImage());
$('#output').append(PF('chart4').exportAsImage());
$('#output').append(PF('chart5').exportAsImage());
$('#output').append(PF('chart6').exportAsImage());
//PF('outputDialog').show();
var innerHTML = $('#output')[0].innerHTML;
if (innerHTML != null){
var openWindow = window.open("", 'Report', "");
openWindow.document.write(innerHTML);
openWindow.document.close();
openWindow.focus();
openWindow.print();
openWindow.close();
}
}
4 - Create a menubar, command button, or any other way of invoking the print() function. Here is my way:
<p:menubar>
<p:menuitem value="Print" icon="ui-icon-print" action="javascript.void(0);" onclick="print();"/>
<p:menuitem value="Email" icon="ui-icon-mail-closed" action="javascript.void(0);" onclick="alert('email');"/>
</p:menubar>
Only put this (onclick="print();").
<p:commandButton value="Print" type="button" icon="ui-icon-print" style="display:block;margin-bottom: 20px" onclick="print();"/>
Thats it.
According to this post, it's not possible to print a chart. A solution is given in the last post.
You can use script to export chart as image to a panel which has same height with chart and z-index property value less than chart. Exp:
<h:form>
<p:commandButton value="Print" style="margin:10px;"
onclick="$('#output').empty().append(PF('chart').exportAsImage());">
<p:printer target="output"></p:printer>
</p:commandButton>
</h:form>
<p:outputPanel id="output" layout="block"
style="position:absolute;height:300px;z-index:1" />
<p:chart widgetVar="chart" type="bar" model="#{bean.barModel}"
style="height:300px;z-index:1000;background:#fff"></p:chart>

how to update h:panelGroup using f:ajax

How to update h:panelGroup using f:ajax.When, i select h:selectBooleanCheckbox getting value from officeAdd1 and set this value into headOfficeAdd1.Am getting officeAdd1 value in bean but i want to update value into headOfficeAdd1.
Thanks...
<h:form id="form">
<p:panel id="display">
<p:spacer width="20" />
<h:panelGrid columns="6">
<h:outputLabel value="Address:"
style="text-align: left;display: block;width:130px;" />
<p:inputTextarea
value="#{companyInformationBean.current.officeAdd1}"
autoResize="true" style="width:170px;" maxlength="150" />
</h:panelGrid>
<h:panelGrid columns="6">
<h:selectBooleanCheckbox id="remember"
value="#{companyInformationBean.current.checkBox}">
<f:ajax event="click" execute="#form"
listener="#{companyInformationBean.checkBoxValue}" />
</h:selectBooleanCheckbox>
<h:outputLabel value="Same as Registered Office Address"
style="text-align: left;display: block;" />
<p:spacer width="20" />
</h:panelGrid>
<p:spacer width="20" />
<h:panelGroup id="hidepanelgroup">
<h:panelGrid id="getaddress" columns="6">
<h:outputLabel value="Head Office Address:"
style="text-align: left;display: block;width:130px;" />
<p:inputTextarea id="headadd"
value="#{companyInformationBean.current.headOfficeAdd1}"
autoResize="true" style="width:170px;" maxlength="150" />
</h:panelGrid>
</h:panelGroup>
</p:panel>
</h:form>
Bean:
public void checkBoxValue()
{
if(current.getCheckBox()==true)
{
logger.info("getofadd"+current.getOfficeAdd1());
current.setHeadOfficeAdd1(current.getOfficeAdd1());
}
else
{
logger.info("checkbox value false");
}
}
You need to specify client IDs-to-render in the <f:ajax render> attribute.
Thus, given that the second textarea has an ID of headadd, this should do:
<f:ajax ... render="headadd" />
Unrelated to the concrete problem, comparing booleans against booleans in a boolean expression really doesn't make any sense. Just check the boolean itself directly.
if (current.getCheckBox())
By the way, try to use self-documenting property and method names. A property name of remember would be more suitable.

How to stay in the dialog if OK button `action` reports error? [duplicate]

I have a CRUD page which shows data from a query (a List of domain objects) in a Primefaces datatable.
<p:dataTable
id="negozi"
var="n"
value="#{nController.theListFromQuery}"
rowKey="#{n.id}"
selection="#{nController.selected}"
selectionMode="single">
<p:column headerText="Field1">
<h:outputText value="#{n.f1}" />
</p:column>
<p:column headerText="Field2">
<h:outputText value="#{n.f2}" />
</p:column>
<p:column style="width:4%">
<p:commandButton
actionListener="#{nController.prepareEdit(n)}"
update=":editDialogId"
oncomplete="editDialog.show()"
value="Edit" />
</p:column>
...
By clicking on the edit button a dialog will be shown:
<p:dialog
header="Edit N"
widgetVar="editDialog"
id="editDialogId">
<h:form id="formDialog">
<h:panelGrid id="editDialogTable" columns="2" cellpadding="10" style="margin:0 auto;">
<p:outputLabel for="field1" value="F1:" />
<p:inputText id="field1" value="#{nController.selected.f1}" />
<p:outputLabel for="field2" value="F2:" />
<p:inputText id="field2" value="#{nController.selected.f2}" />
<p:commandButton
value="Confirm"
actionListener="#{nController.doEdit}"
update=":form"
oncomplete="editDialog.hide()"
rendered="#{nController.selected.id!=null}" />
...
It works. Now I want to make F1 a required field.
I add the "required" attribute to the inputText field and what happens?
When I try to confirm the form without the required field, the entity is not edited (that's right) but the dialog is closed (that's NOT right!)
When I reopen the dialog I can see the red highlight on the required (and invalid) field.
What I want is to prevent the dialog closing if the form is invalid.
Do I have to write some JS or will JSF help me?
The PrimeFaces ajax response puts an args object in the scope which has a validationFailed property. You could just make use of it.
oncomplete="if (args && !args.validationFailed) PF('editDialog').hide()"
(the args precheck is necessary to not cause a JS error when an exception is thrown during request)
You could refactor it to a reusable JS function as follows.
oncomplete="hideDialogOnSuccess(args, 'editDialog')"
function hideDialogOnSuccess(args, dialogWidgetVar) {
if (args && !args.validationFailed) {
PF(dialogWidgetVar).hide();
}
}
this post is now three years old, but I have found helpful, so my findings may help others.
In PF 5.x at least, it seems that the solution provided by BalusC has to be modified in two ways. (1) add the "args" argument to the call in oncomplete event hander, and (2) use the PF primefaces primitive to identify the widget in PF tables. Here is the code I am using:
oncomplete="hideDialogOnSuccess(args, PF('editDialog'))"
function hideDialogOnSuccess(args, dialogWidgetVar) {
if (args && !args.validationFailed) {
dialogWidgetVar.hide();
}
}
I believe this is the cleanest solution.
Doing this you don't need to change your buttons code.
This solution overrides the hide function prototype.
$(document).ready(function() {
PrimeFaces.widget.Dialog.prototype.originalHide = PrimeFaces.widget.Dialog.prototype.hide; // keep a reference to the original hide()
PrimeFaces.widget.Dialog.prototype.hide = function() {
var ajaxResponseArgs = arguments.callee.caller.arguments[2]; // accesses oncomplete arguments
if (ajaxResponseArgs && ajaxResponseArgs.validationFailed) {
return; // on validation error, prevent closing
}
this.originalHide();
};
});
This way, you can keep your code like:
<p:commandButton value="Save" oncomplete="videoDetalheDialogJS.hide();"
actionListener="#{videoBean.saveVideo(video)}" />
to keep the dialog Open on validation Failed, you just need set the commandButton as follows:
<p:commandButton value="save"
action="#{YourBean.yourActionMethod}"
oncomplete="if (!args.validationFailed) PF('yourDialogWidgetVar').hide()"/>
I gonna leave here a complete example:
<h:form id="ad-form">
<p:dialog id="ad-dialog" widgetVar="adDialog" modal="true" width="400"
closeOnEscape="true" resizable="false" header="Addreass">
<p:messages id="a-msgs" closable="true" />
<h:panelGrid columns="2" id="ad-painel-dialog" width="100%">
<p:outputLabel value="Country" for="country" />
<p:inputText id="country" style="width:100%"
value="#{clientSaverBean.editableAddress.country}" />
<p:outputLabel value="City" for="city" />
<p:inputText id="city"
value="#{clientSaverBean.editableAddress.city}" />
<p:outputLabel value="Zip-Code" for="zipcode" />
<p:inputText id="zipcode"
value="#{clientSaverBean.editableAddress.zipCode}" />
<p:outputLabel value="Street" for="street" />
<p:inputTextarea id="street"
value="#{clientSaverBean.editableAddress.street}" />
<p:outputLabel value="Number" for="number" />
<p:inputText id="number"
value="#{clientSaverBean.editableAddress.number}" />
<h:panelGroup />
<f:facet name="footer">
<p:commandButton value="save"
action="#{clientSaverBean.saveAddress}"
process=":ad-form:ad-dialog"
update=":ad-form:a-msgs :ad-form:ad-painel-dialog :client-form:ad-table"
oncomplete="if (!args.validationFailed) PF('adDialog').hide()"/>
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>

Resources