package de.flower.rmt.ui.page.venues.manager.geocode;
import de.flower.common.ui.ajax.event.AjaxEventSender;
import de.flower.common.ui.ajax.markup.html.form.AjaxSubmitLink;
import de.flower.common.ui.panel.BasePanel;
import de.flower.rmt.service.geocoding.GeocodingResult;
import de.flower.rmt.service.geocoding.IGeocodingService;
import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.util.ListModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;
/**
* @author flowerrrr
*/
public abstract class GeocodePanel extends BasePanel {
private final static Logger log = LoggerFactory.getLogger(GeocodePanel.class);
@SpringBean
private IGeocodingService geocodingService;
private IModel<List<GeocodingResult>> resultListModel = new ListModel<>();
private GeocodePanel self = this;
public GeocodePanel() {
// need ajax submit button to have the address field submit its value so that it can be accessed here.
AjaxSubmitLink geocodeButton = new AjaxSubmitLink("geocodeButton") {
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
String value = getAddress();
if (StringUtils.isBlank(value)) {
// avoid useless remote call to google api
resultListModel.setObject(Collections.<GeocodingResult>emptyList());
} else {
List<GeocodingResult> results;
try {
results = geocodingService.geocode(value);
resultListModel.setObject(results);
} catch (Exception e) {
log.error("Geocoding API error in search for [" + value + "]: " + e.getMessage(), e);
resultListModel.setObject(Collections.<GeocodingResult>emptyList());
}
}
self.setVisible(true);
target.add(self);
AjaxEventSender.send(this, GeocodingResult.class);
}
};
// disable validation when clicking this button
geocodeButton.setDefaultFormProcessing(false);
getGeocodeButtonParent().add(geocodeButton);
GeocodeResultsPanel geocodeResultsPanel;
add(geocodeResultsPanel = new GeocodeResultsPanel(resultListModel) {
@Override
protected void onSelect(final AjaxRequestTarget target, final GeocodingResult result) {
self.onSelect(target, result);
}
@Override
public boolean isVisible() {
return resultListModel.getObject() != null;
}
});
geocodeResultsPanel.setOnCloseCallback(new BasePanel.IOnCloseCallback() {
@Override
public void onClose(final AjaxRequestTarget target) {
self.setVisible(false);
target.add(self);
}
});
}
protected abstract void onSelect(AjaxRequestTarget target, GeocodingResult result);
/**
* If add button should be placed outside of this panel hierarchy (waiting for Wicket 6).
* @return
*/
protected MarkupContainer getGeocodeButtonParent() {
return this;
}
/**
* Must return the address that is searched for.
*
* @return
*/
protected abstract String getAddress();
}