2010-12-30 11 views
17

Estoy tratando de tener una tabla que muestre los datos que el usuario ingresa y edite los datos. He descubierto cómo hacer esto con el texto (es decir, pueden editar el nombre de algo en la tabla), pero no puedo hacer que funcione con las celdas de selección.¿Cómo actualizar dinámicamente las elecciones en una SelectionCell usando GWT?

Funciona correctamente si los elementos en la celda de selección están predefinidos, pero no puedo actualizar dinámicamente los elementos en la celda para incluir cosas nuevas después de haber creado la celda.

Para explicar más, tengo una columna "tipo". El usuario ingresa elementos en la tabla con un tipo determinado, pero también puede agregar nuevos tipos más adelante. Cuando hacen clic en el elemento en la columna de tipo, quiero que el cuadro desplegable contenga todos los tipos nuevos que han ingresado, pero no sé cómo lograrlo.

Aquí está el código que tengo hasta ahora (que no se actualiza como yo quiero). record.getTypeList() contendrá entradas adicionales después de que el usuario ingrese nuevos tipos.

SelectionCell editTypeComboBox = new SelectionCell(record.getTypeList()); 

    Column<Assignment, String> typeColumn = new Column<Assignment, String>(editTypeComboBox) { 
     @Override 
     public String getValue(Assignment object) { 
      return object.getType(); 
     } 
    }; 
    typeColumn.setFieldUpdater(new FieldUpdater<Assignment, String>() { 

     @Override 
     public void update(int index, Assignment object, String value) { 
      int row = index; 
      String newType = value; 
      record.editAssignType(row, newType); 
      updateClassGradeLabel(); 
      log.info("Set type to " 
        + value); 
      cellTable.redraw(); 
     } 
    }); 

    cellTable.addColumn(typeColumn, "Type"); 

Editar: Gracias a Peter Knego enemigo que me ayudan a resolver esto. Aquí está la clase DynamicSelectionCell modificado si alguien si está interesado:

/* 
* Copyright 2010 Google Inc. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License. You may obtain a copy of 
* the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
* License for the specific language governing permissions and limitations under 
* the License. 
*/ 
package com.google.gwt.cell.client; 

import com.google.gwt.core.client.GWT; 
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.shared.SafeHtml; 
import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 

/** 
* A {@link Cell} used to render a drop-down list. 
*/ 
public class DynamicSelectionCell extends AbstractInputCell<String, String> { 

    interface Template extends SafeHtmlTemplates { 
    @Template("<option value=\"{0}\">{0}</option>") 
    SafeHtml deselected(String option); 

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

    private static Template template; 

    private HashMap<String, Integer> indexForOption = new HashMap<String, Integer>(); 

    private final List<String> options; 

    /** 
    * Construct a new {@link SelectionCell} with the specified options. 
    * 
    * @param options the options in the cell 
    */ 
    public DynamicSelectionCell(List<String> options) { 
    super("change"); 
    if (template == null) { 
     template = GWT.create(Template.class); 
    } 
    this.options = new ArrayList<String>(options); 
    int index = 0; 
    for (String option : options) { 
     indexForOption.put(option, index++); 
    } 
    } 

    public void addOption(String newOp){ 
     String option = new String(newOp); 
     options.add(option); 
     refreshIndexes(); 
    } 

    public void removeOption(String op){ 
     String option = new String(op); 
     options.remove(indexForOption.get(option)); 
     refreshIndexes(); 
    } 

    private void refreshIndexes(){ 
     int index = 0; 
     for (String option : options) { 
      indexForOption.put(option, index++); 
     } 
    } 

    @Override 
    public void onBrowserEvent(Context context, Element parent, String value, 
     NativeEvent event, ValueUpdater<String> valueUpdater) { 
    super.onBrowserEvent(context, parent, value, event, valueUpdater); 
    String type = event.getType(); 
    if ("change".equals(type)) { 
     Object key = context.getKey(); 
     SelectElement select = parent.getFirstChild().cast(); 
     String newValue = options.get(select.getSelectedIndex()); 
     setViewData(key, newValue); 
     finishEditing(parent, newValue, key, valueUpdater); 
     if (valueUpdater != null) { 
     valueUpdater.update(newValue); 
     } 
    } 
    } 

    @Override 
    public void render(Context context, String value, SafeHtmlBuilder sb) { 
    // Get the view data. 
    Object key = context.getKey(); 
    String viewData = getViewData(key); 
    if (viewData != null && viewData.equals(value)) { 
     clearViewData(key); 
     viewData = null; 
    } 

    int selectedIndex = getSelectedIndex(viewData == null ? value : viewData); 
    sb.appendHtmlConstant("<select tabindex=\"-1\">"); 
    int index = 0; 
    for (String option : options) { 
     if (index++ == selectedIndex) { 
     sb.append(template.selected(option)); 
     } else { 
     sb.append(template.deselected(option)); 
     } 
    } 
    sb.appendHtmlConstant("</select>"); 
    } 

    private int getSelectedIndex(String value) { 
    Integer index = indexForOption.get(value); 
    if (index == null) { 
     return -1; 
    } 
    return index.intValue(); 
    } 
} 

Respuesta

11

Desafortunadamente SelectionCell opciones almacena en una lista privada y no existen métodos para manipular esto después de que los haya establecido en el constructor. Por favor, SelectionCell es una clase bastante simple. Simplemente haga su propia copia (renombrada) y agregue los métodos addOption(..)/removeOption(..) para manipular List<String> options.

+0

Me gusta la idea, pero tengo problemas para importar las clases correctas para hacer que la nueva clase funcione. Copié la clase SelectionCell y la renombré DynamicSelectionCell, pero los métodos render y onBrowserEvent se quejan de que no necesitan ser reemplazados (el render pide ser implementado con diferentes parámetros, mientras que dice que onBrowserEvent no necesita ser implementado en absoluto) . Además, no estoy seguro de qué clase de "Contexto" importar. No estoy seguro de a dónde ir desde aquí, ¿algún consejo? –

+0

¿Qué versión de GWT estás usando? La clase a la que te indiqué es de trunk. Aquí está la versión 2.1.1: http://code.google.com/p/google-web-toolkit/source/browse/tags/2.1.1/user/src/com/google/gwt/cell/client/ SelectionCell.java?r=9485 –

+0

Comprobé mi versión y todavía estaba ejecutando 2.1.0. Después de actualizar a 2.1.1, el problema desapareció. Todo está funcionando como quiero ahora. Gracias por la ayuda. –

Cuestiones relacionadas