Package org.onesocialweb.gwt.client.ui.widget.compose

Source Code of org.onesocialweb.gwt.client.ui.widget.compose.RecipientList

package org.onesocialweb.gwt.client.ui.widget.compose;

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

import org.appfuse.client.widget.BulletList;
import org.appfuse.client.widget.ListItem;
import org.appfuse.client.widget.Paragraph;
import org.appfuse.client.widget.Span;
import org.onesocialweb.gwt.client.ui.event.ComponentHelper;
import org.onesocialweb.gwt.client.ui.event.ComponentListener;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwt.user.client.ui.TextBox;

public class RecipientList extends Composite {

  private final RecipientOracle oracle = RecipientOracle.getInstance();

  private final TextBox itemBox = new TextBox();

  private final SuggestBox box = new SuggestBox(oracle, itemBox);

  private List<String> itemsSelected = new ArrayList<String>();
 
  private final ComponentHelper componentHelper = new ComponentHelper();

  public RecipientList() {
    FlowPanel panel = new FlowPanel();
    initWidget(panel);
    // 2. Show the following element structure and set the last <div> to
    // display: block
    /*
     * <ul class="token-input-list-facebook"> <li
     * class="token-input-input-token-facebook"> <input type="text"style=
     * "outline-color: -moz-use-text-color; outline-style: none; outline-width: medium;"
     * /> </li> </ul> <div class="token-input-dropdown-facebook"
     * style="display: none;"/>
     */
    final Label grow = new Label();
    panel.add(grow);
    grow.addStyleName("grow");
    final BulletList list = new BulletList();
    list.setStyleName("token-input-list-facebook");
    final ListItem item = new ListItem();
    item.setStyleName("token-input-input-token-facebook");
    itemBox
        .getElement()
        .setAttribute(
            "style",
            "outline-color: -moz-use-text-color; outline-style: none; outline-width: medium;");
    box.getElement().setId("suggestion_box");
    item.add(box);
    list.add(item);

    // this needs to be on the itemBox rather than box, or backspace will
    // get executed twice
    itemBox.addKeyDownHandler(new KeyDownHandler() {
      public void onKeyDown(KeyDownEvent event) {
        if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
          // only allow manual entries with @ signs (assumed email
          // addresses)
          if (itemBox.getValue().contains("@"))
            deselectItem(itemBox, list);
        }
        // handle backspace
        if (event.getNativeKeyCode() == KeyCodes.KEY_BACKSPACE) {
          if ("".equals(itemBox.getValue().trim())) {
            ListItem li = (ListItem) list.getWidget(list
                .getWidgetCount() - 2);
            Paragraph p = (Paragraph) li.getWidget(0);
            if (itemsSelected.contains(p.getText())) {
              itemsSelected.remove(p.getText());
              GWT.log("Removing selected item '" + p.getText()
                  + "'", null);
              GWT.log("Remaining: " + itemsSelected, null);
            }
            list.remove(li);
            itemBox.setFocus(true);
            fireComponentResized();
          }
        }

      }
    });

    // also capture separators like , and semicolon to trigger
    itemBox.addKeyPressHandler(new KeyPressHandler() {
      public void onKeyPress(KeyPressEvent event) {

        char keyCode = event.getCharCode();
        char comma = ',';
        char semicolon = ';';
        char space = ' ';

        if (keyCode == comma || keyCode == semicolon
            || keyCode == space) {
          // only allow manual entries with @ signs (assumed email
          // addresses)
          if (itemBox.getValue().contains("@")) {
            deselectItem(itemBox, list);
          }

          // stop these characters from appearing in the textbox
          event.stopPropagation();
          event.preventDefault();

        }

        // grow the size of the input box
        grow.setText(itemBox.getText());

      }
    });

    // used for growing the text input
    itemBox.addKeyUpHandler(new KeyUpHandler() {
      public void onKeyUp(KeyUpEvent event) {

        // grow the size of the input box
        grow.setText(itemBox.getText());
        Integer width = grow.getOffsetWidth() + 25;
        itemBox.setWidth(width.toString());

      }
    });

    box.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
      public void onSelection(SelectionEvent selectionEvent) {
        deselectItem(itemBox, list);
      }
    });

    panel.add(list);

    panel.getElement().setAttribute("onclick",
        "document.getElementById('suggestion_box').focus()");
    box.setFocus(true);
    /*
     * Div structure after a few elements have been added: <ul
     * class="token-input-list-facebook"> <li
     * class="token-input-token-facebook"> <p>What's New Scooby-Doo?</p>
     * <span class="token-input-delete-token-facebook">x</span> </li> <li
     * class="token-input-token-facebook"> <p>Fear Factor</p> <span
     * class="token-input-delete-token-facebook">x</span> </li> <li
     * class="token-input-input-token-facebook"> <input type="text"style=
     * "outline-color: -moz-use-text-color; outline-style: none; outline-width: medium;"
     * /> </li> </ul>
     */
  }
 
  public void addComponentListener(ComponentListener listener) {
    componentHelper.addComponentListener(listener);
  }

  public void removeComponentListener(ComponentListener listener) {
    componentHelper.removeComponentListener(listener);
  }

  public void setFocus() {
    box.setFocus(true);
  }

  public List<String> getRecipients() {
    List<String> result = new ArrayList<String>();
    for (String recipient : itemsSelected) {
      result.add(oracle.getJid(recipient));
    }
    return result;
  }
 
  protected void fireComponentResized() {
    componentHelper.fireComponentResized(this);
  }

  protected void fireComponentShown() {
    componentHelper.fireComponentShown(this);
  }

  protected void fireComponentHidden() {
    componentHelper.fireComponentHidden(this);
  }

  protected void fireComponentMoved() {
    componentHelper.fireComponentMoved(this);
  }

  private void deselectItem(final TextBox itemBox, final BulletList list) {
    if (itemBox.getValue() != null && !"".equals(itemBox.getValue().trim())) {
      /**
       * Change to the following structure: <li class="token-input-token-facebook">
       * <p>
       * What's New Scooby-Doo?
       * </p>
       * <span class="token-input-delete-token-facebook">x</span></li>
       */

      final ListItem displayItem = new ListItem();
      displayItem.setStyleName("token-input-token-facebook");
      Paragraph p = new Paragraph(itemBox.getValue());

      displayItem.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent clickEvent) {
          displayItem
              .addStyleName("token-input-selected-token-facebook");
        }
      });

      /**
       * TODO: Figure out how to select item and allow deleting with
       * backspace key displayItem.addKeyDownHandler(new KeyDownHandler()
       * { public void onKeyDown(KeyDownEvent event) { if
       * (event.getNativeKeyCode() == KeyCodes.KEY_BACKSPACE) {
       * removeListItem(displayItem, list); } } });
       * displayItem.addBlurHandler(new BlurHandler() { public void
       * onBlur(BlurEvent blurEvent) { displayItem.removeStyleName(
       * "token-input-selected-token-facebook"); } });
       */

      Span span = new Span("x");
      span.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent clickEvent) {
          removeListItem(displayItem, list);
        }
      });

      displayItem.add(p);
      displayItem.add(span);
      // hold the original value of the item selected

      GWT.log("Adding selected item '" + itemBox.getValue() + "'", null);
      itemsSelected.add(itemBox.getValue());
      GWT.log("Total: " + itemsSelected, null);

      list.insert(displayItem, list.getWidgetCount() - 1);
      itemBox.setValue("");
      itemBox.setFocus(true);
     
      // notify the container that the List has changed
      fireComponentResized();
    }
  }

  private void removeListItem(ListItem displayItem, BulletList list) {
    GWT.log("Removing: "
        + displayItem.getWidget(0).getElement().getInnerHTML(), null);
    itemsSelected.remove(displayItem.getWidget(0).getElement()
        .getInnerHTML());
    list.remove(displayItem);
   
    fireComponentResized();
  }

}
TOP

Related Classes of org.onesocialweb.gwt.client.ui.widget.compose.RecipientList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.