/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.wicket.extensions.ajax.markup.html.autocomplete; import org.apache.wicket.request.Response; import org.apache.wicket.util.string.Strings; /** * A renderer that abstracts autoassist specific details and allows subclasses to only render the * visual part of the assist instead of having to also render the necessary autoassist javascript * hooks. * * @param <T> * * @since 1.2 * * @author Igor Vaynberg (ivaynberg) */ public abstract class AbstractAutoCompleteRenderer<T> implements IAutoCompleteRenderer<T> { private static final long serialVersionUID = 1L; @Override public void render(final T object, final Response response, final String criteria) { String textValue = getTextValue(object); if (textValue == null) { throw new IllegalStateException( "A call to textValue(Object) returned an illegal value: null for object: " + object.toString()); } textValue = Strings.escapeMarkup(textValue).toString(); response.write("<li textvalue=\"" + textValue + "\""); final CharSequence handler = getOnSelectJavaScriptExpression(object); if (handler != null) { response.write(" onselect=\"" + handler + '"'); } response.write(">"); renderChoice(object, response, criteria); response.write("</li>"); } @Override public void renderHeader(final Response response) { response.write("<ul>"); } @Override public void renderFooter(final Response response, int count) { response.write("</ul>"); } /** * Render the visual portion of the assist. Usually the html representing the assist choice * object is written out to the response use {@link Response#write(CharSequence)} * * @param object * current assist choice * @param response * @param criteria */ protected abstract void renderChoice(T object, Response response, String criteria); /** * Retrieves the text value that will be set on the textbox if this assist is selected * * @param object * assist choice object * @return the text value that will be set on the textbox if this assist is selected */ protected abstract String getTextValue(T object); /** * Allows the execution of a custom javascript expression when an item is selected in the * autocompleter popup (either by clicking on it or hitting enter on the current selection). * <p/> * The javascript to execute must be a javascript expression that will be processed using * javascript's eval(). The function should return the textvalue to copy it into the * corresponding form input field (the default behavior). * * the current text value will be in variable 'input'. * * If the function returns <code>null</code> the chosen text value will be ignored. * <p/> * example 1: * * <pre> * protected CharSequence getOnSelectJavaScript(Address address) * { * final StringBuilder js = new StringBuilder(); * js.append("wicketGet('street').value ='" + address.getStreet() + "';"); * js.append("wicketGet('zipcode').value ='" + address.getZipCode() + "';"); * js.append("wicketGet('city').value ='" + address.getCity() + "';"); * js.append("input"); // <-- do not use return statement here! * return js.toString(); * } * </pre> * * example 2: * * <pre> * protected CharSequence getOnSelectJavaScript(Currency currency) * { * final StringBuilder js = new StringBuilder(); * js.append("val rate = ajaxGetExchangeRateForCurrency(currencySymbol);"); * js.append("if(rate == null) alert('exchange rate service currently not available');"); * js.append("rate"); * return js.toString(); * } * </pre> * * Then the autocompleter popup will be closed. * * @param item * the autocomplete item to get a custom javascript expression for * @return javascript to execute on selection or <code>null</code> if default behavior is * intented */ protected CharSequence getOnSelectJavaScriptExpression(final T item) { return null; } }