import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
*
* TODO needs major refactoring to be easily expandable
*/
-public class IFilterSelect extends Composite implements Paintable, KeyboardListener, ClickListener {
-
+public class IFilterSelect extends Composite implements Paintable,
+ KeyboardListener, ClickListener {
+
public class FilterSelectSuggestion implements Suggestion, Command {
-
+
private String key;
private String caption;
private String iconUri;
public FilterSelectSuggestion(UIDL uidl) {
this.key = uidl.getStringAttribute("key");
this.caption = uidl.getStringAttribute("caption");
- if(uidl.hasAttribute("icon")) {
+ if (uidl.hasAttribute("icon")) {
this.iconUri = uidl.getStringAttribute("icon");
}
}
public String getDisplayString() {
StringBuffer sb = new StringBuffer();
- if(iconUri != null) {
+ if (iconUri != null) {
sb.append("<img src=\"");
sb.append(iconUri);
sb.append("\" alt=\"icon\" class=\"i-icon\" />");
public int getOptionKey() {
return Integer.parseInt(key);
}
-
+
public String getIconUri() {
return iconUri;
}
-
+
public void execute() {
IFilterSelect.this.onSuggestionSelected(this);
}
}
- public class SuggestionPopup extends PopupPanel {
+ public class SuggestionPopup extends PopupPanel implements PositionCallback {
private SuggestionMenu menu;
-
+
private Element up = DOM.createDiv();
private Element down = DOM.createDiv();
private Element status = DOM.createDiv();
this.menu = new SuggestionMenu();
setWidget(menu);
setStyleName(CLASSNAME + "-suggestpopup");
-
+
Element root = getElement();
-
-
+
DOM.setInnerText(up, "prev");
DOM.sinkEvents(up, Event.ONCLICK);
DOM.setInnerText(down, "next");
DOM.appendChild(root, status);
DOM.setElementProperty(status, "className", CLASSNAME + "-status");
}
-
- public void showSuggestions(Collection currentSuggestions, int currentPage, int totalSuggestions) {
+
+ public void showSuggestions(Collection currentSuggestions,
+ int currentPage, int totalSuggestions) {
menu.setSuggestions(currentSuggestions);
int x = IFilterSelect.this.tb.getAbsoluteLeft();
int y = IFilterSelect.this.tb.getAbsoluteTop();
y += IFilterSelect.this.tb.getOffsetHeight();
this.setPopupPosition(x, y);
- int first = currentPage*PAGELENTH + 1;
- int last = first + currentSuggestions.size() - 1 ;
- DOM.setInnerText(status, first + "-" + last + "/" + totalSuggestions);
+ int first = currentPage * PAGELENTH + 1;
+ int last = first + currentSuggestions.size() - 1;
+ DOM.setInnerText(status, first + "-" + last + "/"
+ + totalSuggestions);
setPrevButtonActive(first > 1);
setNextButtonActive(last < totalSuggestions);
-
- show();
+ setPopupPositionAndShow(this);
+
}
-
+
private void setNextButtonActive(boolean b) {
- if(b) {
+ if (b) {
DOM.sinkEvents(down, Event.ONCLICK);
- DOM.setElementProperty(down, "className", CLASSNAME + "-nextpage-on");
+ DOM.setElementProperty(down, "className", CLASSNAME
+ + "-nextpage-on");
} else {
DOM.sinkEvents(down, 0);
- DOM.setElementProperty(down, "className", CLASSNAME + "-nextpage-off");
+ DOM.setElementProperty(down, "className", CLASSNAME
+ + "-nextpage-off");
}
}
private void setPrevButtonActive(boolean b) {
- if(b) {
+ if (b) {
DOM.sinkEvents(up, Event.ONCLICK);
- DOM.setElementProperty(up, "className", CLASSNAME + "-prevpage-on");
+ DOM.setElementProperty(up, "className", CLASSNAME
+ + "-prevpage-on");
} else {
DOM.sinkEvents(up, 0);
- DOM.setElementProperty(up, "className", CLASSNAME + "-prevpage-off");
+ DOM.setElementProperty(up, "className", CLASSNAME
+ + "-prevpage-off");
}
-
+
}
public void selectNextItem() {
MenuItem cur = menu.getSelectedItem();
int index = 1 + menu.getItems().indexOf(cur);
- if(menu.getItems().size() > index)
+ if (menu.getItems().size() > index)
menu.selectItem((MenuItem) menu.getItems().get(index));
else
filterOptions(currentPage + 1);
}
-
+
public void selectPrevItem() {
MenuItem cur = menu.getSelectedItem();
int index = -1 + menu.getItems().indexOf(cur);
- if(index > -1)
+ if (index > -1)
menu.selectItem((MenuItem) menu.getItems().get(index));
else if (index == -1) {
filterOptions(currentPage - 1);
} else {
- menu.selectItem((MenuItem) menu.getItems().get(menu.getItems().size()-1));
+ menu.selectItem((MenuItem) menu.getItems().get(
+ menu.getItems().size() - 1));
}
}
-
+
public void onBrowserEvent(Event event) {
Element target = DOM.eventGetTarget(event);
- if(DOM.compare(target, up)) {
+ if (DOM.compare(target, up)) {
filterOptions(currentPage - 1, lastFilter);
} else if (DOM.compare(target, down)) {
filterOptions(currentPage + 1, lastFilter);
}
public void setPagingEnabled(boolean paging) {
- if(isPagingEnabled == paging)
+ if (isPagingEnabled == paging)
return;
- if(paging) {
+ if (paging) {
DOM.setStyleAttribute(this.down, "display", "block");
DOM.setStyleAttribute(this.up, "display", "block");
DOM.setStyleAttribute(this.status, "display", "block");
DOM.setStyleAttribute(this.status, "display", "none");
}
}
+
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ ApplicationConnection.getConsole().log("callback");
+ if (offsetHeight > Window.getClientHeight()) {
+ offsetHeight = Window.getClientHeight();
+ menu.setHeight(offsetHeight + "px");
+ DOM.setStyleAttribute(menu.getElement(), "overflow", "auto");
+ // add scrollbar width
+ menu
+ .setWidth((menu.getOffsetWidth() * 2 - DOM
+ .getElementPropertyInt(menu.getElement(),
+ "clientWidth"))
+ + "px");
+ }
+ if (offsetHeight + getPopupTop() > Window.getClientHeight()) {
+ int top = Window.getClientHeight() - offsetHeight;
+ setPopupPosition(getPopupLeft(), top);
+ }
+ }
}
public class SuggestionMenu extends MenuBar {
-
+
SuggestionMenu() {
super(true);
setStyleName(CLASSNAME + "-suggestmenu");
public void setSuggestions(Collection suggestions) {
this.clearItems();
Iterator it = suggestions.iterator();
- while(it.hasNext()) {
+ while (it.hasNext()) {
FilterSelectSuggestion s = (FilterSelectSuggestion) it.next();
- MenuItem mi = new MenuItem(
- s.getDisplayString(),
- true,
- s);
+ MenuItem mi = new MenuItem(s.getDisplayString(), true, s);
this.addItem(mi);
- if(s == currentSuggestion)
+ if (s == currentSuggestion)
selectItem(mi);
}
}
public void doSelectedItemAction() {
MenuItem item = this.getSelectedItem();
- if(item != null) {
+ if (item != null) {
doItemAction(item, true);
}
suggestionPopup.hide();
}
private static final String CLASSNAME = "i-filterselect";
-
+
public static final int PAGELENTH = 20;
private final FlowPanel panel = new FlowPanel();
-
+
private final TextBox tb = new TextBox();
-
+
private final SuggestionPopup suggestionPopup = new SuggestionPopup();
-
+
private final HTML popupOpener = new HTML("v");
-
- private final Image selectedItemIcon = new Image();
-
+
+ private final Image selectedItemIcon = new Image();
+
private ApplicationConnection client;
private String paintableId;
-
+
private int currentPage;
private Collection currentSuggestions = new ArrayList();
private boolean clientSideFiltering;
private ArrayList allSuggestions;
-
+
public IFilterSelect() {
selectedItemIcon.setVisible(false);
panel.add(selectedItemIcon);
popupOpener.setStyleName(CLASSNAME + "-popupopener");
popupOpener.addClickListener(this);
}
-
+
public void filterOptions(int page) {
filterOptions(page, tb.getText());
}
public void filterOptions(int page, String filter) {
if (filter.equals(lastFilter) && currentPage == page) {
- if(!suggestionPopup.isAttached())
- suggestionPopup.showSuggestions(currentSuggestions, currentPage, totalSuggestions);
+ if (!suggestionPopup.isAttached())
+ suggestionPopup.showSuggestions(currentSuggestions,
+ currentPage, totalSuggestions);
return;
}
- if(!filter.equals(lastFilter)) {
+ if (!filter.equals(lastFilter)) {
// we are on subsequant page and text has changed -> reset page
page = 0;
}
- if(clientSideFiltering) {
+ if (clientSideFiltering) {
currentSuggestions.clear();
- for(Iterator it = allSuggestions.iterator();it.hasNext();) {
+ for (Iterator it = allSuggestions.iterator(); it.hasNext();) {
FilterSelectSuggestion s = (FilterSelectSuggestion) it.next();
String string = s.getDisplayString().toLowerCase();
- if(string.startsWith(filter.toLowerCase())) {
+ if (string.startsWith(filter.toLowerCase())) {
currentSuggestions.add(s);
}
}
lastFilter = filter;
currentPage = page;
- suggestionPopup.showSuggestions(currentSuggestions, page, currentSuggestions.size());
+ suggestionPopup.showSuggestions(currentSuggestions, page,
+ currentSuggestions.size());
} else {
- filtering = true;
+ filtering = true;
client.updateVariable(paintableId, "filter", filter, false);
client.updateVariable(paintableId, "page", page, true);
lastFilter = filter;
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
this.paintableId = uidl.getId();
this.client = client;
-
- if(client.updateComponent(this, uidl, true))
+
+ if (client.updateComponent(this, uidl, true))
return;
-
- if(uidl.hasAttribute("immediate"))
+
+ if (uidl.hasAttribute("immediate"))
immediate = true;
- else
+ else
immediate = false;
-
- if(uidl.hasVariable("page")) {
+
+ if (uidl.hasVariable("page")) {
this.suggestionPopup.setPagingEnabled(true);
clientSideFiltering = false;
} else {
this.suggestionPopup.setPagingEnabled(false);
clientSideFiltering = true;
}
-
+
currentSuggestions.clear();
UIDL options = uidl.getChildUIDL(0);
totalSuggestions = options.getIntAttribute("totalMatches");
- if(clientSideFiltering) {
+ if (clientSideFiltering) {
allSuggestions = new ArrayList();
}
- for(Iterator i = options.getChildIterator(); i.hasNext();) {
+ for (Iterator i = options.getChildIterator(); i.hasNext();) {
UIDL optionUidl = (UIDL) i.next();
- FilterSelectSuggestion suggestion = new FilterSelectSuggestion(optionUidl);
+ FilterSelectSuggestion suggestion = new FilterSelectSuggestion(
+ optionUidl);
currentSuggestions.add(suggestion);
- if(clientSideFiltering) {
+ if (clientSideFiltering) {
allSuggestions.add(suggestion);
}
- if(optionUidl.hasAttribute("selected")) {
+ if (optionUidl.hasAttribute("selected")) {
tb.setText(suggestion.getReplacementString());
currentSuggestion = suggestion;
}
}
-
- if(filtering && lastFilter.equals(uidl.getStringVariable("filter"))) {
- suggestionPopup.showSuggestions(
- currentSuggestions,
- currentPage,
+
+ if (filtering && lastFilter.equals(uidl.getStringVariable("filter"))) {
+ suggestionPopup.showSuggestions(currentSuggestions, currentPage,
totalSuggestions);
filtering = false;
}
}
-
+
public void onSuggestionSelected(FilterSelectSuggestion suggestion) {
- currentSuggestion = suggestion;
- String newKey = String.valueOf(suggestion.getOptionKey());
- tb.setText(suggestion.getReplacementString());
- setSelectedItemIcon(suggestion.getIconUri());
- if(!newKey.equals(selectedOptionKey)) {
- selectedOptionKey = newKey;
- client.updateVariable(
- paintableId,
- "selected",
- new String[] {selectedOptionKey} ,
- immediate);
- lastFilter = tb.getText();
- }
- suggestionPopup.hide();
+ currentSuggestion = suggestion;
+ String newKey = String.valueOf(suggestion.getOptionKey());
+ tb.setText(suggestion.getReplacementString());
+ setSelectedItemIcon(suggestion.getIconUri());
+ if (!newKey.equals(selectedOptionKey)) {
+ selectedOptionKey = newKey;
+ client.updateVariable(paintableId, "selected",
+ new String[] { selectedOptionKey }, immediate);
+ lastFilter = tb.getText();
}
-
+ suggestionPopup.hide();
+ }
+
private void setSelectedItemIcon(String iconUri) {
- if(iconUri == null) {
+ if (iconUri == null) {
selectedItemIcon.setVisible(false);
} else {
selectedItemIcon.setUrl(iconUri);
}
public void onKeyDown(Widget sender, char keyCode, int modifiers) {
- if (suggestionPopup.isAttached()) {
- switch (keyCode) {
- case KeyboardListener.KEY_DOWN:
- suggestionPopup.selectNextItem();
- break;
- case KeyboardListener.KEY_UP:
- suggestionPopup.selectPrevItem();
- break;
- case KeyboardListener.KEY_PAGEDOWN:
- if(totalSuggestions > currentPage*(PAGELENTH+1))
- filterOptions(currentPage + 1, lastFilter);
- break;
- case KeyboardListener.KEY_PAGEUP:
- if(currentPage > 0)
- filterOptions(currentPage - 1, lastFilter);
- break;
- case KeyboardListener.KEY_ENTER:
- case KeyboardListener.KEY_TAB:
- suggestionPopup.menu.doSelectedItemAction();
- break;
- }
- }
+ if (suggestionPopup.isAttached()) {
+ switch (keyCode) {
+ case KeyboardListener.KEY_DOWN:
+ suggestionPopup.selectNextItem();
+ break;
+ case KeyboardListener.KEY_UP:
+ suggestionPopup.selectPrevItem();
+ break;
+ case KeyboardListener.KEY_PAGEDOWN:
+ if (totalSuggestions > currentPage * (PAGELENTH + 1))
+ filterOptions(currentPage + 1, lastFilter);
+ break;
+ case KeyboardListener.KEY_PAGEUP:
+ if (currentPage > 0)
+ filterOptions(currentPage - 1, lastFilter);
+ break;
+ case KeyboardListener.KEY_ENTER:
+ case KeyboardListener.KEY_TAB:
+ suggestionPopup.menu.doSelectedItemAction();
+ break;
+ }
+ }
}
public void onKeyPress(Widget sender, char keyCode, int modifiers) {
-
-
+
}
public void onKeyUp(Widget sender, char keyCode, int modifiers) {
- switch (keyCode) {
- case KeyboardListener.KEY_ENTER:
- case KeyboardListener.KEY_TAB:
- ; //NOP
- break;
- case KeyboardListener.KEY_DOWN:
- case KeyboardListener.KEY_UP:
- case KeyboardListener.KEY_PAGEDOWN:
- case KeyboardListener.KEY_PAGEUP:
- if(suggestionPopup.isAttached()) {
- break;
- } else {
- // open popup as from gadget
- filterOptions(0, "");
- tb.selectAll();
- break;
- }
- default:
- filterOptions(currentPage);
- break;
- }
+ switch (keyCode) {
+ case KeyboardListener.KEY_ENTER:
+ case KeyboardListener.KEY_TAB:
+ ; // NOP
+ break;
+ case KeyboardListener.KEY_DOWN:
+ case KeyboardListener.KEY_UP:
+ case KeyboardListener.KEY_PAGEDOWN:
+ case KeyboardListener.KEY_PAGEUP:
+ if (suggestionPopup.isAttached()) {
+ break;
+ } else {
+ // open popup as from gadget
+ filterOptions(0, "");
+ tb.selectAll();
+ break;
+ }
+ default:
+ filterOptions(currentPage);
+ break;
+ }
}
/**