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