We will first create the EditContactEvent class and the EditContactEventHanlder interface. After that, we shall reuse the contact popup to allow the user to edit the clicked contact on the contact list.
The EditContactEvent and its Handler
Lets first create the necessary EditContactEvent class and EditContactEventHandler interface. The EditContactEventHandler interface will look like this:package gaej.example.contacts.client.event;
import com.google.gwt.event.shared.EventHandler;
public interface EditContactEventHandler extends EventHandler {
void onEditContact(EditContactEvent event);
}
Next, we add the EditContactEvent class:
package gaej.example.contacts.client.event;
import com.google.gwt.event.shared.GwtEvent;
public class EditContactEvent extends GwtEvent<EditContactEventHandler> {
public static Type<EditContactEventHandler> TYPE = new Type<EditContactEventHandler>();
private final String id;
public EditContactEvent(String id) {
this.id = id;
}
public String getId() {
return id;
}
@Override
protected void dispatch(EditContactEventHandler handler) {
handler.onEditContact(this);
}
@Override
public com.google.gwt.event.shared.GwtEvent.Type<EditContactEventHandler> getAssociatedType() {
return TYPE;
}
}
Notice that our EditContactEvent class now has a constructor which takes a String parameter. This parameter stores the id of the contact that we want to edit in a private String property called id. We have a public method getId() to retrieve the value stored in this property.
Putting the Event to Use
Let's put this the new event we created to use. What we will do is create a binding to the Contact List widget in our ContactsPresenter. Open up ContactsPresenter.java and in the bind() method add the following piece of code:display.getList().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
int selectedRow = display.getClickedRow(event);
if ( selectedRow >= 0) {
String id = contactsLight.get(selectedRow).getId();
eventBus.fireEvent(new EditContactEvent(id));
}
}
});
What happens here? We add a ClickHandler to our List widget. When this list is clicked we use getClickedRow(event) method to retrieve which row was clicked. Now remember that, when we first navigated to the screen, we populated a private List property called contactsLight. The ordering of this list matches the ordering of the list on the screen, so the number of the row clicked will match the record number in the list. Using this record number, we retrieve the id that belongs to the Contact displayed on that record.
All good and well, but don't forget we only stubbed out the method getClickedRow(event) in the ContactsView! We need to create the logic fist so that the view can actually return back the number of the row clicked! Let's do that now. Open up ContactsView and edit the getClickedRow(ClickEvent event) method so that it looks as follows:
@Override
public int getClickedRow(ClickEvent event) {
int selectedRow = -1;
HTMLTable.Cell cell = contactsList.getCellForEvent(event);
// Check for null and suppress if event click is on a check box
if (cell != null) {
if ( cell.getCellIndex() > 0 ) {
selectedRow = cell.getRowIndex();
}
}
return selectedRow;
}
Ok, now we have the logic that retrieves the number of the row clicked. We don't want to raise an event when the user checks the checkbox, so we make sure to include that logic. Now that we got the row number that the user clicked, we lookup the corresponding Contact's id, create a new EditContactEvent, and store the clicked Contact's id in it. Excellent, now someone needs to pick up this event and do something with it.
Reusing the Popup
We now have an event that contains the id of the Contact we like to edit. Since we already have a popup that provides the necessary fields for a contact (firstName, lastName, and email) why not use that for editing as well?Let's add the necessary logic to the ContactPopupPresenter. Open it up and add the following method to it:
private void retrieveContact(String id) {
rpcService.getContact(id, new AsyncCallback<Contact>() {
public void onSuccess(Contact result) {
contact = result;
setValues();
}
public void onFailure(Throwable caught) {
Window.alert("Failed to retrieve contact!");
}
});
}
The first method takes an id string and searches for the appropriate Contact object. We use the rpcService to retrieve it. If successfully retrieved, the private property contact is populated with the retrieved contact object. We then call the setValues() method to display the information of this contact object in the popup.
Let's now add the necessary binding so that when an EditContactEvent is raised, we pick it up and call the new retrieveContact(String id) method. Add the following code to the bind() method in the ContactPopupPresenter class:
eventBus.addHandler(EditContactEvent.TYPE, new EditContactEventHandler() {
@Override
public void onEditContact(EditContactEvent event) {
retrieveContact(event.getId());
display.getDialogBox().center();
}
});
That should be it! Your updated ContactPopupPresenter will now look like this:
package gaej.example.contacts.client.presenter;
import gaej.example.contacts.client.ContactsServiceAsync;
import gaej.example.contacts.shared.Contact;
import gaej.example.contacts.shared.ContactImpl;
import gaej.example.contacts.client.event.AddContactEvent;
import gaej.example.contacts.client.event.AddContactEventHandler;
import gaej.example.contacts.client.event.SavedContactEvent;
import gaej.example.contacts.client.event.EditContactEvent;
import gaej.example.contacts.client.event.EditContactEventHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
public class ContactPopupPresenter implements Presenter {
public interface Display {
HasClickHandlers getSaveButton();
HasClickHandlers getCancelButton();
HasValue<String> getFirstName();
HasValue<String> getLastName();
HasValue<String> getEmail();
DialogBox getDialogBox();
Widget asWidget();
}
private Contact contact;
private final HandlerManager eventBus;
private final ContactsServiceAsync rpcService;
private final Display display;
public ContactPopupPresenter(HandlerManager eventBus, ContactsServiceAsync rpcService, Display display) {
this.eventBus = eventBus;
this.rpcService = rpcService;
this.display = display;
bind();
}
private void bind() {
eventBus.addHandler(AddContactEvent.TYPE, new AddContactEventHandler() {
@Override
public void onAddContact(AddContactEvent event) {
contact = new ContactImpl();
display.getDialogBox().center();
}
});
eventBus.addHandler(EditContactEvent.TYPE, new EditContactEventHandler() {
@Override
public void onEditContact(EditContactEvent event) {
retrieveContact(event.getId());
display.getDialogBox().center();
}
});
display.getCancelButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
display.getDialogBox().hide();
}
});
display.getSaveButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event){
doUpdate();
display.getDialogBox().hide();
}
});
}
private void doUpdate() {
contact.setFirstName(display.getFirstName().getValue());
contact.setLastName(display.getLastName().getValue());
contact.setEmail(display.getEmail().getValue());
rpcService.updateContact(contact, new AsyncCallback<Contact>() {
public void onSuccess(Contact result) {
eventBus.fireEvent(new SavedContactEvent());
}
public void onFailure(Throwable caught) {
Window.alert("Failed to save contact!");
}
});
}
private void retrieveContact(String id) {
rpcService.getContact(id, new AsyncCallback<Contact>() {
public void onSuccess(Contact result) {
contact = result;
setValues();
}
public void onFailure(Throwable caught) {
Window.alert("Failed to retrieve contact!");
}
});
}
private void setValues() {
ContactPopupPresenter.this.display.getFirstName().setValue(contact.getFirstName());
ContactPopupPresenter.this.display.getLastName().setValue(contact.getLastName());
ContactPopupPresenter.this.display.getEmail().setValue(contact.getEmail());
}
@Override
public void go(HasWidgets container) {
// Nothing to bind to - we are a popup!
}
}
Fire it up and lets see if it really does the trick. Click on a contact, edit it, and then press Save. Notice that the popup closes and the Contact is updated in the contact list.
Now it's time to add the delete function!

No comments:
Post a Comment