2013-06-30 5 views
2

Я переношу сайт JSP/Servlets в JSF, и мне трудно реализовать некоторые из наиболее интересных возможностей JSF. Текущая проблема, которую я попытался разрешить в течение нескольких дней, заключается в удалении одной или нескольких строк из <p:dataTable>. Следующий фрагмент кода определяет таблицу:JSF/Primefaces Action Listener не вызывается из p: commandButton

<ui:composition template="/templates/RescueDBAdminTemplate.xhtml" ... > 
<ui:define name="body"> 
    <div id="mainContent"> 
     <h1> Pet Information Edit </h1> 

     <p> 
      This page allows the detailed information for an animal to be inserted or edited. 
     </p> 
     <br /> 

     <!-- 
     ~~~~ The first row contains the AIF number, and two optional hyperlinks to the History and Cage Card 
     ~~~~ pages. Since we have at most three entries, and a layout of 4 columns, we will need a sub-table 
     ~~~~ to evenly space out these objects. 
     ~~~~ --> 
     <table class="w100pct"> 
      <tr> 
       <!-- 
       ~~~~ Display the AIF_NO for the animal at the top of the page. For Reference Only. 
       ~~~~ --> 
       <td class="label" align="left" > 
       AIF Number: #{animals.aifNo} 
       </td> 

       <td align="center"> <a href="/${context}/Protected/AifServlet?COMMAND=HISTORY&amp;AIF_NO=${aifBean.aifNo}" target="window"> Display History </a> </td> 
       <td align="right"> <a href="/${context}/Protected/AifServlet?COMMAND=CARD&amp;AIF_NO=${aifBean.aifNo}" target="window"> Display Cage Card </a> </td> 
      </tr> 
     </table> 

     <p:accordionPanel id="profile" multiple="true" activeIndex="0,1,2,3,4,5,6,7"> 
      <p:tab title="Cage Card Information"> 
       <h:form id="cageCardForm"> 
        <p:panelGrid styleClass="rdbGrid w100pct"> 
         <p:row> 
          <p:column styleClass="block"> Child Friendly: </p:column> 
          <p:column> 
           <p:selectOneMenu id="childFriendly" value="#{animals.isChildFriendly}"> 
            <f:selectItem itemValue="Y" itemLabel="Yes"  /> 
            <f:selectItem itemValue="N" itemLabel="No"  /> 
            <f:selectItem itemValue="U" itemLabel="Unknown" /> 
            <f:selectItem itemValue="O" itemLabel="Older Children Only" /> 
           </p:selectOneMenu> 
          </p:column> 
          <p:column styleClass="block"> Dog Friendly: </p:column> 
          <p:column> 
           <p:selectOneMenu id="dogFriendly" value="#{animals.isDogFriendly}"> 
            <f:selectItem itemValue="Y" itemLabel="Yes"  /> 
            <f:selectItem itemValue="N" itemLabel="No"  /> 
            <f:selectItem itemValue="U" itemLabel="Unknown" /> 
            <f:selectItem itemValue="T" itemLabel="Tolerates" /> 
            <f:selectItem itemValue="S" itemLabel="Some"  /> 
           </p:selectOneMenu> 
          </p:column> 
         </p:row> 
         <p:row> 
          <p:column styleClass="block"> Cat Friendly: </p:column> 
          <p:column> 
           <p:selectOneMenu id="catFriendly" value="#{animals.isCatFriendly}"> 
            <f:selectItem itemValue="Y" itemLabel="Yes"  /> 
            <f:selectItem itemValue="N" itemLabel="No"  /> 
            <f:selectItem itemValue="U" itemLabel="Unknown" /> 
            <f:selectItem itemValue="T" itemLabel="Tolerates" /> 
            <f:selectItem itemValue="S" itemLabel="Some"  /> 
           </p:selectOneMenu> 
          </p:column> 
          <p:column styleClass="block"> Housebroken: </p:column> 
          <p:column> 
           <p:selectOneMenu id="housebroken" value="#{animals.isHousebroken}"> 
            <f:selectItem itemValue="Y" itemLabel="Yes"  /> 
            <f:selectItem itemValue="N" itemLabel="No"  /> 
            <f:selectItem itemValue="U" itemLabel="Unknown" /> 
           </p:selectOneMenu> 
          </p:column> 
         </p:row> 

         <p:row> 
          <p:column styleClass="block" style="text-align:top;"> Cage Card Comments: </p:column> 
          <p:column> <p:inputTextarea name="previousOwner" rows="11" cols="40" value="#{animals.cageCardComment}" /> </p:column> 
          <p:column styleClass="block" style="text-align:top;"> Lifestyle Needs: </p:column> 
          <p:column> <p:inputTextarea name="reasonObtained" rows="11" cols="40" value="#{animals.lifestyleNeeds}" /> </p:column> 
         </p:row> 
        </p:panelGrid> 
       </h:form> 
      </p:tab> 
      <p:tab title="Fees and Expenditures"> 
       <h:form id="feesForm"> 
        <p:panelGrid styleClass="rdbGrid w100pct"> 
         <p:row> 
          <p:column styleClass="block"> Adoption Fee: </p:column> 
         <p:column> 
          <p:inputText size="16" value="#{animals.adoptionFee}" maxlength="64" /> 
         </p:column> 
         <p:column styleClass="block"> Normal Costs: </p:column> 
         <p:column> 
          <p:inputText size="16" value="#{animals.costRegular}" maxlength="64" /> 
         </p:column> 
        </p:row> 
        <p:row> 
         <p:column styleClass="block"> Extra Costs: </p:column> 
         <p:column> 
          <p:inputText size="16" value="${aifBean.costNonRegular}" maxlength="64" /> 
         </p:column> 
         <p:column styleClass="block"> Extra Cost Description </p:column> 
         <p:column> 
          <p:inputTextarea rows="4" cols="40" value="#{animals.nonRegularDesc}" /> 
         </p:column> 
        </p:row> 
        <p:row> 
         <p:column styleClass="block"> Comments </p:column> 
          <p:column colspan="3"> 
           <p:inputTextarea rows="2" cols="80" value="#{animals.comments}" /> 
         </p:column> 
        </p:row> 
        </p:panelGrid> 
       </h:form> 
      </p:tab> 
      <p:tab title="Medical History"> 
       <p:dataTable styleClass="w100pct" var="current" value="#{medical.getMedHistoryByAifNo(param.AIF_NO)}"> 
        <p:column headerText="Delete"> 
         Delete 
        </p:column> 

        <p:column headerText="Procedure Name"> 
         #{current.shortName} 
        </p:column> 

        <p:column headerText="Date"> 
         #{current.treatmentDate} 
        </p:column> 

        <p:column headerText="Vet Information"> 
         #{current.vetName} #{current.vetClinic} 
        </p:column> 

        <p:column headerText="Comments"> 
         #{current.comments} 
        </p:column> 
       </p:dataTable> 
      </p:tab> 
      <p:tab title="Documents"> 
       <h:form id="docListForm"> 
        <p:dataTable id="docListTable" styleClass="w100pct" var="current" value="#{documents.currentDocList}" 
           paginator="true" rows="10" selection="#{documents.selectedDocs}"> 

         <p:column selectionMode="multiple" style="width:2%" /> 

         <p:column headerText="Date"> 
          <h:outputText value="#{current.treatmentDate}" /> 
         </p:column> 

         <p:column headerText="Document Type"> 
          <h:outputText value="#{current.group}" converter="com.rescuedb.DocGroupName" /> 
         </p:column> 

         <p:column headerText="Description"> 
          #{current.description} 
         </p:column> 

         <f:facet name="footer"> 
          <p:commandButton id="docListDelete" value="Delete Selected Records" 
              icon="ui-icon-search" 
              update=":#{p:component('docListTable')}" 
              actionListener="#{documents.deleteReference}" > 
           <f:param name="docNo" value="#{current.docNo}" /> 
           <f:param name="refNo" value="#{animals.aifNo}" /> 
           <f:param name="group" value="#{current.group}" /> 
          </p:commandButton> 
         </f:facet> 
        </p:dataTable> 
       </h:form> 
      </p:tab> 
     </p:accordionPanel> 

    </div> 
</ui:define> 
</ui:composition> 

управляемый компонент, который поддерживает эту страницу следующим образом (это довольно предварительный код, как я до сих пор экспериментируют с PrimeFaces и JSF):

package com.rescuedb.beans.managed; 

import java.io.Serializable; 
import java.util.List; 
import java.util.Map; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.faces.context.FacesContext; 
import javax.faces.event.ActionEvent; 

import org.apache.log4j.Logger; 

import com.rescuedb.Beans.DocMasterBean; 
import com.rescuedb.Beans.DAO.DocMaster; 
import com.rescuedb.Beans.DAO.DocXref; 
import com.rescuedb.Beans.Models.DocMasterDataModel; 
import com.rescuedb.Core.RescueException; 

@ManagedBean(name="documents") 
@ViewScoped 
public class DocumentManagedBean implements Serializable 
{ 

    static final long serialVersionUID = 5L; 

    static Logger logger = Logger.getLogger(DocumentManagedBean.class); 

    private transient DocMaster    docInfo;   // Document Master accessor object 
    private transient DocXref    xrfInfo;   // Document Master accessor object 

    private String currentAifNo; 
    private String refNo; 
    private String docNo; 

    /** 
    * Contains a list of document records, wrapped in a DataModel, for the currently 
    * active foster animal. 
    */ 
    private DocMasterDataModel currentDocList = null;   

    private DocMasterBean[] selectedDocs; 

    public DocumentManagedBean() 
    { 
     logger.trace ("DocumentManagedBean.constructor"); 
     try { 
      // 
      // Retrieve the URL parameter from the context. 
      // 
      FacesContext  context = FacesContext.getCurrentInstance(); 
      Map<String,String> paramMap = context.getExternalContext().getRequestParameterMap(); 
      String    paramAifNo = paramMap.get("AIF_NO"); 

      if (paramAifNo != null) { 
       if (!paramAifNo.isEmpty()) { 
        currentAifNo = paramAifNo; 
        loadCurrentDocList(); 
       } 
      } 
     } catch (Exception e) { 
      logger.error ("Exception caught in DocumentManagedBean() constructor :: " + e.getMessage(), e); 
     } 
    } 

    /** 
    * Initialize the bean from the database. 
    */ 
    @PostConstruct 
    public void initialize() 
    { 
     logger.trace ("DocumentManagedBean.initialize"); 
     try { 
      docInfo = new DocMaster(); 
      xrfInfo = new DocXref(); 
     } catch (Exception e) { 
      logger.error ("Exception in DocumentsManagedBean.initialize() : " + e.getMessage(), e); 
     } 
    } 

    public List<DocMasterBean> getDocList() 
    { 
     logger.trace ("DocumentManagedBean.getDocList"); 
     return docInfo.getRecordList(); 
    } 

    /** 
    * Retrieve the list of documents that are associated wit a specific foster animal. 
    * <p> 
    * @param aifNo 
    * @return 
    */ 
    public DocMasterDataModel getCurrentDocList() 
    { 
     logger.trace ("DocumentManagedBean.getCurrentDocList"); 
     return currentDocList; 
    } 

    /** 
    * Load the document list for the currently active foster animal. 
    */ 
    private void loadCurrentDocList() 
    { 
     DocMaster docMaster = null; 

     logger.info ("DocumentManagedBean.loadCurrentDocList"); 
     try { 
      docMaster = new DocMaster(); 
      if (currentAifNo != null) { 
       if (!currentAifNo.isEmpty()) { 
        docMaster.queryByRefNo (Integer.parseInt(currentAifNo)); 
        currentDocList = new DocMasterDataModel (docMaster.getRecordList()); 
        logger.info ("DocumentManagedBean.loadCurrentDocList :: currentDocList reloaded, length = " + docMaster.getRecordCount()); 
       } else { 
        logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is empty, no records loaded."); 
       } 
      } else { 
       logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is null, no records loaded."); 
      } 
     } catch (Exception e) { 
      logger.error ("Exception in DocumentsManagedBean.loadCurrentDocList() : " + e.getMessage(), e); 
     } 
    } 

    public void deleteReference(ActionEvent event) 
    { 
     boolean  status;    // Status of the update. 
     int   refNo = 0; 
     int   docNo = 0; 

     logger.info ("DocumentManagedBean.deleteReference"); 
     try { 
      // 
      // Retrieve the parameter of the request. 
      // 
      FacesContext  context = FacesContext.getCurrentInstance(); 
      Map<String,String> paramMap = context.getExternalContext().getRequestParameterMap(); 
      String    paramDocNo = paramMap.get("docNo"); 
      String    paramRefNo = paramMap.get("refNo"); 
      logger.info (String.format("DocumentManagedBean.deleteReference :: paramDocNo = [%s]", paramDocNo)); 
      logger.info (String.format("DocumentManagedBean.deleteReference :: paramRefNo = [%s]", paramRefNo)); 

      // 
      // Retrieve the items necessary to delete the proper records. 
      // The refNo parameter will only be specified when a specific cross-referenced 
      // record is to be deleted. If this value is missing, then the master document 
      // is to be deleted. 
      // 
      if (paramRefNo != null) { 
       try { 
        refNo = Integer.parseInt (paramRefNo); 
        this.refNo = paramRefNo; 
       } catch (NumberFormatException e) { 
        refNo = 0; 
       } 
      } 

      // 
      // The docNo has to be present. If the refNo is zero, then we will delete the 
      // master document. If a refNo is present, then we will delete a cross reference. 
      // 
      if (paramDocNo != null) { 
       try { 
        docNo = Integer.parseInt (paramDocNo); 
        this.docNo = paramDocNo; 
       } catch (NumberFormatException e) { 
        docNo = 0; 
        String message = String.format ("Illegal value for docNo (%d)", docNo); 
        logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message)); 
        throw new RescueException ("DS000091", message, "DocumentsManagedBean", "deleteReference"); 
       } 
      } else { 
       logger.error("DocumentManagedBean.deleteReference :: paramDocNo is null"); 
      } 

      // 
      // Delete the cross reference record. 
      // 
      if (refNo != 0) { 
       xrfInfo = new DocXref(); 
       status = xrfInfo.queryByCrossRef (docNo, refNo); 
       if (status != true) { 
        String message = String.format ("Error querying DOC_xref for refNo = %d, docNo = %d", refNo, docNo); 
        logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message)); 
        throw new RescueException ("DS000092", message, "DocumentsManagedBean", "deleteReference"); 
       } else { 
        status = xrfInfo.delete(); 
        logger.warn("DocumentManagedBean.deleteReference :: Document XRef deleted"); 
        // logger.warn("DocumentManagedBean.deleteReference :: TEST TEST TEST Document XRef not actually deleted"); 
        if (status != true) { 
         String message = String.format ("Error deleting DOC_xref for refNo = %d, docNo = %d", refNo, docNo); 
         logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message)); 
         throw new RescueException ("DS000093", message, "DocumentsManagedBean", "deleteReference"); 
        } else { 
         loadCurrentDocList(); 
         logger.error("DocumentManagedBean.deleteReference :: currentDocList reloaded"); 
        } 
       } 
      } else { 
       logger.error("DocumentManagedBean.deleteReference :: refNo is 0. No Records were deleted."); 
      } 
     } catch (RescueException e) { 
      logger.error ("RescueException in DocumentsManagedBean.deleteReference() :: " + e.getMessage(), e); 
     } catch (Exception e) { 
      logger.error ("Exception in DocumentsManagedBean.deleteReference()", e); 
     } 
    } 

    public DocMaster getDocInfo() 
    { 
     logger.info ("DocumentManagedBean.getDocInfo"); 
     return docInfo; 
    } 

    public void setDocInfo(DocMaster docInfo) 
    { 
     logger.info ("DocumentManagedBean.setDocInfo"); 
     this.docInfo = docInfo; 
    } 

    public String getRefNo() 
    { 
     logger.info ("DocumentManagedBean.getRefNo"); 
     return refNo; 
    } 

    public void setRefNo(String refNo) 
    { 
     logger.info ("DocumentManagedBean.setRefNo"); 
     this.refNo = refNo; 
    } 

    public String getDocNo() 
    { 
     logger.info ("DocumentManagedBean.getDocNo"); 
     return docNo; 
    } 

    public void setDocNo(String docNo) 
    { 
     logger.info ("DocumentManagedBean.setDocNo"); 
     this.docNo = docNo; 
    } 

    public DocMasterBean[] getSelectedDocs() 
    { 
     logger.info ("DocumentManagedBean.getSelectedDocs"); 
     return selectedDocs; 
    } 

    public void setSelectedDocs(DocMasterBean[] selectedDocs) 
    { 
     logger.info ("DocumentManagedBean.setSelectedDocs"); 
     this.selectedDocs = selectedDocs; 
    } 
} 

Я пробовал ряд различных стратегий и прочитал множество подробных объяснений этого процесса в других потоках StackOverflow (спасибо, BalusC!), Но до сих пор не смог вызвать сценарий действия.

Моя среда выглядит следующим образом:

  • Java 1.6
  • Затмение Kepler (первоначально Juno)
  • GlassFish 3.1.2
  • PrimeFaces 3.5.0

Из презентации перспектива, XHTML отображается правильно. Элемент <p:dataTable> отображается так же, как и в документации и примерах, но когда я пытаюсь удалить строку, слушатель никогда не вызывается.

Я попытался изменить имя обновления несколько раз. В настоящее время значение параметра update составляет profile:docListForm:docListTable.

Другие сообщения, похоже, указывают, что возникла проблема с <p:commandButton> с точностью до <p:accordianPanel>, но это было для предыдущей версии PrimeFaces (3.2).

Я попытался переместить <p:commandButton> за пределы <p:dataTable>, а также на каждую строку, но поведение не меняется.

+0

В вашем действии слушателя вы получаете любой выход, но ваша форма не обновляется или оно не вызывается вообще? – Andy

+0

У меня нет выхода. Я добавил сообщение журнала как первую исполняемую строку и никогда не попадает в выходной файл, но в журнале появляются другие сообщения журнала из того же класса. –

+0

Хммм ... хорошо. Я буду стараться изо всех сил. – Andy

ответ

-1

Попробуйте добавить Аякса = "ложных" атрибута в CommandButton, что-то вроде этого.

<p:commandButton value="Non-Ajax Submit" actionListener="#{pprBean.savePerson}" 
     ajax="false" /> 

Или использовать часов: CommandButton с Аякса = "ложными" здесь также. В моем приложении у меня такая же проблема много времени, и я получил ответ на несколько недель назад, что проблема со страницей или кодом где-то на странице или исключение из управляемых bean throwing или какая-то логическая ошибка, которая генерирует исключение для JSF, что является основной причиной после запуска события. Это функция JSF2 не запускать событие, если код или логика не сработают.Может быть, это поможет вам

+0

Я пробовал это, что привело к значительному отклику, но слушателя все еще не вызывали. Тем не менее, у меня есть еще больше исследований. –

2

Если слушатель не вызывает попробовать это, он отлично работает в р: столы

<p:column id="delete" headerText="Action" width="65"> 
    <h:commandLink value="Delete" 
    action="#{documents.deleteReference(current.docNo,animals.aifNo,current.group)}" ajax="false" /> 
</p:column> 

И в документах боба:

public void deleteReference(String docNo, String aifNo, String group) 

Вы действительно можете пройти 2 строки, которые вы в конечном итоге выполняете как int, но как Integer-оболочка в методе, а не примитив.

Приветствия,

Thierry

+0

Я подумал об этом и фактически прототипировал что-то очень похожее, но я действительно хочу знать, почему код Ajax не работает, когда он должен. Получение работы с обновлением Ajax важно на данном этапе, поскольку то, что я сейчас делаю, станет прототипом кода для остальной части проекта. Я собираюсь вернуться к основам. Мой текущий план - загрузить исходный код для примера приложения PrimeFaces ShowCase. Я установлю его в своей системе и посмотрю, работает ли он. Метод 'commandLink' будет моим планом возврата. –

Смежные вопросы