Tuesday, May 19, 2015

GWT DataGrid with LeafValueEditor

====== UIBINDER =======

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g='urn:import:com.google.gwt.user.client.ui'
             xmlns:b.grid='urn:import:org.gwtbootstrap3.client.ui.gwt'
             xmlns:b='urn:import:org.gwtbootstrap3.client.ui' >

    <ui:style>
        .padding {
            padding-bottom: 15px;
        }

    </ui:style>

    <b:Row>
        <b:Column size="XS_12">
            <b:Legend text="Users"/>
            <b:Row addStyleNames="{style.padding}">
                <b:Column size="XS_12">
                    <b:Button ui:field="addContact" text="Add contact" pull="RIGHT" />
                </b:Column>
            </b:Row>

            <b:Row addStyleNames="{style.padding}">
                <b:Column size="XS_12 SM_12 MD_12 LG_12" >
                    <b.grid:DataGrid width="100%" height="200px" ui:field="grid" />
                </b:Column>
            </b:Row>
        </b:Column>
    </b:Row>

</ui:UiBinder>

======== JAVA ========

package com.db.emir.co.gwt.client.activities.client.edit_client;

import com.db.emir.co.dm.vo.ClientContactDTO;
import com.db.emir.co.gwt.client.commons.widgets.cells.ActionDelegate;
import com.db.emir.co.gwt.client.commons.widgets.cells.ActionItem;
import com.db.emir.co.gwt.client.commons.widgets.cells.buttons.ButtonDropdownCell;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.HasKeyboardPagingPolicy;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.*;
import com.google.inject.Inject;
import org.gwtbootstrap3.client.ui.Label;
import org.gwtbootstrap3.client.ui.constants.TableType;
import org.gwtbootstrap3.client.ui.gwt.DataGrid;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by panoand on 05/05/2015.
 */
public class ContactListEditor extends Composite implements LeafValueEditor<List<ClientContactDTO>> {

    interface EditClientGridUiBinder extends UiBinder<Widget, ContactListEditor> {}

    public static EditClientGridUiBinder ourUiBinder = GWT.create(EditClientGridUiBinder.class);

    @UiField(provided=true)
    DataGrid grid;

    @Override
    public void setValue(List<ClientContactDTO> value) {
        dataProvider.setList(value);
        sortHandler.setList(value);
    }

    @Override
    public List<ClientContactDTO> getValue() {
        return dataProvider.getList();
    }

    private ListDataProvider<ClientContactDTO> dataProvider;
    private ColumnSortEvent.ListHandler<ClientContactDTO> sortHandler;

    private void add() {
        dataProvider.getList().add(new ClientContactDTO());
        dataProvider.refresh();
    }

    //TODO refresh method does not refresh grid properly, need to be fixed
    //related topic is https://code.google.com/p/google-web-toolkit/issues/detail?id=7114
    private void remove(final int index) {
        if (index < dataProvider.getList().size() && index >= 0 ) {
            dataProvider.getList().remove(index);
            dataProvider.refresh();
        }
    }

    @Inject
    public ContactListEditor() {
        ProvidesKey<ClientContactDTO> keyProvider = new ProvidesKey<ClientContactDTO>() {
            public Object getKey(ClientContactDTO item) {
                return (item == null) ? null : item.getFirstName();
            }
        };

        grid = new GridImpl<ClientContactDTO>(keyProvider);
        grid.setWidth("100%");
        grid.setAutoHeaderRefreshDisabled(true);
        grid.setEmptyTableWidget(new Label("The gris has no data at this moment"));
        grid.setPageSize(50);

        grid.setKeyboardPagingPolicy(HasKeyboardPagingPolicy.KeyboardPagingPolicy.INCREASE_RANGE);
        grid.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.BOUND_TO_SELECTION);
        final SelectionModel<ClientContactDTO> selectionModel = new MultiSelectionModel<ClientContactDTO>(keyProvider);

        // Setting selection model causes incorrect grid updating while removing a row.
        // grid.setSelectionModel(selectionModel, DefaultSelectionEventManager.<UserEntityDTO>createCheckboxManager());

        dataProvider = new ListDataProvider<ClientContactDTO>(Collections.EMPTY_LIST);
        dataProvider.addDataDisplay(grid);

        sortHandler = new ColumnSortEvent.ListHandler<ClientContactDTO>(dataProvider.getList()) {

            @Override
            public void onColumnSort(ColumnSortEvent event) {
                super.onColumnSort(event);
                dataProvider.refresh();
            }
        };
        grid.addColumnSortHandler(sortHandler);

        initColumns();
        initWidget(ourUiBinder.createAndBindUi(this));

    }

    private class GridImpl<T> extends DataGrid {
        public GridImpl(ProvidesKey<T> keyProvider) {
            super(keyProvider);
            setStriped(true);
            setHover(true);
            getTableHeadElement().getParentElement().addClassName(TableType.DEFAULT.getCssName());
        }
    }

    private void initColumns(){

        /*FIRST_NAME*/
        Column<ClientContactDTO, String> firstName = new Column<ClientContactDTO, String>(new EditTextCell()) {
                    @Override
                    public String getValue(ClientContactDTO client) {
                        return client.getFirstName();
                    }
        };
        firstName.setSortable(true);
        sortHandler.setComparator(firstName, new Comparator<ClientContactDTO>() {
            @Override
            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
                return o1.getFirstName().compareTo(o2.getFirstName());
            }
        });
        grid.addColumn(firstName, "First Name");
        grid.setColumnWidth(firstName, "40");
        firstName.setFieldUpdater(new FieldUpdater<ClientContactDTO, String>() {
            @Override
            public void update(int index, ClientContactDTO object, String value) {
                object.setFirstName(value);
            }
        });

        /*LAST_NAME*/
        Column<ClientContactDTO, String> lastName = new Column<ClientContactDTO, String>(new EditTextCell()) {
            @Override
            public String getValue(ClientContactDTO client) {
                return client.getLastName();
            }
        };
        lastName.setSortable(true);
        sortHandler.setComparator(lastName, new Comparator<ClientContactDTO>() {
            @Override
            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
                return o1.getLastName().compareTo(o2.getLastName());
            }
        });
        grid.addColumn(lastName, "Last Name");
        grid.setColumnWidth(lastName, "60");
        lastName.setFieldUpdater(new FieldUpdater<ClientContactDTO, String>() {
            @Override
            public void update(int index, ClientContactDTO object, String value) {
                object.setLastName(value);
            }
        });

        /*EMAIL*/
        Column<ClientContactDTO, String> email = new Column<ClientContactDTO, String>(new EditTextCell()) {
            @Override
            public String getValue(ClientContactDTO client) {
                return client.getEmail();
            }
        };
        email.setSortable(true);
        sortHandler.setComparator(email, new Comparator<ClientContactDTO>() {
            @Override
            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
                return o1.getEmail().compareTo(o2.getEmail());
            }
        });
        grid.addColumn(email, "Email Address");
        grid.setColumnWidth(email, "25");
        email.setFieldUpdater(new FieldUpdater<ClientContactDTO, String>() {
            @Override
            public void update(int index, ClientContactDTO object, String value) {
                object.setEmail(value);
            }
        });

        /*LANGUAGE*/
        Column<ClientContactDTO, String> language = new Column<ClientContactDTO, String>(new EditTextCell()) {
            @Override
            public String getValue(ClientContactDTO client) {
                return client.getLanguage();
            }
        };
        language.setSortable(true);
        sortHandler.setComparator(language, new Comparator<ClientContactDTO>() {
            @Override
            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
                return o1.getLanguage().compareTo(o2.getLanguage());
            }
        });
        grid.addColumn(language, "Language");
        grid.setColumnWidth(language, "30");
        language.setFieldUpdater(new FieldUpdater<ClientContactDTO, String>() {
            @Override
            public void update(int index, ClientContactDTO object, String value) {
                object.setLanguage(value);
            }
        });

//        /*ROLE*/
//        Column<ClientContactDTO, String> role = new Column<ClientContactDTO, String>(new EditTextCell()) {
//            @Override
//            public String getValue(ClientContactDTO client) {
//                return client.getPosition();
//            }
//        };
//        role.setSortable(true);
//        sortHandler.setComparator(role, new Comparator<ClientContactDTO>() {
//            @Override
//            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
//                return o1.getPosition().compareTo(o2.getPosition());
//            }
//        });
//        grid.addColumn(role, "Role");
//        grid.setColumnWidth(role, "30");

        /*TO_CC*/
//        Column<ClientContactDTO, ContactToCC> toCc = new Column<ClientContactDTO, ContactToCC>(new InlineRadioCell("toCc")) {
//            @Override
//            public ContactToCC getValue(ClientContactDTO client) {
//                return client.getContactToCC();
//            }
//        };
//        toCc.setSortable(true);
//        sortHandler.setComparator(toCc, new Comparator<ClientContactDTO>() {
//            @Override
//            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
//                return o1.getContactToCC().compareTo(o2.getContactToCC());
//            }
//        });
//        grid.addColumn(toCc, "To/CC");
//        grid.setColumnWidth(toCc, "30");

        /*PRIMARY_CONTACT*/
        Column<ClientContactDTO, Boolean> primary = new Column<ClientContactDTO, Boolean>(new CheckboxCell()) {
            @Override
            public Boolean getValue(ClientContactDTO client) {
                return client.isPrimary();
            }
        };
        primary.setSortable(true);
        sortHandler.setComparator(primary, new Comparator<ClientContactDTO>() {
            @Override
            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
                return Boolean.compare(o1.isPrimary(), o2.isPrimary());
            }
        });
        grid.addColumn(primary, "Primary Contact");
        grid.setColumnWidth(primary, "30");
        primary.setFieldUpdater(new FieldUpdater<ClientContactDTO, Boolean>() {
            @Override
            public void update(int index, ClientContactDTO object, Boolean value) {
                object.setIsPrimary(value);
            }
        });

        /*CAN_ACCESS_APP*/
        Column<ClientContactDTO, Boolean> access = new Column<ClientContactDTO, Boolean>(new CheckboxCell()) {
            @Override
            public Boolean getValue(ClientContactDTO client) {
                return client.isSendConfidential();
            }
        };
        access.setSortable(true);
        sortHandler.setComparator(access, new Comparator<ClientContactDTO>() {
            @Override
            public int compare(ClientContactDTO o1, ClientContactDTO o2) {
                return Boolean.compare(o1.isSendConfidential(), o2.isSendConfidential());
            }
        });
        grid.addColumn(access, "Can Access App?");
        grid.setColumnWidth(primary, "30");
        access.setFieldUpdater(new FieldUpdater<ClientContactDTO, Boolean>() {
            @Override
            public void update(int index, ClientContactDTO object, Boolean value) {
                object.setSendConfidential(value);
            }
        });

        /*BUTTONS*/
        List<ActionItem<ClientContactDTO>> actionItemList = getActionItemList();
        ButtonDropdownCell<ClientContactDTO> actionCell = new ButtonDropdownCell<ClientContactDTO>(actionItemList);

        Column<ClientContactDTO, ClientContactDTO> actionToClient =
                new Column<ClientContactDTO, ClientContactDTO>(actionCell) {
                    @Override
                    public ClientContactDTO getValue(ClientContactDTO object) {
                        return object;
                    }
                };

        actionToClient.setSortable(false);
        grid.addColumn(actionToClient, "Actions");
        grid.setColumnWidth(actionToClient, "30");

    }

    private List<ActionItem<ClientContactDTO>> getActionItemList() {
        List<ActionItem<ClientContactDTO>> actionItems = new ArrayList<ActionItem<ClientContactDTO>>();

        actionItems.add(new ActionItem<ClientContactDTO>("Add another",
                new ActionDelegate<ClientContactDTO>() {
                    @Override
                    public void execute(ClientContactDTO dto) {
                        add();
                    }

                    @Override
                    public boolean isActive(ClientContactDTO object) {
                        return true;
                    }
                }));
        actionItems.add(new ActionItem<ClientContactDTO>("Remove",
                new ActionDelegate<ClientContactDTO>() {
                    @Override
                    public void execute(ClientContactDTO dto) {
                        int index = dataProvider.getList().indexOf(dto);
                        remove(index);
                    }

                    @Override
                    public boolean isActive(ClientContactDTO object) {
                        return true;
                    }
                }));
        return actionItems;
    }

//    private class InlineRadioCell extends AbstractEditableCell<ContactToCC, ContactToCC> implements LeafValueEditor<ContactToCC> {
//        @Override
//        public boolean isEditing(Context context, Element parent, ContactToCC value) {
//            return false;
//        }
//
//        @Override
//        public void render(Context context, ContactToCC value, SafeHtmlBuilder sb) {
//            setValue(value);
////            sb.append((SafeHtml) cp);
//        }
//
//        private Map<InlineRadio, ContactToCC> map;
//        private FlowPanel cp;
//
//        @UiConstructor
//        public InlineRadioCell(String groupName) {
//            super(BrowserEvents.CHANGE, BrowserEvents.KEYDOWN);
//            cp = new FlowPanel();
//            map = new HashMap<InlineRadio, ContactToCC>();
//            for (ContactToCC e : ContactToCC.class.getEnumConstants()) {
//                InlineRadio rb = new InlineRadio(groupName, e.name());
//                map.put(rb, e);
//                cp.add(rb);
//            }
//        }
//
//        @Override
//        public void setValue(ContactToCC value) {
//            if (value == null)
//                return;
//            InlineRadio rb = (InlineRadio) cp.getWidget(value.ordinal());
//            rb.setValue(true);
//        }
//
//        @Override
//        public ContactToCC getValue() {
//            for (Map.Entry<InlineRadio, ContactToCC> e : map.entrySet()) {
//                if (e.getKey().getValue())
//                    return e.getValue();
//            }
//            return null;
//        }

//    }

    @UiHandler("addContact")
    public void onAddContact(ClickEvent event) {
        add();
    }

}

No comments: