90 lines
3.2 KiB
JavaScript
90 lines
3.2 KiB
JavaScript
// static/js/ui-channels.js – Kanal-Rendering & Listener
|
||
|
||
function renderChannels() {
|
||
console.log("renderChannels() START");
|
||
console.log("→ config.channels existiert?", !!config?.channels);
|
||
console.log("→ channels.length:", config?.channels?.length ?? "undefined");
|
||
|
||
const container = document.getElementById('channels-container');
|
||
if (!container) {
|
||
console.error("channelsContainer nicht gefunden!");
|
||
return;
|
||
}
|
||
|
||
container.innerHTML = '';
|
||
|
||
if (!config?.channels || config.channels.length === 0) {
|
||
container.innerHTML = '<p class="text-center text-muted py-5">Keine Kanäle definiert.</p>';
|
||
return;
|
||
}
|
||
|
||
config.channels.forEach(channel => {
|
||
const col = document.createElement('div');
|
||
col.className = 'col-md-6 mb-4';
|
||
|
||
let html = '';
|
||
|
||
if (channel.type === 'motor') {
|
||
html = `
|
||
<label class="form-label fw-bold">${channel.name} (${channel.port})</label>
|
||
<input type="range" class="form-range motor-slider" min="-100" max="100" value="0" step="5" data-port="${channel.port}">
|
||
<div class="d-flex justify-content-between mt-1 small">
|
||
<span>-100 %</span>
|
||
<span class="value-display fw-bold">0 %</span>
|
||
<span>+100 %</span>
|
||
</div>
|
||
<div class="text-center mt-2">
|
||
<button class="btn btn-sm btn-outline-danger stop-channel-btn" data-port="${channel.port}">
|
||
<i class="bi bi-stop-fill me-1"></i> Stop
|
||
</button>
|
||
</div>
|
||
`;
|
||
} else {
|
||
html = `
|
||
<label class="form-label fw-bold">${channel.name} (${channel.port})</label>
|
||
<button class="btn btn-outline-secondary w-100 toggle-btn" data-port="${channel.port}" data-state="off">
|
||
AUS
|
||
</button>
|
||
`;
|
||
}
|
||
|
||
col.innerHTML = `<div class="card h-100 shadow-sm"><div class="card-body">${html}</div></div>`;
|
||
container.appendChild(col);
|
||
});
|
||
|
||
// Listener hinzufügen (wie bisher)
|
||
document.querySelectorAll('.motor-slider').forEach(slider => {
|
||
const display = slider.parentElement.querySelector('.value-display');
|
||
slider.addEventListener('input', async () => {
|
||
const value = parseInt(slider.value) / 100;
|
||
if (display) display.textContent = `${slider.value} %`;
|
||
await sendControl(slider.dataset.port, value);
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.stop-channel-btn').forEach(btn => {
|
||
btn.addEventListener('click', async () => {
|
||
await sendControl(btn.dataset.port, 0);
|
||
const slider = document.querySelector(`input[data-port="${btn.dataset.port}"]`);
|
||
if (slider) {
|
||
slider.value = 0;
|
||
const display = slider.parentElement.querySelector('.value-display');
|
||
if (display) display.textContent = '0 %';
|
||
}
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.toggle-btn').forEach(btn => {
|
||
btn.addEventListener('click', async () => {
|
||
const state = btn.dataset.state === 'off' ? 'on' : 'off';
|
||
btn.dataset.state = state;
|
||
btn.textContent = state === 'on' ? 'EIN' : 'AUS';
|
||
btn.classList.toggle('btn-success', state === 'on');
|
||
btn.classList.toggle('btn-outline-secondary', state === 'off');
|
||
await sendControl(btn.dataset.port, state === 'on' ? 1 : 0);
|
||
});
|
||
});
|
||
}
|
||
|
||
// Am Ende von ui-channels.js
|
||
window.initChannels = renderChannels; |