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);
}
}
}