package org.aplikator.client.local.widgets; import java.util.ArrayList; import java.util.List; import org.aplikator.client.local.Aplikator; import org.aplikator.client.shared.data.ContainerNodeDTO; import org.aplikator.client.shared.data.Operation; import org.aplikator.client.shared.data.PrimaryKey; import org.aplikator.client.shared.data.RecordContainerDTO; import org.aplikator.client.shared.data.RecordDTO; import org.aplikator.client.shared.descriptor.PropertyDTO; import org.aplikator.client.shared.descriptor.RecordsPageDTO; import org.aplikator.client.shared.descriptor.ViewDTO; import org.aplikator.client.shared.rpc.AplikatorErrorCallback; import org.aplikator.client.shared.rpc.AplikatorService; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.Column; import org.gwtbootstrap3.client.ui.FormLabel; import org.gwtbootstrap3.client.ui.Row; import org.gwtbootstrap3.client.ui.Well; import org.gwtbootstrap3.client.ui.constants.ButtonSize; import org.gwtbootstrap3.client.ui.constants.ColumnSize; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.constants.Pull; import org.gwtbootstrap3.client.ui.html.Div; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.enterprise.client.jaxrs.api.RestClient; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Widget; public class RepeatedFormWidget extends ContainerFieldBase implements NestedCollectionWidget { private static final int BUTTON_HOLDER_WIDTH = 40; RecordContainerDTO recordContainerDTO; private List<FormWidget> nestedForms = new ArrayList<FormWidget>(); private Button buttonCreate; private ViewDTO view; private List<RecordDTO> pageData; private PrimaryKey ownerPrimaryKey; private String ownerPropertyId; private HasFields ownerForm; private boolean enabled = true; private boolean defaultSortId = false; public RepeatedFormWidget(ViewDTO view, PropertyDTO ownerProperty, String localizedName, HasFields ownerForm, boolean enabled, int size, boolean defaultSortId) { super(); this.view = view; this.ownerPropertyId = ownerProperty.getId(); this.ownerForm = ownerForm; this.enabled = enabled; this.defaultSortId = defaultSortId; Well well = new Well(); well.getElement().getStyle().setPosition(Style.Position.RELATIVE); well.addStyleName("clearfix"); wrapper = new Column(ColumnSize.XS_1); this.label = new FormLabel(); this.label.setText(localizedName); this.label.addStyleName("fieldLabel"); initWidget(wrapper); wrapper.add(this.label); wrapper.add(well); setGridSize(size); if (this.view.getSortDescriptors().size() > 0) { this.view.setActiveSort(this.view.getSortDescriptors().get(0).getId()); } // forms container dataPanel = new Column(LayoutUtils.size(12)); buttonCreate = new Button("", IconType.PLUS, new ClickHandler() { public void onClick(ClickEvent event) { RepeatedFormWidget.this.buttonCreateClicked(); } }); buttonCreate.setSize(ButtonSize.DEFAULT); buttonCreate.getElement().getStyle().setMarginTop(5, Style.Unit.PX); buttonCreate.setEnabled(enabled); well.add(dataPanel); well.add(LayoutUtils.addTooltip(buttonCreate, Aplikator.application.getConfigString("aplikator.repeated.create"))); } @Override public void reload() { dataPanel.clear(); dataPanel.add(new LoadingLabel()); RestClient.create(AplikatorService.class, new RemoteCallback<RecordsPageDTO>() { @Override public void callback(RecordsPageDTO resp) { RepeatedFormWidget.this.pageData = resp.getRecords(); redrawPage(null); } }, new AplikatorErrorCallback("aplikator.table.loaderror") ).getRecords(view.getId(), null, defaultSortId ? view.getActiveSort() : null, null, null, ownerPropertyId, (ownerPrimaryKey == null) ? null : ownerPrimaryKey.getSerializationString(), 0, -1); } @Override public void initFromContainer(RecordContainerDTO initializingRecords) { pageData = new ArrayList<RecordDTO>(); for (ContainerNodeDTO containerNode : initializingRecords.getRecords()) { if (ownerPropertyId.equals(containerNode.getEdited().getOwnerPropertyId())) { pageData.add(containerNode.getEdited()); recordContainerDTO.addRecord(view.getId(), containerNode.getEdited(), containerNode.getEdited(), Operation.CREATE); } } redrawPage(initializingRecords); } @Override public void setEnabled(boolean enabled) { this.enabled = enabled; redrawPage(null); } private void repositionButtonCreate() { if (!nestedForms.isEmpty()) { Widget lastForm = ((Column) dataPanel).getWidget(nestedForms.size() - 1); lastForm.removeStyleName("repeatedForm"); lastForm.addStyleName("lastRepeatedForm"); if (lastForm.getOffsetHeight() < 80) { buttonCreate.removeStyleName("button-create-shift-up"); } else { buttonCreate.addStyleName("button-create-shift-up"); } } else { buttonCreate.removeStyleName("button-create-shift-up"); } } private void redrawPage(RecordContainerDTO initializingRecords) { dataPanel.clear(); nestedForms.clear(); for (int i = 1; i <= pageData.size(); i++) { FormWidget form = new FormWidget(this.view, null, ownerForm); form.displayRecord(pageData.get(i - 1).getPrimaryKey(), recordContainerDTO, ownerPropertyId, ownerPrimaryKey, initializingRecords); addForm(form); } repositionButtonCreate(); } private void buttonCreateClicked() { if (!nestedForms.isEmpty()) { Widget lastForm = ((Column) dataPanel).getWidget(nestedForms.size() - 1); lastForm.removeStyleName("lastRepeatedForm"); lastForm.addStyleName("repeatedForm"); } FormWidget form = new FormWidget(this.view, null, ownerForm); form.addRecord(recordContainerDTO, ownerPropertyId, ownerPrimaryKey, null, new AddRecordCallback() { @Override public void recordAdded(RecordDTO recordDTO) { pageData.add(recordDTO); } }); addForm(form); if (ownerForm != null) { ownerForm.setDirty(true); } repositionButtonCreate(); } private void buttonDeleteClicked(FormWidget form) { for (int i = 0; i < nestedForms.size(); i++) { if (form == nestedForms.get(i)) { RecordDTO orig = pageData.get(i); if (orig == null) { return; } nestedForms.remove(i); ((Column) dataPanel).remove(i); recordContainerDTO.addRecord(view.getId(), orig, null, Operation.DELETE); pageData.remove(i); if (ownerForm != null) { ownerForm.setDirty(true); } break; } } repositionButtonCreate(); } private void addForm(final FormWidget form) { nestedForms.add(form); Button buttonDelete = new Button("", IconType.TRASH_O, new ClickHandler() { public void onClick(ClickEvent event) { RepeatedFormWidget.this.buttonDeleteClicked(form); } }); buttonDelete.setSize(ButtonSize.DEFAULT); buttonDelete.setEnabled(enabled); form.setEnabled(enabled); Div formHolder = new Div(); formHolder.add(form); formHolder.getElement().getStyle().setProperty("width", "calc( 100% - " + BUTTON_HOLDER_WIDTH + "px)"); formHolder.setPull(Pull.RIGHT); Div buttonHolder = new Div(); buttonHolder.getElement().getStyle().setWidth(BUTTON_HOLDER_WIDTH, Style.Unit.PX); buttonHolder.add(LayoutUtils.addTooltip(buttonDelete, Aplikator.application.getConfigString("aplikator.table.delete"))); buttonHolder.getElement().getStyle().setPaddingLeft(0, Style.Unit.PX); buttonHolder.getElement().getStyle().setPaddingRight(0, Style.Unit.PX); buttonHolder.getElement().getStyle().setMarginTop(5, Style.Unit.PX); buttonHolder.setPull(Pull.LEFT); Row holder = new Row(); holder.addStyleName("repeatedForm"); holder.add(buttonHolder); holder.add(formHolder); dataPanel.add(holder); } public PrimaryKey getOwnerPrimaryKey() { return ownerPrimaryKey; } public void setOwnerPrimaryKey(PrimaryKey value) { ownerPrimaryKey = value; } public void setRecordContainerDTO(RecordContainerDTO recordContainerDTO) { this.recordContainerDTO = recordContainerDTO; } @Override public void save() { for (FormWidget nestedForm : nestedForms) { if (nestedForm.isDirty()) { nestedForm.save(false); } } } public void setDirty(boolean dirty) { for (FormWidget nestedForm : nestedForms) { nestedForm.setNestedDirty(dirty); } } }