001package com.github.gwtbootstrap.client.ui.incubator;
002
003import com.github.gwtbootstrap.client.ui.Button;
004import com.github.gwtbootstrap.client.ui.Label;
005import com.github.gwtbootstrap.client.ui.ListBox;
006import com.google.gwt.core.client.GWT;
007import com.google.gwt.event.dom.client.ClickEvent;
008import com.google.gwt.uibinder.client.UiBinder;
009import com.google.gwt.uibinder.client.UiField;
010import com.google.gwt.uibinder.client.UiHandler;
011import com.google.gwt.user.client.Window;
012import com.google.gwt.user.client.ui.Composite;
013import com.google.gwt.user.client.ui.HorizontalPanel;
014import com.google.gwt.user.client.ui.VerticalPanel;
015
016import java.util.ArrayList;
017import java.util.List;
018
019/**
020 *
021 * Usage Example:<br/>
022 * <ul><li>
023 * Put following code into your ui.xml file:<br/>
024 * <code>
025 * &lt;bi:PickList ui:field="pickList" /&gt;
026 * </code><br/><br/>
027 *
028 * </li><li>
029 * Populate your picklist using {@link NameValuePairImpl}:<br/>
030 * <code>
031 *     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();<br/>
032 *     nameValuePairs.add(new NameValuePairImpl("item 1", "item_1"));<br/>
033 *     nameValuePairs.add(new NameValuePairImpl("item 2", "item_2"));<br/>
034 *     nameValuePairs.add(new NameValuePairImpl("item 3", "item_3"));<br/>
035 *     pickList.setLeftListElements(nameValuePairs);
036 *     pickList.setRightListElements(nameValuePairs);
037 * </code><br/>
038 * </li></ul>
039 *
040 * Screenshot:
041 * <br/>
042 * <img src="http://gamenism.com/gwt/picklist.png"/>
043 * <br/>
044 *
045 * User: Halil Karakose
046 * Date: 10/18/13
047 * Time: 3:53 PM
048 *
049 * @see NameValuePairImpl
050 */
051public class PickList extends Composite {
052    @UiField
053    VerticalPanel leftPanel;
054    @UiField
055    VerticalPanel rightPanel;
056    @UiField
057    VerticalPanel buttonPanel;
058
059    @UiField
060    Button toRightButton;
061    @UiField
062    Button toLeftButton;
063    @UiField
064    ListBox leftList;
065    @UiField
066    ListBox rightList;
067    @UiField
068    Label rightPanelLabel;
069    @UiField
070    Label leftPanelLabel;
071
072    public void clearLeftList() {
073        clear(leftList);
074    }
075
076    public void clearRightList() {
077        clear(rightList);
078    }
079
080    private void clear(ListBox listBox) {
081        listBox.clear();
082    }
083
084    public void addElementToLeftList(NameValuePair element) {
085        addElement(leftList, element);
086    }
087
088    public void addElementToRightList(NameValuePair element) {
089        addElement(rightList, element);
090    }
091
092    private void addElement(ListBox listBox, NameValuePair element) {
093        listBox.addItem(element.name(), element.value());
094    }
095
096    public List<NameValuePair> getLeftListElements() {
097        return getListBoxElements(leftList);
098    }
099
100    public void setLeftListElements(List<NameValuePair> elements) {
101        populate(elements, leftList);
102    }
103
104    public List<NameValuePair> getRightListElements() {
105        return getListBoxElements(rightList);
106    }
107
108    public void setRightListElements(List<NameValuePair> elements) {
109        populate(elements, rightList);
110    }
111
112    public String getSelectedLabelText() {
113        return rightPanelLabel.getText();
114    }
115
116    public void setSelectedLabelText(String selectedLabelText) {
117        rightPanelLabel.setText(selectedLabelText);
118    }
119
120    public String getCandidateLabelText() {
121        return leftPanelLabel.getText();
122    }
123
124    public void setCandidateLabelText(String selectedLabelText) {
125        leftPanelLabel.setText(selectedLabelText);
126    }
127
128    private List<NameValuePair> getListBoxElements(ListBox listBox) {
129        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
130        for (int i = 0; i < listBox.getItemCount(); i++) {
131            NameValuePairImpl nameValuePair = new NameValuePairImpl(listBox.getItemText(i), listBox.getValue(i));
132            nameValuePairs.add(nameValuePair);
133        }
134        return nameValuePairs;
135    }
136
137    private void populate(List<NameValuePair> leftListElements, ListBox listBox) {
138        for (NameValuePair element : leftListElements) {
139            listBox.addItem(element.name(), element.value());
140        }
141    }
142
143    @UiHandler("toRightButton")
144    public void toRightButtonClicked(ClickEvent event) {
145        moveItem(leftList, rightList, event);
146
147        if (leftList.getItemCount() == 0) {
148            toRightButton.setEnabled(false);
149        }
150
151        if (rightList.getItemCount() >= 1) { // !>= 1! is preferred instead of !== 1! to handle multiple selections
152            toLeftButton.setEnabled(true);
153        }
154    }
155
156    @UiHandler("toLeftButton")
157    public void toLeftButtonClicked(ClickEvent event) {
158        moveItem(rightList, leftList, event);
159        if (rightList.getItemCount() == 0) {
160            toLeftButton.setEnabled(false);
161        }
162
163        if (leftList.getItemCount() >= 1) { // !>= 1! is preferred instead of !== 1! to handle multiple selections
164            toRightButton.setEnabled(true);
165        }
166    }
167
168    private void moveItem(ListBox from, ListBox to, ClickEvent event) {
169        String value = from.getValue();
170        if (value == null) {
171            Window.alert("Select an item first!");
172            return;
173        }
174
175        int itemIndex = from.getSelectedIndex();
176        String item = from.getItemText(itemIndex);
177        GWT.log("value: " + value + "\n"
178                + "selected index: " + itemIndex + "\n"
179                + "selected text: " + item);
180
181        to.addItem(item, value);
182        from.removeItem(itemIndex);
183
184        if (from.getItemCount() > itemIndex) {
185            from.setSelectedIndex(itemIndex);
186        } else if (from.getItemCount() > 0) {
187            from.setSelectedIndex(itemIndex-1); //enters here when last item in the list is removed
188        }
189    }
190
191    interface PickListUiBinder extends UiBinder<HorizontalPanel, PickList> {
192    }
193
194    private static PickListUiBinder ourUiBinder = GWT.create(PickListUiBinder.class);
195
196    public PickList() {
197        initWidget(ourUiBinder.createAndBindUi(this));
198
199        //set padding between cells to make the component look better
200        this.getElement().setAttribute("cellpadding", "1");
201        leftPanel.getElement().setAttribute("cellpadding", "1");
202        buttonPanel.getElement().setAttribute("cellpadding", "1");
203        rightPanel.getElement().setAttribute("cellpadding", "1");
204
205        setLeftListElements(new ArrayList<NameValuePair>());
206        setRightListElements(new ArrayList<NameValuePair>());
207    }
208}