2012-03-12 5 views
4

Je suis l'exemple de Goolge sur comment ajouter ListBoxes/SelectionCells à un CellTable, mais je n'arrive pas à comprendre comment modifier le comportement afin que la correspondance ne soit pas faite avec la valeur de chaîne affichée.Identificateurs complexes GWT CellTable et ListBoxes

Les articles que j'affichage @SelectionCell ne sont pas uniques (autrement dit, il peut y avoir 2 éléments avec le même nom), donc je dois utiliser d'autres domaines associés à l'objet de savoir lequel a été sélectionné

for (IrrigationProgramDTO program: programOptions)  
categoryNames.add(program.getName()); 

SelectionCell categoryCell = new SelectionCell(categoryNames); 
Column<IrrigationGapDTO, String> categoryColumn = new Column<IrrigationGapDTO, String> (categoryCell) { 
     @Override 
     public String getValue(IrrigationGapDTO object) { 
      if (object.getProgramSelected()!=null) 
       return object.getProgramSelected().getName(); 
      else 
       return ""; 
     } 
    };  
    categoryColumn.setFieldUpdater(new FieldUpdater<IrrigationGapDTO, String>() { 
     public void update(int index, IrrigationGapDTO object, String value) { 
      for (IrrigationProgramDTO program: programOptions) { 
        //not valid as there could be more than 1 program with the same name 
       if (program.getName().equals(value)) { 
        object.setProgramSelected(program); 
        break; 
       } 

      } 
     } 

Répondre

1

3 solutions possibles:

1. solution sale:

Au lieu de getName() retour getName() + une identification unique:

public String getValue(IrrigationGapDTO object) { 
    if (object.getProgramSelected()!=null) 
     return object.getProgramSelected().getName()+"_"+object.getUniqueIdentiufier(); 
    else 
     return ""; 
} 

puis dans le FieldUpdater vous pouvez diviser le « _ » caractère et de traiter les doublons

2. Utilisez un identifiant unique au lieu de getName(): Générer simplement des/attribuer un identifiant unique à votre programms et l'utilise à la place du nom.

3. Utilisez IrrigationProgramDTO Type au lieu de String:

Au lieu de String vous pouvez utiliser IrrigationProgramDTO classe dans la définition de la colonne. Cependant, vous devez probablement utiliser un objet SelectionCell défini par l'utilisateur qui prend le type IrrigationProgramDTO au lieu de String comme type de données.

Column<IrrigationGapDTO, IrrigationProgramDTO> categoryColumn = new Column<IrrigationGapDTO, IrrigationProgramDTO> (categoryCell) { 
    @Override 
    public IrrigationProgramDTO (IrrigationGapDTO object) { 
     if (object.getProgramSelected()!=null) 
      return object.getProgramSelected(); 
     else 
      return null; 
    } 

};  
categoryColumn.setFieldUpdater(new FieldUpdater<IrrigationGapDTO, IrrigationProgramDTO>() { 
    public void update(int index, IrrigationGapDTO object, IrrigationProgramDTO value) { 
     object.setProgramSelected(program); 
     } 
    } 
+0

La solution n ° 1 est celle que j'ai implémentée temporairement, mais comme vous dites que c'est sale, je n'aime pas que l'utilisateur voit des nombres étranges ajoutés au programme prénom. # 2 ne peut pas être utilisé car l'identifiant provient d'une base de données. Je vais vérifier # 3. – jpp1jpp1

+0

# 3 est la meilleure option à mon avis. Je customiserais en utilisant une interface inestead d'un objet (si possible), pour réutiliser le code avec le futur DTO ... – gavioto

0

Voici ma mise en œuvre de la solution # 3 @ Ümit:

public static abstract class EditSelectColumn<E, S> { 

    Map<String, S> selectionMap = new HashMap<String, S>(); 

    EditColumn<E> column; 

    protected final String relationshipFieldName; 

    public EditSelectColumn(String relationshipFieldName) { 
     this.relationshipFieldName = relationshipFieldName; 

     for (S option : getOptions()) { 
      assert getOptionString(option) != null : "Option string cannot be null, please check your database"; 
      selectionMap.put(getOptionString(option), option); 
     } 
     SelectionCell cell = new SelectionCell(new ArrayList<String>(selectionMap.keySet())); 
     column = new EditColumn<E>(cell) { 
      @Override 
      public String getValue(E object) { 
       if (getOption(object) == null) 
        return ""; 
       return getOptionString(getOption(object)); 
      } 

      @Override 
      public void setValue(E object, String value) { 
       setOption(object, selectionMap.get(value)); 
      } 
     }; 
    } 

    public EditColumn<E> getColumn() { 
     return column; 
    } 

    public abstract List<S> getOptions(); 

    public abstract String getOptionString(S option); 

    public abstract S getOption(E object); 

    public abstract void setOption(E object, S value); 
} 
+0

Eh bien en fait je lis trop vite. Ce n'est pas la solution # 3 de @ Ümit parce que je ne fais pas ma propre SelectionCell. De plus, cela ne fonctionne pas si vous avez plusieurs fois la même chaîne. – qwertzguy

2

Voici ma nouvelle implémentation de la solution n ° 3 (notez que vous devez ajouter un FieldUpdater à la colonne pour elle au travail):

import java.util.Arrays; 
import java.util.List; 

import com.google.gwt.cell.client.AbstractEditableCell; 
import com.google.gwt.cell.client.Cell; 
import com.google.gwt.cell.client.ValueUpdater; 
import com.google.gwt.core.client.GWT; 
import com.google.gwt.dom.client.BrowserEvents; 
import com.google.gwt.dom.client.Element; 
import com.google.gwt.dom.client.NativeEvent; 
import com.google.gwt.dom.client.SelectElement; 
import com.google.gwt.safehtml.client.SafeHtmlTemplates; 
import com.google.gwt.safehtml.client.SafeHtmlTemplates.Template; 
import com.google.gwt.safehtml.shared.SafeHtml; 
import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 

/** 
* A {@link Cell} used to render a drop-down list. 
* 
* @author Gaspard van Koningsveld 
*/ 
public class ItemSelectionCell<C> extends AbstractEditableCell<C, C> { 

    interface Template extends SafeHtmlTemplates { 
     @Template("<select tabindex=\"-1\" style=\"width:100%\">") 
     SafeHtml beginSelect(); 

     @Template("<option value=\"{0}\">{1}</option>") 
     SafeHtml deselected(int hash, String option); 

     @Template("<option value=\"{0}\" selected=\"selected\">{1}</option>") 
     SafeHtml selected(int hash, String option); 

     @Template("</select>") 
     SafeHtml endSelect(); 
    } 

    private static Template template; 

    private List<C> items; 

    public ItemSelectionCell(C itemsArray[]) { 
     this(Arrays.asList(itemsArray)); 
    } 

    public ItemSelectionCell(List<C> items) { 
     super(BrowserEvents.CHANGE); 
     if (template == null) { 
      template = GWT.create(Template.class); 
     } 
     this.items = items; 
    } 

    @Override 
    public void onBrowserEvent(Context context, Element parent, C value, NativeEvent event, ValueUpdater<C> valueUpdater) { 
     super.onBrowserEvent(context, parent, value, event, valueUpdater); 
     if (BrowserEvents.CHANGE.equals(event.getType())) { 
      SelectElement select = parent.getFirstChild().cast(); 
      int newIndex = select.getSelectedIndex(); 
      valueUpdater.update(items.get(newIndex)); 
     } 
    } 

    @Override 
    public void render(Context context, C value, SafeHtmlBuilder sb) { 
     sb.append(template.beginSelect()); 
     for (int i = 0; i < items.size(); i++) { 
      C item = items.get(i); 
      if (item.equals(value)) { 
       sb.append(template.selected(i, getItemDisplayString(item))); 
      } else { 
       sb.append(template.deselected(i, getItemDisplayString(item))); 
      } 
     } 
     sb.append(template.endSelect()); 
    } 

    public String getItemDisplayString(C item) { 
     return item.toString(); 
    } 

    public List<C> getItems() { 
     return items; 
    } 

    public void setItems(List<C> items) { 
     this.items = items; 
    } 

    @Override 
    public boolean isEditing(Context context, Element parent, C value) { 
     return false; 
    } 
} 
+0

Reviens ici grâce à google, j'avais complètement oublié que j'avais posté ça! Semble fonctionner avec une petite modification pour permettre des valeurs nulles/vides – jpp1jpp1

+0

merci pour cela! –