blob: 2941353bc5293bf0615298f194a49a2dc60e670a [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed 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 com.google.gwt.user.client.ui;
import com.google.gwt.user.client.rpc.IsSerializable;
import java.util.ArrayList;
import java.util.Collection;
/**
* A {@link com.google.gwt.user.client.ui.SuggestOracle} can be used to create
* suggestions associated with a specific query string. It is currently used by
* {@link SuggestBox}.
*
* @see SuggestBox
*/
public abstract class SuggestOracle {
private Response emptyResponse = new Response(new ArrayList<Suggestion>());
/**
* Callback for {@link com.google.gwt.user.client.ui.SuggestOracle}. Every
* {@link Request} should be associated with a callback that should be called
* after a {@link Response} is generated.
*/
public interface Callback {
/**
* Consume the suggestions created by a
* {@link com.google.gwt.user.client.ui.SuggestOracle} in response to a
* {@link Request}.
*
* @param request the request
* @param response the response
*/
void onSuggestionsReady(Request request, Response response);
}
/**
* A {@link com.google.gwt.user.client.ui.SuggestOracle} request.
*/
public static class Request implements IsSerializable {
private int limit = 20;
private String query;
/**
* Constructor for {@link Request}.
*/
public Request() {
}
/**
* Constructor for {@link Request}.
*
* @param query the query string
*/
public Request(String query) {
setQuery(query);
}
/**
* Constructor for {@link Request}.
*
* @param query the query string
* @param limit limit on the number of suggestions that should be created
* for this query
*/
public Request(String query, int limit) {
setQuery(query);
setLimit(limit);
}
/**
* Gets the limit on the number of suggestions that should be created.
*
* @return the limit
*/
public int getLimit() {
return limit;
}
/**
* Gets the query string.
*
* @return the query string
*/
public String getQuery() {
return query;
}
/**
* Sets the limit on the number of suggestions that should be created.
*
* @param limit the limit
*/
public void setLimit(int limit) {
this.limit = limit;
}
/**
* Sets the query string used for this request.
*
* @param query the query string
*/
public void setQuery(String query) {
this.query = query;
}
}
/**
* {@link com.google.gwt.user.client.ui.SuggestOracle} response.
*
* <p>Can optionally have truncation information provided. To indicate that
* there are more results but the number is not known, use:
*
* <p><code>response.setMoreSuggestions(true);</code>
*
* <p>Or to indicate more results with an exact number, use:
*
* <p><code>response.setMoreSuggestionsCount(102);</code>
*/
public static class Response implements IsSerializable {
private Collection<? extends Suggestion> suggestions;
/**
* The response is considered to have "more suggestions" when the number of
* matching suggestions exceeds {@link Request#getLimit}, so the response
* suggestion list is truncated.
*/
private boolean moreSuggestions = false;
/**
* Number of truncated suggestions.
*/
private int numMoreSuggestions = 0;
/**
* Constructor for {@link Response}.
*/
public Response() {
}
/**
* Constructor for {@link Response}.
*
* @param suggestions each element of suggestions must implement the
* {@link Suggestion} interface
*/
public Response(Collection<? extends Suggestion> suggestions) {
setSuggestions(suggestions);
}
/**
* Gets how many more suggestions there are.
*
* @return the count. if there no more suggestions or the number of more
* suggestions is unknown, returns 0.
*/
public int getMoreSuggestionsCount() {
return this.numMoreSuggestions;
}
/**
* Gets the collection of suggestions. Each suggestion must implement the
* {@link Suggestion} interface.
*
* @return the collection of suggestions
*/
public Collection<? extends Suggestion> getSuggestions() {
return this.suggestions;
}
/**
* Gets whether or not the suggestion list was truncated due to the
* {@Request#getLimit}.
*/
public boolean hasMoreSuggestions() {
return this.moreSuggestions;
}
/**
* Sets whether or not the suggestion list was truncated due to the
* {@Request#getLimit}.
*/
public void setMoreSuggestions(boolean moreSuggestions) {
this.moreSuggestions = moreSuggestions;
}
/**
* Sets whether or not the suggestion list was truncated due to the
* {@Request#getLimit}, by providing an exact count of remaining
* suggestions.
*
* @param count number of truncated suggestions. Pass 0 to indicate there
* are no other suggestions, which is equivlent to
* {@link #setMoreSuggestions(false)}.
*/
public void setMoreSuggestionsCount(int count) {
this.numMoreSuggestions = count;
this.moreSuggestions = (count > 0);
}
/**
* Sets the suggestions for this response. Each suggestion must implement
* the {@link Suggestion} interface.
*
* @param suggestions the suggestions
*/
public void setSuggestions(Collection<? extends Suggestion> suggestions) {
this.suggestions = suggestions;
}
}
/**
* Suggestion supplied by the
* {@link com.google.gwt.user.client.ui.SuggestOracle}. Each suggestion has a
* display string and a replacement string. The display string is what is
* shown in the SuggestBox's list of suggestions. The interpretation of the
* display string depends upon the value of its oracle's
* {@link SuggestOracle#isDisplayStringHTML()}. The replacement string is the
* string that is entered into the SuggestBox's text box when the suggestion
* is selected from the list.
*
* <p>
* Replacement strings are useful when the display form of a suggestion
* differs from the input format for the data. For example, suppose that a
* company has a webpage with a form which requires the user to enter the
* e-mail address of an employee. Since users are likely to know the name of
* the employee, a SuggestBox is used to provide name suggestions as the user
* types. When the user types the letter <i>f</i>, a suggestion with the
* display string <i>foo bar</i> appears. When the user chooses this
* suggestion, the replacement string, <i>foobar@company.com</i>, is entered
* into the SuggestBox's text box.
* </p>
*
* <p>
* This is an example where the input data format for the suggestion is not as
* user-friendly as the display format. In the event that the display of a
* suggestion exactly matches the input data format, the
* <code>Suggestion</code> interface would be implemented in such a way that
* the display string and replacement string would be identical.
* </p>
*
* <h3>Associating Data Transfer Objects (DTOs) with Suggestion Objects</h3>
* Some applications retrieve suggesstions from a server, and may want to send
* back a DTO with each suggestion. In the previous example, a DTO returned
* with the suggestion may provide additional contact information about the
* selected employee, and this information could be used to fill out other
* fields on the form. To send back a DTO with each suggestion, extend the
* <code>Suggestion</code> interface and define a getter method that has a
* return value of the DTO's type. Define a class that implements this
* subinterface and use it to encapsulate each suggestion.
*
* <p>
* To access a suggestion's DTO when the suggestion is selected, add a
* {@link com.google.gwt.event.dom.client.ChangeHandler} to the SuggestBox
* (see SuggestBox's documentation for more information). In the
* <code>SuggestionHandler.onSuggestionSelected(SuggestionEvent event)</code>
* method, obtain the selected <code>Suggestion</code> object from the
* {@link com.google.gwt.event.dom.client.ChangeHandler} object, and downcast
* the <code>Suggestion</code> object to the subinterface. Then, acces the DTO
* using the DTO getter method that was defined on the subinterface.
* </p>
*/
public interface Suggestion {
/**
* Gets the display string associated with this suggestion. The
* interpretation of the display string depends upon the value of its
* oracle's {@link SuggestOracle#isDisplayStringHTML()}.
*
* @return the display string for this suggestion
*/
String getDisplayString();
/**
* Gets the replacement string associated with this suggestion. When this
* suggestion is selected, the replacement string will be entered into the
* SuggestBox's text box.
*
* @return the string to be entered into the SuggestBox's text box when this
* suggestion is selected
*/
String getReplacementString();
}
/**
* Constructor for {@link com.google.gwt.user.client.ui.SuggestOracle}.
*/
public SuggestOracle() {
}
/**
* Should {@link Suggestion} display strings be treated as HTML? If true, this
* all suggestions' display strings will be interpreted as HTML, otherwise as
* text.
*
* @return by default, returns false
*/
public boolean isDisplayStringHTML() {
return false;
}
/**
* Generate a {@link Response} based on a default request. The request query
* must be null as it represents the results the oracle should return based on
* no query string.
* <p>
* After the {@link Response} is created, it is passed into
* {@link Callback#onSuggestionsReady(com.google.gwt.user.client.ui.SuggestOracle.Request, com.google.gwt.user.client.ui.SuggestOracle.Response)}
* .
* </p>
*
* @param request the request
* @param callback the callback to use for the response
*/
public void requestDefaultSuggestions(Request request, Callback callback) {
assert (request.query == null);
callback.onSuggestionsReady(request, emptyResponse);
}
/**
* Generate a {@link Response} based on a specific {@link Request}. After the
* {@link Response} is created, it is passed into
* {@link Callback#onSuggestionsReady(com.google.gwt.user.client.ui.SuggestOracle.Request, com.google.gwt.user.client.ui.SuggestOracle.Response)}.
*
* @param request the request
* @param callback the callback to use for the response
*/
public abstract void requestSuggestions(Request request, Callback callback);
}