'use strict'; function pad(n) { return (n<10) ? '0' + n : n; } function getYMD(d) { return d.getUTCFullYear()+'-'+pad(d.getUTCMonth()+1)+'-'+pad(d.getUTCDate()); } function updateClock() { var now = new Date(); var s = getYMD(now)+' '+pad(now.getUTCHours())+':'+pad(now.getUTCMinutes())+' UTC'; $('#clock').html(s); var table = document.getElementById("TableHolder"); if (!table.isTonight) return; var rows = table.childNodes; for (var i=2; it0 ? "color:darkgreen" : "color:darkred"); } }; function addEmptyRow(prev, start) { var empty = { fStart: "0000/00/00 "+(start?start:""), fMeasurementTypeKey:0, fMeasurementID:0, fSourceKEY:0, }; addRow(empty, false, prev); } function debug(txt) { var dbg = document.getElementById("debug"); dbg.appendChild(document.createTextNode(txt)); dbg.appendChild(document.createElement("br")); } function addRow(row, disabled, prev) { var table = document.getElementById("TableHolder"); var sources = table.sources; var measurements = table.measurements; var tr = document.createElement("tr"); tr.setAttribute("width", "100%"); if (!prev) table.appendChild(tr); else table.insertBefore(tr, prev.nextSibling); // ---------- column 1 ---------- var input1t = document.createElement("input"); input1t.setAttribute("type","time"); input1t.setAttribute("size","10"); input1t.setAttribute("autofocus","true"); if (row.fMeasurementID!=0) input1t.setAttribute("hidden", "true"); input1t.setAttribute("value", row.fStart.substr(11)); if (disabled) input1t.setAttribute("disabled", "true"); /* input1t.onblur = function() { var prevRow = tr.previousSibling; while (prevRow && prevRow.firstChild.firstChild.hidden) prevRow = prevRow.previousSibling; var nextRow = tr.nextSibling; while (nextRow && nextRow.firstChild.firstChild.hidden) nextRow = nextRow.nextSibling; var prevEl = prevRow ? prevRow.firstChild : undefined; var nextEl = nextRow ? nextRow.firstChild : undefined; var prevTime = ""; if (prevEl && prevEl.firstChild.constructor.name=="HTMLInputElement") prevTime = prevEl.firstChild.value; var nextTime = ""; if (nextEl && nextEl.firstChild.constructor.name=="HTMLInputElement") nextTime = nextEl.firstChild.value; alert(prevTime+"/"+input1t.value+"/"+nextTime); }*/ var td1 = document.createElement("td"); td1.setAttribute("style","white-space:nowrap;padding-left:4px;padding-right:2px;"); td1.setAttribute("align","center"); td1.appendChild(input1t); // Check if this is the transition from disabled to enabled. // In this case enable all previous [+] if (tr.previousSibling && tr.previousSibling.firstChild.firstChild.disabled && !disabled) { var prevRow = tr.previousSibling; var tm = prevRow.firstChild.firstChild.value; while (1) { prevRow.firstChild.childNodes[1].removeAttribute("disabled"); prevRow = prevRow.previousSibling; if (prevRow.firstChild.firstChild.value!=tm) break; } } var input1p = document.createElement("input"); input1p.setAttribute("style","width:20px"); input1p.setAttribute("type","button"); input1p.setAttribute("value","+"); if (row.fMeasurementID!=0) input1p.setAttribute("hidden", "true"); // FIXME: Enable if this is the last "+" in tonight if (disabled && ! (table.isTonight && row.last)) input1p.setAttribute("disabled", "true"); input1p.onclick = function() { // FiXME: Do not allow deleting of last line var nextRow = tr; while (nextRow.nextSibling) { if (!nextRow.nextSibling.firstChild.firstChild.hidden) break; nextRow = nextRow.nextSibling; } addEmptyRow(nextRow, input1t.value); } td1.appendChild(input1p); var input1m = document.createElement("input"); input1m.setAttribute("style","width:20px"); input1m.setAttribute("type","button"); input1m.setAttribute("value","-"); if (row.fMeasurementID!=0) input1m.setAttribute("hidden", "true"); if (disabled) input1m.setAttribute("disabled", "true"); input1m.setAttribute("data-toggle", "tooltip"); if (row.fScheduleID) input1m.setAttribute("title", row.fScheduleID+" ["+row.fLastUpdate+"]"); input1m.onclick = function() { //if (table.childNodes.length==3) // return; var nextRow = tr.nextSibling; table.removeChild(tr); while (nextRow) { var inp = nextRow.firstChild.firstChild; if (!inp.hidden) break; var xx = nextRow; nextRow = nextRow.nextSibling; table.removeChild(xx); } if (table.childNodes.length==2) addEmptyRow(); } td1.appendChild(input1m); tr.appendChild(td1); // ---------- column 2 ----------- var select2 = document.createElement("select"); // select2.setAttribute("style", "width:100px"); select2.setAttribute("class", "measurement"); if (disabled) select2.setAttribute("disabled", "true"); for (var i=0; itable.loadTime) { save.removeAttribute("disabled"); load.removeAttribute("disabled"); ldate.removeAttribute("disabled"); // If this is a dayin the future, but no schedule is in the db, // create an empty one if (schedule.length==0) addEmptyRow(); } else { save.setAttribute("disabled", "true"); load.setAttribute("disabled", "true"); ldate.setAttribute("disabled", "true"); } // Update the header of the date/time column var tm = document.getElementById("time"); while (tm.firstChild) tm.removeChild(tm.firstChild); var nxt = new Date(day.getTime()+24*3600*1000); var d1 = pad(day.getUTCMonth()+1)+'-'+pad(day.getUTCDate()); var d2 = pad(nxt.getUTCMonth()+1)+'-'+pad(nxt.getUTCDate()); tm.appendChild(document.createTextNode(d1+ " / "+d2)); var offset = new Date(table.loadedDay).getTime(); // other day loaded and tonight if (!table.isTonight || !table.loadedDay) table.cutTime = "12:00:00"; // Now loop over all rows and add them one by one to the table for (var i=0; i2) { var cols = table.lastChild.childNodes; var time = cols[0].firstChild; if (time.disabled) { debug("disabled="+time.value); if (dateToLoad) { cut = time.value; break; } } count++; table.removeChild(table.lastChild); } debug(count+" lines removed "); document.getElementById("savedate").value = date; // it helps to know if this is tonight or not var now = new Date(); var day = new Date(date); var night = getYMD(new Date(now.getTime()-12*3600*1000)); table.isTonight = date==night; table.currentDay = date; table.loadedDay = dateToLoad; table.loadTime = now.getTime(); if (!table.isTonight || !table.loadedDay) table.cutTime = undefined; // remember the currently displayed day (FIXME: Move to table property?) table.prevDay = getYMD(new Date(day.getTime()-24*3600*1000)); table.nextDay = getYMD(new Date(day.getTime()+24*3600*1000)); debug("day="+date+"|"+date.length); debug("dayToLoad="+table.loadedDay); debug("cut="+cut); var data = "n="+(dateToLoad?dateToLoad:date); if (cut && (!table.isTonight || table.loadedDay)) data += "&t="+cut; debug("data="+data); // request data from the datanbase and on reception, display the data $.ajax({ type: "POST", cache: false, url: "load.php", data: data, success: onDataReceived, error: function(xhr) { if (xhr.status==0) alert("ERROR[0] - Request failed!"); else alert("ERROR[0] - "+xhr.statusText+" ["+xhr.status+"]"); } }); } function onReady() { if (location.href.search('debug')==-1) $("#debug").hide(); /*--------------------------------------------------------------------------------------------- Initialize jQuery datapicker (type='date' not supported by firefox) ----------------------------------------------------------------------------------------------*/ if ($('input').prop('type') != 'date' ) { var date_opt = { dateFormat: 'yy-mm-dd', showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true, autoSize: true, } $('[type="date"]').datepicker(date_opt); } /*--------------------------------------------------------------------------------------------- Initialize jQuery tooltips ----------------------------------------------------------------------------------------------*/ //$(document).ready(function(){$('[data-toggle="tooltip"]').tooltip();}); $('[data-toggle="tooltip"]').tooltip(); /*--------------------------------------------------------------------------------------------- Prevent any user interaction during AJAX requests ----------------------------------------------------------------------------------------------*/ $(document).ajaxStart(function() { $('#wait').fadeIn(); }).ajaxStop(function() { $('#wait').fadeOut(200); }); /*--------------------------------------------------------------------------------------------- Check if a dedicated day was requested, if not start with the current day. Load the data from the database and display the calendar and the data. ----------------------------------------------------------------------------------------------*/ var reg = /^\?day=(20[123][0-9]-[01][0-9]-[0123][0-9])/; var res = reg.exec(location.search); var day; if (!res) { var now = new Date(); if (now.getUTCHours()<12) now = new Date(now.getTime()-12*3600*1000); day = getYMD(now); } else day = res[1]; loadDay(day); /*--------------------------------------------------------------------------------------------- Start updating the clock ----------------------------------------------------------------------------------------------*/ updateClock(); setInterval(updateClock, 1000); /*--------------------------------------------------------------------------------------------- Loading of previous data. Get the previous date with existing data through PreviousData.php Same Shedule.ph passed to load on the controls with extra parameter 'prev' to indicate that data is from previous schedule. ----------------------------------------------------------------------------------------------*/ // FIXME: Do not overwrite the disabled part of the schedule if it is TONIGHT!!!! function onLoad() { var cd = document.getElementById("TableHolder"); var dt = document.getElementById("loaddate"); loadDay(cd.currentDay, dt.value); } $('#load').click(onLoad); $('#loaddate').keypress(function(event) { if (event.which==13) { onLoad(); } event.preventDefault(); }); /*--------------------------------------------------------------------------------------------- Savng and updating of schedule. Data array is generated from the current table to be submitted to saveSchedule.php for the execution of queries. ----------------------------------------------------------------------------------------------*/ function onSaveClick() { var table = document.getElementById("TableHolder"); var rows = table.childNodes; var schedule = []; // cutTime is the last time of a measurement which is past // and should not be updated. This assumes that all // time values are sequential. //var cutTime = "12:00:00"; //var prevTime = new Date(currentDay+" 12:00:00"); // FIXME: Make sure dates are sequentiel for (var i=2; i