2012-12-27 16 views
8

Supponiamo che il codice di questa pagina:Come posso ottenere l'elemento selezionato nel metodo Ajax?

<h:form prependId="false" id="form"> 

    <h:selectManyCheckbox id="checkBoxList" value="#{backedBean.lstIdSelectedItems}" layout="pageDirection"> 
     <f:selectItems value="#{backedBean.lstAvailableItems}" var="item" itemLabel="#{item.label}" itemValue="#{item.value}" /> 
     <f:ajax listener="#{backedBean.itemClicked}" /> 
    </h:selectManyCheckbox> 

</h:form> 

E il codice di una sessione gestita fagiolo:

public class BackedBean implements Serializable { 
    private List<SelectItem> lstAvailableItems; 
    private List<Long> lstIdSelectedItems; 

public BackedBean() { 
    lstAvailableItems = new ArrayList<SelectItem>(); 
    lstIdSelectedItems = new ArrayList<Long>(); 
} 

@PostConstruct 
private void postConstruct(){ 
    for (int i = 0; i < 10; i++) { 
     SelectItem item = new SelectItem(new Long(i), "CHKID " + i); 
     lstAvailableItems.add(item); 
    } 
} 

public void itemClicked(AjaxBehaviorEvent ae){ 
    HtmlSelectManyCheckbox uiCmp = (HtmlSelectManyCheckbox)ae.getSource(); 

    // (1) Here I would like to get the ID of the item that has been clicked. 

} 

In (1) Vorrei ottenere l'ID dell'elemento che è stato cliccato dall'utente. Riesco a vedere nell'array IstSelectedItems gli ID di tutti gli elementi selezionati dall'utente, ma come posso ottenere l'ID dell'elemento su cui l'utente ha fatto clic?

Ho provato a utilizzare il tag f: attribute all'interno di selectManyCheckbox, ma l'attributo non si trova nella mappa dei componenti quando il metodo del listener ajax viene chiamato nel bean backed. Ho usato questo, ma non funziona:

<h:selectManyCheckbox id="checkBoxList" value="#{backedBean.lstIdSelectedItems}" layout="pageDirection"> 
    <f:selectItems value="#{backedBean.lstAvailableItems}" var="item" itemLabel="#{item.label}" itemValue="#{item.value}"> 
     <f:attribute name="clicked" value="#{item.value}" /> 
    </f:selectItems> 
    <f:ajax listener="#{backedBean.itemClicked}" /> 
</h:selectManyCheckbox> 

Qualche idea?

Saluti.

risposta

11

Siete quindi interessati al cambiamento del valore effettivo e non solo al nuovo valore. Immettere un valore valueChangeListener che confronta il vecchio valore con il nuovo valore e prepara alcune proprietà che potrebbero essere intercettate dal metodo del listener ajax.

E.g.

<h:selectManyCheckbox value="#{bean.selectedItems}" valueChangeListener="#{bean.selectedItemsChanged}" converter="javax.faces.Long"> 
    <f:selectItems value="#{bean.availableItems}" /> 
    <f:ajax listener="#{bean.itemSelected}" /> 
</h:selectManyCheckbox> 

con

private Map<String, Long> availableItems; // +getter 
private List<Long> selectedItems; // +getter+setter 
private Long selectedItem; 
private boolean selectedItemRemoved; 

@PostConstruct 
public void init() { 
    availableItems = new LinkedHashMap<String, Long>(); 

    for (long i = 0; i < 10; i++) { 
     availableItems.put("CHKID " + i, i); 
    } 
} 

public void selectedItemsChanged(ValueChangeEvent event) { 
    List<Long> oldValue = (List<Long>) event.getOldValue(); 
    List<Long> newValue = (List<Long>) event.getNewValue(); 

    if (oldValue == null) { 
     oldValue = Collections.emptyList(); 
    } 

    if (oldValue.size() > newValue.size()) { 
     oldValue = new ArrayList<Long>(oldValue); 
     oldValue.removeAll(newValue); 
     selectedItem = oldValue.iterator().next(); 
     selectedItemRemoved = true; 
    } 
    else { 
     newValue = new ArrayList<Long>(newValue); 
     newValue.removeAll(oldValue); 
     selectedItem = newValue.iterator().next(); 
     selectedItemRemoved = false; 
    } 
} 

public void itemSelected(AjaxBehaviorEvent event) { 
    System.out.println("Selected item: " + selectedItem); 
    System.out.println("Selected item removed? " + selectedItemRemoved); 
} 
0

Quando nella lista "selectedItems" si deselezionato l'elemento terminale, il codice nessuna chiamata al metodo itemSelected.

+0

Una risposta a questo riassunto appartiene come un commento all'OP ... Si noti anche che questa domanda è stata posta quattro anni fa e aveva una risposta accettata (e approfondita). – kwishnu