Last active
September 16, 2015 10:01
-
-
Save nabil-hassan/20db1c07a132dfaab346 to your computer and use it in GitHub Desktop.
GWT CompositeEditor Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.nabilh.gwtsandbox.client.widgets.form.phone; | |
import com.google.gwt.core.client.GWT; | |
import com.google.gwt.editor.client.CompositeEditor; | |
import com.google.gwt.editor.client.EditorDelegate; | |
import com.google.gwt.editor.client.LeafValueEditor; | |
import com.google.gwt.event.dom.client.ClickEvent; | |
import com.google.gwt.uibinder.client.UiBinder; | |
import com.google.gwt.uibinder.client.UiConstructor; | |
import com.google.gwt.uibinder.client.UiField; | |
import com.google.gwt.uibinder.client.UiHandler; | |
import com.google.gwt.user.client.Window; | |
import com.google.gwt.user.client.ui.Button; | |
import com.google.gwt.user.client.ui.Composite; | |
import com.google.gwt.user.client.ui.VerticalPanel; | |
import com.google.gwt.user.client.ui.Widget; | |
import net.nabilh.gwtsandbox.shared.dto.PhoneNumberDTO; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.logging.Logger; | |
/** | |
* This widget implements {@link com.google.gwt.editor.client.CompositeEditor} to represent a | |
* list of {@link PhoneNumberField} widgets as rows, which the user can add to and remove from using embedded controls.<br/><br/> | |
* Author: Nabil Hassan <br/> | |
* Date: 08/09/2015 18:11 <br/> | |
*/ | |
public class PhoneNumberListField extends Composite implements CompositeEditor<List<PhoneNumberDTO>, PhoneNumberDTO, PhoneNumberField>, LeafValueEditor<List<PhoneNumberDTO>> { | |
public static final Logger LOG = Logger.getLogger(PhoneNumberListField.class.getName()); | |
interface Binder extends UiBinder<Widget, PhoneNumberListField> {} | |
private static Binder uiBinder = GWT.create(Binder.class); | |
private List<PhoneNumberField> rows = new ArrayList<PhoneNumberField>(); | |
private CompositeEditor.EditorChain<PhoneNumberDTO, PhoneNumberField> editorChain; | |
private EditorDelegate<List<PhoneNumberDTO>> editorDelegate; | |
@UiField | |
Button addBtn, removeBtn; | |
@UiField | |
VerticalPanel panel; | |
private int sizeLimit; | |
@UiConstructor | |
public PhoneNumberListField(int sizeLimit) { | |
this.sizeLimit = sizeLimit; | |
initWidget(uiBinder.createAndBindUi(this)); | |
panel.getElement().setAttribute("cellpadding", "5"); | |
} | |
@Override | |
public PhoneNumberField createEditorForTraversal() { | |
LOG.finest("Creating new sub-editor for traversal"); | |
return new PhoneNumberField(); | |
} | |
@Override | |
public String getPathElement(PhoneNumberField phoneNumberField) { | |
LOG.finest("getPathElement() called for phoneNumberField: " + phoneNumberField); | |
return "[" + rows.indexOf(phoneNumberField) + "]"; | |
} | |
@Override | |
public void setValue(List<PhoneNumberDTO> phoneNumberDTOs) { | |
LOG.finest("setValue() called on: " + editorDelegate.getPath()); | |
// Clear and detach current sub-editor list. | |
if (rows != null && rows.size() > 0) { | |
LOG.finest("Clearing current sub-editor list of " + rows.size() + " rows"); | |
for (PhoneNumberField row : rows) { | |
editorChain.detach(row); | |
} | |
rows.clear(); | |
panel.clear(); | |
} | |
// Setup the new editor chain. | |
if (phoneNumberDTOs != null) { | |
for (PhoneNumberDTO dto : phoneNumberDTOs) { | |
addPhoneNumberToList(dto, false); | |
} | |
} | |
} | |
@Override | |
public List<PhoneNumberDTO> getValue() { | |
LOG.finest("getValue() called on: " + editorDelegate.getPath()); | |
List<PhoneNumberDTO> value = new ArrayList<PhoneNumberDTO>(); | |
for (PhoneNumberField field : rows) { | |
value.add(editorChain.getValue(field)); | |
} | |
LOG.finest("Returning a list of " + value.size() + " values"); | |
return value; | |
} | |
@Override | |
public void setDelegate(EditorDelegate<List<PhoneNumberDTO>> editorDelegate) { | |
this.editorDelegate = editorDelegate; | |
} | |
@Override | |
public void setEditorChain(EditorChain<PhoneNumberDTO, PhoneNumberField> editorChain) { | |
this.editorChain = editorChain; | |
} | |
@Override | |
public void flush() { | |
// Not implemented | |
} | |
@Override | |
public void onPropertyChange(String... strings) { | |
// Not implemented | |
} | |
@UiHandler("addBtn") | |
public void handleClick_addBtn(ClickEvent event) { | |
addPhoneNumberToList(new PhoneNumberDTO(), true); | |
} | |
@UiHandler("removeBtn") | |
public void handleClick_removeBtn(ClickEvent event) { | |
if (rows != null && rows.size() > 0) { | |
PhoneNumberField phoneNo = rows.get(rows.size() - 1); | |
LOG.finest("Removing phone number: " + phoneNo); | |
editorChain.detach(phoneNo); | |
rows.remove(phoneNo); | |
panel.remove(phoneNo); | |
} | |
} | |
private void addPhoneNumberToList(PhoneNumberDTO dto, boolean enforceSizeLimit) { | |
// Prevent the user from adding further phone numbers when the size limit has been reached. | |
// N.B. the size limit is not enforced when called from setValue() (i.e. when loading). | |
if (enforceSizeLimit && rows.size() >= sizeLimit) { | |
Window.alert("Cannot add further phone numbers, size limit of: " + sizeLimit + " has been reached"); | |
return; | |
} | |
LOG.finer("Adding sub-editor for phone number DTO: " + dto); | |
PhoneNumberField phoneNoField = new PhoneNumberField(); | |
phoneNoField.setLabelText("Phone No " + (rows.size() + 1)); | |
panel.add(phoneNoField); | |
rows.add(phoneNoField); | |
editorChain.attach(dto, phoneNoField); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' | |
xmlns:g='urn:import:com.google.gwt.user.client.ui'> | |
<g:VerticalPanel> | |
<g:HorizontalPanel spacing="5"> | |
<g:Button ui:field="addBtn" text="Add Phone No"/> | |
<g:Button ui:field="removeBtn" text="Remove Phone No"/> | |
</g:HorizontalPanel> | |
<g:VerticalPanel ui:field="panel"> | |
<!-- Phone Number Fields Will Be Attached Here --> | |
</g:VerticalPanel> | |
</g:VerticalPanel> | |
</ui:UiBinder> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment