Display multiple meters in tabbed interface
This commit is contained in:
+21
-1
@@ -432,6 +432,15 @@ static void handleRoot() {
|
|||||||
if (!requireAuth()) { Serial.println("[HTTP] GET / -> 401"); return; }
|
if (!requireAuth()) { Serial.println("[HTTP] GET / -> 401"); return; }
|
||||||
Serial.println("[HTTP] GET /");
|
Serial.println("[HTTP] GET /");
|
||||||
String meterRows;
|
String meterRows;
|
||||||
|
bool useTabs = meterCount > 1;
|
||||||
|
if (useTabs) {
|
||||||
|
meterRows += "<div class=tabs><div class=tab-nav>";
|
||||||
|
for (int i = 0; i < meterCount; i++) {
|
||||||
|
String label = strlen(meters[i].name) > 0 ? escHtml(meters[i].name) : "Meter " + String(i);
|
||||||
|
meterRows += "<button class=tab-btn" + String(i == 0 ? " active" : "") + " data-tab=" + String(i) + ">" + label + "</button>";
|
||||||
|
}
|
||||||
|
meterRows += "</div>";
|
||||||
|
}
|
||||||
for (int i = 0; i < meterCount; i++) {
|
for (int i = 0; i < meterCount; i++) {
|
||||||
char maxStr[8], curStr[8];
|
char maxStr[8], curStr[8];
|
||||||
dtostrf(meters[i].maxDuty, 1, 1, maxStr);
|
dtostrf(meters[i].maxDuty, 1, 1, maxStr);
|
||||||
@@ -443,7 +452,9 @@ static void handleRoot() {
|
|||||||
dtostrf(meters[i].rangeMin, 1, 1, rMinStr);
|
dtostrf(meters[i].rangeMin, 1, 1, rMinStr);
|
||||||
dtostrf(meters[i].rangeMax, 1, 1, rMaxStr);
|
dtostrf(meters[i].rangeMax, 1, 1, rMaxStr);
|
||||||
|
|
||||||
meterRows += "<fieldset><legend>Meter " + String(i) + "</legend>";
|
if (useTabs) meterRows += "<div class=tab-panel" + String(i == 0 ? " active" : "") + " data-tab=" + String(i) + ">";
|
||||||
|
meterRows += "<fieldset>";
|
||||||
|
if (!useTabs) meterRows += "<legend>Meter " + String(i) + "</legend>";
|
||||||
meterRows += "<div class=row><label>Pin</label><input name=m" + String(i) + "_pin type=number min=0 max=99 value=" + String(meters[i].pin) + "></div>";
|
meterRows += "<div class=row><label>Pin</label><input name=m" + String(i) + "_pin type=number min=0 max=99 value=" + String(meters[i].pin) + "></div>";
|
||||||
meterRows += "<div class=row><label>Name</label><input name=m" + String(i) + "_name value='" + nameVal + "'></div>";
|
meterRows += "<div class=row><label>Name</label><input name=m" + String(i) + "_name value='" + nameVal + "'></div>";
|
||||||
meterRows += "<div class=row><label>Unit</label><input name=m" + String(i) + "_unit value='" + unitVal + "'></div>";
|
meterRows += "<div class=row><label>Unit</label><input name=m" + String(i) + "_unit value='" + unitVal + "'></div>";
|
||||||
@@ -455,7 +466,9 @@ static void handleRoot() {
|
|||||||
meterRows += "<input name=m" + String(i) + "_cur type=range min=0 max=100 step=0.1 value=" + String(curStr) + ">";
|
meterRows += "<input name=m" + String(i) + "_cur type=range min=0 max=100 step=0.1 value=" + String(curStr) + ">";
|
||||||
meterRows += "<span class=val id=m" + String(i) + ">" + String(curStr) + "%</span>";
|
meterRows += "<span class=val id=m" + String(i) + ">" + String(curStr) + "%</span>";
|
||||||
meterRows += "</div></fieldset>";
|
meterRows += "</div></fieldset>";
|
||||||
|
if (useTabs) meterRows += "</div>";
|
||||||
}
|
}
|
||||||
|
if (useTabs) meterRows += "</div>";
|
||||||
|
|
||||||
String countOpts;
|
String countOpts;
|
||||||
for (int i = 1; i <= MAX_METERS; i++) {
|
for (int i = 1; i <= MAX_METERS; i++) {
|
||||||
@@ -537,6 +550,10 @@ html += ".tgl-lbl{margin-bottom:0!important;line-height:18px}.switch{position:re
|
|||||||
html += ".switch input{opacity:0;width:0;height:0}.slid{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:#ccc;border-radius:18px;transition:.3s}";
|
html += ".switch input{opacity:0;width:0;height:0}.slid{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:#ccc;border-radius:18px;transition:.3s}";
|
||||||
html += ".slid::before{content:\"\";position:absolute;height:14px;width:14px;left:2px;top:2px;background:#fff;border-radius:50%;transition:.3s;box-shadow:0 1px 3px rgba(0,0,0,.2)}";
|
html += ".slid::before{content:\"\";position:absolute;height:14px;width:14px;left:2px;top:2px;background:#fff;border-radius:50%;transition:.3s;box-shadow:0 1px 3px rgba(0,0,0,.2)}";
|
||||||
html += ".switch input:checked+.slid{background:#4361ee}.switch input:checked+.slid::before{transform:translateX(14px)}";
|
html += ".switch input:checked+.slid{background:#4361ee}.switch input:checked+.slid::before{transform:translateX(14px)}";
|
||||||
|
html += ".tab-nav{display:flex;gap:4px;margin-bottom:16px;flex-wrap:wrap}";
|
||||||
|
html += ".tab-btn{padding:8px 16px;border:1px solid #d1d5db;background:#f8f9fc;border-radius:8px 8px 0 0;cursor:pointer;font-size:13px;font-weight:600;color:#666;transition:all .2s;font-family:inherit}";
|
||||||
|
html += ".tab-btn:hover{background:#e8eaf0}.tab-btn.active{background:#fff;border-color:#4361ee;color:#4361ee;border-bottom-color:#fff}";
|
||||||
|
html += ".tab-panel{display:none}.tab-panel.active{display:block}";
|
||||||
html += "</style></head><body><div class=card>";
|
html += "</style></head><body><div class=card>";
|
||||||
html += "<div class=hdr><img src=/logo.png alt=logo><div><h1>M1730</h1><div class=sub>Configuration</div></div></div><div class=info>";
|
html += "<div class=hdr><img src=/logo.png alt=logo><div><h1>M1730</h1><div class=sub>Configuration</div></div></div><div class=info>";
|
||||||
html += "<div><span>Hostname</span><span>" + String(hostname) + "</span></div>";
|
html += "<div><span>Hostname</span><span>" + String(hostname) + "</span></div>";
|
||||||
@@ -561,6 +578,9 @@ html += ".switch input:checked+.slid{background:#4361ee}.switch input:checked+.s
|
|||||||
html += "x.open('GET','/set?i='+this.name.match(/\\d+/)[0]+'&v='+this.value,true);x.send();";
|
html += "x.open('GET','/set?i='+this.name.match(/\\d+/)[0]+'&v='+this.value,true);x.send();";
|
||||||
html += "});}});";
|
html += "});}});";
|
||||||
html += "document.querySelector('select[name=meter_count]').addEventListener('change',function(){this.form.submit();});";
|
html += "document.querySelector('select[name=meter_count]').addEventListener('change',function(){this.form.submit();});";
|
||||||
|
if (meterCount > 1) {
|
||||||
|
html += "document.querySelectorAll('.tab-btn').forEach(function(b){b.addEventListener('click',function(){var t=this.dataset.tab;document.querySelectorAll('.tab-btn').forEach(function(x){x.classList.remove('active')});document.querySelectorAll('.tab-panel').forEach(function(x){x.classList.remove('active')});this.classList.add('active');document.querySelector('.tab-panel[data-tab=\"'+t+'\"]').classList.add('active')})});";
|
||||||
|
}
|
||||||
html += "</script></body></html>";
|
html += "</script></body></html>";
|
||||||
server.send(200, "text/html", html);
|
server.send(200, "text/html", html);
|
||||||
Serial.printf("[HTTP] GET / -> 200 (%u bytes)\n", html.length());
|
Serial.printf("[HTTP] GET / -> 200 (%u bytes)\n", html.length());
|
||||||
|
|||||||
Reference in New Issue
Block a user