Coverage Report - org.apache.tapestry.dojo.form.Autocompleter
 
Classes in this File Line Coverage Branch Coverage Complexity
Autocompleter
0%
0/86
0%
0/34
1.875
 
 1  
 // Copyright May 4, 2006 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 package org.apache.tapestry.dojo.form;
 15  
 
 16  
 import org.apache.tapestry.*;
 17  
 import org.apache.tapestry.engine.DirectServiceParameter;
 18  
 import org.apache.tapestry.engine.IEngineService;
 19  
 import org.apache.tapestry.engine.ILink;
 20  
 import org.apache.tapestry.form.ValidatableField;
 21  
 import org.apache.tapestry.form.ValidatableFieldSupport;
 22  
 import org.apache.tapestry.json.IJSONWriter;
 23  
 import org.apache.tapestry.json.JSONObject;
 24  
 import org.apache.tapestry.services.DataSqueezer;
 25  
 import org.apache.tapestry.valid.ValidatorException;
 26  
 
 27  
 import java.util.ArrayList;
 28  
 import java.util.HashMap;
 29  
 import java.util.List;
 30  
 import java.util.Map;
 31  
 
 32  
 /**
 33  
  * An html field similar to a <code>select</code> input field that 
 34  
  * is wrapped by a dojo ComboBox widget.
 35  
  * 
 36  
  * This component uses the {@link IAutocompleteModel} to retrieve and match against
 37  
  * selected values.
 38  
  * 
 39  
  * @author jkuhnert
 40  
  */
 41  0
 public abstract class Autocompleter extends AbstractFormWidget implements ValidatableField, IJSONRender, IDirect
 42  
 {
 43  
     // mode, can be remote or local (local being from html rendered option elements)
 44  
     private static final String MODE_REMOTE = "remote";
 45  
     private static final String MODE_LOCAL = "local";    
 46  
     
 47  
     /**
 48  
      * 
 49  
      * {@inheritDoc}
 50  
      */
 51  
     protected void renderFormWidget(IMarkupWriter writer, IRequestCycle cycle)
 52  
     {
 53  0
         IAutocompleteModel model = getModel();
 54  0
         if (model == null)
 55  0
             throw Tapestry.createRequiredParameterException(this, "model");
 56  
         
 57  0
         Object value = getValue();
 58  0
         Object key = value != null && !"".equals(value.toString()) ? model.getPrimaryKey(value) : null;
 59  
         
 60  0
         renderDelegatePrefix(writer, cycle);
 61  
         
 62  0
         writer.begin("select");
 63  0
         writer.attribute("name", getName());
 64  0
         writer.attribute("autocomplete", "off"); // turn off native html autocomplete
 65  
         
 66  0
         if (isDisabled())
 67  0
             writer.attribute("disabled", "disabled");
 68  
         
 69  0
         renderIdAttribute(writer, cycle);
 70  
         
 71  0
         renderDelegateAttributes(writer, cycle);
 72  
         
 73  0
         getValidatableFieldSupport().renderContributions(this, writer, cycle);
 74  
         
 75  
         // Apply informal attributes.
 76  0
         renderInformalParameters(writer, cycle);
 77  
         
 78  0
         writer.print(" ");
 79  
         
 80  0
         if (isLocal()) 
 81  
         {
 82  0
             List list = model.getValues("");
 83  0
             for (int i=0; i<list.size(); i++) 
 84  
             {
 85  0
                 Object optionKey = model.getPrimaryKey(list.get(i));
 86  
 
 87  0
                 writer.begin("option");
 88  0
                 writer.attribute("value", getDataSqueezer().squeeze(optionKey));
 89  
 
 90  0
                 if (optionKey!=null && optionKey.equals(key))
 91  0
                     writer.attribute("selected", "selected");
 92  
                 
 93  0
                 writer.print(model.getLabelFor(list.get(i)));
 94  0
                 writer.end();
 95  
             }
 96  
         }
 97  
         
 98  0
         writer.end();
 99  0
         renderDelegateSuffix(writer, cycle);
 100  
         
 101  0
         Map parms = new HashMap();
 102  0
         parms.put("id", getClientId());
 103  
         
 104  0
         JSONObject json = new JSONObject();
 105  0
         if (!isLocal())
 106  
         {
 107  0
             ILink link = getDirectService().getLink(true, new DirectServiceParameter(this));
 108  0
             json.put("dataUrl", link.getURL() + "&filter=%{searchString}");
 109  
         }
 110  
         
 111  0
         json.put("mode", isLocal() ? MODE_LOCAL : MODE_REMOTE);
 112  0
         json.put("widgetId", getName());
 113  0
         json.put("name", getName());
 114  0
         json.put("searchDelay", getSearchDelay());
 115  0
         json.put("fadeTime", getFadeTime());
 116  0
         json.put("maxListLength", getMaxListLength());
 117  0
         json.put("forceValidOption", isForceValidOption());
 118  0
         json.put("disabled", isDisabled());
 119  0
         json.put("autoComplete", getAutoCompleteField());
 120  
         
 121  0
         json.put("value", key != null ? getDataSqueezer().squeeze(key) : "");
 122  0
         json.put("label", value != null ? model.getLabelFor(value) : "");
 123  
         
 124  0
         parms.put("props", json.toString());
 125  0
         parms.put("form", getForm().getName());
 126  0
         parms.put("widget", this);
 127  
         
 128  0
         PageRenderSupport prs = TapestryUtils.getPageRenderSupport(cycle, this);
 129  0
         getScript().execute(this, cycle, prs, parms);
 130  0
     }
 131  
     
 132  
     /**
 133  
      * {@inheritDoc}
 134  
      */
 135  
     public void renderComponent(IJSONWriter writer, IRequestCycle cycle)
 136  
     {
 137  0
         IAutocompleteModel model = getModel();
 138  
         
 139  0
         if (model == null)
 140  0
             throw Tapestry.createRequiredParameterException(this, "model");
 141  
         
 142  0
         List filteredValues = model.getValues(getFilter());
 143  
         
 144  0
         if (filteredValues == null)
 145  0
             return;
 146  
         
 147  0
         Object key = null;
 148  0
         String label = null;
 149  
         
 150  0
         JSONObject json = writer.object();
 151  
         
 152  0
         for (int i=0; i < filteredValues.size(); i++) {
 153  0
             Object value = filteredValues.get(i);
 154  
             
 155  0
             key = model.getPrimaryKey(value);
 156  0
             label = model.getLabelFor(value);
 157  
             
 158  0
             json.put(getDataSqueezer().squeeze(key), label );
 159  
         }
 160  
         
 161  0
     }
 162  
     
 163  
     /**
 164  
      * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
 165  
      */
 166  
     protected void rewindFormWidget(IMarkupWriter writer, IRequestCycle cycle)
 167  
     {
 168  0
         String value = cycle.getParameter(getName());
 169  
         
 170  0
         Object object = null;
 171  
         
 172  
         try
 173  
         {
 174  0
             if (value != null && value.length() > 0)
 175  0
                 object = getModel().getValue(getDataSqueezer().unsqueeze(value));
 176  
             
 177  0
             getValidatableFieldSupport().validate(this, writer, cycle, object);
 178  
             
 179  0
             setValue(object);
 180  
         }
 181  0
         catch (ValidatorException e)
 182  
         {
 183  0
             getForm().getDelegate().record(e);
 184  0
         }
 185  0
     }
 186  
     
 187  
     /** 
 188  
      * {@inheritDoc}
 189  
      */
 190  
     public boolean isStateful()
 191  
     {
 192  0
         return true;
 193  
     }
 194  
     
 195  
     /**
 196  
      * Triggerd by using filterOnChange logic.
 197  
      * 
 198  
      * {@inheritDoc}
 199  
      */
 200  
     public void trigger(IRequestCycle cycle)
 201  
     {
 202  0
         setFilter(cycle.getParameter("filter"));
 203  0
     }
 204  
     
 205  
     public abstract IAutocompleteModel getModel();
 206  
     
 207  
     /** How long to wait(in ms) before searching after input is received. */
 208  
     public abstract int getSearchDelay();
 209  
     
 210  
     /** The duration(in ms) of the fade effect of list going away. */
 211  
     public abstract int getFadeTime();
 212  
     
 213  
     /** The maximum number of items displayed in select list before the scrollbar is activated. */
 214  
     public abstract int getMaxListLength();
 215  
     
 216  
     /** Forces select to only allow valid option strings. */
 217  
     public abstract boolean isForceValidOption();
 218  
     
 219  
     /** Forces select to work in local mode (no xhr). */
 220  
     public abstract boolean isLocal();    
 221  
     
 222  
     /** @since 2.2 * */
 223  
     public abstract Object getValue();
 224  
 
 225  
     /** @since 2.2 * */
 226  
     public abstract void setValue(Object value);
 227  
     
 228  
     /** @since 4.1 */
 229  
     public abstract void setFilter(String value);
 230  
     
 231  
     /** @since 4.1 */
 232  
     public abstract String getFilter();
 233  
 
 234  
     /** @since 4.1.4 */
 235  
     public abstract boolean getAutoCompleteField();
 236  
     
 237  
     /** Injected. */
 238  
     public abstract DataSqueezer getDataSqueezer();
 239  
     
 240  
     /**
 241  
      * Injected.
 242  
      */
 243  
     public abstract ValidatableFieldSupport getValidatableFieldSupport();
 244  
 
 245  
     /**
 246  
      * Injected.
 247  
      */
 248  
     public abstract IEngineService getDirectService();
 249  
     
 250  
     /**
 251  
      * Injected.
 252  
      */
 253  
     public abstract IScript getScript();
 254  
     
 255  
     /**
 256  
      * @see org.apache.tapestry.form.AbstractFormComponent#isRequired()
 257  
      */
 258  
     public boolean isRequired()
 259  
     {
 260  0
         return getValidatableFieldSupport().isRequired(this);
 261  
     }
 262  
 
 263  
     /** 
 264  
      * {@inheritDoc}
 265  
      */
 266  
     public List getUpdateComponents()
 267  
     {
 268  0
         List comps = new ArrayList();
 269  0
         comps.add(getClientId());
 270  
         
 271  0
         return comps;
 272  
     }
 273  
     
 274  
     /** 
 275  
      * {@inheritDoc}
 276  
      */
 277  
     public boolean isAsync()
 278  
     {
 279  0
         return true;
 280  
     }
 281  
     
 282  
     /** 
 283  
      * {@inheritDoc}
 284  
      */
 285  
     public boolean isJson()
 286  
     {
 287  0
         return true;
 288  
     }
 289  
 }