Coverage Report - org.kuali.student.common.ui.client.widgets.search.KSPicker
 
Classes in this File Line Coverage Branch Coverage Complexity
KSPicker
0%
0/161
0%
0/72
2.561
KSPicker$1
0%
0/4
0%
0/2
2.561
KSPicker$2
0%
0/6
0%
0/2
2.561
KSPicker$3
0%
0/4
0%
0/2
2.561
KSPicker$4
0%
0/7
0%
0/6
2.561
KSPicker$5
0%
0/4
0%
0/2
2.561
KSPicker$6
0%
0/7
0%
0/2
2.561
KSPicker$7
0%
0/1
N/A
2.561
KSPicker$BasicWidget
0%
0/128
0%
0/84
2.561
KSPicker$BasicWidget$1
0%
0/9
0%
0/6
2.561
KSPicker$BasicWidget$2
0%
0/4
N/A
2.561
KSPicker$BasicWidget$3
0%
0/3
N/A
2.561
KSPicker$BasicWidget$4
0%
0/4
0%
0/2
2.561
KSPicker$BasicWidget$5
0%
0/3
N/A
2.561
KSPicker$BasicWidget$6
0%
0/5
0%
0/2
2.561
KSPicker$SelectionContainerWidget
0%
0/9
N/A
2.561
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.ui.client.widgets.search;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashSet;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 
 23  
 import org.kuali.student.common.assembly.data.Data;
 24  
 import org.kuali.student.common.assembly.data.Data.DataValue;
 25  
 import org.kuali.student.common.assembly.data.Data.StringValue;
 26  
 import org.kuali.student.common.assembly.data.Data.Value;
 27  
 import org.kuali.student.common.assembly.data.LookupMetadata;
 28  
 import org.kuali.student.common.assembly.data.QueryPath;
 29  
 import org.kuali.student.common.search.dto.SearchRequest;
 30  
 import org.kuali.student.common.search.dto.SearchResult;
 31  
 import org.kuali.student.common.ui.client.application.Application;
 32  
 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
 33  
 import org.kuali.student.common.ui.client.configurable.mvc.WidgetConfigInfo;
 34  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.SelectItemWidgetBinding;
 35  
 import org.kuali.student.common.ui.client.mvc.Callback;
 36  
 import org.kuali.student.common.ui.client.mvc.HasCrossConstraints;
 37  
 import org.kuali.student.common.ui.client.mvc.HasDataValue;
 38  
 import org.kuali.student.common.ui.client.mvc.HasFocusLostCallbacks;
 39  
 import org.kuali.student.common.ui.client.mvc.TranslatableValueWidget;
 40  
 import org.kuali.student.common.ui.client.service.CachingSearchService;
 41  
 import org.kuali.student.common.ui.client.util.SearchUtils;
 42  
 import org.kuali.student.common.ui.client.util.SearchUtils.SearchRequestWrapper;
 43  
 import org.kuali.student.common.ui.client.widgets.HasInputWidget;
 44  
 import org.kuali.student.common.ui.client.widgets.KSDropDown;
 45  
 import org.kuali.student.common.ui.client.widgets.KSErrorDialog;
 46  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 47  
 import org.kuali.student.common.ui.client.widgets.KSTextBox;
 48  
 import org.kuali.student.common.ui.client.widgets.list.KSCheckBoxList;
 49  
 import org.kuali.student.common.ui.client.widgets.list.KSLabelList;
 50  
 import org.kuali.student.common.ui.client.widgets.list.KSRadioButtonList;
 51  
 import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
 52  
 import org.kuali.student.common.ui.client.widgets.list.ListItems;
 53  
 import org.kuali.student.common.ui.client.widgets.list.SearchResultListItems;
 54  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
 55  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
 56  
 import org.kuali.student.common.ui.client.widgets.suggestbox.IdableSuggestOracle.IdableSuggestion;
 57  
 import org.kuali.student.common.ui.client.widgets.suggestbox.KSSuggestBox;
 58  
 import org.kuali.student.common.ui.client.widgets.suggestbox.SearchSuggestOracle;
 59  
 
 60  
 import com.google.gwt.core.client.GWT;
 61  
 import com.google.gwt.dom.client.Element;
 62  
 import com.google.gwt.event.dom.client.BlurEvent;
 63  
 import com.google.gwt.event.dom.client.BlurHandler;
 64  
 import com.google.gwt.event.dom.client.ClickEvent;
 65  
 import com.google.gwt.event.dom.client.ClickHandler;
 66  
 import com.google.gwt.event.dom.client.KeyUpEvent;
 67  
 import com.google.gwt.event.dom.client.KeyUpHandler;
 68  
 import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
 69  
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 70  
 import com.google.gwt.event.logical.shared.ValueChangeHandler;
 71  
 import com.google.gwt.event.shared.HandlerRegistration;
 72  
 import com.google.gwt.user.client.DOM;
 73  
 import com.google.gwt.user.client.ui.Anchor;
 74  
 import com.google.gwt.user.client.ui.Composite;
 75  
 import com.google.gwt.user.client.ui.FlowPanel;
 76  
 import com.google.gwt.user.client.ui.HasText;
 77  
 import com.google.gwt.user.client.ui.SuggestBox;
 78  
 import com.google.gwt.user.client.ui.Widget;
 79  
 
 80  0
 public class KSPicker extends Composite implements HasFocusLostCallbacks, HasValueChangeHandlers<String>, HasDataValue, TranslatableValueWidget, HasInputWidget, HasCrossConstraints {
 81  
 
 82  0
     private FlowPanel layout = new FlowPanel();
 83  
     private BasicWidget basicWidget;
 84  0
     private Anchor advSearchLink = new Anchor(getMessage("advSearch"));
 85  0
     private AdvancedSearchWindow advSearchWindow = null;
 86  
     private SearchPanel searchPanel;
 87  
     public SearchPanel getSearchPanel() {
 88  0
                 return searchPanel;
 89  
         }
 90  
 
 91  
         private WidgetConfigInfo config;
 92  
     private Callback<List<SelectedResults>> advancedSearchCallback;
 93  0
         private List<Callback<SelectedResults>> basicSelectionCallbacks =
 94  
         new ArrayList<Callback<SelectedResults>>();
 95  0
     private List<Callback<String>> basicSelectionTextChangeCallbacks =
 96  
         new ArrayList<Callback<String>>();
 97  0
     private CachingSearchService cachingSearchService = CachingSearchService.getSearchService();
 98  
         
 99  0
     private SearchRequestWrapper searchRequestWrapper = new SearchRequestWrapper();
 100  
         
 101  0
     public KSPicker(WidgetConfigInfo config) {
 102  0
         this.config = config;
 103  0
                 init(config.lookupMeta, config.additionalLookups);
 104  0
         }
 105  
 
 106  0
     public KSPicker(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata){
 107  0
             init(inLookupMetadata, additionalLookupMetadata);
 108  0
     }
 109  
 
 110  
     @Override
 111  
     public Widget getInputWidget(){
 112  0
             if(basicWidget != null){
 113  0
                     return basicWidget.get();
 114  
             }
 115  0
             return null;
 116  
 
 117  
     }
 118  
 
 119  
     private void init(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata) {
 120  0
             this.initWidget(layout);
 121  0
         if (inLookupMetadata == null) {
 122  0
             KSErrorDialog.show(new Throwable(getMessage("invalidLookupConfig")));
 123  0
             return;
 124  
         }
 125  
 
 126  0
         if(config == null) {
 127  0
             config = new WidgetConfigInfo();
 128  
         }
 129  
 
 130  0
         setupBasicSearch(inLookupMetadata);
 131  0
         setupAdvancedSearch(additionalLookupMetadata);
 132  0
     }
 133  
 
 134  
     private static String getMessage(final String messageId) {
 135  0
         return Application.getApplicationContext().getMessage(messageId);
 136  
     }
 137  
 
 138  
     private void setupBasicSearch(LookupMetadata inLookupMetadata) {
 139  
 
 140  
             //setup initial search widget such as suggest box, drop down etc.
 141  0
             if (inLookupMetadata.getWidget() != null){
 142  0
                     switch (inLookupMetadata.getWidget()){
 143  
                             case SUGGEST_BOX:
 144  0
                                     setupSuggestBox(inLookupMetadata);
 145  0
                                     break;
 146  
                             case DROP_DOWN:
 147  
                             case CHECKBOX_LIST:
 148  
                             case RADIO:
 149  0
                                     setupListWidget(inLookupMetadata);
 150  0
                                     break;
 151  
                             case NO_WIDGET:
 152  0
                                     if(getMessage(inLookupMetadata.getId()+"-name")!=null){
 153  0
                                        advSearchLink.setText(getMessage(inLookupMetadata.getId()+"-name"));
 154  
                                     }   
 155  
                                     else
 156  0
                                     if ((inLookupMetadata.getName() != null) && (inLookupMetadata.getName().trim().length() > 0)) {
 157  0
                             advSearchLink.setText(inLookupMetadata.getName().trim());
 158  
                         }
 159  0
                         basicWidget = new BasicWidget(new SelectionContainerWidget());
 160  0
                         break;
 161  
                             default:
 162  0
                                     setupDefaultWidget(inLookupMetadata);
 163  
                     }
 164  
             } else {
 165  0
                         setupDefaultWidget(inLookupMetadata);
 166  
             }
 167  0
     }
 168  
 
 169  
     private void setupDefaultWidget(LookupMetadata inLookupMetadata){
 170  0
         basicWidget = new BasicWidget(config != null && config.canEdit ? new KSTextBox() : new KSLabel());
 171  0
         GWT.log("KSTextBox for " + inLookupMetadata.getSearchTypeId(), null);
 172  0
         layout.add(basicWidget.get());
 173  0
     }
 174  
 
 175  
     private void setupSuggestBox(LookupMetadata inLookupMetadata){
 176  0
         if(config.canEdit) {
 177  0
                 final SearchSuggestOracle orgSearchOracle = new SearchSuggestOracle(inLookupMetadata);
 178  0
                 final KSSuggestBox suggestBox = new KSSuggestBox(orgSearchOracle, true);
 179  0
                 suggestBox.addKeyUpHandler(new KeyUpHandler() {
 180  
                     @Override
 181  
                     public void onKeyUp(KeyUpEvent event) {
 182  0
                         for(Callback<String> basicSelectionTextChangeCallback: basicSelectionTextChangeCallbacks){
 183  0
                             basicSelectionTextChangeCallback.exec("Text Changed");
 184  
                         }
 185  0
                     }
 186  
                 });
 187  0
                 suggestBox.addSelectionChangeHandler(new SelectionChangeHandler(){
 188  
 
 189  
                     @Override
 190  
                     public void onSelectionChange(SelectionChangeEvent event) {
 191  0
                             IdableSuggestion currentSuggestion = suggestBox.getSelectedSuggestion();
 192  0
                         SelectedResults selectedResults = new SelectedResults(
 193  
                                 currentSuggestion.getReplacementString(), currentSuggestion.getId());
 194  0
                         for(Callback<SelectedResults> basicSelectionCallback: basicSelectionCallbacks){
 195  0
                             basicSelectionCallback.exec(selectedResults);
 196  
                         }
 197  0
                     }
 198  
                 });
 199  0
                 basicWidget = new BasicWidget(suggestBox);
 200  0
                 ((KSSuggestBox) basicWidget.get()).setAutoSelectEnabled(false);
 201  0
                 orgSearchOracle.setTextWidget(((SuggestBox) basicWidget.get()).getTextBox());
 202  0
         } else {
 203  0
             basicWidget = new BasicWidget(new KSLabel());
 204  
         }
 205  0
         layout.add(basicWidget.get());
 206  0
     }
 207  
 
 208  
     private void setupListWidget(LookupMetadata inLookupMetadata){
 209  
 
 210  
         //FIXME should we search on values to populate drop down here or later when user will access the screen?
 211  0
         if(config.canEdit) {
 212  
 
 213  0
             KSSelectItemWidgetAbstract listItemWidget = null;
 214  0
             switch (inLookupMetadata.getWidget()){
 215  
                     case DROP_DOWN:
 216  0
                             listItemWidget = new KSDropDown();
 217  0
                             break;
 218  
                     case CHECKBOX_LIST:
 219  0
                             listItemWidget = new KSCheckBoxList();
 220  0
                             ((KSCheckBoxList)listItemWidget).setIgnoreMultipleAttributes(true);
 221  0
                             break;
 222  
                     case RADIO:
 223  0
                             listItemWidget = new KSRadioButtonList();
 224  
                             break;
 225  
             }
 226  0
             basicWidget = new BasicWidget(listItemWidget);
 227  0
             SearchUtils.initializeSearchRequest(inLookupMetadata, searchRequestWrapper);
 228  0
             if(!searchRequestWrapper.isDeferSearch()) populateListWidget(searchRequestWrapper.getSearchRequest());
 229  0
         } else {
 230  0
                 if (inLookupMetadata.getWidget() == LookupMetadata.Widget.DROP_DOWN || inLookupMetadata.getWidget() == LookupMetadata.Widget.RADIO){
 231  0
                 basicWidget = new BasicWidget(new KSLabel());
 232  
                 } else {
 233  
                         //FIXME: This method of creating read is very inefficient, need better solution
 234  0
                         basicWidget = new BasicWidget(new KSLabelList());
 235  0
                 SearchUtils.initializeSearchRequest(inLookupMetadata, searchRequestWrapper);
 236  0
                 if(!searchRequestWrapper.isDeferSearch()) populateListWidget(searchRequestWrapper.getSearchRequest());
 237  
                 }
 238  0
             layout.add(basicWidget.get());
 239  
         }
 240  0
     }
 241  
 
 242  
     private void setupAdvancedSearch(List<LookupMetadata> additionalLookupMetadata) {
 243  
 
 244  
         //setup advanced search widget such as advanced search box, browse hierarchy search box etc.
 245  0
         List<LookupMetadata> advancedLightboxLookupdata = getLookupMetadataBasedOnWidget(additionalLookupMetadata, LookupMetadata.Widget.ADVANCED_LIGHTBOX);
 246  0
         if ((advancedLightboxLookupdata != null) && config.canEdit) {
 247  
 
 248  
                 //Title for advanced search window
 249  
                 String advSearchTitle;
 250  0
                 advSearchTitle = getMessage(advancedLightboxLookupdata.get(0).getId()+"-title");
 251  0
                 if (basicWidget.get() instanceof SelectionContainerWidget){
 252  0
                         if(advSearchTitle==null)
 253  0
                            advSearchTitle = advancedLightboxLookupdata.get(0).getTitle();
 254  
                 } else {
 255  0
                         if(advSearchTitle==null)
 256  0
                            advSearchTitle = "Advanced Search: " + advancedLightboxLookupdata.get(0).getTitle();
 257  
                         else
 258  0
                            advSearchTitle = "Advanced Search: " + advSearchTitle; 
 259  
                 }
 260  
                 
 261  
             //for multiple searches, show a drop down for user to select from
 262  0
             if (advancedLightboxLookupdata.size() == 1) {
 263  0
                 String actionLabel = advancedLightboxLookupdata.get(0).getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
 264  0
                 searchPanel = new SearchPanel(advancedLightboxLookupdata.get(0));
 265  0
                 searchPanel.setActionLabel(actionLabel);
 266  0
                 advSearchWindow = new AdvancedSearchWindow(advSearchTitle, searchPanel);
 267  0
             } else {
 268  0
                 searchPanel = new SearchPanel(advancedLightboxLookupdata);
 269  0
                 advSearchWindow = new AdvancedSearchWindow(advSearchTitle, searchPanel);
 270  0
                 searchPanel.addLookupChangedCallback(new Callback<LookupMetadata>() {
 271  
                     @Override
 272  
                     public void exec(LookupMetadata selectedLookup) {
 273  0
                         String actionLabel = (selectedLookup == null)? null : selectedLookup
 274  
                                 .getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
 275  0
                         searchPanel.setActionLabel(actionLabel);
 276  0
                     }
 277  
                 });
 278  0
                 LookupMetadata initialLookupMetaData = advancedLightboxLookupdata.get(0);
 279  0
                 String actionLabel = (initialLookupMetaData == null)? null : initialLookupMetaData
 280  
                         .getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
 281  0
                 searchPanel.setActionLabel(actionLabel);
 282  
             }
 283  0
             searchPanel.setMultiSelect(true);
 284  
 
 285  0
             String previewMode = additionalLookupMetadata.get(0).getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_PREVIEW_MODE);
 286  0
             if (previewMode != null && previewMode.equals("true")) {
 287  0
                 searchPanel.setActionLabel("Preview");
 288  
             }
 289  
 
 290  0
             searchPanel.addSelectionCompleteCallback(new Callback<List<SelectedResults>>() {
 291  
                 public void exec(List<SelectedResults> results) {
 292  0
                         if (results != null && results.size() > 0) {
 293  0
                             if (advancedSearchCallback != null) {
 294  0
                                 advancedSearchCallback.exec(results);
 295  
                             }
 296  
                             else {
 297  0
                                 basicWidget.setResults(results);
 298  
                             }
 299  0
                         advSearchWindow.hide();
 300  
                         }
 301  0
                 }
 302  
             });
 303  
 
 304  0
             advSearchLink.addClickHandler(new ClickHandler(){
 305  
                 @Override
 306  
                 public void onClick(ClickEvent event) {
 307  0
                    if(advSearchWindow != null){
 308  0
                        advSearchWindow.show();
 309  
                    }
 310  0
                 }
 311  
             });
 312  0
             layout.add(advSearchLink);
 313  
         }
 314  0
     }
 315  
 
 316  
     private void populateListWidget(SearchRequest sr){
 317  
         
 318  0
         cachingSearchService.search(sr, new KSAsyncCallback<SearchResult>(){
 319  
 
 320  
             @Override
 321  
             public void onSuccess(SearchResult results) {
 322  0
                 if(results != null){
 323  0
                     ((KSSelectItemWidgetAbstract)basicWidget.get()).setListItems(new SearchResultListItems(results.getRows(), config.lookupMeta));
 324  
                 } else {
 325  0
                     ((KSSelectItemWidgetAbstract)basicWidget.get()).setListItems(new SearchResultListItems(null, config.lookupMeta));
 326  
                     //FIXME is this configuration error?
 327  
                 }
 328  
                 //((KSDropDown)basicWidget.get()).processOutstandingCallback();  //due to possible race condition
 329  0
                 ((KSSelectItemWidgetAbstract)basicWidget.get()).setInitialized(true);
 330  0
                 layout.add(basicWidget.get());
 331  0
             }
 332  
         });
 333  0
     }
 334  
 
 335  
         private List<LookupMetadata> getLookupMetadataBasedOnWidget(List<LookupMetadata> additionalLookupMetadata, LookupMetadata.Widget widgetType) {
 336  
 
 337  
             //lookup does not need to have additional lookup e.g. if the lookup is for suggest box within advanced search lightbox
 338  0
             if (additionalLookupMetadata == null) {
 339  0
                 return null;
 340  
             }
 341  
 
 342  0
             List<LookupMetadata> lookups = new ArrayList<LookupMetadata>();
 343  0
             for (LookupMetadata addLookupData : additionalLookupMetadata) {
 344  0
                     if (addLookupData.getWidget() == widgetType) {
 345  0
                             lookups.add(addLookupData);
 346  
                     }
 347  
             }
 348  0
             return (lookups.size() > 0 ? lookups : null);
 349  
     }
 350  
 
 351  0
     public class BasicWidget implements HasDataValue, HasFocusLostCallbacks, TranslatableValueWidget {
 352  
                 private Widget basicWidget;
 353  
 
 354  0
                 public BasicWidget(Widget basicWidget){
 355  0
                         this.basicWidget = basicWidget;
 356  0
             initAccessibility();
 357  0
                 }
 358  
 
 359  
         private void initAccessibility() {
 360  0
             Element element = basicWidget.getElement();
 361  0
             element.setAttribute("role", "combobox");
 362  0
             element.setAttribute("aria-autocomplete", "list");
 363  0
             element.setAttribute("aria-haspopup", "true");
 364  0
         }
 365  
 
 366  
         public void setResults(List<SelectedResults> results) {
 367  0
                         if (basicWidget instanceof KSTextBox) {
 368  0
                                 ((KSTextBox)basicWidget).setText(results.get(0).getDisplayKey());  //FIXME: what about the result id?
 369  0
                         } else if (basicWidget.getClass().getName().contains("ContainerWidget")) {
 370  0
                                 List<String> selections = new ArrayList<String>();
 371  0
                                 for (SelectedResults result: results) {
 372  
                                         //selections.add(result.getDisplayKey());                                                  //FIXME: what about the result ids?
 373  0
                                         selections.add(result.getReturnKey());                            //we don't need display key, at least for now
 374  
                                 }
 375  0
                                 ((SelectionContainerWidget) basicWidget).setSelections(selections);
 376  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 377  0
                 IdableSuggestion theSuggestion = new IdableSuggestion();
 378  0
                 theSuggestion.setReplacementString(results.get(0).getDisplayKey());
 379  0
                 theSuggestion.setId(results.get(0).getReturnKey());
 380  0
                 theSuggestion.setAttrMap(results.get(0).getResultRow().getColumnValues());
 381  0
                                 ((KSSuggestBox) basicWidget).setValue(theSuggestion);
 382  
                         }
 383  0
                 }
 384  
                 public void clear() {
 385  0
                     if(basicWidget instanceof KSTextBox) {
 386  0
                 ((KSTextBox)basicWidget).setText(null);
 387  0
             } else if(basicWidget instanceof KSSuggestBox) {
 388  0
                 ((KSSuggestBox) basicWidget).setValue((String)null);
 389  0
             } else if(basicWidget instanceof KSLabel) {
 390  0
                 ((KSLabel)basicWidget).setText(null);
 391  0
             } else if(basicWidget instanceof KSDropDown) {
 392  0
                 ((KSDropDown)basicWidget).clear();
 393  
             } else {
 394  0
                 ((KSSuggestBox) basicWidget).setValue(null, false);
 395  
             }
 396  0
                 }
 397  
                 public void setValue(final String id, String translation) {
 398  0
                         if(basicWidget instanceof KSTextBox) {
 399  0
                                 ((KSTextBox)basicWidget).setText(translation);
 400  0
                         } else if(basicWidget instanceof KSSuggestBox) {
 401  0
                                 ((KSSuggestBox) basicWidget).setValue(id, translation);
 402  0
                         } else if(basicWidget instanceof KSLabel) {
 403  0
                             ((KSLabel)basicWidget).setText(translation);
 404  0
                         } else if(basicWidget instanceof KSSelectItemWidgetAbstract) {
 405  0
                             ListItems searchResults = ((KSSelectItemWidgetAbstract)basicWidget).getListItems();
 406  0
                             if (searchResults != null) {
 407  0
                                 ((KSSelectItemWidgetAbstract)basicWidget).selectItem(id);
 408  
                             }
 409  
                             else {
 410  0
                     ((KSSelectItemWidgetAbstract)basicWidget).addWidgetReadyCallback(new Callback<Widget>() {
 411  
                         @Override
 412  
                         public void exec(Widget widget) {
 413  0
                             final ListItems searchResults = ((KSSelectItemWidgetAbstract)widget).getListItems();
 414  
 
 415  0
                             if(id != null){
 416  0
                                 for (String itemId : searchResults.getItemIds()) {
 417  0
                                     if (itemId.equals(id.trim())) {
 418  0
                                         ((KSSelectItemWidgetAbstract)basicWidget).selectItem(itemId);
 419  0
                                         break;
 420  
                                     }
 421  
                                 }
 422  
                             } else {
 423  0
                                 ((KSSelectItemWidgetAbstract)basicWidget).clear();
 424  
                             }
 425  0
                         }
 426  
                     });
 427  
                 }
 428  
 
 429  0
             } else {
 430  0
                                 ((KSSuggestBox) basicWidget).setValue("", true);
 431  
                         }
 432  0
                 }
 433  
 
 434  
                 public void setValue(final Value value, boolean fireEvents) {
 435  0
                         if (basicWidget instanceof KSTextBox || basicWidget instanceof KSLabel) {
 436  0
                                 if(value != null){
 437  0
                                         ((HasText)basicWidget).setText((String) value.get());
 438  
                                 }
 439  
                                 else{
 440  0
                                         ((HasText)basicWidget).setText("");
 441  
                                 }
 442  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 443  
                                 //Do check here
 444  0
                                 if(value != null){
 445  0
                                         if(!config.isRepeating){
 446  0
                                                 ((KSSuggestBox) basicWidget).setValue((String)value.get(), fireEvents);
 447  
                                         }
 448  
                                         else{
 449  0
                                                 DataValue dataValue = (DataValue)value;
 450  0
                                                 Data d = dataValue.get();
 451  0
                                                 QueryPath path = QueryPath.parse("0");
 452  0
                                                 String v = d.query(path);
 453  0
                                                 ((KSSuggestBox) basicWidget).setValue((String)v, fireEvents);
 454  0
                                         }
 455  
                                 }
 456  
                                 else{
 457  0
                                         ((KSSuggestBox) basicWidget).setValue("", fireEvents);
 458  
                                 }
 459  0
                         } else if(basicWidget instanceof KSSelectItemWidgetAbstract) {
 460  0
                                 SelectItemWidgetBinding.INSTANCE.setWidgetValue((KSSelectItemWidgetAbstract)basicWidget, value);
 461  
             }
 462  0
                 }
 463  
                 public String getDisplayValue() {
 464  0
                     String result = "";
 465  0
                     if (basicWidget instanceof KSTextBox) {
 466  0
                 result = ((KSTextBox)basicWidget).getText();
 467  0
             } else if (basicWidget instanceof KSSuggestBox) {
 468  0
                 IdableSuggestion suggestion = ((KSSuggestBox)basicWidget).getCurrentSuggestion();
 469  0
                 if(suggestion != null) {
 470  0
                     result = suggestion.getReplacementString();
 471  
                 }
 472  0
             }  else if (basicWidget instanceof KSDropDown) {
 473  0
                 KSDropDown dropDown = (KSDropDown)basicWidget;
 474  0
                 StringValue value = new StringValue(((KSDropDown) basicWidget).getSelectedItem());
 475  0
                 String itemId = dropDown.getSelectedItem();
 476  
 
 477  0
                 if(itemId != null && !itemId.isEmpty()) {
 478  0
                     result = dropDown.getListItems().getItemText(itemId);
 479  
                 }
 480  
             }
 481  0
                     return result;
 482  
                 }
 483  
                 public Value getValue() {
 484  0
                         if (basicWidget instanceof KSTextBox) {
 485  0
                                 StringValue value = new StringValue(((KSTextBox)basicWidget).getText());
 486  0
                                 return value;
 487  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 488  
                                 //Do check here
 489  0
                                 if(!config.isRepeating){
 490  0
                                         StringValue value = new StringValue(((KSSuggestBox) basicWidget).getValue());
 491  0
                                         return value;
 492  
                                 }
 493  
                                 else{
 494  0
                                         Data data = new Data();
 495  0
                                         data.set(new Data.IntegerKey(0),((KSSuggestBox) basicWidget).getValue());
 496  0
                                         DataValue value = new DataValue(data);
 497  0
                                         return value;
 498  
                                 }
 499  0
                         }  else if (basicWidget instanceof KSSelectItemWidgetAbstract) {
 500  0
                                 return SelectItemWidgetBinding.INSTANCE.getWidgetValue((KSSelectItemWidgetAbstract)basicWidget);
 501  
                         }
 502  
 
 503  0
                         return null;
 504  
                 }
 505  
 
 506  
                 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
 507  0
                         if (basicWidget instanceof KSTextBox) {
 508  0
                                 return ((KSTextBox)basicWidget).addValueChangeHandler(handler);
 509  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 510  0
                                 return ((KSSuggestBox) basicWidget).addValueChangeHandler(handler);
 511  
                         }
 512  0
                         return null;
 513  
                 }
 514  
 
 515  
         public void addValuesChangeHandler(ValueChangeHandler<List<String>> handler) {
 516  0
             if (basicWidget.getClass().getName().contains("ContainerWidget")) {
 517  0
                 ((SelectionContainerWidget) basicWidget).addValueChangeHandler(handler);
 518  
             }
 519  0
         }
 520  
                 public void addSelectionChangeHandler(SelectionChangeHandler handler) {
 521  0
                     if (basicWidget instanceof KSSelectItemWidgetAbstract)  {
 522  0
                                 ((KSSelectItemWidgetAbstract) basicWidget).addSelectionChangeHandler(handler);
 523  0
                         }else if(config!=null&&!config.isRepeating&&basicWidget instanceof KSSuggestBox){
 524  0
                                 ((KSSuggestBox) basicWidget).addSelectionChangeHandler(handler);
 525  
                         }
 526  0
                 }
 527  
 
 528  
                 @Override
 529  
                 public void addValueChangeCallback(final Callback<Value> callback) {
 530  0
                         ValueChangeHandler<String> handler = new ValueChangeHandler<String>(){
 531  
                                 @Override
 532  
                                 public void onValueChange(ValueChangeEvent<String> event) {
 533  0
                                         StringValue value = new StringValue(event.getValue());
 534  0
                                         callback.exec(value);
 535  0
                                 }
 536  
                         };
 537  0
                         addValueChangeHandler(handler);
 538  0
                 }
 539  
 
 540  
                 @Override
 541  
                 public void addFocusLostCallback(final Callback<Boolean> callback) {
 542  0
                         if (basicWidget instanceof KSTextBox) {
 543  0
                                 ((KSTextBox)basicWidget).addBlurHandler(new BlurHandler(){
 544  
                                         @Override
 545  
                                         public void onBlur(BlurEvent event) {
 546  0
                                                 callback.exec(true);
 547  
 
 548  0
                                         }
 549  
                                 });
 550  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 551  0
                                 ((KSSuggestBox) basicWidget).getTextBox().addBlurHandler(new BlurHandler(){
 552  
                     @Override
 553  
                     public void onBlur(BlurEvent event) {
 554  
                             //Don't blur the widget if the suggestion list is showing
 555  0
                             if(!((KSSuggestBox) basicWidget).isSuggestionListShowing()){
 556  0
                             callback.exec(true);
 557  
                             }
 558  0
                     }
 559  
                                 });
 560  0
                         } else if (basicWidget instanceof KSSelectItemWidgetAbstract) {
 561  0
                 ((KSSelectItemWidgetAbstract) basicWidget).addBlurHandler(new BlurHandler(){
 562  
                     @Override
 563  
                     public void onBlur(BlurEvent event) {
 564  0
                         callback.exec(true);
 565  0
                     }
 566  
                 });
 567  
             }
 568  0
                 }
 569  
 
 570  
         @Override
 571  
         public void setValue(Value value) {
 572  0
             this.setValue(value, true);
 573  0
         }
 574  
 
 575  
         public Widget get() {
 576  0
             return basicWidget;
 577  
         }
 578  
 
 579  
         @Override
 580  
         public void setValue(final Map<String, String> translations) {
 581  
                 //TODO: Reviewed in M6 cleanup, unknown:  Update to also work with a KSLabelList that doesn't require pre-population of all list items
 582  0
                 if (basicWidget instanceof KSSelectItemWidgetAbstract){
 583  0
                         Callback<Widget> widgetReadyCallback = new Callback<Widget>(){
 584  
                                         public void exec(Widget widget) {
 585  0
                                                 ((KSSelectItemWidgetAbstract)widget).clear();
 586  0
                                         for (String id:translations.keySet()){
 587  0
                                                 ((KSSelectItemWidgetAbstract)widget).selectItem(id);
 588  
                                         }
 589  0
                                         }
 590  
                         };
 591  0
                         if (!((KSSelectItemWidgetAbstract)basicWidget).isInitialized()){
 592  0
                                 ((KSSelectItemWidgetAbstract)basicWidget).addWidgetReadyCallback(widgetReadyCallback);
 593  
                         } else{
 594  0
                                 widgetReadyCallback.exec(basicWidget);
 595  
                         }
 596  0
                 } else {
 597  0
                         GWT.log("Basic picker widget not coded to handle multiple translations", null);
 598  
                 }
 599  0
         }
 600  
 
 601  
     }
 602  
 
 603  
     /**
 604  
      * An empty widget used to contain selections from an Advanced Search window, when NO_WIDGET has been
 605  
      * specified for initial lookup definition. This is mostly used for creating a link to advanced search
 606  
      * window.
 607  
      * 
 608  
      */
 609  
     private class SelectionContainerWidget extends Widget implements HasValueChangeHandlers<List<String>> {
 610  0
             private List<String> selections = new ArrayList<String>();
 611  
 
 612  0
             public SelectionContainerWidget(){
 613  0
                     this.setElement(DOM.createSpan());
 614  0
             }
 615  
 
 616  
                 public List<String> getSelections() {
 617  0
                         return selections;
 618  
                 }
 619  
 
 620  
                 public void setSelections(List<String> selections) {
 621  0
                         this.selections = selections;
 622  0
                         ValueChangeEvent.fire(this, this.selections);
 623  0
                 }
 624  
 
 625  
                 @Override
 626  
                 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<List<String>> handler) {
 627  0
                         return super.addHandler(handler, ValueChangeEvent.getType());
 628  
                 }
 629  
     }
 630  
 
 631  
 
 632  
     public AdvancedSearchWindow getSearchWindow(){
 633  0
         return advSearchWindow;
 634  
     }
 635  
 
 636  
     public void addBasicSelectionCompletedCallback(Callback<SelectedResults> callback) {
 637  0
         basicSelectionCallbacks.add(callback);
 638  0
     }
 639  
 
 640  
     public void addBasicSelectionTextChangeCallback(Callback<String> callback) {
 641  0
         basicSelectionTextChangeCallbacks.add(callback);
 642  0
     }
 643  
 
 644  
         @Override
 645  
         public void addValueChangeCallback(Callback<Value> callback) {
 646  0
                 basicWidget.addValueChangeCallback(callback);
 647  0
         }
 648  
 
 649  
         @Override
 650  
         public void setValue(Value value) {
 651  0
                 setValue(value, true);
 652  0
         }
 653  
 
 654  
     public void setValue(String value){
 655  0
         basicWidget.setValue(new StringValue(value));
 656  0
     }
 657  
 
 658  
         public void setValue(Value value, boolean fireEvents) {
 659  
                 //suggest.reset();
 660  0
                 basicWidget.setValue(value, fireEvents);
 661  0
         }
 662  
         public void clear() {
 663  0
             basicWidget.clear();
 664  0
         }
 665  
 
 666  
     @Override
 667  
     public void setValue(String id, String translation) {
 668  0
         basicWidget.setValue(id, translation);
 669  0
     }
 670  
 
 671  
     @Override
 672  
     public Value getValue() {
 673  0
         return basicWidget.getValue();
 674  
     }
 675  
         public String getDisplayValue() {
 676  0
             return basicWidget.getDisplayValue();
 677  
         }
 678  
         @Override
 679  
         public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
 680  0
                 return basicWidget.addValueChangeHandler(handler);
 681  
         }
 682  
 
 683  
         public void addValuesChangeHandler(ValueChangeHandler<List<String>> handler) {
 684  0
         if(basicWidget != null)
 685  0
                 basicWidget.addValuesChangeHandler(handler);
 686  0
         }
 687  
 
 688  
         public void addSelectionChangeHandler(SelectionChangeHandler handler) {
 689  0
         if(basicWidget != null)
 690  0
                 basicWidget.addSelectionChangeHandler(handler);
 691  0
         }
 692  
 
 693  
         
 694  
         @Override
 695  
         public void addFocusLostCallback(Callback<Boolean> callback) {
 696  0
                 basicWidget.addFocusLostCallback(callback);
 697  0
         }
 698  
 
 699  
     public void setAdvancedSearchCallback(Callback<List<SelectedResults>> advancedSearchCallback) {
 700  0
         this.advancedSearchCallback = advancedSearchCallback;
 701  0
     }
 702  
 
 703  
     @Override
 704  
     public void setValue(Map<String, String> translations) {
 705  0
         basicWidget.setValue(translations);
 706  0
     }
 707  
 
 708  
         @Override
 709  
     public HashSet<String> getCrossConstraints() {
 710  0
                 return searchRequestWrapper.getCrossConstraints();
 711  
         }
 712  
 
 713  
         @Override
 714  
         public void reprocessWithUpdatedConstraints() {
 715  0
         SearchUtils.initializeSearchRequest(config.lookupMeta, searchRequestWrapper);
 716  0
         populateListWidget(searchRequestWrapper.getSearchRequest());
 717  0
         }
 718  
 
 719  
         public Callback<List<SelectedResults>> getAdvancedSearchCallback() {
 720  0
                 return advancedSearchCallback;
 721  
         }
 722  
 
 723  
     @Override
 724  
     protected void onEnsureDebugId(String baseID) {
 725  0
         super.onEnsureDebugId(baseID);
 726  0
         Widget basicInputWidget = getInputWidget();
 727  0
         if (basicInputWidget != null) {
 728  0
             basicInputWidget.ensureDebugId(baseID + "-KSPicker-widget");
 729  
         }
 730  0
         advSearchLink.ensureDebugId(baseID + "-Advanced-Search-anchor");
 731  0
     }
 732  
 
 733  
 }