/* * Copyright (C) 2013 Red Hat, Inc. and/or its affiliates. * * Licensed 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.jboss.errai.demo.grocery.client.local; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.persistence.EntityManager; import org.jboss.errai.databinding.client.api.DataBinder; import org.jboss.errai.databinding.client.api.StateSync; import org.jboss.errai.demo.grocery.client.local.convert.RelativeTimeConverter; import org.jboss.errai.demo.grocery.client.local.convert.UsernameConverter; import org.jboss.errai.demo.grocery.client.shared.Item; import org.jboss.errai.ioc.client.api.LoadAsync; import org.jboss.errai.ui.client.widget.HasModel; import org.jboss.errai.ui.shared.api.annotations.AutoBound; import org.jboss.errai.ui.shared.api.annotations.Bound; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; @Dependent @Templated("#main") @LoadAsync public class GroceryItemWidget extends Composite implements HasModel<Item> { private static Integer NEXT_AVAILABLE_ID = 0; private int id; @Inject protected EntityManager em; @Inject private @AutoBound DataBinder<Item> itemBinder; @Inject private @Bound @DataField Label name; @Inject private @Bound @DataField Label comment; @Inject private @Bound(property = "department.name") @DataField Label department; @Inject @DataField private SimplePanel formHolder; @Inject private EditForm itemEditForm; @Inject private Event<ItemEditNotifier> itemEditEvent; @Inject private Event<ItemEditNotifier> itemDeleteEvent; @Inject private @Bound @DataField CheckBox checkBox; private @Bound(converter = RelativeTimeConverter.class) @DataField final Element addedOn = DOM.createSpan(); private @Bound(converter = UsernameConverter.class) @DataField final Element addedBy = DOM.createSpan(); @Inject @DataField private Button deleteButton; @PostConstruct public void init() { this.id = NEXT_AVAILABLE_ID; NEXT_AVAILABLE_ID++; deleteButton.addStyleName("hidden"); formHolder.clear(); formHolder.add(itemEditForm); formHolder.addStyleName("hidden"); } /** * Changes the model object visualized by this class to the given one. * * @param item * The item that should become the model of this class. Must not be null. * @return The proxied version of the given item object, for purposes of data binding. If you intend to make any * changes to the state of the item after adding it to this widget, you must do so via this returned proxy. If * you modify the item directly (rather than via the proxy) then this UI widget will not update. */ @Override public void setModel(Item item) { System.out.println("ItemWidget: adopting model object " + System.identityHashCode(item)); itemBinder.setModel(item, StateSync.FROM_MODEL); } @Override public Item getModel() { return itemBinder.getModel(); } /** * The following functions handle user interaction with the web app * * @param event * The user-generated interactive event */ @EventHandler public void onMouseOver(MouseOverEvent event) { if (!inEditMode()) { String carpeDiem = getModel().getName(); System.out.println("MouseOver " + carpeDiem); addStyleName("active"); deleteButton.removeStyleName("hidden"); } } @EventHandler public void onMouseOut(MouseOutEvent event) { if (!inEditMode()) { System.out.println("MouseOut " + itemBinder.getModel().getName()); removeStyleName("active"); deleteButton.addStyleName("hidden"); } } @EventHandler public void onClick(ClickEvent event) { Item item = itemBinder.getModel(); Boolean currentValue = checkBox.getValue(); // Tick/untick checkbox if (currentValue.equals(false)) { checkBox.setValue(true); item.setCheckBox(true); addStyleName("completed"); } else { checkBox.setValue(false); item.setCheckBox(false); removeStyleName("completed"); } setModel(item); } @EventHandler public void onClick(DoubleClickEvent event) { System.out.println("Double click -- edit item"); itemEditEvent.fire(new ItemEditNotifier(id, ItemEditNotifier.EDIT_EVENT)); } @EventHandler("deleteButton") public void onDeleteButtonClicked(ClickEvent event) { event.preventDefault(); System.out.println("Delete item"); itemEditForm.storeOldItem(getModel(), this.id); itemDeleteEvent.fire(new ItemEditNotifier(this.id, ItemEditNotifier.DELETE_EVENT)); } /** * Private helper functions */ @SuppressWarnings("unused") private void processEditEvent(@Observes ItemEditNotifier notifier) { if (notifier.getNotifierType() == ItemEditNotifier.DELETE_EVENT) return; if (notifier.isCreatedBy(this.id)) { if (!inEditMode()) switchToEditMode(); Item oldItem = getModel(); setModel(itemEditForm.getItemBinder().getModel()); itemEditForm.storeOldItem(oldItem, id); } else { if (inEditMode()) { switchToDisplayMode(); } } } private void switchToEditMode() { hideOtherFields(); formHolder.removeStyleName("hidden"); } private void switchToDisplayMode() { formHolder.addStyleName("hidden"); showOtherFields(); } private boolean inEditMode() { if (formHolder.getStyleName().contains("hidden")) return false; return true; } private void hideOtherFields() { checkBox.addStyleName("hidden"); comment.addStyleName("hidden"); department.addStyleName("hidden"); addedBy.setAttribute("display", "none"); addedOn.setAttribute("display", "none"); } private void showOtherFields() { checkBox.removeStyleName("hidden"); comment.removeStyleName("hidden"); department.removeStyleName("hidden"); addedBy.removeAttribute("display"); addedOn.removeAttribute("display"); } /** * Close edit form from within widget and update widget data * @param item */ public void closeEditForm(Item item) { setModel(item); switchToDisplayMode(); } @PreDestroy private void toBeDestroyed() { System.out.println("GroceryItemWidget for " + name + " is being destroyed."); } }