2010-11-29 3 views
3

J'ai actuellement 2 boutons de commande et une liste. Basé sur la sélection de la liste, le résultat généré peut être affiché dans un fichier téléchargeable ou rendu sous forme de tableau HTML. Le code getFile() est basé sur BalusC's PDF Handling tutorial, alors que getTable() définit resultTable.h: actions commandButton multiples: télécharger le fichier et rendre le tableau ajax

<h:form> 
<fieldset> 
    <h:selectManyListbox id="listbox" value="#{form.items}"> 
     <f:selectItems value="#{form.allItems}"> 
    </h:selectManyListbox> 
</fieldset> 
<h:commandButton value="Get File" action="#{form.getFile}"> 
<h:commandButton value="Get Table" action="#{form.getTable}"> 
    <f:ajax render="result_table" execute="listbox" /> 
</h:commandButton> 
<h:panelGrid id="result_table"> 
    <table> 
     <thead></thead> 
     <tbody> 
      <ui:repeat var="table" value="#{form.resultTable}"> 
      </ui:repeat> 
     </tbody> 
    </table> 
</h:panelGrid> 

Les deux boutons fonctionnent correctement jusqu'à présent. Cependant, je veux combiner les deux actions en un seul bouton. Quand je le teste avec un bouton qui déclenche les deux actions, rien ne se passe (pas de sauvegarde de fichier comme boîte de dialogue ou rendu). Est-ce parce qu'une action est ajax ou parce que l'autre action se termine par facesContext.responseComplete();?

<h:commandButton value="Get Both" action="#{form.getBoth}"> 
    <f:ajax render="result_table" execute="listbox" /> 
</h:commandButton> 

getBoth() { 
    getTable(); 
    getFile(); 
} 

De plus, je voudrais une case à cocher où si elle est cochée, enregistrer en tant que boîte de dialogue apparaît et la table est rendue. Si elle n'est pas cochée, seule la table est rendue.

Répondre

1

Malheureusement, ce n'est pas possible avec HTTP. Vous ne pouvez envoyer qu'une seule réponse par demande. Vous ne pouvez pas fusionner la réponse contenant le fichier PDF et la réponse ajax en une seule réponse. Comme il s'agit d'une restriction HTTP, JSF ne peut pas faire grand-chose pour vous. En outre, le téléchargement d'un fichier en utilisant Ajax n'est pas du tout possible car JavaScript ne peut pas forcer le navigateur à ouvrir une boîte de dialogue ni à accéder au système de fichiers du disque local en raison des restrictions de sécurité.

Une solution serait de tirer deux requêtes HTTP sur un seul clic où la deuxième demande retourne Content-Disposition: attachment de sorte que la réponse de l'autre demande conserve intacte. Vous pouvez y parvenir en ajoutant un onclick au bouton de commande.

<h:commandButton onclick="window.location='/context/pdfservlet/filename.pdf'"> 

et créer un servlet PDF qui ressemblent à peu près comme this FileServlet example. Comme vous le voyez, il n'est pas possible d'invoquer une action JSF par ceci. Vous devez refactoriser la méthode de téléchargement PDF à une classe HttpServlet qui fait le travail dans la méthode doGet(). Pour toute communication nécessaire entre le bean géré par JSF et la servlet, vous pouvez utiliser la portée de session ou transmettre les informations souhaitées (uniquement l'identificateur de fichier PDF?) Par chemin d'accès ou par paramètre.

+0

Merci pour l'explication. Je vais continuer à utiliser les deux boutons. – luciaengel

+0

Il y a vraiment un moyen. Voir mise à jour. – BalusC

+0

J'ai déjà la Content-Disposition en pièce jointe, mais au lieu d'un fichier en entrée 'input = new BufferedInputStream (nouveau FileInputStream (fichier), DEFAULT_BUFFER_SIZE);' , j'ai un autre inputStream 'new BufferedInputStream (nouveau ByteArrayInputStream (output_b. toByteArray()), DEFAULT_BUFFER_SIZE); 'parce que le fichier est créé à la volée dans' output_b' sans enregistrer au serveur. Donc je ne pense pas que je serais capable d'utiliser ça surclic. – luciaengel

0

Je passe pour un cas similaire, dans mon cas, je suis résolu en utilisant ajax richfaces tag lib et surround commandbonnette avec une balise de forme ajax.

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
xmlns:rich="http://richfaces.org/rich" 
xmlns:a4j="http://richfaces.org/a4j"> 

<a4j:form id="formDownloads"> 
<rich:panel> 
      <h:commandButton value="Exportar para PDF" status= "block" ... /> 
</rich:panel> 
</a4j:form>