Package com.todo.client

Source Code of com.todo.client.ToDoCell$Templates

package com.todo.client;

import java.util.Date;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.todo.client.events.ToDoEvent;
import com.todo.client.events.ToDoRemovedEvent;
import com.todo.client.events.ToDoUpdatedEvent;

/**
* A cell that renders {@link ToDoItem} instances. This cell is rendered in both view and edit modes
* based on user interaction. In edit mode, browser events are handled in order to update the model
* item state.
*
* @author ceberhardt
*
*/
public class ToDoCell extends AbstractCell<ToDoItem> {

  /**
   * The HTML templates used to render the cell.
   */
  interface Templates extends SafeHtmlTemplates {

    /**
     * The view-mode template
     */
    @SafeHtmlTemplates.Template("<div class='{2}' data-timestamp='{3}'>" + "{0} "
        + "<label>{1}</label>" + "<button class='destroy'></a>" + "</div>")
    SafeHtml view(SafeHtml checked, SafeHtml task, String done, String timestamp);

    /**
     * A template the renders a checked input
     */
    @SafeHtmlTemplates.Template("<input class='toggle' type='checkbox' checked>")
    SafeHtml inputChecked();

    /**
     * A template the renders an un-checked input
     */
    @SafeHtmlTemplates.Template("<input class='toggle' type='checkbox'>")
    SafeHtml inputClear();

    /**
     * The edit-mode template
     */
    @SafeHtmlTemplates.Template("<div class='listItem editing'><input class='edit' value='{0}' type='text'></div>")
    SafeHtml edit(String task);
  }

  private static Templates templates = GWT.create(Templates.class);

  /**
   * The item that is currently being edited
   */
  private ToDoItem editingItem = null;

  /**
   * A flag that indicates that we are starting to edit the cell
   */
  private boolean beginningEdit = false;

  private EventBus eventBus;

  public ToDoCell() {
    super("click", "keyup", "blur", "dblclick");
    eventBus = ToDoEvent.getGlobalEventBus();
  }

  @Override
  public void render(Context context, ToDoItem value, SafeHtmlBuilder sb) {
    // render the cell in edit or view mode
    if (isEditing(value)) {
      SafeHtml rendered = templates.edit(value.getTitle());
      sb.append(rendered);
    } else {
      SafeHtml rendered =
          templates.view(value.isCompleted() ? templates.inputChecked() : templates.inputClear(),
              SafeHtmlUtils.fromString(value.getTitle()), value.isCompleted() ? "listItem view completed"
                  : "listItem view",
              // NOTE: The addition of a timestamp here is a bit of a HACK! The problem
              // is that the CellList uses a HasDataPresenter for rendering. This class
              // caches the more recent rendered contents for each cell, skipping a render
              // if it looks like the cell hasn't changed. However, this fails for editable cells
              // that are able to change the DOM representation directly. This hack simply
              // ensures that the presenter always renders the cell.
              Long.toString(new Date().getTime()));
      sb.append(rendered);
    }
  }

  @Override
  public boolean isEditing(Context context, Element parent, ToDoItem value) {
    return isEditing(value);
  }

  @Override
  public void onBrowserEvent(Context context, Element parent, ToDoItem value, NativeEvent event,
      ValueUpdater<ToDoItem> valueUpdater) {

    String type = event.getType();

    if (isEditing(value)) {

      // handle keyup events
      if ("keyup".equals(type)) {
        int keyCode = event.getKeyCode();

        // handle enter key to commit the edit
        if (keyCode == KeyCodes.KEY_ENTER) {
          commitEdit(parent, value);
          endEdit(context, parent, value);
        }

        // handle escape key to cancel the edit
        if (keyCode == KeyCodes.KEY_ESCAPE) {
          endEdit(context, parent, value);
        }
      }

      // handle blur event
      if ("blur".equals(type) && !beginningEdit) {
        commitEdit(parent, value);
        endEdit(context, parent, value);
      }

    } else {

      // handle double clicks to enter edit more
      if ("dblclick".equals(type)) {
        beginEdit(context, parent, value);

        beginningEdit = true;
        InputElement input = getInputElement(parent);
        input.focus();
        beginningEdit = false;
      }

      // when not in edit mode - handle click events on the cell
      if ("click".equals(type)) {

        EventTarget eventTarget = event.getEventTarget();
        Element clickedElement = Element.as(eventTarget);
        String tagName = clickedElement.getTagName();

        // check whether the checkbox was clicked
        if (tagName.equals("INPUT")) {

          // if so, synchronize the model state
          InputElement input = clickedElement.cast();
          value.setCompleted(input.isChecked());
          eventBus.fireEvent(new ToDoUpdatedEvent(value));

          // update the 'row' style
          if (input.isChecked()) {
            getViewRootElement(parent).addClassName("completed");
          } else {
            getViewRootElement(parent).removeClassName("completed");
          }

        } else if (tagName.equals("BUTTON")) {
          // if the delete anchor was clicked - delete the item
          eventBus.fireEvent(new ToDoRemovedEvent(value));
        }
      }
    }

  }

  /**
   * Commits the changes in text value to the ToDoItem
   */
  private void commitEdit(Element parent, ToDoItem value) {
    InputElement input = getInputElement(parent);
    value.setTitle(input.getValue());
    eventBus.fireEvent(new ToDoUpdatedEvent(value));
  }

  /**
   * Begins editing the given item, rendering the cell in edit mode
   */
  private void beginEdit(Context context, Element parent, ToDoItem value) {
    editingItem = value;
    renderCell(context, parent, value);
  }

  /**
   * Ends editing the given item, rendering the cell in view mode
   */
  private void endEdit(Context context, Element parent, ToDoItem value) {
    editingItem = null;
    renderCell(context, parent, value);
  }

  /**
   * Renders the cell, replacing the contents of the parent with the newly rendered content.
   */
  private void renderCell(Context context, Element parent, ToDoItem value) {
    SafeHtmlBuilder sb = new SafeHtmlBuilder();
    render(context, value, sb);
    parent.setInnerHTML(sb.toSafeHtml().asString());
  }

  /**
   * Gets whether the given item is being edited.
   */
  private boolean isEditing(ToDoItem item) {
    return editingItem == item;
  }

  /**
   * Get the input element in edit mode.
   */
  private InputElement getInputElement(Element parent) {
    return parent.getFirstChild().getFirstChild().<InputElement> cast();
  }

  /**
   * Gets the root DIV element of the view mode template.
   */
  private DivElement getViewRootElement(Element parent) {
    return parent.getFirstChild().<DivElement> cast();
  }

}
TOP

Related Classes of com.todo.client.ToDoCell$Templates

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.