2011-10-21 11 views
5

Nel codice seguente l'azione commandButton di jsf html viene chiamata perfettamente. Ma l'azione commandButton di primefaces non viene chiamata.PrimoFaces CommandButton Azione non chiamata all'interno di Composite

<ui:component   
       xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:h="http://java.sun.com/jsf/html" 
      xmlns:ui="http://java.sun.com/jsf/facelets" 
      xmlns:p="http://primefaces.prime.com.tr/ui" 
    xmlns:composite="http://java.sun.com/jsf/composite"> 

    <composite:interface> 
     <composite:attribute 
      name="managedBean"   
      type="java.lang.Object" 
      required="true">      
     </composite:attribute> 
    </composite:interface> 

    <composite:implementation> 
     <f:view contentType="text/html"> 
      <h:form id="componentes"> 
       <h:panelGrid columns="3"> 
        <h:panelGroup>    
         <h:outputText 
           escape = "false" 
           value = "#{cc.attrs.managedBean['value']}"  
          rendered = "#{!cc.attrs.managedBean['editing']}"/> 
         <p:editor 
          widgetVar = "editor" 
           value = "#{cc.attrs.managedBean.value}" 
          rendered = "#{cc.attrs.managedBean.editing}"/> 
        </h:panelGroup> 
        <!-- ACTION IS CALLED -->         
        <h:commandButton 
           action = "#{cc.attrs.managedBean.toogleEditing}" 
           value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
           update = "componentes"/> 

            <!-- ACTION IS NOT CALLED -->   
        <p:commandButton 
           action = "#{cc.attrs.managedBean.toogleEditing}" 
           value = "#{cc.attrs.managedBean.editing?'Back':'Edit'}" 
           update = "componentes"/> 
       </h:panelGrid> 
      </h:form>      
     </f:view> 
    </composite:implementation> 
</ui:component> 

Se posto lo stesso codice è al di fuori di un composito (una normale pagina XHTML), entrambi funzionano bene:

<!DOCTYPE html 
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html 
    xml:lang="pt" 
     lang="pt" 
     xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:p="http://primefaces.prime.com.tr/ui"> 

    <h:head id="head"> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
     <title>Item de Texto</title> 
    </h:head> 
    <h:body id="body">   
     <f:view contentType="text/html"> 
      <h:form id="componentes"> 
       <h:panelGrid columns="3"> 
        <h:panelGroup>    
         <h:outputText 
           escape = "false" 
           value = "#{editableHTMLText.value}" 
          rendered = "#{!editableHTMLText.editing}"/> 
         <p:editor 
          widgetVar = "editor" 
           value = "#{editableHTMLText.value}" 
          rendered = "#{editableHTMLText.editing}"/> 
        </h:panelGroup> 

            <!-- ACTION IS CALLED -->       
        <h:commandButton 
           action = "#{editableHTMLText.toogleEditing}" 
           value = "#{editableHTMLText.editing?'Back':'Edit'}" 
           update = "componentes"/> 

            <!-- ACTION IS CALLED --> 
        <p:commandButton 
           action = "#{editableHTMLText.toogleEditing}" 
           value = "#{editableHTMLText.editing?'Back':'Edit'}" 
           update = "componentes"/> 
       </h:panelGrid> 
      </h:form>      
     </f:view> 
    </h:body> 
</html> 

Questo è il codice di fagioli:

import java.io.Serializable; 

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.SessionScoped; 


@ManagedBean 
@SessionScoped 
public class EditableHTMLText implements Serializable{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 8439126615761864409L; 

    private String    value    = "Test<br>of<br>HTML<br>text<br><b>ITEM</b><br>"; 
    private boolean    editing    = false; 


    public void toogleEditing(){ 

     this.setEditing(!this.isEditing()); 
     System.out.println("Editing State: " + this.editing); 
    } 


    public String getValue(){ 

     return value; 
    } 


    public void setValue(String value){ 

     this.value = value; 
    } 


    public boolean isEditing(){ 

     return editing; 
    } 


    public void setEditing(boolean editing){ 

     this.editing = editing; 
    } 

} 

Qualche suggerimento?

risposta

5

Quando si è utilizzato il componente composito, era già inserito in un tag h: form? Quando si hanno moduli annidati, l'azione del pulsante di comando non viene attivata.

Un altro problema possono essere le parti ajax che si sta tentando. Il pulsante Primefaces ha l'attributo update, ma quello standard JSF non ha questo. Farà sempre un aggiornamento completo della pagina (tranne quando nidificato in o f: tag ajax è utilizzato al suo interno)

0

Si può provare ad inserire ajax = attributo "falso" in p: commandButton.

0

Ho anche riscontrato questo problema e testato i tuoi codici, sembra che primefaces non sia in grado di avvisare gli errori di convalida nello stesso "xhtml" ma in altri panelGrid, potresti aver bisogno di un pannello padre Grid per incapsulare correttamente tutte le griglie del tuo form .

Se si riempie completamente l'intero modulo, si noterà che viene chiamata l'azione commandButton Primefaces, altrimenti "digerirà" silenziosamente gli errori di convalida che si possono avere.

1

Avevo anche problemi con i commandButton non attivanti. Nel mio caso, le reqeuests ajax e non-ajax non hanno funzionato. 1. come descritto sopra, accertarsi di cancellare tutti i moduli presenti nel modulo. facile da fare con l'uso composito. 2. se si dispone di più pulsanti, provare a utilizzare il flag "processo". Aiutato nel mio caso.

<p:commandButton id="submitButton" value="Submit" type="submit" 
    actionListener="#{bean.save}" 
    update="message" 
    process="txtComment, @this" 
    icon="ui-icon-disk"/> 

process="txtComment, @this" esegue il metodo setter di inputText con id txtComment e il metodo commandButton.

10

Oggi ho raggiunto lo stesso identico problema con PrimeFaces 5.1. Nel mio caso non avevo moduli nidificati e stavo già impostando l'attributo process su p:commandButton con gli elementi del modulo che volevo elaborare. Tuttavia questo non ha funzionato ancora.

La "soluzione" è stato quello di aggiungere @this alla lista dei componenti per elaborare, in questo modo:

<p:commandButton process="myFormField1 myFormField2 @this">

Senza @this (che non è di solito necessario, dal momento che il pulsante di per sé non dovrebbe aver bisogno di essere elaborato/convalidato) ho trovato alcun modo per fare qualsiasi di essi per funzionare all'interno di un composito:

  • <p:commandButton action="#{bean.myAction}"...>
  • <p:commandButton type="button"> con nidificata <p:ajax event="click" action="#{bean.myAction}"...>
  • <p:commandButton type="button" onclick="myAction()"> con associati <p:remoteCommand name="myAction" action="#{bean.myAction}">

Con debug dell'applicazione, ho visto che la convalida e aggiornare le fasi di modello sono stati eseguiti correttamente, ma poi nella fase di applicazione invoke nessun evento accodato era presente e quindi non l'azione è stata eseguita In realtà, ho potuto specificare qualsiasi cosa mi piacesse all'interno dei valori degli attributi action e actionListener di <p:commandButton> senza che PrimeFaces o JSF si lamentassero in alcun modo.

Questi, invece, non funzionano come dovrebbero, ma non si dispone di trasformazione parziale in atto, in modo che non può essere una soluzione praticabile:

  • <p:commandButton action="#{bean.myAction}" ajax="false"...>
  • <p:commandButton type="button"...> con nidificato <f:ajax event="click" action="#{bean.myAction}"...>

Deve essere un bug PrimeFaces.

+0

pulsante non viene licenziato, se non viene elaborato. ha senso. – erencan

+1

Non lo fa, poiché l'attributo "processo" indica quali * altri * campi devono essere elaborati/inviati. L'impostazione "@questo" nell'attributo di processo non è richiesta per i pulsanti all'esterno di un composito. E, se lo fosse, sarebbe almeno "ridondante". –

+0

Vorrei poterlo sospendere più di una volta. Questa è la risposta giusta, o dovrei dire @questo. Anche nel 2018 con le primeface 6. Non ho mai avuto problemi con p: l'attivazione di CommandButton fino a quando ne ho inserito uno in un composito. –

0

Per aggiungere alle risposte di cui sopra, per completezza.

Uno degli aspetti che non rientrano nelle risposte di cui sopra è il Targets attributo mancante nella composite:interface

Dalla documentazione di JSF attribuiscono

obiettivi: Se questo elemento ha un metodo di firma attributo, il valore dell'attributo target deve essere interpretato come elenco separato di ID client (non tabulazione) (relativo al componente di livello superiore ) dei componenti all'interno dello < composito: implementazione > sezione. Lo spazio viene utilizzato come delimitatore per la compatibilità con i tipi di dati IDREFS e NMTOKENS dallo schema XML. Ogni voce nell'elenco deve essere interpretata come l'id di un componente interno a cui deve essere applicato il MethodExpression dal tag componente composito nella pagina di utilizzo. Se questo elemento ha un attributo firma del metodo, ma nessun attributo target, il valore dell'attributo name viene utilizzato come singola voce nell'elenco . Se il valore dell'attributo name non è uno dei valori speciali elencati nella descrizione dell'attributo name, gli obiettivi (o il valore derivato) non devono corrispondere all'ID di un componente interno .

<cc:interface> 
    <cc:attribute name="value" /> 
    <cc:attribute name="action" targets="buttonId" /> 
    <cc:attribute name="actionListener" targets="buttonId" /> 
</cc:interface> 
<cc:implementation> 
    <p:commandButton id="buttonId" value="#{cc.attrs.value}" /> 
</cc:implementation> 

@source: https://stackoverflow.com/a/19680483/1850844

Problemi correlati