-
Notifications
You must be signed in to change notification settings - Fork 651
[Draft] Infowindow API Proposal
Current Infowindow API is okay, but users are asking for more. Let's see can we can improve that! 😄
cdb.vis.Vis.addInfowindow(map, layer, fields [, options])
allows us to setup an infowindow for a layer. We need to pass a native map, the sublayer and an array of strings with the names of the fields that will be displayed. The following options could be specified: templateType
, triggerEvent
, templateName
, extraFields
, cursorInteraction
(but they are not documented in the docs).
Here's an example (using cartodb.createLayer
):
var map = L.map('map', { ... });
cartodb.createLayer(map, {
...
})
.addTo(map)
.done(function(layer) {
var sublayer = layer.getSubLayer(0);
sublayer.setInteraction(true); // It looks like this is not necessary
cdb.vis.Vis.addInfowindow(map, sublayer, ['cartodb_id','name']);
});
And here's another example (using cartodb.createVis
):
cartodb.createVis('map', 'https://wadus.cartodb.com/api/v2/viz/48b32c96-ffce-11e4-96bd-0e4fddd5de28/viz.json', {...})
.done(function(vis, layers) {
var sublayer = layers[1].getSubLayer(0);
// you can get the native map to work with it
var map = vis.getNativeMap();
// It doesn't work if we don't set this
map.viz = vis;
cdb.vis.Vis.addInfowindow(map, sublayer, ['cartodb_id','name']);
// Since we have the `vis` here, it would probably be easier to do something like:
// vis.addInfowindow(sublayer, ['cartodb_id','name']);
})
More info here.
Infowindows can be customized via sublayer.infowindow
. This is a Backbone.Model with the following attributes: template
, sanitizeTemplate
, width
,
maxHeight
. This model exposes some more attributes like: fields
, etc, but they are not documented.
Here's an example:
...
sublayer.infowindow.set({
template: $('#infowindow_template').html(),
width: 218,
maxHeight: 100
});
...
More info here.
Someone could hack a custom infowindow by listening and taking advantage of the featureClick
event on a sublayer.
Here's an example:
sublayer.setInteraction(true);
sublayer.setInteractivity('place');
sublayer.on('featureClick', function(e, latlng, pos, data, layerNumber) {
cartodb.log.log(e, latlng, pos, data, layerNumber);
$("#myInfowindow").css({'display':'block','left':pos.x-75,'bottom':($(window).height()-pos.y+20), 'cursor': 'pointer'});
$("#myInfowindow").find('p').text(data.place);
});
More info here.
- A visualization/map can only have one opened infowindow at a time.
- The information (fields/attributes) that is displayed in the infowindow is always linked to a feature that belongs to a mapnik/cartodb sublayer.
- The attributes that are displayed in the infowindow are retrieved using the Maps API (attributes endpoint).
- Open an infowindow from javascript and listen to events to know when this happens (example).
- Close an infowindow.
- Change data provider for infowindows. For example: many users want to show data from a custom sql based on cartodb_id and other stuff (example).
Other requests:
- Create infowindows form scratch (without the need of a viz.json).
- DOMready events to do things after infowindow it's rendered.
- Show custom content, like graphs generated using Google Charts (example).
- Extend template formatting options (to format numbers and so on).
- Manage layer order interaction properly.
- Customize infowindow size from CartoDB. Currently this can be done using cartodb.js using a hack (so an API endpoint should be provided for that (example).
Infowindows will now always be accessed through sublayers and the cartodb.Infowindow
object, instead of relying on cdb.vis.Vis.addInfowindow
.
// Accessing infowindows
sublayer.infowindow // Returns a cartodb.Infowindow
// Updating infowindows
sublayer.infowindow.set({
template: '<p>wadus: {{ wadus }}</p>', // string, mustache, function(data){},
fields: ['wadus'],
sanitizeTemplate: true|false,
width: 400,
maxHeight: 300
});
// Opening an infowindow on a sublayer feature
sublayer.infowindow.open('23234');
// Setting a dynamic function as a template for the infowindow. Function
// can return a string with the template or a Promise.
sublayer.infowindow.set('template', function(data) {
var promise = new cartodb.Promise();
$.get('http://javi.cartodb.com/api/v1/sql?q=select * from generate_series(1, 3) AS wadus', function(data) {
var rows = _.pluck(data.rows, 'generate_series');
var template = "<p>{{ rows[0].wadus }}</p>"
promise.trigger('done', template);
})
return promise;
});
sublayer.infowindow.isOpened(); // Returns true if there's an opened infowindow
sublayer.infowindow.close(); // Closes the infowindow (if opened)
sublayer.infowindow.enable(); // Enables the infowindow for the layer
sublayer.infowindow.disable(); // Disables the infowindow for the layer
// Events
sublayer.infowindow.on('open', function() { ... });
sublayer.infowindow.on('close', function() { ... });
sublayer.infowindow.on('load', function(featureId, data) { ... }); // Data has been rendered
- GMaps InfoWindow API. Features:
- Customize the infowindow via options.
- Getting/setting the content of an infowindow (also an option).
- Getting/setting the position (latlng) of the infowindow (also an option).
- Open an infowindow in a map (in the given position or in the position of an associated marker).
- Listen to events that are triggered when attributes change, DOM inside of the infowindow is ready, etc.
- Leaflet Popup API. Features:
- Customize the infowindow via options.
- Add a popup to a map.
- Open a popup on a map.
- Getting/setting the content of the popup.
- Getting/setting the position (latlng) of the popup.