In this step you learn
  • How setup code joins the query with &&.
  • How ExtjsUtils.QUERY.setQueryGlobalProperties declares values and functions the query shares.
  • runNow, and how buttons find the function they call.

A query is one expression (step 1), so it cannot declare variables or run statements before the list of layers. Setup is done with calls joined by &&: each call does its work and returns true, so the expression goes on, and the last value - the list - is what the platform keeps.

SetupCall(...) && OtherSetupCall(...) && [ /* the layers */ ];

addRemoteWMSServer (step 3) was one. The most useful one is ExtjsUtils.QUERY.setQueryGlobalProperties: each key of the object becomes a name the whole query can use - a value, a list, a function - for as long as this query is applied. Applying another query removes them.

Click the picture to run it live - nothing is saved.
The query 36 lines · runs as is
// Globals and functions: setQueryGlobalProperties declares the names the query shares, runNow runs once when the query is applied, and buttons call functions by name.
// A query is one expression, so it cannot declare variables with var: setQueryGlobalProperties
// puts each key on window while this query is applied, and returns true, so the && chain goes on
// to the layers. A button's handler is looked up in the layer's functions first (this = the
// layer), then among the globals.
ExtjsUtils.QUERY.setQueryGlobalProperties({
  CAPITAL: { name: "Brasilia", lon: -47.88, lat: -15.79 },
  // the one name the platform calls by itself, once, after the globals are in place
  runNow: function () {
    ExtjsUtils.ALERTIFY.log("The query is applied - press the buttons in the panel.");
  },
  goToCapital: function () {
    var map = ExtjsUtils.JS.getMap();
    var center = new OpenLayers.LonLat(CAPITAL.lon, CAPITAL.lat)
      .transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
    map.setCenter(center, 9);
    ExtjsUtils.ALERTIFY.log("Here is " + CAPITAL.name + ".");
  },
}) && [
  {
    title: "States",
    name: "CSR:estados",
    source: "calculate", // a calculated layer without expression shows the map as it is - and has a panel for the buttons
    visibility: true,
    opacity: 0.5,
    paramsButtonConfig: [{ type: "query", pressed: true }],
    descriptionHtml:
      "{{button|id=go_capital|text=Go to the capital|handler=goToCapital}}" + // a global function
      "{{button|id=which_layer|text=Which layer is this?|handler=sayTitle}}", // a function of the layer
    functions: {
      sayTitle: function () {
        ExtjsUtils.ALERTIFY.log("This button belongs to the layer \"" + this.title + "\".");
      },
    },
  },
];

What happens

  • CAPITAL is a shared value; goToCapital a shared function that uses it.
  • runNow is the one name the platform calls by itself: once, when the query is applied, after the globals are in place - here, to greet the reader.
  • The buttons need a panel, and only calculated, file and tile layers have one (step 5). So the states are a calculated layer with no expression: it shows the map as it is, with a panel for the buttons.
  • Buttons name the function they call: {{button|handler=goToCapital}}. The platform looks for the name first in the layer’s own functions - where this is the layer, as in sayTitle - and then among the globals.
  • Write these as regular functions: an arrow function has no this of its own, so a layer function written as one cannot reach its layer.

Globals cannot reuse a name the page already has (map, app, Ext…): pick names of your own.

Settings for the whole query

The same && chain carries the settings of the whole query, with ExtjsUtils.CONFIGURATION.setOptions. For example, when the map is embedded in another page, keepOnLeave: false stops the mouse wheel from zooming the map once the pointer has left it, until the reader clicks the map again - so scrolling the page does not zoom the map:

ExtjsUtils.CONFIGURATION.setOptions({ keepOnLeave: false }) && [ /* the layers */ ];

A layer’s own settings stay in the layer (step 2), and a link can add its own (step 9). Where to find it shows the three places, and which one wins when a setting exists in two.

Try this

  1. Change CAPITAL to another city - Manaus is at longitude -60.02, latitude -3.12.
  2. Add a third button that calls goToCapital too: two buttons, one function.
  3. Write var x = 1; before ExtjsUtils.QUERY... and run it: the map opens without your layers - a statement breaks the expression.
  4. Turn sayTitle into an arrow function, sayTitle: () => ...: this is no longer the layer, and the title is lost.

Read more