开发者

GWT Different column types in same column?

I'm working on a GWT app, and so far I'm loving the Java developer friendly UI framework!

So far I've been able to do pretty much anything with the widgets, but this one has me stumped. I have a cell table, that I use as a user input source. Its just a way for users to enter key-value pairs to call my service. User can dynamically add rows and delete rows.

Now the tricky part is I want to force the user to enter value for some keys. There are only certain 4-5 acceptable values for these keys so for those rows I would like to replace the editableTextCell with a selectionCell. Not sure how I can mix cell types within a table, given that the column cell type declaration is done whi开发者_开发问答le adding the column to the table.

Any input is appreciated!

Thanks


You'll have to create a custom Cell that sometimes renders a <select> and sometimes renders an <input>. If you look at the code of EditableTextCell and SelectionCell you can get ideas about how to accomplish that. It may be pretty simple - you could compose one of each, and in your render function just pass the data to the appropriate cell.

Something like...

public class ChoosyCell extends AbstractCell<YourData> {
    SelectionCell selectCell = new SelectionCell<YourData>();
    EditableTextCell textCell = new EditableTextCell<YourData>();

    public void render(Context context, YourData data, SafeHtmlBuilder sb) {
        if (data.isTheLimitedType()) {
            selectCell.render(context, data, sb);
        } else {
            textCell.render(context,data, sb);
        }
     }
}

(untested code)


Very useful. Here is my take on a conditionally rendered CheckboxCell


    import com.google.gwt.cell.client.AbstractCell;
    import com.google.gwt.cell.client.CheckboxCell;
    import com.google.gwt.cell.client.ValueUpdater;
    import com.google.gwt.dom.client.Element;
    import com.google.gwt.dom.client.EventTarget;
    import com.google.gwt.dom.client.NativeEvent;
    import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

    /**
     * CheckboxCell that is conditionally rendered if the enclosing column's
     * Boolean com.google.gwt.user.cellview.client.Column.getValue(T object) method returns true.
     */
    public class ConditionallyRenderedCheckboxCell extends AbstractCell {

        public ConditionallyRenderedCheckboxCell() {
        //We handle the same events as CheckboxCell
        super("change", "keydown");
        }

        private CheckboxCell cell = null;

        @Override
        public void render(Context context, Boolean renderCheckboxCell, SafeHtmlBuilder sb) {
            if (renderCheckboxCell) {            
                this.cell = new CheckboxCell(false,true);  
                //Render the checkbox cell unchecked
                this.cell.render(context, false, sb);
            }
         }

        @Override
        public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context,
            Element parent, Boolean value, NativeEvent event,
            ValueUpdater valueUpdater) {

        //If we have created a checkbox cell, do event handling, otherwise, ignore it.
        if( this.cell != null ){
            super.onBrowserEvent(context, parent, value, event, valueUpdater);

            // Handle the change event.
            if ("change".equals(event.getType())) {

            // Ignore events that occur outside of the outermost element.
            EventTarget eventTarget = event.getEventTarget();

            if (parent.isOrHasChild(Element.as(eventTarget))) {

                // Use this to get the selected element!!
                Element el = Element.as(eventTarget);

                //Check if we really clicked on the checkbox
                if (el.getNodeName().equalsIgnoreCase("input") && el.getPropertyString("type").equalsIgnoreCase("checkbox")) {

                //If an value updater was defined, invoke it
                if(valueUpdater != null)
                    valueUpdater.update(el.getPropertyBoolean("checked"));          
                }
            }
            }
        }
        }        
    }


A little bit later answer, but any way. Few days ago a faced this task also - text or combo boxes has to be used in one column for cell editing. Here are my implementation:

final GridInlineEditingTextOrCombo editing = new GridInlineEditingTextOrCombo(attributeTableGrid);
    editing.addEditor(valueCol);

And custom GridInlineEditing implementation is as this:

/**
 * Class intended to create GridInlineEditing functionality,
 * but with two type of editors in one column - TextField or SimpleComboBox,
 * depending of SnmpParameterDefDTO.getAllowedValues().
 */
class GridInlineEditingTextOrCombo extends GridInlineEditing<SnmpParameterDefDTO> {
    IsField<String> textField = new TextField();
    SimpleComboBox<String> simpleComboBox = new SimpleComboBox<String>(new StringLabelProvider<String>());
    Grid.GridCell currentCell = null;
    private boolean currentCellChanged = false;
    IsField<String> currentCellEditor;
    //ComboBox<String> comboBox = new ComboBox<String>();

    public GridInlineEditingTextOrCombo(Grid<SnmpParameterDefDTO> editableGrid) {
    super(editableGrid);
    simpleComboBox.setEditable(false);
    simpleComboBox.setAllowTextSelection(false);
    simpleComboBox.setTriggerAction(ComboBoxCell.TriggerAction.ALL);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <O> IsField<O> getEditor(ColumnConfig<SnmpParameterDefDTO, ?> columnConfig) {
    IsField<O> field = super.getEditor(columnConfig);
    if(field!=null ){
        if(!currentCellChanged){
        return (IsField<O>)currentCellEditor;
        }else{
        currentCellChanged = false;
        SnmpParameterDefDTO param = this.editableGrid.getStore().get(this.currentCell.getRow());
        if(param.getAllowedValues() == null || param.getAllowedValues().size() == 0){
            currentCellEditor = (IsField<String>)field;
        }else{
            simpleComboBox.getStore().clear();
            simpleComboBox.add(param.getAllowedValues());
            currentCellEditor = simpleComboBox;
        }
        return (IsField<O>)currentCellEditor;
        }
    }
    return null;
    }

    @Override
    public <T> void addEditor(ColumnConfig<SnmpParameterDefDTO, T> columnConfig, IsField<T> field) {
    throw new RuntimeException("You can not call this method. Please use addEditor(ColumnConfig<SnmpParameterDefDTO, T> columnConfig) instead");
    }

    public <T> void addEditor(ColumnConfig<SnmpParameterDefDTO, T> columnConfig) {
    super.addEditor(columnConfig, (IsField<T>)textField);
    }

    @Override
    public void startEditing(Grid.GridCell cell){
    currentCell = cell;
    currentCellChanged = true;
    super.startEditing(cell);
    }

It is rather workaround, not elegant implementation, but any way, it works fine

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜