/* * Copyright (C) 2026 Private Island Networks Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * file: ss.js * */ "use strict"; /* constructor spreadsheet */ function SpreadSheet(selector) { var ss = this; this.activeCell = null; this.panel = $(selector); this.panel.addEventListener('click', function(event){ if (event.target.classList.contains('mc-edit')) { ss.editCell.call(ss, event); } else if (event.target.classList.contains('mc-icon') || event.target.nodeName==="IMG") { ss.actions.call(ss, event); } else if (event.target.classList.contains('mc-sortable')) { data = ajaxData(); data.sort=event.target.innerHTML.toLowerCase(); ss.getNewTable(event,data); } }); this.getNewTable = function(event, data) { $.loading('block'); if (data == undefined) { data = ajaxData(); } $.get('/' + getPrefix(), data, function(resp) { resp = JSON.parse(resp); let values = resp.values; console.log(resp.values); cols=$$(".mc-values"); for (let i = 0; i < 16; i++) { cols[i].textContent = "0x" + values[i].toString(16); } $.loading('none'); }); } } SpreadSheet.prototype = { constructor: SpreadSheet, actions: spreadSheet_actions, editCell: spreadSheet_editCell, newRow: spreadSheet_newRow }; function spreadSheet(selector) { return new SpreadSheet(selector); } function spreadSheet_actions(event) { event.preventDefault(); // this fixed my href bug on 3/2/18! $.loading('block'); var ss = this; var link, icon, td, tr, id, action, txt, el, data, m; if (event.target.nodeName==="IMG") { icon = event.target; link = icon.parentNode; } else { link=event.target; } action=link.dataset.action; td=link.parentNode.parentNode; // link is wrapped in a div and then a td cell tr = td.parentElement; id = tr.dataset.id; txt = td.innerHTML; // modal actions if (action === 'edit' || action === 'cut' || action === 'notify' || action === 'modify') { $.get('/' + getPrefix() + '/' + action + '/' + id, null, function(resp) { var resp = getResponse(resp); $.loading('none'); if (action === 'edit') { m = modal('large'); } else { m = modal(); } if (resp.r === MC_CONSTANTS.REDIRECT) { window.location.assign(resp.d); } else if (resp.r === MC_CONSTANTS.NONE) { m.display(resp.d) $('button[value="submit"]', m.modalContainer) .addEventListener('click', submitForm); } else { processError(resp); } }) } // replace object actions else if (action === "recalc") { $.get('/' + getPrefix() + '/' + action + '/' + id, null, function(resp) { var resp = getResponse(resp); $.loading('none'); tr.innerHTML = resp.d; if (resp.n) { m = modal('large'); m.display(resp.n); } }); } function submitForm(e) { console.log('submit Form'); $.loading('block'); var form = $('form', m.modalContainer); // var nodes = form.childNodes; var data = new FormData(form); // nodes.forEach(addToFormData, data); $.post('/' + getPrefix() + '/' + action + '/' + id, data, function(resp) { resp = getResponse(resp); if (resp.r === MC_CONSTANTS.NONE) { m.hide(); ss.getNewTable(e); } else if (resp.r === MC_CONSTANTS.FORM) { form.innerHTML=resp.d; $('button[value="submit"]',m.modalContainer).addEventListener('click', submitForm ); } else { processError(resp); } $.loading('none'); }); } } /* set up a handler for a new SpreadSheet item / row */ function spreadSheet_newRow(selector) { var ss = this; var m = modal('large'); try{ $(selector).addEventListener('click',function(event) { $.get('/' + getPrefix() + '/new/', null, function(resp) { resp = getResponse(resp); if (resp.r === MC_CONSTANTS.NONE) { m.display(resp.d); $('button[value="submit"]', m.modalContainer).addEventListener('click', submitForm); } else { processError(resp); } }); }); } catch(event) { console.log('spreadSheet_newRow problem') } function submitForm(e) { $.loading('block'); var form = $('form', m.modalContainer); var nodes = form.childNodes; var data = new FormData(); nodes.forEach(addToFormData, data); $.post('/' + getPrefix() + '/new/', data, function(resp) { resp = getResponse(resp); if (resp.r === MC_CONSTANTS.NONE) { m.hide(); ss.getNewTable(e); } else if (resp.r === MC_CONSTANTS.FORM) { form.innerHTML=resp.d; $('button[value="submit"]',m.modalContainer).addEventListener('click', submitForm ); } else { processError(resp); } $.loading('none'); }); } } function spreadSheet_editCell(event) { console.log('editCell'); var td=event.target; var tr = td.parentElement; var id = tr.dataset.id; var type=td.dataset.type; var field=td.dataset.field; var txt = td.innerHTML; var el, data; if (type==="text") { td.innerHTML=""; el = document.createElement("input"); el.addEventListener('keypress', keyHandler); $('body').addEventListener('click',clickHandler); // append the input el.className="mc-ss-input" el.value=txt; td.appendChild(el); el.focus(); } /* TODO: do I need to be worried that the handler won't be set in time? */ else if (type==="date") { var cal = calendar('.mc-cal'); cal.container.addEventListener("evtCalClose", calCloseHandler); cal.open(td); } /* calendar has been closed */ function calCloseHandler(event) { console.log('calCloseHandler'); cal.container.removeEventListener('evtCalClose',calCloseHandler); if (event.detail.cancel) { return; } $.loading('block'); data = { id: id, field: "date", value: cal.getSelectedDate().toISOString(), }; $.post('/' + getPrefix() + '/modify', data, function(resp) { resp = getResponse(resp); if(resp.r == MC_CONSTANTS.NONE) { td.innerHTML=resp.d; } else { processError(resp); } $.loading('none'); }); } function keyHandler(event) { console.log(keyHandler); var el = event.target; var key = event.keyCode; var txt = el.value; if (key==27) { event.preventDefault(); el.remove(); td.innerHTML=txt; } else if (key==13) { event.preventDefault(); var data = { id: id, field: field, value: txt, }; el.remove(); td.innerHTML=txt; $.post('/' + getPrefix() + '/modify', data, function(response) { console.log("upload text suceeded"); }); } } function clickHandler(event) { console.log('clickHandler'); if(event.target.nodeName==="TD") { return; // don't cancel out of a cell we just clicked } $('body').removeEventListener('click',clickHandler); var children = td.childNodes; children.forEach(function(val) { val.remove(); }) td.innerHTML=txt; } }