0

I'm trying to configure the Twitter Typeahead library to work with a GeoServer WFS layer, so I can create an auto-complete feature search function.

Typeahead has the Bloodhound suggestion engine, which can work with a remote data source. There's a good working example at http://jsfiddle.net/Fresh/bbzt9hcr/ where the transform function is used to convert the nested JSON response into an array which is displayed in the Typeahead dropdown.

I believe that it's necessary to use JSONP and a callback function in order to avoid cross-origin issues in GeoServer (please correct me if I'm wrong) so I'm using the following code to achieve this:

var parameters = { format_options: "callback:typeaheadCallback", service: "WFS", version: "1.0.0", request: "GetFeature", typeName: "repairernames", outputFormat: "text/javascript", propertyName: "repairername", CQL_FILTER: "repairername like 'QUERY%'" } var repairers = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { wildcard: '%QUERY', url: 'http://localhost/geoserver/blah/wfs?' + jQuery.param(parameters), transform: function (result) { return $.map(result.features, function (feature) { return { value: feature.properties.repairername }; }); }, prepare: function(query, settings) { settings.dataType = "jsonp" settings.url = settings.url.replace('QUERY', query) return settings; } } }); function typeaheadCallback(json){ console.log("Typeahead callback response: ", json); return json; }

The change compared to the working demo is the new prepare function (described here) which tells Bloodhound/Typeahead to use JSONP, and the callback typeaheadCallback which is specified in the parameters.

Via the debugger I can see that the request to GeoServer is successfully implemented, and the console.log in the typeaheadCallback shows that valid values are returned as JSON.

enter image description here

The problem is that the transform function is never called, so the returned JSON object from GeoServer isn't transformed, and therefore isn't sent to the Typeahead dropdown menu, which therefore doesn't display results.

How can I configure Typeahead and Bloodhound to work with a GeoServer WFS layer?

1

JSONP is not enabled by default (there are security concerns related to it), you have to add a variable to the GeoServer startup: http://docs.geoserver.org/latest/en/user/services/wms/global.html

As an alternative, you can enable CORS in the web container running GeoServer instead (check the web container specific instructions on how to enable it).

  • Thanks for the tip. The answer involved a few changes to my code, including enabling CORS on the GeoServer, specifying outputFormat=application%2Fjson and manually encoding all of the parameters into the URL, eg &CQL_FILTER=repairername%20like%20%27QUERY%25%27 – Stephen Lead Apr 18 '17 at 5:30
0

A few years later and I finally got around to writing this up properly - see http://www.stephenlead.com/posts/using-geoserver-as-the-source-for-a-type-ahead

In short, I needed to add the prepare and transform functions to the Bloodhound engine as shown below:

// Initialize the Bloodhound engine
var bloodhoundEngine = new Bloodhound({
  datumTokenizer: function(datum) {
      return Bloodhound.tokenizers.whitespace(datum.value);
    },
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  limit: 15,
  remote: {
    url: typeaheadBase + '%QUERY',
    wildcard: '%QUERY',
    prepare: function(query, settings) {
      // Build the query string in a GeoServer-ready format
      settings.url = typeaheadBase + jQuery.param(typeaheadParams);
      settings.url += "&CQL_FILTER=strToUpperCase(" + nameField + ")%20like%20%27QUERY%25%27";
      settings.url = settings.url.replace('QUERY', query.toUpperCase());
      return settings;
    },
    transform: function(response) {
      // temporarily persist the geometries of the returned states
      geometries = {};
      return $.map(response.features, function(feature) {
        geometries[feature.properties[nameField]] = feature.geometry;

        // Return the state name to the TypeAhead suggestion dropdown
        return (feature.properties[nameField]);
      });
    }
  },
});
bloodhoundEngine.initialize();

See the working demo at https://slead.github.io/GeoServer_TypeAhead/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.