org.unitime.timetable.gwt.client.Lookup.java Source code

Java tutorial

Introduction

Here is the source code for org.unitime.timetable.gwt.client.Lookup.java

Source

/*
 * Licensed to The Apereo Foundation under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 *
 * The Apereo Foundation licenses this file to you 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 org.unitime.timetable.gwt.client;

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

import org.unitime.timetable.gwt.client.aria.AriaStatus;
import org.unitime.timetable.gwt.client.aria.AriaTextBox;
import org.unitime.timetable.gwt.client.widgets.UniTimeDialogBox;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable;
import org.unitime.timetable.gwt.client.widgets.UniTimeTableHeader;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.HasCellAlignment;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.HasColSpan;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.HasStyleName;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.MouseClickListener;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.TableEvent;
import org.unitime.timetable.gwt.command.client.GwtRpcResponseList;
import org.unitime.timetable.gwt.command.client.GwtRpcService;
import org.unitime.timetable.gwt.command.client.GwtRpcServiceAsync;
import org.unitime.timetable.gwt.resources.GwtAriaMessages;
import org.unitime.timetable.gwt.resources.GwtMessages;
import org.unitime.timetable.gwt.resources.GwtResources;
import org.unitime.timetable.gwt.shared.PersonInterface;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;

/**
 * @author Tomas Muller
 */
public class Lookup extends UniTimeDialogBox implements HasValue<PersonInterface> {
    protected static final GwtAriaMessages ARIA = GWT.create(GwtAriaMessages.class);
    protected static final GwtResources RESOURCES = GWT.create(GwtResources.class);
    protected static final GwtMessages MESSAGES = GWT.create(GwtMessages.class);

    private VerticalPanel iPanel;
    private UniTimeTable<PersonInterface> iTable;
    private ScrollPanel iScroll;
    private AriaTextBox iQuery;
    private String iOptions;
    private Timer iTimer;
    private String iLastQuery = null;
    private PersonInterface iValue = null;

    private static final GwtRpcServiceAsync RPC = GWT.create(GwtRpcService.class);

    public Lookup() {
        super(true, true);
        setText(MESSAGES.dialogPeopleLookup());
        setEscapeToHide(true);
        iPanel = new VerticalPanel();
        iPanel.setSpacing(2);
        iQuery = new AriaTextBox();
        iQuery.setWidth("400px");
        iQuery.setAriaLabel(ARIA.peopleLookupName());
        HorizontalPanel queryPanel = new HorizontalPanel();
        Label filterText = new Label(MESSAGES.propName(), false);
        filterText.getElement().getStyle().setMarginRight(5, Unit.PX);
        queryPanel.setWidth("75px");
        queryPanel.add(filterText);
        queryPanel.setCellHorizontalAlignment(filterText, HasHorizontalAlignment.ALIGN_RIGHT);
        queryPanel.setCellVerticalAlignment(filterText, HasVerticalAlignment.ALIGN_MIDDLE);
        queryPanel.add(iQuery);
        HTML blank = new HTML("&nbsp;");
        blank.setWidth("75px");
        queryPanel.add(blank);
        iPanel.add(queryPanel);
        iPanel.setCellHorizontalAlignment(queryPanel, HasHorizontalAlignment.ALIGN_CENTER);
        iTable = new UniTimeTable<PersonInterface>();
        iScroll = new ScrollPanel(iTable);
        iScroll.setSize("800px", "500px");
        iScroll.setStyleName("unitime-ScrollPanel");
        iPanel.add(iScroll);
        setWidget(iPanel);

        List<UniTimeTableHeader> header = new ArrayList<UniTimeTableHeader>();
        header.add(new UniTimeTableHeader(MESSAGES.colNamePerson()));
        header.add(new UniTimeTableHeader(MESSAGES.colEmail()));
        header.add(new UniTimeTableHeader(MESSAGES.colPhone()));
        header.add(new UniTimeTableHeader(MESSAGES.colDepartment()));
        header.add(new UniTimeTableHeader(MESSAGES.colSource()));
        iTable.addRow(null, header);
        iTable.setAllowSelection(true);
        iTable.setWidth("100%");
        iTimer = new Timer() {
            @Override
            public void run() {
                update();
            }
        };
        iTable.addMouseClickListener(new MouseClickListener<PersonInterface>() {
            @Override
            public void onMouseClick(TableEvent<PersonInterface> event) {
                if (event.getData() != null) {
                    iTimer.cancel();
                    Lookup.this.hide();
                    setValue(event.getData(), true);
                }
            }
        });
        iQuery.addKeyUpHandler(new KeyUpHandler() {
            public void onKeyUp(KeyUpEvent event) {
                iTimer.schedule(500);
            }
        });

        sinkEvents(Event.ONKEYDOWN);
    }

    private void scrollToSelectedRow() {
        int row = iTable.getSelectedRow();
        if (row < 0)
            return;

        Element scroll = iScroll.getElement();

        Element item = iTable.getRowFormatter().getElement(iTable.getSelectedRow());
        if (item == null)
            return;

        int realOffset = 0;
        while (item != null && !item.equals(scroll)) {
            realOffset += item.getOffsetTop();
            item = item.getOffsetParent();
        }

        scroll.setScrollTop(realOffset - scroll.getOffsetHeight() / 2);
    }

    public void onBrowserEvent(final Event event) {
        switch (DOM.eventGetType(event)) {
        case Event.ONKEYDOWN:
            if (event.getKeyCode() == KeyCodes.KEY_DOWN && iTable.getRowCount() > 1 && iTable.getData(1) != null) {
                int row = iTable.getSelectedRow();
                if (row >= 0)
                    iTable.setSelected(row, false);
                if (row < 0) {
                    row = 1;
                } else {
                    row++;
                }
                if (row >= iTable.getRowCount())
                    row = 1;
                iTable.setSelected(row, true);
                setAriaStatus();
                scrollToSelectedRow();
                event.preventDefault();
                event.stopPropagation();
            }
            if (event.getKeyCode() == KeyCodes.KEY_UP && iTable.getRowCount() > 1 && iTable.getData(1) != null) {
                int row = iTable.getSelectedRow();
                if (row >= 0)
                    iTable.setSelected(row, false);
                if (row < 0) {
                    row = iTable.getRowCount() - 1;
                } else {
                    row--;
                }
                if (row <= 0)
                    row = iTable.getRowCount() - 1;
                ;
                iTable.setSelected(row, true);
                setAriaStatus();
                scrollToSelectedRow();
                event.preventDefault();
                event.stopPropagation();
            }
            if (event.getKeyCode() == KeyCodes.KEY_ENTER) {
                int row = iTable.getSelectedRow();
                if (row >= 0) {
                    PersonInterface person = iTable.getData(row);
                    if (person != null) {
                        iTimer.cancel();
                        Lookup.this.hide();
                        setValue(person, true);
                        AriaStatus.getInstance().setText(ARIA.suggestionSelected(toAriaString(person)));
                    }
                }
            }
            break;
        }
    }

    protected String toAriaString(PersonInterface person) {
        String aria = person.getName();
        if (person.getEmail() != null && !person.getEmail().isEmpty())
            aria += ", " + MESSAGES.colEmail() + " " + person.getEmail();
        if (person.getPhone() != null && !person.getPhone().isEmpty())
            aria += ", " + MESSAGES.colPhone() + " " + person.getPhone();
        if (person.getDepartment() != null && !person.getDepartment().isEmpty())
            aria += ", " + MESSAGES.colDepartment() + " " + person.getDepartment();
        if (person.getSource() != null && !person.getSource().isEmpty())
            aria += ", " + MESSAGES.colSource() + " " + person.getSource();
        return aria;
    }

    protected void setAriaStatus() {
        int row = iTable.getSelectedRow();
        if (row >= 1) {
            PersonInterface person = iTable.getData(row);
            if (person != null)
                AriaStatus.getInstance()
                        .setText(ARIA.onSuggestion(row, iTable.getRowCount() - 1, toAriaString(person)));
        }
    }

    public void setQuery(String query) {
        iQuery.setText(query);
    }

    public void setOptions(String options) {
        iOptions = options;
    }

    public void update() {
        final String q = iQuery.getText().trim();
        if (q.equals(iLastQuery))
            return;
        if (q.isEmpty()) {
            iTable.clearTable(1);
            return;
        }
        iTable.clearTable(1);
        List<Widget> line = new ArrayList<Widget>();
        line.add(new LoadingImage());
        iTable.addRow(null, line);
        RPC.execute(new PersonInterface.LookupRequest(q, iOptions),
                new AsyncCallback<GwtRpcResponseList<PersonInterface>>() {
                    @Override
                    public void onSuccess(GwtRpcResponseList<PersonInterface> result) {
                        iLastQuery = q;
                        iTable.clearTable(1);
                        boolean hasId = true;
                        for (PersonInterface person : result) {
                            List<Widget> line = new ArrayList<Widget>();
                            line.add(new Label(person.getName(), false));
                            line.add(new Label(person.getEmail(), false));
                            line.add(new Label(person.getPhone(), false));
                            line.add(new Label(person.getDepartment()));
                            line.add(new Label(person.getSource()));
                            iTable.addRow(person, line);
                            if (person.getId() == null || person.getId().isEmpty()
                                    || "null".equals(person.getId())) {
                                int row = iTable.getRowCount() - 1;
                                for (int col = 0; col < iTable.getCellCount(row); col++)
                                    iTable.getCellFormatter().addStyleName(row, col, "unitime-Disabled");
                                if (hasId) {
                                    hasId = false;
                                    if (row > 1)
                                        for (int col = 0; col < iTable.getCellCount(row); col++)
                                            iTable.getCellFormatter().addStyleName(row, col, "unitime-TopLineDash");
                                }
                            }
                        }
                        if (result.isEmpty()) {
                            List<Widget> line = new ArrayList<Widget>();
                            line.add(new ErrorLine(MESSAGES.errorNoPersonMatchingQuery(q), false));
                            iTable.addRow(null, line);
                            AriaStatus.getInstance().setText(MESSAGES.errorNoPersonMatchingQuery(q));
                        } else {
                            if (iTable.getSelectedRow() < 1)
                                iTable.setSelected(1, true);
                            if (result.size() == 1) {
                                AriaStatus.getInstance()
                                        .setText(ARIA.showingOneSuggestion(toAriaString(result.get(0))));
                            } else if (iTable.getSelectedRow() == 1) {
                                AriaStatus.getInstance().setText(ARIA.showingMultipleSuggestions(result.size(), q,
                                        toAriaString(result.get(0))));
                            } else {
                                AriaStatus.getInstance()
                                        .setText(ARIA.showingMultipleSuggestionsNoneSelected(result.size(), q));
                            }
                        }
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        iTable.clearTable(1);
                        List<Widget> line = new ArrayList<Widget>();
                        line.add(new ErrorLine(MESSAGES.failedLookup(caught.getMessage()), true));
                        iTable.addRow(null, line);
                        AriaStatus.getInstance().setText(MESSAGES.failedLookup(caught.getMessage()));
                    }
                });
    }

    public static class ErrorLine extends Label implements HasColSpan, HasStyleName {
        private boolean iError;

        public ErrorLine(String text, boolean error) {
            super(text);
            iError = error;
        }

        @Override
        public int getColSpan() {
            return 5;
        }

        @Override
        public String getStyleName() {
            return (iError ? "unitime-ErrorMessage" : "unitime-Message");
        }
    }

    public static class LoadingImage extends Image implements HasColSpan, HasCellAlignment {
        public LoadingImage() {
            super(RESOURCES.loading_small());
        }

        @Override
        public int getColSpan() {
            return 5;
        }

        @Override
        public HorizontalAlignmentConstant getCellAlignment() {
            return HasHorizontalAlignment.ALIGN_CENTER;
        }
    }

    public static native void createTriggers()/*-{
                                              $wnd.peopleLookup = function(query, callback, options) {
                                              @org.unitime.timetable.gwt.client.Lookup::peopleLookup(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;)(query,callback,options);
                                              };
                                              }-*/;

    public void center() {
        super.center();
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
            @Override
            public void execute() {
                iLastQuery = null;
                iQuery.setFocus(true);
                iQuery.selectAll();
                update();
            }
        });
    }

    public static void peopleLookup(String query, final JavaScriptObject callback, String options) {
        final Lookup lookup = new Lookup();
        if (query != null && !query.trim().isEmpty())
            lookup.setQuery(query);
        lookup.addValueChangeHandler(new ValueChangeHandler<PersonInterface>() {
            @Override
            public void onValueChange(ValueChangeEvent<PersonInterface> event) {
                if (event.getValue() != null)
                    lookup.fireCallback(callback, event.getValue().getId(), event.getValue().getFirstName(),
                            event.getValue().getMiddleName(), event.getValue().getLastName(),
                            event.getValue().getEmail(), event.getValue().getPhone(),
                            event.getValue().getAcademicTitle(), event.getValue().getName());
            }
        });
        lookup.setOptions(options);
        lookup.center();
    }

    public native void fireCallback(JavaScriptObject callback, String... person)/*-{
                                                                                callback(person);
                                                                                }-*/;

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<PersonInterface> handler) {
        return addHandler(handler, ValueChangeEvent.getType());
    }

    @Override
    public PersonInterface getValue() {
        return iValue;
    }

    @Override
    public void setValue(PersonInterface value) {
        setValue(value, false);
    }

    @Override
    public void setValue(PersonInterface value, boolean fireEvents) {
        iValue = value;
        if (fireEvents)
            ValueChangeEvent.fire(this, value);
    }
}