h:panelGrid run action after clicking into blank space - jsf

When I click somewhere inside my panelGrid, it runs action from my commandButton which is inside as well. Whole accordionPanel is inside h:form ..
jsf:
<p:accordionPanel value="#{test.getAllTests()}" var="currentTest" activeIndex="false">
<p:tab title="#{currentTest.name}">
<h:panelGrid columns="2" cellpadding="10">
<p:graphicImage value="resources/img/testIT/#{currentTest.imageSrc}" width="100" height="100" />
<p:outputLabel>
<h2>#{currentTest.name}</h2>
<p>#{currentTest.description}</p>
<p:commandButton value="Zvolit test" styleClass="testChoseButton" actionListener="#{test.setSelectedTest(currentTest)}" action="testProgress.xhtml" />
<p:spacer height="5px" width="20px" style="float: right;" />
<p:button value="Statistika testu" styleClass="testChoseButton" />
</p:outputLabel>
</h:panelGrid>
</p:tab>
</p:accordionPanel>
test.setSelectedTest(currentTest):
public void setSelectedTest(Test selectedTest) {
this.selectedTest = selectedTest;
System.err.println("Selected test: " + selectedTest.getId() + " - " + selectedTest.getName());
}
I do not know what more you could need guys. Thnx for help.

You're misusing p:outputLabel, it generates a HTML <label> element which is not what you want. I'd think both these will work:
p:outputPanel
h:panelGroup
They can both produce a HTML span or a div based on the layout attribute.
I'd take <h:panelGroup> which is meant for exactly this kind of grouping.

Related

Removing the selections on selectOneListbox / selectManyMenu on a button click in Primefaces

So i have designed a simple form having selectOneListbox / selectManyMenu elements which I am using to generate a piece of text based upon the user selections.
It's working fine. Now what I want is when the user clicks 'clear' button, the selections should be undone and the page should come back to the initial state(no selections).
How can I achieve this ?
xhtml
<h:form>
<h:panelGrid columns="6" style="margin-bottom:10px;" cellpadding="5" columnClasses="label, value">
<p:panel>
<h6 style="width:10.4em;background-color:#ACBECE;">Comment Type</h6>
<!-- comment type -->
<p:selectOneListbox id="basic1" value="#{decisionTreeBean.option1}" style=" font-size: 12px;background-color:silver;width:12em; height:10em; border-style:solid !important;border-width:0.5px !important; border-color:grey !important;">
<f:selectItems value="#{decisionTreeBean.commentType}" var="X" itemLabel="#{X}" itemValue="#{X}" />
</p:selectOneListbox>
</p:panel>
<p:panel>
<h6 style="width:10.4em;background-color:#ACBECE;">MTCN</h6>
<p:selectManyMenu id="advanced1" value="#{decisionTreeBean.option2}" showCheckbox="true" style="font-size: 12px;background-color:silver;width:12em; height:10em; border-style:solid !important;border-width:0.5px !important; border-color:grey !important;">
<f:selectItems value="#{decisionTreeBean.mtcns}" var="X" itemLabel="#{X}" itemValue="#{X}" />
</p:selectManyMenu>
</p:panel>
</h:panelGrid>
<!-- Text Area -->
<p:inputTextarea id="decisionNotes" readonly="#{facesContext.renderResponse}" value="#{decisionTreeBean.decisionNotes}" styleClass="dispostionInputTextArea" autoResize="true">
</p:inputTextarea>
<br/>
<p:commandButton id="generateBtn" value="Generate Text" action="#{decisionTreeBean.generateText}" update=":#{p:component('decisionNotes')}">
</p:commandButton>
<p:commandButton id="clearBtn" value="Clear" action="#{decisionTreeBean.clearText}" update=":#{p:component('decisionNotes')}">
</p:commandButton>
<p:ajaxStatus onstart="PF('statusDialog').show()"
onsuccess="PF('statusDialog').hide()" />
<p:dialog widgetVar="statusDialog" modal="true" draggable="false"
closable="false" resizable="false" showHeader="false">
<p:graphicImage value="/images/ajax-loader.gif" />
</p:dialog>
</h:form>
In my bean, I have a clear method which clears the content of the textarea. I want this button to undo the selections as well as part of the ajax call.
public void clearText() {
this.decisionNotes=" ";
}
(for brevity I have included just 2 columns here in xhtml. There are in total 5 separate selection columns with same functionality)
I would simply reset the values of the Menu/Box in the bean method too:
public void clearText() {
this.decisionNotes=" ";
this.option1 = null;
//and so on...
}
Then you just need to update the components in the update attribute of your button. But I'd update the whole form instead of each component if you want to refresh nearly each component in the form. So just use update="#form":
Note: The default process value of p:commandButton is #form. So your clear button will process the whole form on every click altough it doesn't need to. I'd set it to process="#this", so it will just perform it's action.

How to align images horizontally with JSF

I'm sure this a duplicate but what I found here and elsewhere on the net just didn't work for me.
Whatever I do, the images in the following code are aligned vertically, but I want them horizontally.
<script>
var aa = "src='images/img?r=' + Math.random()"
var bb = "src='images/trans?x=' + Math.random()"
</script>
<hr />
<h:panelGroup layout="horizontal">
<h:form>
<h:commandLink>
<h:graphicImage width="100" id="img1"
value="images/img?r=1#{Math.random()}" alt="not found">
</h:graphicImage>
<f:ajax render="#this :pg2"></f:ajax>
</h:commandLink>
</h:form>
<h:form id="pg2">
<h:graphicImage width="100" id="img2"
value="images/trans?y=#{Math.random()}" onclick="eval(bb)">
</h:graphicImage>
</h:form>
</h:panelGroup>
<h:messages></h:messages>
<hr />
(And don't get confused about that #{Math.random()}. It works just because I have a bean called "Math".)
I'm using tomcat 8 and jsf version 2.2.8.
Can you try this
<h:panelGrid columns="2" width="210px" columnClasses="small, small">
<h:panelGroup id="a1">
<h:form>
<h:commandLink>
<h:graphicImage width="100" id="img1"
value="images/img?r=1#{Math.random()}" alt="not found">
</h:graphicImage>
<f:ajax render="#this :pg2"></f:ajax>
</h:commandLink>
</h:form>
</h:panelGroup>
<h:panelGroup id="b1">
<h:form id="pg2">
<h:graphicImage width="100" id="img2"
value="images/trans?y=#{Math.random()}" onclick="eval(bb)">
</h:graphicImage>
</h:form>
</h:panelGroup>
</h:panelGrid>
with CSS:
.small{
width:102px;
vertical-align: text-top;
}
Let us know
Edit. changed div to panelGroup
try to add display: inline-block style to the second form
as you see in here the images need to be inside divs which contain this css

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 get the selected image from <p:galleria

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}"/>

Delete picture in a carousel + update

I'v a Carousel with the possiblity to update pictures (stored in db) and to view them in a bigger size. That works fine. But now, i would like to remove them. And that works almost. Almost means, the picture is deleted but the carousel is not correctly refreshed. Here is my code:
<p:tab title="#{vms_uimsgs['vehicle.tab.images']}">
<h:form id="pictures" enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{vmsVehicleActionBean.handleFileUpload}" mode="advanced" update="vehiclePictureCarousel" sizeLimit="10000000" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
<p:carousel id="vehiclePictureCarousel" var="imageId" value="#{vmsVehicleActionBean.imageIds}" itemStyleClass="vehiclePictureItem" effect="fade">
<f:facet name="header" value="#{vms_uimsgs['vehicle.tab.images']}"/>
<p:panelGrid columns="1" style="width:100%" cellpadding="5">
<p:graphicImage value="#{graphicImageStore.streamedImageById}" rendered="#{graphicImageStore.hasImage(imageId)}">
<f:param name="id" id="id" value="#{imageId}" />
</p:graphicImage>
<p:commandLink id="deleteImage" update="vehiclePictureCarousel" oncomplete="#{vmsVehicleActionBean.deleteImage()}" title="Delete Picture">
<h:outputText styleClass="ui-icon ui-icon-close" style="margin:0 auto;" />
<f:setPropertyActionListener value="#{imageId}" target="#{vmsVehicleActionBean.selectedImageId}" />
</p:commandLink>
</p:panelGrid>
</p:carousel>
</h:form>
</p:tab>
Or asked differently, why is my carousel correctly refreshed when i add a picture with my file uploader and not when i remove one with a commandlink inside the carousel?
Of course, when a reload the whole page, everything is correct. But I don't want that.
The problem come from oncomplete="#{vmsVehicleActionBean.deleteImage()}", oncomplete is an attribute to call javascript method when ajax have completed, so you should use:
facelet:
actionListener="#{vmsVehicleActionBean.deleteImage(imageId)}"
bean:
public void deleteImage(String imageId){
//delete here
}

Resources