Hi Guys,
I’ve seen this question asked severally but no one has actually given the option of making it work.
Is there anyone who can share a sample project that has implemented the google search option? I would like to use the location name as a field input.
Thanks in advance,
Kenince
artamonov
(Yuriy Artamonov)
#3
Hi,
You could use Java Client for Google APIs and SuggestionPickerField UI component.
Just set a SearchExecutor
that will call Google Maps APIs:
suggestionPickerField.setSearchExecutor((searchString, searchParams) -> {
return Arrays.asList(entity1, entity2, ...); // call Google APIs here
});
Hello Yuriy,
Could you be having a sample project where this has been implemented?
Regards…
artamonov
(Yuriy Artamonov)
#6
It is not that hard to use Google APIs even without external dependencies.
For instance, define SuggestionPickerField as follows:
<suggestionPickerField id="placesSuggestionPicker"
metaClass="demo_Place"
caption="Places search"
width="300px">
<actions>
<action id="clear"/>
</actions>
</suggestionPickerField>
Then assign your SearchExecutor:
@Inject
private SuggestionPickerField placesSuggestionPicker;
@Override
public void init(Map<String, Object> params) {
super.init(params);
placesSuggestionPicker.setSearchExecutor(this::loadPlaces);
In loadPlaces
method call Google APIs using HttpURLConnection
:
private List loadPlaces(String input, @SuppressWarnings("unused") Map<String, Object> searchParams) {
log.info("Searching for {}", input);
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
String sb = PLACES_API_BASE + TYPE_AUTOCOMPLETE +
OUT_JSON +
"?sensor=false" +
"&key=" + googleApiConfig.getApiKey() +
"&input=" +
URLEncoder.encode(input, "utf8");
URL url = new URL(sb);
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
} catch (Exception e) {
log.error("Error processing Places API URL", e);
return Collections.emptyList();
} finally {
if (conn != null) {
conn.disconnect();
}
}
try {
// Create a JSON object hierarchy from the results
JSONObject jsonObj = new JSONObject(jsonResults.toString());
if (jsonObj.has("error_message")) {
String errorMessage = jsonObj.getString("error_message");
if (errorMessage != null) {
log.error("Google API error {}", errorMessage);
return Collections.emptyList();
}
}
JSONArray predictionsJsonArray = jsonObj.getJSONArray("predictions");
ArrayList<Place> resultList = new ArrayList<>(predictionsJsonArray.length());
// fill result list
for (int i = 0; i < predictionsJsonArray.length(); i++) {
Place place = metadata.create(Place.class);
place.setTitle(predictionsJsonArray.getJSONObject(i).getString("description"));
resultList.add(place);
}
return resultList;
} catch (JSONException e) {
log.error("Error processing JSON results", e);
return Collections.emptyList();
}
}
It will load places asynchronously on user input:
See the complete demo: GitHub - cuba-labs/places-search: Google Maps Autocomplete in SuggestionPickerField
Do not forget to setup your Google API key in web-app.properties:
google.apiKey = YOUR_KEY_HERE
1 Like