Skip to content

Commit

Permalink
Implement table cell updates: start with bool: update module enabled
Browse files Browse the repository at this point in the history
index.css: modal window using gradient colors

index.js: 
- add # in table cells (rowNr)
- add disabled to checkbox, button and range if ro
- processVarNode: use hasOwnProperty to catch boolean false also
- processVarNode: add isArray to process array values (currently checkbox only supported -> WIP)

pio.ini: disable Artnet and ddp temporarily

Module.h: add enabledChanged

SysModModel:
- setValueB: add rowNr parameter (tbd for other types): for rows: create array if not yet and assign value to array element

SysModModules:
- mdlEnabled.chFun: create value array if not exist, if exists set modules enabled status and trigger enabledChange function

SysModUI: 
- setChFunAndWs: add check for value arrays 
- processJson: check if var id has # (rowNr)
- processJson: if rowNr, use the value array to check the right value
- processJson: if bool call setValueB with rownr

SysModWeb:
- add print clIsFull.chFun 
- call setValueB with rowNr
- add addResponseArray to deal with value arrays
  • Loading branch information
ewoudwijma committed Aug 7, 2023
1 parent c31c638 commit c6aa7d7
Show file tree
Hide file tree
Showing 13 changed files with 482 additions and 391 deletions.
2 changes: 1 addition & 1 deletion data/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ h1,h2 {
right: 0px;
top: 0px;
/* calc(var(--th) - 1px); */
background-color: var(--c-o);
background: linear-gradient(to bottom, #ffbe3390 0%, #b60f6290 100%); /*var(--c-o);*/
transform: translateY(100%);
transition: transform 0.4s;
padding: 8px;
Expand Down
57 changes: 33 additions & 24 deletions data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function makeWS() {
}
}

function generateHTML(parentNode, json, tableRow = -1) {
function generateHTML(parentNode, json, rowNr = -1) {
// console.log("generateHTML", parentNode, json);
if (Array.isArray(json)) {
json.sort(function(a,b) {
Expand Down Expand Up @@ -210,7 +210,7 @@ function generateHTML(parentNode, json, tableRow = -1) {
}
else if (json.type == "url") {
//tbd: th and table row outside this if
if (tableRow == -1) {
if (rowNr == -1) {
newNode = cE("p");
newNode.appendChild(labelNode);
//add label
Expand All @@ -222,15 +222,15 @@ function generateHTML(parentNode, json, tableRow = -1) {
valueNode.setAttribute('target', "_blank");
valueNode.innerText = json.value;

if (tableRow == -1) {
if (rowNr == -1) {
valueNode.id = json.id;
newNode.appendChild(valueNode);
} else {
valueNode.id = json.id + tableRow;
valueNode.id = json.id + "#" + rowNr;
newNode = valueNode;
}
} else { //input
if (tableRow == -1) {
if (rowNr == -1) {
newNode = cE("p");
newNode.appendChild(labelNode);
//add label
Expand All @@ -247,18 +247,21 @@ function generateHTML(parentNode, json, tableRow = -1) {
if (json.type == "checkbox") {
valueNode = cE("input");
valueNode.type = json.type;
valueNode.disabled = json.ro;
if (json.value) valueNode.checked = json.value;
valueNode.addEventListener('change', (event) => {console.log(json.type + " change", event);setCheckbox(event.target);});
} else if (json.type == "button") {
valueNode = cE("input");
valueNode.type = json.type;
valueNode.disabled = json.ro;
valueNode.value = initCap(json.id);
valueNode.addEventListener('click', (event) => {console.log(json.type + " click", event);setButton(event.target);});
} else if (json.type == "range") {
valueNode = cE("input");
valueNode.type = json.type;
valueNode.max = 255;
// valueNode.addEventListener('input', (event) => {console.log(json.type + " input", event);gId(json.id + "_rv").innerText = this.value;});
valueNode.disabled = json.ro;
valueNode.addEventListener('change', (event) => {
console.log(json.type + " change", event.target, json.id);
gId(json.id + "_rv").innerText = event.target.value;
Expand Down Expand Up @@ -294,11 +297,11 @@ function generateHTML(parentNode, json, tableRow = -1) {
}
} //not checkbox or button or range

if (tableRow == -1) {
if (rowNr == -1) {
valueNode.id = json.id;
newNode.appendChild(valueNode);
} else {
valueNode.id = json.id + tableRow;
valueNode.id = json.id + "#" + rowNr;
newNode = valueNode;
}

Expand All @@ -311,8 +314,8 @@ function generateHTML(parentNode, json, tableRow = -1) {

if (newNode) parentNode.appendChild(newNode); //add new node to parent

//don't call uiFun on tablerows (for the moment)
if (tableRow == -1) {
//don't call uiFun on rowNrs (for the moment)
if (rowNr == -1) {
//call ui Functionality, if defined (to set label, comment, select etc)
if (json.uiFun >= 0) { //>=0 as element in var
uiFunCommands.push(json.id);
Expand All @@ -328,10 +331,10 @@ function generateHTML(parentNode, json, tableRow = -1) {
divNode.id = json.id + "_n";
divNode.classList.add("ndiv");
newNode.appendChild(divNode);
generateHTML(divNode, json.n, tableRow);
generateHTML(divNode, json.n, rowNr);
}
else
generateHTML(newNode, json.n, tableRow); //details (e.g. module)
generateHTML(newNode, json.n, rowNr); //details (e.g. module)
}
}
return newNode;
Expand Down Expand Up @@ -379,7 +382,7 @@ function processUpdate(json) {
function processVarNode(node, key, json) {
let overruleValue = false;

if (json.label) {
if (json.hasOwnProperty("label")) {
console.log("processUpdate label", key, json.label);
if (node.nodeName.toLocaleLowerCase() == "input" && node.type == "button") {
node.value = initCap(json.label);
Expand All @@ -395,7 +398,7 @@ function processVarNode(node, key, json) {
labelNode.innerText = initCap(json.label);
}
}
if (json.comment) {
if (json.hasOwnProperty("comment")) {
console.log("processUpdate comment", key, json.comment);
// normal: <p><label><input id><comment></p>
// table or canvas <p><label><comment></p><canvas id>
Expand All @@ -418,7 +421,7 @@ function processVarNode(node, key, json) {
}
commentNode.innerText = json.comment;
}
if (json.select) {
if (json.hasOwnProperty("select")) {
console.log("processUpdate select", key, json.select);
if (node.nodeName.toLocaleLowerCase() == "span") { //readonly. tbd: only the displayed value needs to be in the select
var index = 0;
Expand Down Expand Up @@ -447,7 +450,7 @@ function processVarNode(node, key, json) {
}
}
}
if (json.table) {
if (json.hasOwnProperty("table")) {
console.log("processUpdate table", key, json.table);
//remove table rows
let tbodyNode = cE('tbody');
Expand Down Expand Up @@ -489,26 +492,34 @@ function processVarNode(node, key, json) {
//replace the table body
node.replaceChild(tbodyNode, node.lastChild); //replace <table><tbody>
}
if (json.value && !overruleValue) { //after select, in case used
// if (key=="ledFix" || key =="ledFixGen"|| key =="reset0")
// console.log("processUpdate value", key, json.value, node);
if (json.hasOwnProperty("value") && !overruleValue) { //after select, in case used
//hasOwnProperty needed to catch also boolean json.value when it is false
// if (key=="mdlEnabled" || key=="clIsFull" || key=="pin2")
// console.log("processUpdate value", key, json, json.value, node);
if (node.nodeName.toLocaleLowerCase() == "span") //read only vars
node.textContent = json.value;
else if (node.nodeName.toLocaleLowerCase() == "a") {
else if (node.nodeName.toLocaleLowerCase() == "a") { //url links
node.innerText = "🔍";
node.setAttribute('href', json.value);
} else if (node.nodeName.toLocaleLowerCase() == "canvas")
userFunId = key; //prepare for websocket data
else if (node.type == "checkbox")
node.checked = json.value;
else //inputs
else if (Array.isArray(json.value)) {
let rowNr = 0;
for (let x of json.value) {
gId(key + "#" + rowNr).checked = x; //tbd support all types!!
rowNr++;
}
// node.checked = json.value;
} else //inputs
node.value = json.value;
}
if (json.json) { //json send html nodes cannot process, store in jsonValues array
if (json.hasOwnProperty("json")) { //json send html nodes cannot process, store in jsonValues array
console.log("processUpdate json", key, json.json, node);
jsonValues[key] = json.json;
}
if (json.file) { //json send html nodes cannot process, store in jsonValues array
if (json.hasOwnProperty("file")) { //json send html nodes cannot process, store in jsonValues array
console.log("processUpdate file", key, json.file, node);

//we need to send a request which the server can handle using request variable
Expand Down Expand Up @@ -643,8 +654,6 @@ function toggleModal(element) {
}

gId('modalView').style.transform = (isModal) ? "translateY(0px)":"translateY(100%)";


}
// https://stackoverflow.com/questions/324303/cut-and-paste-moving-nodes-in-the-dom-with-javascript

Expand Down
4 changes: 3 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ lib_deps =

[appmod_leds]
build_flags =
-D APPMOD_LEDS -D USERMOD_ARTNET -D USERMOD_DDP
-D APPMOD_LEDS
; -D USERMOD_ARTNET
; -D USERMOD_DDP
lib_deps =
https://github.com/FastLED/FastLED.git

Expand Down
1 change: 1 addition & 0 deletions src/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Module {
virtual void loop() {}

virtual void connected() {}
virtual void enabledChanged(bool tf) {}

virtual void testManager() {}
virtual void performanceManager() {}
Expand Down
32 changes: 27 additions & 5 deletions src/Sys/SysModModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,35 @@ JsonObject SysModModel::setValueI(const char * id, int value) {
return var;
}

JsonObject SysModModel::setValueB(const char * id, bool value) {
JsonObject SysModModel::setValueB(const char * id, bool value, uint8_t rowNr) {
JsonObject var = findVar(id);
if (!var.isNull()) {
if (var["value"].isNull() || var["value"] != value) {
// print->print("setValue changed %s %s->%s\n", id, var["value"].as<String>().c_str(), value?"true":"false");
var["value"] = value;
ui->setChFunAndWs(var);
// print->printJson("setValueB", var);
if (rowNr == (uint8_t)-1) { //normal situation
if (var["value"].isNull() || var["value"] != value) {
print->print("setValueB changed %s (%d) %s->%s\n", id, rowNr, var["value"].as<String>().c_str(), value?"true":"false");
var["value"] = value;
ui->setChFunAndWs(var);
}
}
else {
//if we deal with multiple rows, value should be an array, if not we create one

if (var["value"].isNull() || !var["value"].is<JsonArray>()) {
print->print("setValueB var %s (%d) value %s not array, creating\n", id, rowNr, var["value"].as<String>().c_str());
// print->printJson("setValueB var %s value %s not array, creating", id, var["value"].as<String>().c_str());
var.createNestedArray("value");
}

if (var["value"].is<JsonArray>()) {
//set the right value in the array (if array did not contain values yet, all values before rownr are set to false)
if (var["value"][rowNr] != value) {
var["value"][rowNr] = value;
ui->setChFunAndWs(var);
}
}
else
print->print("setValueB %s could not create value array\n", id);
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/Sys/SysModModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SysModModel:public Module {
static JsonObject setValueI(const char * id, int value);

//setValue bool
static JsonObject setValueB(const char * id, bool value);
static JsonObject setValueB(const char * id, bool value, uint8_t rowNr=-1);

//Set value with argument list
static JsonObject setValueV(const char * id, const char * format, ...); //static to use in *Fun
Expand Down
23 changes: 22 additions & 1 deletion src/Sys/SysModModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,29 @@ void Modules::setup() {
ui->initCheckBox(tableVar, "mdlSucces", false, true, [](JsonObject var) { //uiFun
web->addResponse(var["id"], "label", "Success");
});
ui->initCheckBox(tableVar, "mdlEnabled", false, false, [](JsonObject var) { //uiFun not readonly! (tbd)
ui->initCheckBox(tableVar, "mdlEnabled", true, false, [](JsonObject var) { //uiFun not readonly! (tbd)
//initially set to true, but as enabled are table cells, will be updated to an array
web->addResponse(var["id"], "label", "Enabled");
}, [](JsonObject var) { //chFun
print->printJson("mdlEnabled.chFun", var);
//if value not array, create and initialize
uint8_t rowNr = 0;
if (!var["value"].is<JsonArray>()) {
var.createNestedArray("value");
for (Module *module: modules) {
var["value"][rowNr] = module->enabled;
rowNr++;
}
} else { //read array and set module enabled
for (bool enabled:var["value"].as<JsonArray>()) {
if (modules[rowNr]->enabled != enabled) {
print->print(" mdlEnabled.chFun %d %s: %d->%d\n", rowNr, modules[rowNr]->name, modules[rowNr]->enabled, enabled);
modules[rowNr]->enabled = enabled;
modules[rowNr]->enabledChanged(enabled);
}
rowNr++;
}
}
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/Sys/SysModSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void SysModSystem::addResetReasonsSelect(JsonArray select) {
select.add("TGWDT_CPU_RESET"); //11, /**<11, Time Group reset CPU*/
select.add("SW reset CPU (12)");//SW_CPU_RESET"); //12, /**<12, */
select.add("RTCWDT_CPU_RESET"); //13, /**<13, RTC Watch dog Reset CPU*/
select.add("for APP CPU, reseted by PRO CPU");//EXT_CPU_RESET"); //14, /**<14, */
select.add("for APP CPU, reset by PRO CPU");//EXT_CPU_RESET"); //14, /**<14, */
select.add("RTCWDT_BROWN_OUT_RESET"); //15, /**<15, Reset when the vdd voltage is not stable*/
select.add("RTCWDT_RTC_RESET"); //16 /**<16, RTC Watch dog reset digital core and rtc module*/
}
Expand Down
32 changes: 30 additions & 2 deletions src/Sys/SysModUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ void SysModUI::setChFunAndWs(JsonObject var, const char * value) { //value: bypa
web->addResponseB(var["id"], "value", var["value"].as<bool>());
else if (var["value"].is<const char *>())
web->addResponse(var["id"], "value", var["value"].as<const char *>());
else if (var["value"].is<JsonArray>())
web->addResponseArray(var["id"], "value", var["value"].as<JsonArray>());
else {
print->print("unknown type for %s\n", var["value"].as<String>().c_str());
web->addResponse(var["id"], "value", var["value"]);
Expand Down Expand Up @@ -286,17 +288,43 @@ const char * SysModUI::processJson(JsonVariant &json) {
}
else { //normal change
if (!value.is<JsonObject>()) { //no vars (inserted by uiFun responses)

//check if we deal with multiple rows (from table type)
char * rowNr = strtok((char *)key, "#");
if (rowNr != NULL ) {
key = rowNr;
rowNr = strtok(NULL, " ");
}

JsonObject var = mdl->findVar(key);

print->print("processJson k:%s r:%s (%s == %s ? %d)\n", key, rowNr?rowNr:"na", var["value"].as<String>().c_str(), value.as<String>().c_str(), var["value"] == value);

if (!var.isNull())
{
if (var["value"] != value) { // if changed
bool changed = false;
//if we deal with multiple rows, value should be an array and check the corresponding array item
//if value not array we change it anyway
if (rowNr) {
//var value should be array
if (var["value"].is<JsonArray>())
changed = var["value"][atoi(rowNr)] != value;
else {
print->printJson("we want an array for value but : ", var);
changed = true; //we should change anyway
}
}
else //normal situation
changed = var["value"] != value;

if (changed) {
// print->print("processJson %s %s->%s\n", key, var["value"].as<String>().c_str(), value.as<String>().c_str());

//set new value
if (value.is<const char *>())
mdl->setValueC(key, value.as<const char *>());
else if (value.is<bool>())
mdl->setValueB(key, value.as<bool>());
mdl->setValueB(key, value.as<bool>(), rowNr?atoi(rowNr):-1);
else if (value.is<int>())
mdl->setValueI(key, value.as<int>());
else {
Expand Down
Loading

0 comments on commit c6aa7d7

Please sign in to comment.