001    /**
002     * Copyright 2010 The Kuali Foundation Licensed under the
003     * Educational Community License, Version 2.0 (the "License"); you may
004     * not use this file except in compliance with the License. You may
005     * obtain a copy of the License at
006     *
007     * http://www.osedu.org/licenses/ECL-2.0
008     *
009     * Unless required by applicable law or agreed to in writing,
010     * software distributed under the License is distributed on an "AS IS"
011     * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
012     * or implied. See the License for the specific language governing
013     * permissions and limitations under the License.
014     */
015    
016    package org.kuali.student.common.ui.client.widgets.suggestbox;
017    
018    import java.util.Map;
019    
020    import org.kuali.student.common.ui.client.mvc.Callback;
021    import org.kuali.student.common.ui.client.mvc.TranslatableValueWidget;
022    import org.kuali.student.common.ui.client.util.UtilConstants;
023    import org.kuali.student.common.ui.client.widgets.HasWatermark;
024    import org.kuali.student.common.ui.client.widgets.KSTextBox;
025    import org.kuali.student.common.ui.client.widgets.list.HasSelectionChangeHandlers;
026    import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
027    import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
028    import org.kuali.student.common.ui.client.widgets.suggestbox.IdableSuggestOracle.IdableSuggestion;
029    
030    import com.google.gwt.event.dom.client.BlurEvent;
031    import com.google.gwt.event.dom.client.BlurHandler;
032    import com.google.gwt.event.logical.shared.SelectionEvent;
033    import com.google.gwt.event.logical.shared.SelectionHandler;
034    import com.google.gwt.event.shared.HandlerRegistration;
035    import com.google.gwt.user.client.ui.SuggestBox;
036    import com.google.gwt.user.client.ui.SuggestOracle;
037    
038    // TODO implement some form of focus handling for SuggestBox
039    public class KSSuggestBox extends SuggestBox implements HasSelectionChangeHandlers, TranslatableValueWidget, HasWatermark{
040        
041        private IdableSuggestion currentSuggestion = null;
042        private IdableSuggestOracle oracle;
043        private String currentId = "";
044        
045        public KSSuggestBox(IdableSuggestOracle oracle) {
046            this(oracle, true);
047        }
048        
049        public KSSuggestBox(IdableSuggestOracle oracle, boolean enabled){
050            super(oracle, new KSTextBox());
051            super.getTextBox().setEnabled(enabled);
052            this.oracle = oracle;
053            oracle.addSearchCompletedCallback(new Callback<IdableSuggestion>() {
054                @Override
055                public void exec(IdableSuggestion result) {
056                    currentSuggestion = result;
057                    currentId = KSSuggestBox.this.getSelectedId();
058                    SelectionChangeEvent.fire(KSSuggestBox.this);
059                }
060            });
061            this.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>(){
062    
063                @Override
064                public void onSelection(SelectionEvent<SuggestOracle.Suggestion> event) {
065                    currentSuggestion = (IdableSuggestion)(event.getSelectedItem());
066                    getTextBox().setFocus(true);
067                    currentId = KSSuggestBox.this.getSelectedId();
068                    SelectionChangeEvent.fire(KSSuggestBox.this);
069                }
070            });
071            
072            this.getTextBox().addBlurHandler(new BlurHandler(){
073    
074                @Override
075                public void onBlur(BlurEvent event) {
076                    String currentText = KSSuggestBox.this.getText();
077                    boolean isEmpty = false;
078                    if(currentText != null && !currentText.equals("")){
079                            if((currentSuggestion != null && !KSSuggestBox.this.getText().equals(currentSuggestion.getReplacementString()))
080                                            || currentSuggestion == null){
081                                    currentSuggestion = KSSuggestBox.this.oracle.getSuggestionByText(currentText);
082                            }
083                        
084                        if(currentSuggestion == null){
085                            currentSuggestion = new IdableSuggestion();
086                            String impossibleCharacters = UtilConstants.IMPOSSIBLE_CHARACTERS;
087                            currentSuggestion.setId(impossibleCharacters);
088                            currentSuggestion.setDisplayString(impossibleCharacters);
089                            currentSuggestion.setReplacementString(impossibleCharacters);
090                        }
091                    }
092                    else if(currentText == null || currentText.equals("")){
093                        isEmpty = true;
094                        currentId = "";
095                            currentSuggestion = new IdableSuggestion();
096                            currentSuggestion.setId("");
097                            currentSuggestion.setDisplayString("");
098                            currentSuggestion.setReplacementString("");                     
099                    }
100                    
101                    if(!KSSuggestBox.this.getSelectedId().equals(currentId)){
102                            currentId = KSSuggestBox.this.getSelectedId();
103                        if(isEmpty){
104                            currentId = "";
105                        }
106                        if (!currentId.equals(UtilConstants.IMPOSSIBLE_CHARACTERS)) {
107                            SelectionChangeEvent.fire(KSSuggestBox.this);
108                        }
109                    }                
110                }
111            });
112        }
113        
114        public void reset(){
115            this.setText("");
116            currentSuggestion = null;
117        }
118    
119        public IdableSuggestion getSelectedSuggestion() {
120            return currentSuggestion;
121        }   
122        
123        public String getSelectedId() {
124            String id = "";
125            if(currentSuggestion != null){
126                id = currentSuggestion.getId();
127            }
128            if(currentId!=null && !currentId.isEmpty() && (id==null || id.isEmpty())){
129                id = UtilConstants.IMPOSSIBLE_CHARACTERS;
130            }
131            return id;
132        }
133    
134        public IdableSuggestOracle getOracle() {
135            return oracle;
136        }
137    
138        @Override
139        public String getValue() {
140            return this.getSelectedId();
141        }
142    
143        @Override
144        public void setValue(String id) {
145            if(id == null || id.equals("")){
146                    currentSuggestion = new IdableSuggestion();
147                    currentSuggestion.setId("");
148                    currentSuggestion.setDisplayString("");
149                    currentSuggestion.setReplacementString("");
150                    currentId = KSSuggestBox.this.getSelectedId();
151                KSSuggestBox.this.setText("");
152            }
153            else
154            {
155                    oracle.getSuggestionByIdSearch(id, new Callback<IdableSuggestion>(){
156            
157                        @Override
158                        public void exec(IdableSuggestion result) {
159                            currentSuggestion = result;
160                            KSSuggestBox.this.setText((currentSuggestion == null) ? "" : currentSuggestion.getReplacementString());
161                            currentId = KSSuggestBox.this.getSelectedId();
162                        }
163                    });
164            }
165        }   
166        
167        public void setValue(String id, final Callback<IdableSuggestion> callback) {
168            if(id == null || id.equals("")){
169                    currentSuggestion = new IdableSuggestion();
170                    currentSuggestion.setId("");
171                    currentSuggestion.setDisplayString("");
172                    currentSuggestion.setReplacementString("");
173                    KSSuggestBox.this.setText("");
174                    currentId = KSSuggestBox.this.getSelectedId();
175                    callback.exec(currentSuggestion);
176            }
177            else
178            {
179                    oracle.getSuggestionByIdSearch(id, new Callback<IdableSuggestion>(){
180            
181                        @Override
182                        public void exec(IdableSuggestion result) {
183                            currentSuggestion = result;
184                            KSSuggestBox.this.setText((currentSuggestion == null) ? "" : currentSuggestion.getReplacementString());
185                            currentId = KSSuggestBox.this.getSelectedId();
186                            callback.exec(currentSuggestion);
187                        }
188                    });
189            }
190        }
191        
192        public void setValue(String id, String translation) {
193            currentSuggestion = new IdableSuggestion();
194            currentSuggestion.setId(id);
195            currentSuggestion.setDisplayString(translation);
196            currentSuggestion.setReplacementString(translation);
197            KSSuggestBox.this.setText(translation);
198            currentId = KSSuggestBox.this.getSelectedId();
199        }
200        
201        @Override
202        public void setValue(String id, boolean fireEvents) {
203            if(fireEvents == true){
204                    
205                    if(id == null || id.equals("")){
206                            currentSuggestion = new IdableSuggestion();
207                            currentSuggestion.setId("");
208                            currentSuggestion.setDisplayString("");
209                            currentSuggestion.setReplacementString("");
210                            KSSuggestBox.this.setText("");
211                            currentId = KSSuggestBox.this.getSelectedId();
212                    }
213                    else
214                    {
215                            oracle.getSuggestionByIdSearch(id, new Callback<IdableSuggestion>(){
216                    
217                                @Override
218                                public void exec(IdableSuggestion result) {
219                                    currentSuggestion = result;
220                                    KSSuggestBox.this.setText((currentSuggestion == null) ? "" : currentSuggestion.getReplacementString());         
221                                    if(!KSSuggestBox.this.getSelectedId().equals(currentId)){
222                                            SelectionChangeEvent.fire(KSSuggestBox.this);
223                                            currentId = KSSuggestBox.this.getSelectedId();
224                                    }
225                                }
226                            });
227                    }
228                    
229            }
230            else
231            {
232                    this.setValue(id);
233            }
234    
235        }
236        
237        public void setValue(IdableSuggestion theSuggestion) {
238            currentSuggestion = theSuggestion;
239            SelectionChangeEvent.fire(KSSuggestBox.this);
240            KSSuggestBox.this.setText((currentSuggestion == null) ? "" : currentSuggestion.getReplacementString());
241            currentId = KSSuggestBox.this.getSelectedId();
242        }
243        
244            @Override
245            public HandlerRegistration addSelectionChangeHandler(
246                            SelectionChangeHandler handler) {
247                    return addHandler(handler, SelectionChangeEvent.getType());
248            }
249    
250        public IdableSuggestion getCurrentSuggestion() {
251            return currentSuggestion;
252        }
253    
254        @Override
255        public void setValue(Map<String, String> translations) {
256            // TODO ryan - THIS METHOD NEEDS JAVADOCS
257            
258        }
259        
260            @Override
261            public void setWatermarkText(String text) {
262                    ((KSTextBox)super.getTextBox()).setWatermarkText(text);
263            }
264            
265            @Override
266            public boolean hasWatermark(){
267                    return ((KSTextBox)super.getTextBox()).hasWatermark();
268            }
269            
270            @Override
271            public boolean watermarkShowing() {
272                    return ((KSTextBox)super.getTextBox()).hasWatermark();
273            }
274    
275    }