/*
* Copyright (c) 2013 Bundesamt für Kartographie und Geodäsie.
* See license.txt in the BKG WebMap distribution or repository for the
* full text of the license.
*
* Author: Dirk Thalheim
*/
/**
* @requires OpenLayers/BaseTypes/Class.js
* @requires OpenLayers/Util.js
* @requires BKGWebMap/Control/Geocoder/View.js
* @requires BKGWebMap/Util.js
* @requires BKGWebMap/Layer/MarkerLayer.js
*/
/**
* @classdesc Darstellung von Geocodierungsergebnissen als HTML-Liste
*
* @constructor BKGWebMap.Control.Geocoder.ListView
* @param {object} options
**/
BKGWebMap.Control.Geocoder.ListView = OpenLayers.Class(BKGWebMap.Control.Geocoder.View, {
/**
* Referenz zum Ergebniscontainer
* @type node
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
div: null,
/**
* Basisname für CSS-Klassen
* @type string
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
displayClass: null,
/**
* Texte für Labels
* @type object
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
labels: {
/** Keine Suche gestartet. */
init : '<p>Bitte nutzen Sie das Suchfeld.</p>',
/** Keine Ergebnisse. */
noResults : '<p>Keine Ergebnisse gefunden</p>',
/** Meinten Sie */
didYouMean : '<span class="didyou">Meinten Sie: </span>',
/** Führe Suche durch */
searching : '<p>Suche ...</p>'
},
initialize: function(options) {
this.displayClass = this.CLASS_NAME.replace("BKGWebMap.", "bkg").replace(/\./g, "");
OpenLayers.Util.extend(this, options);
this.draw();
},
draw: function() {
var div = this.div;
if (!div) {
// TODO: generiere Div auf HTML-Seite
// ...
}
OpenLayers.Element.addClass(div, this.displayClass);
div.innerHTML = this.labels.init;
return div;
},
/**
* Wird ausgelöst, wenn eine neue Suche gestartet wird.
* @memberOf BKGWebMap.Control.Geocoder.ListView
* @param {object} evt - Eventobjekt mit element und object
*/
onStartSearch: function(evt) {
this.div.innerHTML = this.labels.searching;
},
/**
* Wird ausgelöst, wenn ein Fehler bei der Geocodierung auftrat.
* @memberOf BKGWebMap.Control.Geocoder.ListView
* @param {object} evt - Eventobjekt mit element, object und response
* @param {BKGWebMap.Protocol.Geoindex.Response} evt.response
*/
onError: function(evt) {
this.div.innerHTML = 'Fehler bei der Suche!';
// TODO: Details!
},
/**
* Wird ausgelöst, wenn die Geocodierung erfolgreich war.
* @memberOf BKGWebMap.Control.Geocoder.ListView
* @param {object} evt - Eventobjekt mit element, object und response
* @param {BKGWebMap.Protocol.Geoindex.Response} evt.response
*/
onLocationUpdate: function(evt) {
this.div.innerHTML = '';
var response = evt.response;
// Ergebnisse lokal speichern
this.features = response.features;
if(!response.features) {
return
}
// render search input
var query = document.createElement("h2");
query.innerHTML = response.data;
OpenLayers.Element.addClass(query, this.displayClass + "SearchTerm");
this.div.appendChild(query);
// Click auf Suchanfrage zoomt auf alle Ergebnisse:
OpenLayers.Event.observe(query, "click", OpenLayers.Function.bindAsEventListener(this.zoomToDataExtend, this));
// Anzeige der Meinten Sie Features. Nur relevant für geoindex
BKGWebMap.Util.each(
response.suggestions,
OpenLayers.Function.bind(
function(index, suggestion){ this.div.appendChild( this.renderSuggestion(suggestion)); }, this
)
);
// Anzeige der Ergebnisse
var ul = document.createElement("ul");
OpenLayers.Element.addClass(ul, this.displayClass + "ResultList");
this.div.appendChild(ul);
// Keine Ergebnisse:
if (response.features.length == 0) {
var li = document.createElement('li');
li.innerHTML += this.labels.noResults;
ul.appendChild(li);
return;
}
// Ergebnissliste:
BKGWebMap.Util.each(
response.features,
OpenLayers.Function.bind(
function(index, feature) { ul.appendChild( this.renderFeature(feature) ); }, this
)
);
},
/**
* Generiert das HTML für einen alternativen Suchvorschlag.
*
* @param {OpenLayers.Feature.Vector} suggestion - alternativer Suchvorschlag.
* @return {node}
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
renderSuggestion : function(suggestion) {
var a = document.createElement('a');
a.href = 'javascript:void(0);';
a.id = 'test';
a.innerHTML = suggestion.attributes.fulltext;
var wrapper = document.createElement('div');
OpenLayers.Element.addClass(wrapper, this.displayClass + 'DidYouMean');
wrapper.innerHTML = this.labels.didYouMean;
wrapper.appendChild(a);
// Click auf DidYouMean soll Suche auslösen
var applySuggestion = function(evt) {
this.applySuggestion(suggestion.attributes.fulltext);
OpenLayers.Event.stop(evt);
};
OpenLayers.Event.observe(a, "click", OpenLayers.Function.bindAsEventListener(applySuggestion, this));
return wrapper;
},
/**
* Generiert das HTML für ein einzelnes Feature in der Ergebnisliste.
*
* @param {OpenLayers.Feature.Vector} feature - Das zu rendernde Feature
* @return node
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
renderFeature : function(feature) {
// DOM generieren
var li = document.createElement('li');
OpenLayers.Element.addClass(li, this.displayClass + "ResultListItem");
var text = feature.attributes.text;
var typ = feature.attributes.typ;
li.innerHTML = text + '<br/><span class="featureType">' + typ + '</span>';
// DOMElement dem Feature zuweisen
feature.resultListItem = li;
// Mouseevents für Listelement registrieren
var toggleHighligth = function(evt) {
this.geocoder.hoverFeature(feature, this.hover);
OpenLayers.Event.stop(evt);
};
OpenLayers.Event.observe(li, "mouseover", OpenLayers.Function.bindAsEventListener(toggleHighligth, {geocoder: this.geocoder, hover: true}));
OpenLayers.Event.observe(li, "mouseout", OpenLayers.Function.bindAsEventListener(toggleHighligth, {geocoder: this.geocoder, hover: false}));
var togglePopup = function(evt) {
BKGWebMap.Layer.MarkerLayer.togglePopup(this);
if(this.popup && this.popup.visible()) {
var geometry = this.attributes.bbox ? this.attributes.bbox : this.geometry;
this.layer.map.zoomToExtent(geometry.getBounds());
}
OpenLayers.Event.stop(evt);
};
OpenLayers.Event.observe(li, "click", OpenLayers.Function.bindAsEventListener(togglePopup, feature));
return li;
},
/**
* Wird auferufen, wenn auf den DidYouMean-Link geclickt wird. Löst ein erneutes Geocoding mit dem vorgeschlagenen
* Suchbegriff aus.
*
* @param {string} term - Der Suchvorschlag
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
applySuggestion: function(term) {
this.geocoder.input.value = term;
this.geocoder.triggerSearch();
},
/**
* Zoomt auf die Ausdehnung aller Features.
* @param evt
* @memberOf BKGWebMap.Control.Geocoder.ListView
*/
zoomToDataExtend: function(evt) {
if(!this.features || this.features.length == 0) return;
this.map.zoomToExtent(BKGWebMap.Util.getDataExtent(this.features), true);
},
/**
* Eventhandler, wenn Feature hervorgehoben wird.
*
* @memberOf BKGWebMap.Control.Geocoder.ListView
* @param {object} evt - Eventobjekt mit element, feature und Hoverstatus
* @param {OpenLayers.Feature} evt.feature - das hervorzuhebende Feature
* @param {boolean} evt.hover - der Status zum hervorheben
*/
onHoverFeature: function(evt) {
if(evt.hover) {
OpenLayers.Element.addClass(evt.feature.resultListItem, 'highlighted');
} else {
OpenLayers.Element.removeClass(evt.feature.resultListItem, 'highlighted');
}
},
CLASS_NAME: "BKGWebMap.Control.Geocoder.ListView"
});