Coverage Report - org.kuali.student.common.ui.client.widgets.search.KSPicker
 
Classes in this File Line Coverage Branch Coverage Complexity
KSPicker
0%
0/148
0%
0/62
2.508
KSPicker$1
0%
0/4
0%
0/2
2.508
KSPicker$2
0%
0/6
0%
0/2
2.508
KSPicker$3
0%
0/4
0%
0/2
2.508
KSPicker$4
0%
0/7
0%
0/6
2.508
KSPicker$5
0%
0/4
0%
0/2
2.508
KSPicker$6
0%
0/7
0%
0/2
2.508
KSPicker$7
0%
0/1
N/A
2.508
KSPicker$BasicWidget
0%
0/128
0%
0/84
2.508
KSPicker$BasicWidget$1
0%
0/9
0%
0/6
2.508
KSPicker$BasicWidget$2
0%
0/4
N/A
2.508
KSPicker$BasicWidget$3
0%
0/3
N/A
2.508
KSPicker$BasicWidget$4
0%
0/4
0%
0/2
2.508
KSPicker$BasicWidget$5
0%
0/3
N/A
2.508
KSPicker$BasicWidget$6
0%
0/5
0%
0/2
2.508
KSPicker$SelectionContainerWidget
0%
0/9
N/A
2.508
 
 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  0
                                     setupListWidget(inLookupMetadata);
 149  0
                                     break;
 150  
                             case RADIO:
 151  0
                                     setupListWidget(inLookupMetadata);
 152  0
                                     break;
 153  
                             case NO_WIDGET:
 154  0
                         if ((inLookupMetadata.getName() != null) && (inLookupMetadata.getName().trim().length() > 0)) {
 155  0
                             advSearchLink.setText(inLookupMetadata.getName().trim());
 156  
                         }
 157  0
                         basicWidget = new BasicWidget(new SelectionContainerWidget());
 158  0
                         break;
 159  
                             default:
 160  0
                                     setupDefaultWidget(inLookupMetadata);
 161  
                     }
 162  
             } else {
 163  0
                         setupDefaultWidget(inLookupMetadata);
 164  
             }
 165  0
     }
 166  
 
 167  
     private void setupDefaultWidget(LookupMetadata inLookupMetadata){
 168  0
         basicWidget = new BasicWidget(config != null && config.canEdit ? new KSTextBox() : new KSLabel());
 169  0
         GWT.log("KSTextBox for " + inLookupMetadata.getSearchTypeId(), null);
 170  0
         layout.add(basicWidget.get());
 171  0
     }
 172  
 
 173  
     private void setupSuggestBox(LookupMetadata inLookupMetadata){
 174  0
         if(config.canEdit) {
 175  0
                 final SearchSuggestOracle orgSearchOracle = new SearchSuggestOracle(inLookupMetadata);
 176  0
                 final KSSuggestBox suggestBox = new KSSuggestBox(orgSearchOracle, true);
 177  0
                 suggestBox.addKeyUpHandler(new KeyUpHandler() {
 178  
                     @Override
 179  
                     public void onKeyUp(KeyUpEvent event) {
 180  0
                         for(Callback<String> basicSelectionTextChangeCallback: basicSelectionTextChangeCallbacks){
 181  0
                             basicSelectionTextChangeCallback.exec("Text Changed");
 182  
                         }
 183  0
                     }
 184  
                 });
 185  0
                 suggestBox.addSelectionChangeHandler(new SelectionChangeHandler(){
 186  
 
 187  
                     @Override
 188  
                     public void onSelectionChange(SelectionChangeEvent event) {
 189  0
                             IdableSuggestion currentSuggestion = suggestBox.getSelectedSuggestion();
 190  0
                         SelectedResults selectedResults = new SelectedResults(
 191  
                                 currentSuggestion.getReplacementString(), currentSuggestion.getId());
 192  0
                         for(Callback<SelectedResults> basicSelectionCallback: basicSelectionCallbacks){
 193  0
                             basicSelectionCallback.exec(selectedResults);
 194  
                         }
 195  0
                     }
 196  
                 });
 197  0
                 basicWidget = new BasicWidget(suggestBox);
 198  0
                 ((KSSuggestBox) basicWidget.get()).setAutoSelectEnabled(false);
 199  0
                 orgSearchOracle.setTextWidget(((SuggestBox) basicWidget.get()).getTextBox());
 200  0
         } else {
 201  0
             basicWidget = new BasicWidget(new KSLabel());
 202  
         }
 203  0
         layout.add(basicWidget.get());
 204  0
     }
 205  
 
 206  
     private void setupListWidget(LookupMetadata inLookupMetadata){
 207  
 
 208  
         //FIXME should we search on values to populate drop down here or later when user will access the screen?
 209  0
         if(config.canEdit) {
 210  
 
 211  0
             KSSelectItemWidgetAbstract listItemWidget = null;
 212  0
             switch (inLookupMetadata.getWidget()){
 213  
                     case DROP_DOWN:
 214  0
                             listItemWidget = new KSDropDown();
 215  0
                             break;
 216  
                     case CHECKBOX_LIST:
 217  0
                             listItemWidget = new KSCheckBoxList();
 218  0
                             ((KSCheckBoxList)listItemWidget).setIgnoreMultipleAttributes(true);
 219  0
                             break;
 220  
                     case RADIO:
 221  0
                             listItemWidget = new KSRadioButtonList();
 222  
                             break;
 223  
             }
 224  0
             basicWidget = new BasicWidget(listItemWidget);
 225  0
             SearchUtils.initializeSearchRequest(inLookupMetadata, searchRequestWrapper);
 226  0
             if(!searchRequestWrapper.isDeferSearch()) populateListWidget(searchRequestWrapper.getSearchRequest());
 227  0
         } else {
 228  0
                 if (inLookupMetadata.getWidget() == LookupMetadata.Widget.DROP_DOWN || inLookupMetadata.getWidget() == LookupMetadata.Widget.RADIO){
 229  0
                 basicWidget = new BasicWidget(new KSLabel());
 230  
                 } else {
 231  
                         //FIXME: This method of creating read is very inefficient, need better solution
 232  0
                         basicWidget = new BasicWidget(new KSLabelList());
 233  0
                 SearchUtils.initializeSearchRequest(inLookupMetadata, searchRequestWrapper);
 234  0
                 if(!searchRequestWrapper.isDeferSearch()) populateListWidget(searchRequestWrapper.getSearchRequest());
 235  
                 }
 236  0
             layout.add(basicWidget.get());
 237  
         }
 238  0
     }
 239  
 
 240  
     private void setupAdvancedSearch(List<LookupMetadata> additionalLookupMetadata) {
 241  
 
 242  
         //setup advanced search widget such as advanced search box, browse hierarchy search box etc.
 243  0
         List<LookupMetadata> advancedLightboxLookupdata = getLookupMetadataBasedOnWidget(additionalLookupMetadata, LookupMetadata.Widget.ADVANCED_LIGHTBOX);
 244  0
         if ((advancedLightboxLookupdata != null) && config.canEdit) {
 245  
 
 246  
             //for multiple searches, show a drop down for user to select from
 247  0
             if (advancedLightboxLookupdata.size() == 1) {
 248  0
                 String actionLabel = advancedLightboxLookupdata.get(0).getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
 249  0
                 searchPanel = new SearchPanel(advancedLightboxLookupdata.get(0));
 250  0
                 searchPanel.setActionLabel(actionLabel);
 251  0
                 advSearchWindow = new AdvancedSearchWindow("Advanced Search: " + advancedLightboxLookupdata.get(0).getTitle(), searchPanel);
 252  0
             } else {
 253  0
                 searchPanel = new SearchPanel(advancedLightboxLookupdata);
 254  0
                 advSearchWindow = new AdvancedSearchWindow("Advanced Search: " + advancedLightboxLookupdata.get(0).getTitle(), searchPanel);
 255  0
                 searchPanel.addLookupChangedCallback(new Callback<LookupMetadata>() {
 256  
                     @Override
 257  
                     public void exec(LookupMetadata selectedLookup) {
 258  0
                         String actionLabel = (selectedLookup == null)? null : selectedLookup
 259  
                                 .getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
 260  0
                         searchPanel.setActionLabel(actionLabel);
 261  0
                     }
 262  
                 });
 263  0
                 LookupMetadata initialLookupMetaData = advancedLightboxLookupdata.get(0);
 264  0
                 String actionLabel = (initialLookupMetaData == null)? null : initialLookupMetaData
 265  
                         .getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
 266  0
                 searchPanel.setActionLabel(actionLabel);
 267  
             }
 268  0
             searchPanel.setMultiSelect(true);
 269  
 
 270  
             /*
 271  
             advSearchWindow.addActionCompleteCallback(new Callback<Boolean>() {
 272  
                 @Override
 273  
                 public void exec(Boolean result) {
 274  
                     searchPanel.getActionCompleteCallback().exec(true);
 275  
                 }
 276  
             }); */
 277  
 
 278  0
             String previewMode = additionalLookupMetadata.get(0).getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_PREVIEW_MODE);
 279  0
             if (previewMode != null && previewMode.equals("true")) {
 280  0
                 searchPanel.setActionLabel("Preview");
 281  
             }
 282  
 
 283  0
             searchPanel.addSelectionCompleteCallback(new Callback<List<SelectedResults>>() {
 284  
                 public void exec(List<SelectedResults> results) {
 285  0
                         if (results != null && results.size() > 0) {
 286  0
                             if (advancedSearchCallback != null) {
 287  0
                                 advancedSearchCallback.exec(results);
 288  
                             }
 289  
                             else {
 290  0
                                 basicWidget.setResults(results);
 291  
                             }
 292  0
                         advSearchWindow.hide();
 293  
                         }
 294  0
                 }
 295  
             });
 296  
 
 297  0
             advSearchLink.addClickHandler(new ClickHandler(){
 298  
                 @Override
 299  
                 public void onClick(ClickEvent event) {
 300  0
                    if(advSearchWindow != null){
 301  0
                        advSearchWindow.show();
 302  
                    }
 303  0
                 }
 304  
             });
 305  0
             layout.add(advSearchLink);
 306  
         }
 307  0
     }
 308  
 
 309  
     private void populateListWidget(SearchRequest sr){
 310  
         
 311  0
         cachingSearchService.search(sr, new KSAsyncCallback<SearchResult>(){
 312  
 
 313  
             @Override
 314  
             public void onSuccess(SearchResult results) {
 315  0
                 if(results != null){
 316  0
                     ((KSSelectItemWidgetAbstract)basicWidget.get()).setListItems(new SearchResultListItems(results.getRows(), config.lookupMeta));
 317  
                 } else {
 318  0
                     ((KSSelectItemWidgetAbstract)basicWidget.get()).setListItems(new SearchResultListItems(null, config.lookupMeta));
 319  
                     //FIXME is this configuration error?
 320  
                 }
 321  
                 //((KSDropDown)basicWidget.get()).processOutstandingCallback();  //due to possible race condition
 322  0
                 ((KSSelectItemWidgetAbstract)basicWidget.get()).setInitialized(true);
 323  0
                 layout.add(basicWidget.get());
 324  0
             }
 325  
         });
 326  0
     }
 327  
 
 328  
         private List<LookupMetadata> getLookupMetadataBasedOnWidget(List<LookupMetadata> additionalLookupMetadata, LookupMetadata.Widget widgetType) {
 329  
 
 330  
             //lookup does not need to have additional lookup e.g. if the lookup is for suggest box within advanced search lightbox
 331  0
             if (additionalLookupMetadata == null) {
 332  0
                 return null;
 333  
             }
 334  
 
 335  0
             List<LookupMetadata> lookups = new ArrayList<LookupMetadata>();
 336  0
             for (LookupMetadata addLookupData : additionalLookupMetadata) {
 337  0
                     if (addLookupData.getWidget() == widgetType) {
 338  0
                             lookups.add(addLookupData);
 339  
                     }
 340  
             }
 341  0
             return (lookups.size() > 0 ? lookups : null);
 342  
     }
 343  
 
 344  0
     public class BasicWidget implements HasDataValue, HasFocusLostCallbacks, TranslatableValueWidget {
 345  
                 private Widget basicWidget;
 346  
 
 347  0
                 public BasicWidget(Widget basicWidget){
 348  0
                         this.basicWidget = basicWidget;
 349  0
             initAccessibility();
 350  0
                 }
 351  
 
 352  
         private void initAccessibility() {
 353  0
             Element element = basicWidget.getElement();
 354  0
             element.setAttribute("role", "combobox");
 355  0
             element.setAttribute("aria-autocomplete", "list");
 356  0
             element.setAttribute("aria-haspopup", "true");
 357  0
         }
 358  
 
 359  
         public void setResults(List<SelectedResults> results) {
 360  0
                         if (basicWidget instanceof KSTextBox) {
 361  0
                                 ((KSTextBox)basicWidget).setText(results.get(0).getDisplayKey());  //FIXME: what about the result id?
 362  0
                         } else if (basicWidget.getClass().getName().contains("ContainerWidget")) {
 363  0
                                 List<String> selections = new ArrayList<String>();
 364  0
                                 for (SelectedResults result: results) {
 365  
                                         //selections.add(result.getDisplayKey());                                                  //FIXME: what about the result ids?
 366  0
                                         selections.add(result.getReturnKey());                            //we don't need display key, at least for now
 367  
                                 }
 368  0
                                 ((SelectionContainerWidget) basicWidget).setSelections(selections);
 369  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 370  0
                 IdableSuggestion theSuggestion = new IdableSuggestion();
 371  0
                 theSuggestion.setReplacementString(results.get(0).getDisplayKey());
 372  0
                 theSuggestion.setId(results.get(0).getReturnKey());
 373  0
                 theSuggestion.setAttrMap(results.get(0).getResultRow().getColumnValues());
 374  0
                                 ((KSSuggestBox) basicWidget).setValue(theSuggestion);
 375  
                         }
 376  0
                 }
 377  
                 public void clear() {
 378  0
                     if(basicWidget instanceof KSTextBox) {
 379  0
                 ((KSTextBox)basicWidget).setText(null);
 380  0
             } else if(basicWidget instanceof KSSuggestBox) {
 381  0
                 ((KSSuggestBox) basicWidget).setValue((String)null);
 382  0
             } else if(basicWidget instanceof KSLabel) {
 383  0
                 ((KSLabel)basicWidget).setText(null);
 384  0
             } else if(basicWidget instanceof KSDropDown) {
 385  0
                 ((KSDropDown)basicWidget).clear();
 386  
             } else {
 387  0
                 ((KSSuggestBox) basicWidget).setValue(null, false);
 388  
             }
 389  0
                 }
 390  
                 public void setValue(final String id, String translation) {
 391  0
                         if(basicWidget instanceof KSTextBox) {
 392  0
                                 ((KSTextBox)basicWidget).setText(translation);
 393  0
                         } else if(basicWidget instanceof KSSuggestBox) {
 394  0
                                 ((KSSuggestBox) basicWidget).setValue(id, translation);
 395  0
                         } else if(basicWidget instanceof KSLabel) {
 396  0
                             ((KSLabel)basicWidget).setText(translation);
 397  0
                         } else if(basicWidget instanceof KSSelectItemWidgetAbstract) {
 398  0
                             ListItems searchResults = ((KSSelectItemWidgetAbstract)basicWidget).getListItems();
 399  0
                             if (searchResults != null) {
 400  0
                                 ((KSSelectItemWidgetAbstract)basicWidget).selectItem(id);
 401  
                             }
 402  
                             else {
 403  0
                     ((KSSelectItemWidgetAbstract)basicWidget).addWidgetReadyCallback(new Callback<Widget>() {
 404  
                         @Override
 405  
                         public void exec(Widget widget) {
 406  0
                             final ListItems searchResults = ((KSSelectItemWidgetAbstract)widget).getListItems();
 407  
 
 408  0
                             if(id != null){
 409  0
                                 for (String itemId : searchResults.getItemIds()) {
 410  0
                                     if (itemId.equals(id.trim())) {
 411  0
                                         ((KSSelectItemWidgetAbstract)basicWidget).selectItem(itemId);
 412  0
                                         break;
 413  
                                     }
 414  
                                 }
 415  
                             } else {
 416  0
                                 ((KSSelectItemWidgetAbstract)basicWidget).clear();
 417  
                             }
 418  0
                         }
 419  
                     });
 420  
                 }
 421  
 
 422  0
             } else {
 423  0
                                 ((KSSuggestBox) basicWidget).setValue("", true);
 424  
                         }
 425  0
                 }
 426  
 
 427  
                 public void setValue(final Value value, boolean fireEvents) {
 428  0
                         if (basicWidget instanceof KSTextBox || basicWidget instanceof KSLabel) {
 429  0
                                 if(value != null){
 430  0
                                         ((HasText)basicWidget).setText((String) value.get());
 431  
                                 }
 432  
                                 else{
 433  0
                                         ((HasText)basicWidget).setText("");
 434  
                                 }
 435  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 436  
                                 //Do check here
 437  0
                                 if(value != null){
 438  0
                                         if(!config.isRepeating){
 439  0
                                                 ((KSSuggestBox) basicWidget).setValue((String)value.get(), fireEvents);
 440  
                                         }
 441  
                                         else{
 442  0
                                                 DataValue dataValue = (DataValue)value;
 443  0
                                                 Data d = dataValue.get();
 444  0
                                                 QueryPath path = QueryPath.parse("0");
 445  0
                                                 String v = d.query(path);
 446  0
                                                 ((KSSuggestBox) basicWidget).setValue((String)v, fireEvents);
 447  0
                                         }
 448  
                                 }
 449  
                                 else{
 450  0
                                         ((KSSuggestBox) basicWidget).setValue("", fireEvents);
 451  
                                 }
 452  0
                         } else if(basicWidget instanceof KSSelectItemWidgetAbstract) {
 453  0
                                 SelectItemWidgetBinding.INSTANCE.setWidgetValue((KSSelectItemWidgetAbstract)basicWidget, value);
 454  
             }
 455  0
                 }
 456  
                 public String getDisplayValue() {
 457  0
                     String result = "";
 458  0
                     if (basicWidget instanceof KSTextBox) {
 459  0
                 result = ((KSTextBox)basicWidget).getText();
 460  0
             } else if (basicWidget instanceof KSSuggestBox) {
 461  0
                 IdableSuggestion suggestion = ((KSSuggestBox)basicWidget).getCurrentSuggestion();
 462  0
                 if(suggestion != null) {
 463  0
                     result = suggestion.getReplacementString();
 464  
                 }
 465  0
             }  else if (basicWidget instanceof KSDropDown) {
 466  0
                 KSDropDown dropDown = (KSDropDown)basicWidget;
 467  0
                 StringValue value = new StringValue(((KSDropDown) basicWidget).getSelectedItem());
 468  0
                 String itemId = dropDown.getSelectedItem();
 469  
 
 470  0
                 if(itemId != null && !itemId.isEmpty()) {
 471  0
                     result = dropDown.getListItems().getItemText(itemId);
 472  
                 }
 473  
             }
 474  0
                     return result;
 475  
                 }
 476  
                 public Value getValue() {
 477  0
                         if (basicWidget instanceof KSTextBox) {
 478  0
                                 StringValue value = new StringValue(((KSTextBox)basicWidget).getText());
 479  0
                                 return value;
 480  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 481  
                                 //Do check here
 482  0
                                 if(!config.isRepeating){
 483  0
                                         StringValue value = new StringValue(((KSSuggestBox) basicWidget).getValue());
 484  0
                                         return value;
 485  
                                 }
 486  
                                 else{
 487  0
                                         Data data = new Data();
 488  0
                                         data.set(new Data.IntegerKey(0),((KSSuggestBox) basicWidget).getValue());
 489  0
                                         DataValue value = new DataValue(data);
 490  0
                                         return value;
 491  
                                 }
 492  0
                         }  else if (basicWidget instanceof KSSelectItemWidgetAbstract) {
 493  0
                                 return SelectItemWidgetBinding.INSTANCE.getWidgetValue((KSSelectItemWidgetAbstract)basicWidget);
 494  
                         }
 495  
 
 496  0
                         return null;
 497  
                 }
 498  
 
 499  
                 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
 500  0
                         if (basicWidget instanceof KSTextBox) {
 501  0
                                 return ((KSTextBox)basicWidget).addValueChangeHandler(handler);
 502  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 503  0
                                 return ((KSSuggestBox) basicWidget).addValueChangeHandler(handler);
 504  
                         }
 505  0
                         return null;
 506  
                 }
 507  
 
 508  
         public void addValuesChangeHandler(ValueChangeHandler<List<String>> handler) {
 509  0
             if (basicWidget.getClass().getName().contains("ContainerWidget")) {
 510  0
                 ((SelectionContainerWidget) basicWidget).addValueChangeHandler(handler);
 511  
             }
 512  0
         }
 513  
                 public void addSelectionChangeHandler(SelectionChangeHandler handler) {
 514  0
                     if (basicWidget instanceof KSSelectItemWidgetAbstract)  {
 515  0
                                 ((KSSelectItemWidgetAbstract) basicWidget).addSelectionChangeHandler(handler);
 516  0
                         }else if(config!=null&&!config.isRepeating&&basicWidget instanceof KSSuggestBox){
 517  0
                                 ((KSSuggestBox) basicWidget).addSelectionChangeHandler(handler);
 518  
                         }
 519  0
                 }
 520  
 
 521  
                 @Override
 522  
                 public void addValueChangeCallback(final Callback<Value> callback) {
 523  0
                         ValueChangeHandler<String> handler = new ValueChangeHandler<String>(){
 524  
                                 @Override
 525  
                                 public void onValueChange(ValueChangeEvent<String> event) {
 526  0
                                         StringValue value = new StringValue(event.getValue());
 527  0
                                         callback.exec(value);
 528  0
                                 }
 529  
                         };
 530  0
                         addValueChangeHandler(handler);
 531  0
                 }
 532  
 
 533  
                 @Override
 534  
                 public void addFocusLostCallback(final Callback<Boolean> callback) {
 535  0
                         if (basicWidget instanceof KSTextBox) {
 536  0
                                 ((KSTextBox)basicWidget).addBlurHandler(new BlurHandler(){
 537  
                                         @Override
 538  
                                         public void onBlur(BlurEvent event) {
 539  0
                                                 callback.exec(true);
 540  
 
 541  0
                                         }
 542  
                                 });
 543  0
                         } else if (basicWidget instanceof KSSuggestBox) {
 544  0
                                 ((KSSuggestBox) basicWidget).getTextBox().addBlurHandler(new BlurHandler(){
 545  
                     @Override
 546  
                     public void onBlur(BlurEvent event) {
 547  
                             //Don't blur the widget if the suggestion list is showing
 548  0
                             if(!((KSSuggestBox) basicWidget).isSuggestionListShowing()){
 549  0
                             callback.exec(true);
 550  
                             }
 551  0
                     }
 552  
                                 });
 553  0
                         } else if (basicWidget instanceof KSSelectItemWidgetAbstract) {
 554  0
                 ((KSSelectItemWidgetAbstract) basicWidget).addBlurHandler(new BlurHandler(){
 555  
                     @Override
 556  
                     public void onBlur(BlurEvent event) {
 557  0
                         callback.exec(true);
 558  0
                     }
 559  
                 });
 560  
             }
 561  0
                 }
 562  
 
 563  
         @Override
 564  
         public void setValue(Value value) {
 565  0
             this.setValue(value, true);
 566  0
         }
 567  
 
 568  
         public Widget get() {
 569  0
             return basicWidget;
 570  
         }
 571  
 
 572  
         @Override
 573  
         public void setValue(final Map<String, String> translations) {
 574  
                 //TODO: Reviewed in M6 cleanup, unknown:  Update to also work with a KSLabelList that doesn't require pre-population of all list items
 575  0
                 if (basicWidget instanceof KSSelectItemWidgetAbstract){
 576  0
                         Callback<Widget> widgetReadyCallback = new Callback<Widget>(){
 577  
                                         public void exec(Widget widget) {
 578  0
                                                 ((KSSelectItemWidgetAbstract)widget).clear();
 579  0
                                         for (String id:translations.keySet()){
 580  0
                                                 ((KSSelectItemWidgetAbstract)widget).selectItem(id);
 581  
                                         }
 582  0
                                         }
 583  
                         };
 584  0
                         if (!((KSSelectItemWidgetAbstract)basicWidget).isInitialized()){
 585  0
                                 ((KSSelectItemWidgetAbstract)basicWidget).addWidgetReadyCallback(widgetReadyCallback);
 586  
                         } else{
 587  0
                                 widgetReadyCallback.exec(basicWidget);
 588  
                         }
 589  0
                 } else {
 590  0
                         GWT.log("Basic picker widget not coded to handle multiple translations", null);
 591  
                 }
 592  0
         }
 593  
 
 594  
     }
 595  
 
 596  
     private class SelectionContainerWidget extends Widget implements HasValueChangeHandlers<List<String>> {
 597  0
             private List<String> selections = new ArrayList<String>();
 598  
 
 599  0
             public SelectionContainerWidget(){
 600  0
                     this.setElement(DOM.createSpan());
 601  0
             }
 602  
 
 603  
                 public List<String> getSelections() {
 604  0
                         return selections;
 605  
                 }
 606  
 
 607  
                 public void setSelections(List<String> selections) {
 608  0
                         this.selections = selections;
 609  0
                         ValueChangeEvent.fire(this, this.selections);
 610  0
                 }
 611  
 
 612  
                 @Override
 613  
                 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<List<String>> handler) {
 614  0
                         return super.addHandler(handler, ValueChangeEvent.getType());
 615  
                 }
 616  
     }
 617  
 
 618  
 
 619  
     public AdvancedSearchWindow getSearchWindow(){
 620  0
         return advSearchWindow;
 621  
     }
 622  
 
 623  
     public void addBasicSelectionCompletedCallback(Callback<SelectedResults> callback) {
 624  0
         basicSelectionCallbacks.add(callback);
 625  0
     }
 626  
 
 627  
     public void addBasicSelectionTextChangeCallback(Callback<String> callback) {
 628  0
         basicSelectionTextChangeCallbacks.add(callback);
 629  0
     }
 630  
 
 631  
         @Override
 632  
         public void addValueChangeCallback(Callback<Value> callback) {
 633  0
                 basicWidget.addValueChangeCallback(callback);
 634  0
         }
 635  
 
 636  
         @Override
 637  
         public void setValue(Value value) {
 638  0
                 setValue(value, true);
 639  0
         }
 640  
 
 641  
     public void setValue(String value){
 642  0
         basicWidget.setValue(new StringValue(value));
 643  0
     }
 644  
 
 645  
         public void setValue(Value value, boolean fireEvents) {
 646  
                 //suggest.reset();
 647  0
                 basicWidget.setValue(value, fireEvents);
 648  0
         }
 649  
         public void clear() {
 650  0
             basicWidget.clear();
 651  0
         }
 652  
 
 653  
     @Override
 654  
     public void setValue(String id, String translation) {
 655  0
         basicWidget.setValue(id, translation);
 656  0
     }
 657  
 
 658  
     @Override
 659  
     public Value getValue() {
 660  0
         return basicWidget.getValue();
 661  
     }
 662  
         public String getDisplayValue() {
 663  0
             return basicWidget.getDisplayValue();
 664  
         }
 665  
         @Override
 666  
         public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
 667  0
                 return basicWidget.addValueChangeHandler(handler);
 668  
         }
 669  
 
 670  
         public void addValuesChangeHandler(ValueChangeHandler<List<String>> handler) {
 671  0
         if(basicWidget != null)
 672  0
                 basicWidget.addValuesChangeHandler(handler);
 673  0
         }
 674  
 
 675  
         public void addSelectionChangeHandler(SelectionChangeHandler handler) {
 676  0
         if(basicWidget != null)
 677  0
                 basicWidget.addSelectionChangeHandler(handler);
 678  0
         }
 679  
 
 680  
         
 681  
         @Override
 682  
         public void addFocusLostCallback(Callback<Boolean> callback) {
 683  0
                 basicWidget.addFocusLostCallback(callback);
 684  0
         }
 685  
 
 686  
     public void setAdvancedSearchCallback(Callback<List<SelectedResults>> advancedSearchCallback) {
 687  0
         this.advancedSearchCallback = advancedSearchCallback;
 688  0
     }
 689  
 
 690  
     @Override
 691  
     public void setValue(Map<String, String> translations) {
 692  0
         basicWidget.setValue(translations);
 693  0
     }
 694  
 
 695  
         @Override
 696  
     public HashSet<String> getCrossConstraints() {
 697  0
                 return searchRequestWrapper.getCrossConstraints();
 698  
         }
 699  
 
 700  
         @Override
 701  
         public void reprocessWithUpdatedConstraints() {
 702  0
         SearchUtils.initializeSearchRequest(config.lookupMeta, searchRequestWrapper);
 703  0
         populateListWidget(searchRequestWrapper.getSearchRequest());
 704  0
         }
 705  
 
 706  
         public Callback<List<SelectedResults>> getAdvancedSearchCallback() {
 707  0
                 return advancedSearchCallback;
 708  
         }
 709  
 
 710  
 }