Quick start
The example below, running in the Mappia calculator - click it to run it live. Full-size picture
- Run it
Click the picture: the map opens right here and runs the example. Nothing is saved, and nothing to install.
- Try it
- Replace 15 with 25: after the countdown, only the slopes steeper than 25 degrees stay orange.
- Type abc instead: the field is flagged as not a number.
- Make it yours
Copy the query, change it - the key parameters are below - and run it again in the playground, or paste it into the Mappia editor to save it as your map.
Key parameters
| Parameter | Example | What it does |
|---|---|---|
id | minimum | Names the text: read it as inputs.id['minimum'] in beforeCalc, and by position (inputs[0] here) inside expression. |
value | 15 | The starting text. The input always holds a string, so convert it with parseFloat before comparing. |
isnumeric | true | Marks the field invalid when the text is not a number. It only validates: the value still arrives as text. |
fieldLabel | Min. slope (°) | Label shown at the left of the box, about 100 pixels wide: a longer text wraps. |
style | text-align:right; | CSS for the box, for example to right-align numbers. |
Every parameter, with its type and default, is in the reference at the end of this page.
Complete example
The query 21 lines · runs as is
// Textfield: type the minimum slope. isnumeric only validates - the value is still a string.
[
{
title: "Slopes steeper than a typed value",
name: "CSR:bioma_cerrado_declividade",
source: "calculate",
opacity: 0.9,
visibility: true,
paramsButtonConfig: [{ type: "query", pressed: true }],
descriptionHtml:
"{{textfield|id=minimum|fieldLabel=Min. slope (°)|value=15|isnumeric=true}}",
beforeCalc: function (inputs) {
this.setCalculateLegend([
{ color: [211, 84, 0], value: 1, title: "Steeper than " + inputs.id["minimum"] + " degrees" },
]);
},
expression: function (layersVals, inputs) {
return layersVals[0] >= parseFloat(inputs[0]) ? 1 : this.nullValue;
},
},
];Customize it
Convert the text
The value is the text exactly as typed, a string even with isnumeric. Convert it where you use it: parseFloat(inputs[0]) inside expression, or parseFloat(inputs.id["minimum"]) || 0 in beforeCalc to fall back to 0 when the field is empty.
isnumeric does not stop the user from typing letters, and invalid text still reaches the layer. parseFloat("abc") is NaN, and every comparison with NaN is false. Guard against it:
expression: function (layersVals, inputs) {
var minimum = parseFloat(inputs[0]);
if (isNaN(minimum)) return this.nullValue;
return layersVals[0] >= minimum ? 1 : this.nullValue;
},
Typing and recalculation
Every keystroke counts as a change, and the layer recalculates after the usual countdown (about 2.5 seconds, shown on a button). With updateAutomatically: true on the layer there is no countdown and each keystroke starts a new calculation, so leave it off for text boxes.
For work that should run once per edit, use the afteredit event: it fires when the field loses focus with changed text. Attach it from a label placed after the field:
descriptionHtml:
"{{textfield|id=minimum|fieldLabel=Min. slope (°)|value=15|isnumeric=true}}" +
"{{label|id=minimum_echo|getid=minimum|getid=on_afteredit=Ext.getCmp('minimum_echo').setText('Last value: ' + this.getRawValue())}}",
From code, Ext.getCmp("minimum").on("afteredit", function (field) { ... }) does the same.
Change the text from code
Ext.getCmp("minimum").setRawValue("25") replaces the text, and getRawValue() reads it. Setting the text does not count as a change, so the layer does not recalculate. Add an InputManager to the layer and call its forceRecalc() after.
Show only your inputs
hideLegendButton: true on the layer hides its generated legend and opacity slider, so the panel shows only your descriptionHtml.
Pitfalls
- Inside
expressionthere is noinputs.id; read the text by position. - Several text fields are
inputs[0],inputs[1]… in the order they appear indescriptionHtml. Labels and buttons take no position.