I have a Struts 2 application where I'm creating a function Export to Excel. I am using a button that is not inside a s:form tag
<button class="action-button" id = "exportToExcel" style="float: right;height: 2em;padding: 0 1em; margin-right: 2%;" onClick="exportTableToExcel()">Export to Excel</button>
In the exportTableToExcel() i'm making an ajax call to send html table(pivot report data) to be sent as json data.
In my ajax call the url is specified as :
url: './pivotSaveToExcelAction/createExcelReport.action'
The struts.xml entry is as follows:
<package name="pivotSaveToExcelAction" namespace="/pivotSaveToExcelAction" extends="json-default">
<action name="createExcelReport" class="....PivotSaveToExcelAction">
<result type="json"/>
</action>
</package>
Can anyone tell me where i'm going wrong?
I get the error:
There's no action mapped for namespace /reports/pivotTable/pivotSaveToExcelAction and action name createExcelReport.
Related
since fileLimit doesn't exist in primefaces 3.4 anymore I'm trying a work around implementing a validator, the problem is that the method validate is never invoked. That's my Validator:
#FacesValidator(value ="fileLimitValidator")
public class FileLimitValidator implements Validator {
#Override
public void validate(final FacesContext context, final UIComponent component,
final Object value) throws ValidatorException {
final String fileLimit = (String)component.getAttributes().get("fileLimit");
final String size = (String)component.getAttributes().get("size");
if (fileLimit!=null && size!=null) {
if (Integer.valueOf(size) >= Integer.valueOf(fileLimit)) {
FacesUtils.throwErrorExceptionFromComponent(component,"fichero_confidencialidad_error");
}
}
}
}
and in my facelet I've tried:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" >
<f:validator validatorId="fileLimitValidator"/>
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
and:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="fileLimitValidator">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
and:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
and:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator.validate}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
but the validate method is never called. What is the correct way to do it?
According to the FileUpload and FileUploadRenderer source code, the validator is only invoked when mode="simple" is been used (note: this in turn requires ajax="false" on command). The advanced mode will namely not set the uploaded file as component's submitted value, causing it to remain null until the listener method is invoked. As long as the submitted value is null, the validators are not invoked.
I'm not sure if this is intentional. Theoretically, it should be possible to set UploadedFile as submitted value and have the validator to rely on it. You might want to create an enhancement report at PrimeFaces issue tracker.
In the meanwhile, in spite of it being a poor practice, your best bet is really performing the validation in fileUploadListener method. You can just trigger validation failure add faces messages through the FacesContext like follows:
if (fail) {
context.validationFailed();
context.addMessage(event.getComponent().getClientId(context), new FacesMessage(
FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
}
Otherwise, you'd need to create a custom renderer for the <p:fileUpload> which sets the submitted value during the decode() (I however don't guarantee that it would work in practice, you'll maybe stumble upon a peculiar problem which may turn out to be the reason why PrimeFaces didn't initially implement it like that).
By the way, your first and second validator attempt are correct. The third attempt works only if you used #ManagedBean instead of #FacesValidator (which is often done when injection of an #EJB is mandatory — which isn't possible in a #FacesValidator). The fourth attempt is invalid.
For validating a required primefaces file upload in mode advanced (ajax) it is possible to use this:
<f:metadata>
<f:event listener="#{bean.processValidations()}" type="postValidate" />
</f:metadata>
Where the implementation of the bean.processValidations() method would be something along the lines of:
public void processValidations() {
FacesContext context = FacesContext.getCurrentInstance();
UIInput fileUploadComponent = fileUploadsBean.getFileUploadComponent();
if (fileUploadComponent!=null && !isFileUploaded()) {
fileUploadComponent.setValid(false);
context.addMessage(fileUploadComponent.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
context.validationFailed();
}
}
Where fileUploadsBean would be a REQUEST scoped CDI bean (won't work with standard JSF ManagedBeans) which you inject to your bean which has the processValidations() method defined, the method fileUploadsBean.getFileUploadComponent() returns the primefaces file upload component (you will use <p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...> for that). The method isFileUploaded() will determine if the file has been uploaded or not (probably just a null check on a member variable which you fill from fileUploadListener).
If you want to highlight the file upload button you can of course conditionally add a styleClass which you can then use for adding a red border for example.
styleClass="#{fileUploadsBean.fileUploadComponent.valid ? '' : 'validationFailed'}"
As a result the validation failed message for the primefaces file upload will be displayed along with all other jsf validation messages. You might have problem with maintaining order of the validation messages (will be always at the end), but it still beats displaying the failed upload file validation after user dealt with all the standard jsf validation messages from different fields and your action in a backing bean has been finally reached.
I have some problem to pass a entire bean in a dialog.
I would like to open a dialog with Dialog Framework in Primefaces, and pass the method and attributes content in bean.
I tried to make this code, but it don't work.How should I do?
<p:commandButton value="open dialog" ajax="true"
actionListener="#{processController.openSelectFieldDialog}"
update="tableResult , :notificationForm:info-messages">
<f:attribute name="controller" value="#{processController}" />
</p:commandButton>
This is the code inside openSelectFieldDialog method:
public void openSelectFieldDialog(){
RequestContext.getCurrentInstance().openDialog("genericSelectFieldDialog");
}
And this is the code inside the dialog controller:
public void onload() {
Object somethingBean= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("controller");
}
I understand that i pass parameters on openDialog method, but i don't find any example on primefaces site. Can you help me?
Thanks
Currently, i'm working on an AJAX-Controller for my finished Extension.
AjaxController.php - Controller
Lager.php - Extension itself - has HTML outputs
the extension Lager.php runs only on the product view page, styled via catalog.xml in base/default/layouts and shows up under the pricebox.
So. The AjaxRequest, which is sent up by another extension which doesn't matters, works fine like the AjaxController too. But there's a problem. In AjaxController.php i've got a command to execute a function in Lager.php. It does, and with firebug i'm able to see, that he got the right response (the HTML output) too, but i think the layout is false. .. The new Html doesn't show up anywhere on the product view.
AjaxController.php (works fine but no HTML output, or no styling.. cause in html output in firebug theres no included css anymore):
<?php
require_once "Mage/Catalog/controllers/ProductController.php";
class Lager_Lager_AjaxController extends Mage_Catalog_ProductController
{
public function indexAction()
{
$this->loadLayout();
$this->renderLayout();
}
public function refreshAction()
{
$selected = $this->getRequest()->getParam('selected');
if($selected == 'true')
{
$productId = $this->getRequest()->getParam('productid');
if($productId)
{
$block = $this->getLayout()->getBlockSingleton('lager/lager')->runLager($productId); //does html output
}
}
else
{
}
}
}
?>
The config.xml part of the ajax implementation:
<frontend>
<routers>
<lager>
<use>standard</use>
<args>
<module>Lager_Lager</module>
<frontName>lager</frontName>
</args>
</lager>
</routers>
</frontend>
the catalog.xml part of the extension implementation:
<block type="catalog/product_view" name="product.info" template="catalog/product/view.phtml">
<!--
<action method="addReviewSummaryTemplate"><type>default</type><template>review/helper/summary.phtml</template></action>
<action method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary_short.phtml</template></action>
<action method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
BEGIN LAGER IMPLEMENTATION -->
<block type="lager/lager" name="lager" template="lager/lager.phtml" /> <!-- Lager Einbindung -->
<lager_ajax_refresh>
<block type="lager/lager" name="lager" output="toHtml" template="lager/lager.phtml" />
</lager_ajax_refresh>
<!-- END -->
<block type="catalog/product_view_media" name="product.info.media" as="media" template="catalog/product/view/media.phtml"/>
<block type="core/text_list" name="alert.urls" as="alert_urls" translate="label">
<label>Alert Urls</label>
</block>
<action method="setTierPriceTemplate"><template>catalog/product/view/tierprices.phtml</template></action>
So the Ajax Controller doesn't use the layout configuration of the extension which is implemented in catalog.xml ..
http://www.directupload.net/file/d/3601/h94loqef_png.htm
I want to get the value of the input Textarea and show it in the same page by clicking on the command button "compiler "
however i don't get any result ! and the contnet is only shown when I update with the browser updater
Sh How do I upate the page and the managed beans to show the content of a primefaces textarea in the same page
this is the code:
<p:layoutUnit position="west" size="520" header="Code à executer" resizable="true" >
<h:form id="moncode">
<p:inputTextarea id="mycode" value="#{fichier.code}" rows="17" cols="50" />
<p:commandButton value="compiler" id="btn3" action="guest.xhtml" styleClass="myButtonClass" />
</h:form>
</p:layoutUnit>
<p:layoutUnit position="east" size="550" header="Resultat d'execution" resizable="true" >
<h:outputText value="#{fichier.code}" />
</p:layoutUnit>
<p:layoutUnit position="south" >
my application is about compiling a given code: I write a code and then I executed with the button "compiler" so a file will be created however the file is always created with "null" and I think because the var "code" is not yet set in the managed bean that why I want to update the page so the managed bean ill be set here is compile:
`
private String code;
private String error;
public String getCode() {
return code;
}
public String getError() {
return error;
}
public void setCode(String code) {
this.code = code;
}
public void compile() throws IOException {
File file = new File("C:\\Users\\Rad1\\test.c");
PrintWriter ecrivain;
ecrivain = new PrintWriter(new BufferedWriter (new FileWriter(file)));
ecrivain.println(code);
ecrivain.close();
`
There are two ways to achieve what you want: either by using a synchronous submit of a form with a subsequesnt postback, or by sending an AJAX request to partially update necessary parts of the page.
Synchronous submit
<p:inputTextarea id="mycode" value="#{fichier.code}" rows="17" cols="50" />
<p:commandButton value="compiler" id="btn3" action="#{fichier.action}" styleClass="myButtonClass" ajax="false" />
<h:outputText id="upd" value="#{fichier.code}" />
with action method
public String action() {
//do business job
return null;
}
This way a fields will be refreshed by making a postback. Don't forget that the bean Fichier must be view scoped. Note the ajax="false" attribute of <p:commandButton>.
AJAX call
<p:inputTextarea id="mycode" value="#{fichier.code}" rows="17" cols="50" />
<p:commandButton value="compiler" id="btn3" action="#{fichier.action}" styleClass="myButtonClass" update="upd" />
<h:outputText id="upd" value="#{fichier.code}" />
with the same action method
public String action() {
//do business job
return null;
}
This way only the contents of <h:outputText> will be updated after AJAX call is finished. Don't forget that the bean Fichier should also be view scoped. Note that id attribute of <h:outputText> must be specified.
Actually, you don't call the action itself. Your action forwards to a certain page. There is no race condition or syncronization problems in a JSF action betwwen setting the properties and the action itself. I recommend you to read JSF life cycles tutorial by BalusC Aplly request values phase run before the action.
Try to call action on command Button.
<p:commandButton value="compiler" id="btn3" action="#{fichier.compile}" update="outputCode" styleClass="myButtonClass" />
Add an id attribute to your output panel and specify it in the action button.
<p:layoutUnit id="outputCode" position="east" size="550" header="Resultat d'execution" resizable="true" >
<h:outputText value="#{fichier.code}" />
</p:layoutUnit>
P.S. It is also good to read this BalusC answer for better understanding of actions, Ajax/non Ajax request etc.
I am using PrimeFaces 2.2. I am using p:fileuplaod, when fileUploads then using update i change the image on my page. Here it is.
<p:fileUpload id="countryFlag" widgetVar="uploader" description="Image"
update="Flag" allowTypes="*.jpg;*.png;*.gif;*.jpeg;" auto="true"
fileUploadListener="#{countryPages_Detail.imageUpload}">
<p:ajax oncomplete="test('Flag')" />
</p:fileUpload>
<p:graphicImage id="Flag" value="#{countryPages_Detail.imagePath}"
width="80" height="50" cache="false">
<f:event type="preRenderComponent" listener="#{countryPages_Detail.putImage}" />
</p:graphicImage>
What i want to do using script is that when upload completes, and using ajax when the image has been changed, then i want to check the image src attribute. Here is my test() function, it is not complete, but here it is
function test(imageId) {
var imgId = imageId;
var image = $("#saarcImagesTable tr").find("img[id='imageId']")
alert("Image change");
}
But I am getting error that
Parent not an instance of ClientBehaviorHolder: org.primefaces.component.fileupload.FileUpload#e39f71
Why am I am getting this error? What am I doing wrong?
Thanks
The p:fileUpload component does not implement the ClientBehaviorHolder interface as the message states and therefore is no component that can contain the ajax tag (see this post).
I am not familiar with the fileUpload component, but I've seen in the documentation of PF 3.2 that the p:fileUpload has an oncomplete attribute.