2013-09-04 16 views
8

Possiedo un datatable che visualizza varie entità basate su un elenco <>. Quando seleziono una cella per il montaggio, voglio essere in grado di ottenere l'entità in qualche modo per aggiornarla. Ovviamente c'è event.getRowIndex, che posso quindi utilizzare con l'Elenco <>, ma non è sempre conveniente. C'è forse un altro modo per ottenere l'entità da CellEditEvent?PrimeFaces DataTable CellEdit ottiene entità/oggetto

risposta

22

Un modo sarebbe di EL-valutare a livello di codice l'attuale <p:dataTable var>.

dato un

<p:dataTable value="#{bean.entities}" var="entity"> 

si potrebbe ottenere come segue

public void onCellEdit(CellEditEvent event) { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    Entity entity = context.getApplication().evaluateExpressionGet(context, "#{entity}", Entity.class); 
    // ... 
} 

Un altro modo, se non siete interessati nella discussione CellEditEvent, sarebbe quello di ignorare l'argomento CellEditEvent del tutto passando invece l'argomento attualmente iterato come argomento:

<p:ajax event="cellEdit" listener="#{bean.onCellEdit(entity)}" /> 

con

public void onCellEdit(Entity entity) { 
    // ... 
} 

Si prega di notare che non si può tenere il CellEditEvent e passare gli argomenti aggiuntivi. Questa risposta sarebbe stata altrimenti ovviamente fornita.

+0

Beh, ho bisogno di CellEditEvent, il più conveniente sarebbe in qualche modo includere anche CellEdi tEvent come argomento insieme a un'entità se possibile. Risultante in un metodo: public void onCellEdit (evento CellEditEvent, entità Entity). Altrimenti probabilmente andrò con la prima. – ChrisGeo

+1

Non è possibile passare ulteriori argomenti. Correlato: http: // stackoverflow.it/questions/3909267/difference-between-action-and-actionlistener/3909382 # 3909382 Quindi sì, la prima è la strada da percorrere. È possibile, se necessario, nascondere il codice standard in un metodo di utilità. Oppure, se ti capita di utilizzare [Libreria OmniFace di utilità JSF] (http://code.google.com/p/omnifaces/), usa semplicemente Entity Entity = Faces.evaluateExpressionGet ("# {entity}") '. – BalusC

6

ho lottato con questo problema due e non mi è piaciuto a seconda del nome var così ho trovato questa soluzione:

public void onCellEdit(CellEditEvent event) { 
    Entity entity =(Entity)((DataTable)event.getComponent()).getRowData(); 
} 

nota che l'entità viene aggiornato possono essere fuse direttamente nel DB, anche puoi ancora ottenere il vecchio valore. PS: grazie @BalusC per tutto :)

0

Mi è piaciuta la risposta di @ user1928596 quindi l'ho estesa un po 'per ottenere il datapoint esatto rappresentato dalla cella e aggiornare solo quello. Questo fa accoppiare il testo dell'intestazione della colonna databile al codice back-end, ma non conosco un modo migliore per farlo.

Ciò che mi ha davvero sorpreso del risultato è che quando modifico i dati nel datatable, anche i dati nel backing bean vengono modificati. Non ho bisogno di cellEditEvent.getNewValue() perché i dati nella vista sono in qualche modo legati ai dati nel backing bean. Pensavo fosse solo per la visualizzazione. L'istruzione del registro alla fine del metodo onCellEdit() aveva lo scopo di mostrare i vecchi e nuovi valori per l'oggetto Event ma mostra solo il nuovo valore.

Ecco la cella modificabile DataTable:

DataTable

Ecco il codice di visualizzazione:

<p:dataTable id="facilitatorAdminEvents" var="event" value="#{testBean.facilitatorEvents}" editable="true" editMode="cell"> 
      <p:ajax event="cellEdit" listener="#{testBean.editEvent}" update="facilitatorAdminEvents" /> 
     <p:column headerText="Event Name"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.name}"></h:outputText></f:facet><f:facet name="input"><p:inputText value="#{event.name}" style="width:100%" /></f:facet></p:cellEditor></p:column> 
     <p:column headerText="Start Date"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.startdate}"><f:convertDateTime pattern="M/d/yyyy" /></h:outputText> 
      </f:facet><f:facet name="input"><p:calendar id="eventStartdate" value="#{event.startdate}" effect="fold" /></f:facet></p:cellEditor> 
     </p:column> 
     <p:column headerText="End Date"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.enddate}"><f:convertDateTime pattern="M/d/yyyy" /></h:outputText> 
      </f:facet><f:facet name="input"><p:calendar id="eventEnddate" value="#{event.enddate}" effect="fold" /></f:facet></p:cellEditor> 
     </p:column> 
     <p:column headerText="Status"><p:cellEditor><f:facet name="output"><h:outputText value="#{event.status}" /></f:facet> 
      <f:facet name="input"> 
        <p:selectOneMenu id="eventstatuses" value="#{event.status}" style="width: 100%; margin: auto; " scrollHeight="80" showHeader="false" label="Statuses"> 
         <f:selectItems value="#{testBean.eventStatuses}" var="status" itemLabel="#{status}" /> 
        </p:selectOneMenu> 
      </f:facet></p:cellEditor> 
     </p:column> 
     <p:column id="delete" style="text-align: center; vertical-align: middle; min-width: 54px; "> 
      <p:commandButton update="facilitatorAdminEvents" icon="ui-icon-close" actionListener="#{testBean.deleteEvent(event.id)}"></p:commandButton> 
     </p:column> 
    </p:dataTable> 

E il metodo onCellEdit (che ho chiamato editEvent()):

public void editEvent(CellEditEvent cellEditEvent) { 
    Object newValue = cellEditEvent.getNewValue(); 
    String columnHeader = cellEditEvent.getColumn().getHeaderText(); 
    Event editedEvent = (Event) ((DataTable) cellEditEvent.getComponent()).getRowData(); 
    Event eventBeforeEdit = null; 
    for (Event thisEvent : events) { // Find this event in the list of cached events. 
     if (editedEvent.getId() == thisEvent.getId()) { 
      eventBeforeEdit = thisEvent; 
     } 
    } 
    log.info("Updating event " + eventBeforeEdit + " to " + editedEvent); 
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); 
    String update = null; 
    if ("Event Name".equals(columnHeader)) { 
     update = "update events set name = '" + newValue + "' where id = " + editedEvent.getId(); 
    } else if ("Start Date".equals(columnHeader)) { 
     update = "update events set startdate = '" + dateFormatter.format(newValue) + "' where id = " + editedEvent.getId(); 
    } else if ("End Date".equals(columnHeader)) { 
     update = "update events set enddate = '" + dateFormatter.format(newValue) + "' where id = " + editedEvent.getId(); 
    } else if ("Status".equals(columnHeader)) { 
     update = "update events set status = '" + newValue + "' where id = " + editedEvent.getId(); 
    } else { 
     log.error("Unrecognized value " + newValue + " encountered during event edit."); 
     FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Event Save Failure:", "Apologies but we were unable to parse your entry " + newValue); 
     FacesContext.getCurrentInstance().addMessage(null, message); 
     return; 
    } 
    try { 
     mysqlNamedParameterJdbcTemplate.update(update, new HashMap<String, String>()); 
    } catch (DuplicateKeyException e) { // There may be an event with the same name. 
     FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Event Save Failure:", 
       "That name has already been used for an archived or logically deleted event. " + "Please use a different name for the new event to avoid confusion."); 
     FacesContext.getCurrentInstance().addMessage(null, message); 
     return; 
    } 
    log.info("Event " + eventBeforeEdit + " updated to " + editedEvent); 
    loadEvents(); 
} 
Problemi correlati