Как создать зависимую ячейку раскрывающегося списка/выбора в таблице ячеек GWT 2.3?

Я использую таблицу ячеек gwt2.3.

В моей таблице ячеек будет несколько столбцов, из которых несколько зависимых столбцов.

бывший. Столбцы имени и адреса являются зависимыми Столбцы имени и адреса содержат мои пользовательские ячейки выбора.

В столбце Имя: 1 ячейка содержит Джон, Том, Стив

когда в ячейке имени содержится Джон, я хочу установить США и Великобританию в адресной ячейке.

если пользователь меняет ячейку имени на tom, я хочу установить Индию и Китай в адресной ячейке

если пользователь меняет ячейку имени на Стив, я хочу установить японию и бутан в адресной ячейке

Я хочу изменить зависимые данные из адресной ячейки при изменении выбора ячеек имени.

Как я могу добиться этого? Любой пример кода или указатели для этого?


person StackOverFlow    schedule 26.01.2013    source источник
comment
Ваше объяснение довольно сложно понять... Вы хотите изменить ячейку в тот момент, когда вы меняете выбор?   -  person Sam    schedule 29.01.2013
comment
@ Сэм, я так думаю. Вайбхав, мы попробовали похожее решение, и код получился невероятно дерьмовым!!!!   -  person appbootup    schedule 30.01.2013
comment
@Vaibhav Я пробовал то же самое, но это не сработало!!!!!!. потому что трудно отличить отдельные элементы Dom от Row. Я изменил поведение столбцов, как вы хотите. т. е. изменение первого столбца первой строки влияет на второй столбец или может быть любым столбцом в качестве кода. затем выберите другую строку, первая строка станет такой, какая она есть. и все изменения истекли из первой строки.   -  person bNd    schedule 31.01.2013
comment
Ваш вопрос не ясен: у вас есть два столбца, каждый из которых содержит раскрывающийся список, и вы хотите, чтобы при выборе параметра из первого раскрывающегося списка он изменял доступные значения из второго раскрывающегося списка, верно? И вы сделали пользовательскую ячейку для раскрывающегося списка, верно?   -  person qwertzguy    schedule 31.01.2013
comment
@qwertzguy #1 Да, я сделал customSelectionCell для раскрывающегося списка   -  person StackOverFlow    schedule 31.01.2013
comment
@VaibhaV Какой класс расширяет ваш customSelectionCell? Какой тип обрабатывает ваша CellTable (параметризованный тип)? И как вы получаете значения для отображения во втором раскрывающемся списке в зависимости от значения первого раскрывающегося списка? (IE: нужно ли извлекать значения или нет?)   -  person qwertzguy    schedule 31.01.2013
comment
@qwertzguy #1 Моя CustomSelectionCell расширяет AbstractEditableCell‹String, CustomSelectionCell .ViewData› #2 CellTable‹RecordInfo› #3 Все зависимые данные извлекаются на стороне клиента   -  person StackOverFlow    schedule 01.02.2013
comment
@qwertzguy При изменении выбора ячейки имени необходимо установить зависимые данные выбора в той же записи строки ячейки адреса.   -  person StackOverFlow    schedule 01.02.2013


Ответы (4)


Это решение предназначено для GWT 2.5, но, вероятно, должно работать и в 2.3. Я думаю, что лучше всего изменить элемент RecordInfo при изменении выбора в первом столбце. Вы можете сделать это аналогично этому в CustomSelectionCell:

@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())) {
        Xxxxx newValue = getSelectedValueXxxxx();
        valueUpdater.update(newValue);
    }
}

Затем, когда вы используете свою ячейку, добавьте fieldUpdater, подобный этому, который обновит RecordInfo новым значением и попросит перерисовать строку:

column.setFieldUpdater(new FieldUpdater<.....>() {
    ....
    recordInfo.setXxxxx(newValue);
    cellTable.redrawRow(index);
    ....
});

Это вызовет рендеринг другого CustomSelectionCell, там вы сможете проверить, изменилось ли значение RecordInfo, и при необходимости обновить значения выбора. Пример:

@Override
public void render(Context context, C value, SafeHtmlBuilder sb) {
    if (!value.getXxxxx().equals(this.lastValue)) {
        this.items = loadItemsForValueXxxx(value.getXxxxx());
    }
    .... // Your usual render.
}

Будьте осторожны, когда вы изменяли элементы, чтобы также установить выбранный элемент по умолчанию.

person qwertzguy    schedule 04.02.2013
comment
Можете ли вы предоставить образец демо + код, будет хорошо поиграть/поэкспериментировать - person StackOverFlow; 04.02.2013
comment
Нет, извините, у меня нет времени воссоздавать проект и перекодировать ваш CustomSelectionCell и т. д. Но вам не составит труда интегрировать эти фрагменты кода. - person qwertzguy; 05.02.2013
comment
@qwertzguy: не могли бы вы объяснить немного больше, я пытаюсь сделать то же самое. я знаю, как обновить список ячеек выбора, но не понимаю, как запустить метод рендеринга ячейки выбора в средстве обновления поля другого столбца. - person Ankit Singla; 25.06.2014
comment
@AnkitSingla Вам нужно использовать setFieldUpdater (2-й фрагмент кода) в другом столбце. Вызов cellTable.redrawRow(index) вызовет рендеринг всех столбцов. - person qwertzguy; 25.06.2014
comment
@qwertzguy: у меня есть карта ‹?, список‹?››, первый столбец выбора содержит набор ключей карты, и я хочу обновить список второго столбца выбора на основе выбора столбца 1. проблема в том, что он обновляет все строки, я просто хочу обновить текущую строку. - person Ankit Singla; 27.06.2014
comment
@qwertzguy: спасибо, приятель, я понял. - person Ankit Singla; 27.06.2014

Или вы можете сделать что-то вроде создания пользовательской ячейки, в которой есть методы, которые вы можете вызывать в getValue этого конкретного столбца.

сказать

final DynamicSelectionCell selection = new DynamicSelectionCell("...");
    Column<GraphFilterCondition, String> operandColumn=new Column<GraphFilterCondition, String>(selection) {
        @Override
        public String getValue(FilterCondition object) {
            if(object.getWhereCol()!=null){
                 ((DynamicSelectionCell)this.getCell()).addOptions(new String[]{">","<",">="});
            }
            if(object.getWhereCondition()!=null){
                return object.getWhereCondition().getGuiName();
            }
            return "";
        }
    };

Это должно сработать, я думаю.

Также проверьте этот другой вопрос

person Photon    schedule 01.03.2013

Это моя реализация DynamicSelectionCell.

DynamicSelectionCell позволяет отображать разные параметры для разных строк в одной и той же таблице GWT.

Используйте один объект DynamicSelectionCell и метод addOption, чтобы добавить параметры для каждой строки. Параметры хранятся в карте с ключом, являющимся номером строки.

Для каждой строки $i в таблице отображаются параметры, хранящиеся в карте для ключа $i.

Работает на DataGrid, CellTable.

КОД

public class DynamicSelectionCell extends AbstractInputCell<String, String> {

    public TreeMap<Integer, List<String>> optionsMap = new TreeMap<Integer, List<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 TreeMap<Integer, HashMap<String, Integer>> indexForOption = new TreeMap<Integer, HashMap<String, Integer>>();

    /**
     * Construct a new {@link SelectionCell} with the specified options.
     *
     * @param options the options in the cell
     */
    public DynamicSelectionCell() {
        super("change");
        if (template == null) {
            template = GWT.create(Template.class);
        }
    }

    public void addOption(List<String> newOps, int key){
        optionsMap.put(key, newOps);
        HashMap<String, Integer> localIndexForOption = new HashMap<String, Integer>();
        indexForOption.put(ind, localIndexForOption);
        refreshIndexes();
    }

    public void removeOption(int index){        
        optionsMap.remove(index);
        refreshIndexes();
    }

    private void refreshIndexes(){
        int ind=0;
        for (List<String> options : optionsMap.values()){
            HashMap<String, Integer> localIndexForOption = new HashMap<String, Integer>();
            indexForOption.put(ind, localIndexForOption);
            int index = 0;
            for (String option : options) {
                localIndexForOption.put(option, index++);
            }
            ind++;
        }
    }

    @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 = optionsMap.get(context.getIndex()).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, context.getIndex());
        sb.appendHtmlConstant("<select tabindex=\"-1\">");
        int index = 0;
        try{
        for (String option : optionsMap.get(context.getIndex())) {
            if (index++ == selectedIndex) {
                sb.append(template.selected(option));
            } else {
                sb.append(template.deselected(option));
            }
        }
        }catch(Exception e){
            System.out.println("error");
        }
        sb.appendHtmlConstant("</select>");
    }

    private int getSelectedIndex(String value, int ind) {
        Integer index = indexForOption.get(ind).get(value);
        if (index == null) {
            return -1;
        }
        return index.intValue();
    }
} 
person Varun Tulsian    schedule 15.07.2014

Ответ Варуна Тулсиана очень хорош, но код неполный.

DynamicSelectionCell сохраняет параметры каждой строки на карте. Когда ячейка обновляется или визуализируется, она сопоставляет индекс строки из вашего контекста с соответствующим списком строк на вашей карте.

Для потомков см. упрощенную и обновленную версию ниже:

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;

/**
 *  key: rowIndex
 *  value: List of options to show for this row
 */
public TreeMap<Integer, List<String>> optionsMap = new TreeMap<Integer, List<String>>();

/**
 * Construct a new {@link SelectionCell} with the specified options.
 *
 */
public DynamicSelectionCell() {
    super("change");
    if (template == null) {
        template = GWT.create(Template.class);
    }
}

public void addOptions(List<String> newOps, int rowIndex) {
    optionsMap.put(rowIndex, newOps);
}

public void removeOptions(int rowIndex) {
    optionsMap.remove(rowIndex);
}

@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 = optionsMap.get(context.getIndex()).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, context.getIndex());
    sb.appendHtmlConstant("<select tabindex=\"-1\">");
    int index = 0;
    try {
        for (String option : optionsMap.get(context.getIndex())) {
            if (index++ == selectedIndex) {
                sb.append(template.selected(option));
            } else {
                sb.append(template.deselected(option));
            }
        }
    } catch (Exception e) {
        System.out.println("error");
    }
    sb.appendHtmlConstant("</select>");
}

private int getSelectedIndex(String value, int rowIndex) {
    if (optionsMap.get(rowIndex) == null) {
        return -1;
    }
    return optionsMap.get(rowIndex).indexOf(value);
}
}
person Lolleroni    schedule 24.09.2015