in-c4/static/form.js
2024-04-30 16:27:00 +02:00

181 lines
4.9 KiB
JavaScript

let items = {};
const id = new URLSearchParams(window.location.search).get('id');
document.onreadystatechange = function() {
if (document.readyState === 'interactive') {
fetchItems(fillForm);
}
}
function fetchItems(cb) {
fetch('/api/items').then(r => r.json()).then((data) => {
items = data;
cb();
});
}
function fillForm() {
const item = items[id];
knownTypes();
const is_in = document.getElementById('is_in');
for (const [_, item] of Object.entries(items)) {
const option = document.createElement('option');
option.value = item.id;
option.textContent = `${item.id} ${item.name && `(${item.name})` || ''}`
is_in.appendChild(option);
};
document.getElementById('id').placeholder = '';
if (id && item) {
document.getElementById('id').value = item.id;
document.getElementById('is_in').value = item.is_in;
document.getElementById('coords_bl').value = item.coords_bl;
document.getElementById('coords_tr').value = item.coords_tr;
document.getElementById('type').value = item.type;
document.getElementById('name').value = item.name;
document.getElementById('content').value = item.content;
document.getElementById('note').value = item.note;
document.getElementById('hidden').checked = item.hidden;
document.getElementById('last_updated').value = formatTimestamp(item.last_updated);
formCoordsToMap();
}
const saveBtn = document.getElementById('save');
const delBtn = document.getElementById('delete');
saveBtn.onclick = function(e) {
e.preventDefault();
save();
};
delBtn.onclick = function(e) {
e.preventDefault();
del();
}
}
function knownTypes() {
let map = {};
for (const i of Object.values(items)) {
if (i.type) {
map[i.type] = true;
}
}
let types = Object.keys(map).sort().join(', ')
document.getElementById('knowntypes').textContent = `Known types: ${types}.`;
}
function save() {
const item = {
id: document.getElementById('id').value || '',
is_in: document.getElementById('is_in').value || null,
coords_bl: document.getElementById('coords_bl').value || null,
coords_tr: document.getElementById('coords_tr').value || null,
type: document.getElementById('type').value || null,
name: document.getElementById('name').value || null,
content: document.getElementById('content').value || null,
note: document.getElementById('note').value || null,
hidden: document.getElementById('hidden').checked,
}
fetchItems(() => {
if (item.id.includes('?')) {
let n = 1;
while (true) {
const candidate = item.id.replace('?', n++);
if (!Object.keys(items).includes(candidate)) {
item.id = candidate;
break;
}
}
}
if (items[item.id]) {
if (!id || (id && id != item.id)) {
alert(`ID ${item.id} exists. Please chose a different ID or edit the existing ${item.id} item!`);
return;
}
}
const original_id = id || item.id;
fetch(`/api/items/${original_id}`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(item),
})
.then(r => {
if (r.ok) {
window.location.href = '../';
} else {
r.text().then(t => alert(`Error:\n${t}`));
}
}).catch(error => {
alert(`Error:\n${error}`);
});
});
}
function del() {
if (id && confirm('Are you sure?')) {
fetch(`/api/items/${id}`, {method: 'DELETE'}).then(r => {
if (r.ok) {
window.location.href = '../';
} else {
r.text().then(t => alert(`Error:\n${t}`));
}
}).catch(error => {
alert(`Error:\n${error}`);
});
}
}
let clicks = {x: [], y: []};
function mapClick(e) {
let x = Math.floor(36 / e.target.width * e.layerX);
let y = Math.floor(18 / e.target.height * e.layerY);
let humanPos = (x, y) => {
return `${String.fromCharCode(65 + 16 - y)}${x}`;
};
if (x > 0 && x < 36 && y > 0 && y < 18) {
if (clicks.x.length > 1) {
clicks.x = [x];
clicks.y = [y];
} else {
clicks.x.push(x);
clicks.y.push(y);
}
if (clicks.x.length > 1) {
clicks.x.sort((a,b) => a-b);
clicks.y.sort((a,b) => a-b);
renderMap(clicks.x, clicks.y);
let coords_bl = humanPos(clicks.x[0], clicks.y[1]);
let coords_tr = humanPos(clicks.x[1], clicks.y[0]);
document.getElementById('coords_bl').value = coords_bl;
document.getElementById('coords_tr').value = coords_tr;
}
}
}
function formCoordsToMap() {
const coords_bl = document.getElementById('coords_bl').value || '';
const coords_tr = document.getElementById('coords_tr').value || '';
if (coords_bl.length > 1 && coords_tr.length > 1) {
coordsToMap(coords_bl, coords_tr);
}
}
function formatTimestamp(ts) {
const date = new Date(ts * 1000);
// using Swedish format as a hack to get an iso formatted date
return date.toLocaleDateString("sv", {timeZone: "UTC"}).replace(/\-\d+$/,'')
}