sclass HSlider { S id = aGlobalID(), name, label, unit; double min, max, value, step = 1; bool useWebSocket = true; !include #1028121 // setField + change() bool requiresWebSocket() { true; } // ID of numerical value display S valueID() { ret id + "_value"; } S html() { ret div(span(str(value), id := valueID()) + prependSpaceIfNempty(unit), style := "width: 8ch; display: inline-block; text-align: right") + " " + tag input("", type := "range", +id, +name, +min, +max, +value, +step, oninput := !useWebSocket ? null : jsDollarVars([[ document.getElementById($valueID).innerHTML = this.value; if (typeof wsSend !== 'undefined') wsSend(JSON.stringify({sliderValue: {id: $id, value: this.value}})); ]], +id, +valueID())) + " " + hlabelFor(id, label); } void onWebSocketJSON(Map map) { Map map2 = optCast Map(map.get("sliderValue")), ret if null; S id = cast map2.get("id"); if (!eq(id, this.id)) ret; Number value = cast map2.get("value"); setField(value := toDouble(value)); } }