package org.aplikator.client.local.widgets; import org.aplikator.client.local.Aplikator; import org.aplikator.client.shared.data.ItemSuggestion; import org.aplikator.client.shared.data.RecordDTO; import org.aplikator.client.shared.descriptor.PropertyDTO; import org.aplikator.client.shared.descriptor.SuggestionsDTO; 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.Modal; import org.gwtbootstrap3.client.ui.ModalBody; import org.gwtbootstrap3.client.ui.Row; import org.gwtbootstrap3.client.ui.SuggestBox; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.Well; import org.gwtbootstrap3.client.ui.constants.ColumnSize; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.constants.ModalBackdrop; import org.gwtbootstrap3.client.ui.constants.Pull; import org.gwtbootstrap3.client.ui.html.Div; import org.gwtbootstrap3.client.ui.html.Span; import org.jboss.errai.common.client.api.ErrorCallback; 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.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.SuggestOracle; import com.google.gwt.user.client.ui.SuggestOracle.Suggestion; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SingleSelectionModel; public class ReferenceFieldWidget extends ContainerFieldBase implements DataField<Integer> { Row searchPanel; Row formPanel; private Button buttonSearch; private Button buttonDelete; private final Button buttonSwitch; private SuggestBox typeahead; private TextBox searchBox; private boolean searchBoxActive = false; private Integer value;// TODO change to pk private PropertyDTO property; private ViewDTO view; private TableListerWidget table; private Modal dialogBox; private ModalBody dialogContents; private RecordDTO selectedRecordDTO = null; private boolean dirty; public ReferenceFieldWidget(String caption, ViewDTO view, Widget child, int size) { super(); this.view = view; wrapper = new Column(ColumnSize.XS_1); initWidget(wrapper); this.label = new FormLabel(); this.label.addStyleName("fieldLabel"); this.label.setText(caption); if (caption != null && !"".equals(caption) && !"null".equals(caption)) { wrapper.add(this.label); } setGridSize(size); // forms container dataPanel = new Row(); dataPanel.add(child); buttonSearch = new Button("", IconType.SEARCH, new ClickHandler() { public void onClick(ClickEvent event) { if (dialogBox == null) { dialogBox = createDialogBox(); } dialogBox.setPixelSize(Window.getClientWidth() - 40, Window.getClientHeight()); dialogBox.show(); if (ReferenceFieldWidget.this.view.getActivePrimarySortProperty() != null && searchBoxActive) { ReferenceFieldWidget.this.view.setSearchString(searchBox.getText()); } table.refresh(); } }); Widget buttonSearchWrapper = LayoutUtils.addTooltip(buttonSearch, Aplikator.application.getConfigString("aplikator.reference.search")); //buttonSearchWrapper.getElement().getStyle().setDisplay(Style.Display.INLINE_BLOCK); buttonSearch.getElement().getStyle().setDisplay(Style.Display.TABLE_CELL); buttonSearch.getElement().getStyle().setProperty("width", "auto"); buttonSearch.getElement().getStyle().setVerticalAlign(Style.VerticalAlign.BASELINE); buttonDelete = new Button("", IconType.TRASH_O, new ClickHandler() { public void onClick(ClickEvent event) { selectedRecordDTO = null; resetSearchBox(); setValue(-1, true); buttonDelete.setVisible(false); } }); buttonDelete.getElement().getStyle().setMarginLeft(0, Style.Unit.PX); buttonDelete.getElement().getStyle().setMarginBottom(10, Style.Unit.PX); buttonDelete.getElement().getStyle().setMarginRight(0, Style.Unit.PX); Widget buttonDeleteWrapper = LayoutUtils.addTooltip(buttonDelete, Aplikator.application.getConfigString("aplikator.reference.delete")); buttonDelete.setVisible(false); searchPanel = new Row(); //searchPanel.addStyleName("refHeader"); searchPanel.getElement().getStyle().setMarginLeft(0, Style.Unit.PX); searchPanel.getElement().getStyle().setMarginRight(0, Style.Unit.PX); Div searchBlock = new Div(); searchBlock.getElement().getStyle().setMarginTop(0, Style.Unit.PX); searchBlock.getElement().getStyle().setMarginBottom(0, Style.Unit.PX); searchBlock.getElement().getStyle().setPaddingLeft(15, Style.Unit.PX); searchBlock.setPull(Pull.LEFT); searchBlock.getElement().getStyle().setProperty("width", "calc( 100% - 40px )"); searchBlock.getElement().getStyle().setDisplay(Style.Display.TABLE); Div deleteBlock = new Div(); deleteBlock.getElement().getStyle().setMarginTop(0, Style.Unit.PX); deleteBlock.getElement().getStyle().setMarginBottom(0, Style.Unit.PX); deleteBlock.setPull(Pull.RIGHT); deleteBlock.add(buttonDeleteWrapper); if (view.getActivePrimarySortProperty() != null) { ItemSuggestOracle oracle = new ItemSuggestOracle(); searchBox = new TextBox(); //searchBox.getElement().getStyle().setProperty("maxWidth", "100px"); //searchBox.getElement().getStyle().setDisplay(Style.Display.INLINE_BLOCK); searchBox.getElement().getStyle().setDisplay(Style.Display.TABLE_CELL); searchBox.getElement().getStyle().setProperty("width", "auto"); typeahead = new SuggestBox(oracle, searchBox); resetSearchBox(); //searchBox.setStyleName(RefFormWidgetResources.INSTANCE.css().refSearchLeft()); searchBox.addFocusHandler(new FocusHandler() { public void onFocus(FocusEvent event) { searchBox.setText(""); searchBoxActive = true; } }); typeahead.addSelectionHandler(new SelectionHandler<Suggestion>() { @Override public void onSelection(SelectionEvent<Suggestion> se) { ItemSuggestion selectedSuggestion = (ItemSuggestion) se.getSelectedItem(); int id = selectedSuggestion.getId(); selectedRecordDTO = ((ItemSuggestion) selectedSuggestion).getRecord(); setValue(id, true); } }); typeahead.getElement().getStyle().setDisplay(Style.Display.TABLE_CELL); Span prepend = new Span(); prepend.setText(Aplikator.application.getConfigString("aplikator.reference.searchby")); prepend.getElement().getStyle().setMarginRight(5, Style.Unit.PX); //prepend.getElement().getStyle().setDisplay(Style.Display.TABLE_CELL); //prepend.getElement().getStyle().setProperty("width","auto"); searchBlock.add(prepend); searchBlock.add(typeahead); searchBlock.add(buttonSearch); } else { searchBlock.add(buttonSearch); } searchPanel.add(searchBlock); searchPanel.add(deleteBlock); buttonSwitch = new Button(""); buttonSwitch.setIcon(IconType.EDIT); buttonSwitch.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { searchPanel.setVisible(true); searchPanel.addStyleName("refHeader"); buttonSwitch.setVisible(false); buttonDelete.setVisible(true); } }); buttonSwitch.getElement().getStyle().setMarginLeft(0, Style.Unit.PX); buttonSwitch.getElement().getStyle().setMarginBottom(10, Style.Unit.PX); buttonSwitch.getElement().getStyle().setMarginRight(0, Style.Unit.PX); formPanel = new Row(); formPanel.getElement().getStyle().setMarginLeft(0, Style.Unit.PX); formPanel.getElement().getStyle().setMarginRight(0, Style.Unit.PX); Column formHolder = new Column(LayoutUtils.size(11), dataPanel); formHolder.getElement().getStyle().setProperty("width", "calc( 100% - 45px )"); Column buttonHolder = new Column(LayoutUtils.size(1), LayoutUtils.addTooltip(buttonSwitch, Aplikator.application.getConfigString("aplikator.reference.switch"))); buttonHolder.getElement().getStyle().setWidth(40, Style.Unit.PX); buttonHolder.getElement().getStyle().setFloat(Style.Float.RIGHT); //formHolder.getElement().getStyle().setPaddingRight(0, Style.Unit.PX); //formHolder.getElement().getStyle().setPaddingLeft(0, Style.Unit.PX); buttonHolder.getElement().getStyle().setPaddingLeft(0, Style.Unit.PX); buttonHolder.getElement().getStyle().setPaddingRight(0, Style.Unit.PX); formPanel.add(formHolder); formPanel.add(buttonHolder); searchPanel.setVisible(true); formPanel.setVisible(false); Well well = new Well(); wrapper.add(well); well.add(searchPanel); well.add(formPanel); } private void resetSearchBox() { if (view.getActivePrimarySortProperty() != null) { searchBox.setText(view.getActivePrimarySortProperty().getLocalizedName() + ":"); searchBoxActive = false; } } public PropertyDTO getProperty() { return property; } public void setProperty(PropertyDTO property) { this.property = property; } public void setValue(Integer value) { setValue(value, false); selectedRecordDTO = null; resetSearchBox(); } public void setValue(Integer value, boolean fireEvents) { Integer oldValue = this.value; this.value = value; if (fireEvents) { //if (value != null && !value.equals(oldValue)) { setDirty(true); //} ValueChangeEvent.fire(this, value); } if (value != null && value.intValue() > 0) { searchPanel.setVisible(false); formPanel.setVisible(true); buttonSwitch.setVisible(true); } else { searchPanel.setVisible(true); searchPanel.removeStyleName("refHeader"); formPanel.setVisible(false); } } public Integer getValue() { return value; } public void setEnabled(boolean enabled) { buttonSearch.setEnabled(enabled); buttonSwitch.setEnabled(enabled); if (searchBox != null) { searchBox.setEnabled(enabled); } } public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Integer> handler) { return this.addHandler(handler, ValueChangeEvent.getType()); } private Modal createDialogBox() { dialogContents = new ModalBody(); final Modal dialogBox = new Modal(); dialogBox.getElement().getStyle().setOverflowY(Style.Overflow.AUTO);//fix against hiding scrollbar in modal stack dialogBox.setDataBackdrop(ModalBackdrop.STATIC); dialogBox.setTitle(Aplikator.application.getConfigString("aplikator.reference.dialogtitle") + " - " + view.getLocalizedName()); dialogBox.add(dialogContents); Row buttonPanel = new Row(); buttonPanel.addStyleName("refButtonPanel"); Button closeButton = new Button(Aplikator.application.getConfigString("aplikator.reference.cancel"), IconType.BAN, new ClickHandler() { public void onClick(ClickEvent event) { dialogBox.hide(); } }); closeButton.addStyleName("refSelectButton"); buttonPanel.add(closeButton); final Button OKButton = new Button(Aplikator.application.getConfigString("aplikator.reference.select"), IconType.CHECK, new ClickHandler() { public void onClick(ClickEvent event) { dialogBox.hide(); selectedRecordDTO = table.getSelectedRecord(); setValue(table.getSelectedPrimaryKey().getId(), true); } }); OKButton.setEnabled(false); OKButton.addStyleName("refSelectButton"); buttonPanel.add(OKButton); dialogContents.add(buttonPanel); table = (TableListerWidget) TableFactory.create(view, null, null, 450); table.addStyleName("refTablePanel"); dialogContents.add(table); table.addNestedEditorNotification(new NestedEditorNotification() { @Override public void nestedEditorStarted() { OKButton.setEnabled(false); } @Override public void nestedEditorFinished() { OKButton.setEnabled(true); } }); final SingleSelectionModel<RecordDTO> selectionModel = table.getListSelectionModel(); selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { public void onSelectionChange(SelectionChangeEvent event) { if (selectionModel.getSelectedObject() != null) { OKButton.setEnabled(true); } else { OKButton.setEnabled(false); } } }); return dialogBox; } public RecordDTO getSelectedRecord() { return selectedRecordDTO; } @Override public void setDirty(boolean dirty) { this.dirty = dirty; } @Override public boolean isDirty() { return dirty; } @Override public void grabFocus() { } @Override public void addEnterHandler(Command command) { } public class ItemSuggestOracle extends SuggestOracle { public boolean isDisplayStringHTML() { return true; } public void requestSuggestions(SuggestOracle.Request req, SuggestOracle.Callback callback) { RestClient.create(AplikatorService.class, new ItemSuggestCallback(req, callback), new AplikatorErrorCallback() ).getSuggestions(view.getId(), view.getActiveSort(), req.getQuery()); } class ItemSuggestCallback implements RemoteCallback<SuggestionsDTO>, ErrorCallback { private SuggestOracle.Request req; private SuggestOracle.Callback callback; public ItemSuggestCallback(SuggestOracle.Request r, SuggestOracle.Callback c) { req = r; callback = c; } @Override public boolean error(Object message, java.lang.Throwable throwable) { callback.onSuggestionsReady(req, new SuggestOracle.Response()); return false; } @Override public void callback(SuggestionsDTO dto) { callback.onSuggestionsReady(req, new SuggestOracle.Response(dto.getSuggestions())); } } } }