<% /* File: shared/resultset_table_v2.inc $Revision$ $Id$ */ %> <% FCLTHeader.Requires({ plugins: ["jQuery"], js: ["resultset_table_v2.js", "sorttable.js"] }); var APIname = getQParam("API",""); var useHamburger = S("inline_actions_hamburger"); if (getQParam("touch","") == 1 || device.test(device.isTouch)) useHamburger = 1; // Hamburger onClick var hasInlineActions = false; var book_id = null; if (APIname == "REPORT") { var API = new API_func(); book_id = getQParam("BOOKMARK"); var sql = "SELECT fac_bookmark_path, " + " fac_bookmark_query" + " FROM fac_bookmark" + " WHERE fac_bookmark_id = " + safe.quoted_sql(book_id); var oRs = Oracle.Execute(sql); if (oRs.EOF) { Response.Write("Bookmark niet gevonden"); Response.End; } var path = oRs("fac_bookmark_path").Value; var query = oRs("fac_bookmark_query").Value; oRs.Close(); if (rooturl + path != Request.ServerVariables("SCRIPT_NAME")) { shared.internal_error("Invalid bookmark path"); } // // getQParam/getFParam onderscheppen en 'voeden' uit FAC_BOOKMARK_URL // // Simuleer een Request.Querystring compatible collection function bmcoll(key) { var nn = 1; var coll = Server.CreateObject("Scripting.Dictionary"); var params = query.split("&"); for (var i in params) { var xx = params[i].split("="); if (xx[0].toUpperCase() == key.toUpperCase() && xx.length > 1) { coll.Add(nn++, unescape(String(xx[1]).replace(/\+/g, " "))); // spaties gaan niet vanzelf } } return coll; } getQParam = function (pName, defVal) { return _get_Param(bmcoll, pName, defVal) } getQParamInt = function (pName, defVal) { return _get_ParamInt(bmcoll, pName, defVal) } getQParamDate = function (pName, defVal) { return _get_ParamDate(bmcoll, pName, defVal) } } var p_autosortby = getQParam('autosortby', "") || getFParam('autosortby', ""); var autosortbyrev = false; if (p_autosortby.substr(0,1) == '-') { var autosortbyrev = true; p_autosortby = p_autosortby.substr(1); } //
printform is nodig bij printen reserveringen i.v.m. POST formulier // maar mag niet binnen een ander voorkomen en moet eigenlijk wel binnen body staan // Formulier als tekstring samenstellen en m.b.v. $(function(){}) binnen de body zetten (resultset_table_v2.js) var postformHTML = ''; if (Request.ServerVariables("REQUEST_METHOD") == "POST") { var postformHTML = '
' + '' + '' // input outputmode wordt gezet in doOutput() + '' // input autosortby wordt gezet in doOutput() + ''; var items = new Enumerator(Request.Form()); while (!items.atEnd()) { var itemName = items.item(); for (var i = 1; i <= Request.Form(itemName).count; i++) { // De input velden outputmode en showall zijn standaard al gedefinieerd. Niet dubbel definiëren // Een eventuele submit ook niet doorgeven tijdens afdruk. if (itemName != "outputmode" && itemName != "showall" && itemName != "do_submit") postformHTML += ''; } items.moveNext(); } postformHTML += '' + '
'; } var isPlain = false; var isPrinting = false; var isExcel = false; var isCSV = false; var isCSV2XLSX = false; var isZIP = false; var isGraph = false; function ResultsetTable(params) { this.beforeEachRow = null; this.rowClass = null; this.rowData = null; this.newHeader = null; this.emptySetString = L("lcl_empty_rstable"); this.sql = null; this.sqltotals = null; this.dataset = null; this.filter = ""; this.filterParams = null; this.ID = null; this.flexModule = null; this.flexId = null; this.flexGroupId = null; this.flexParentGroupId = null; this.flexChangeNiveau = null; this.flexParams = null; this.rowNum = 0; this.keyColumn = null; this.dblClick = null; this.disableInlineActions = null; this.rowActionEnabler = null; this.multiActionEnabler = null; this.inlineDetails = null; this.hasInlineDetails = null; this.inlineDetailsChanged = null; this.summaryCalc = null; this.summaryShow = null; this.totalColumnText = null; this.totalCalc = null; this.totalShow = null; this.summaryId = null; this.noPrint = null; /* if true: suppress print/excel icons */ this.noExcel = null; /* if true: suppress excel icon */ this.outputmode = null; // print naar: 0 = screen, 1 = printer met flex, 2 = excel met flex, 3 = XML/XSL, 4 = CSV, // 5 = printer zonder flex, 6 = excel zonder flex., 7 = zipfile met bijlagen this.endText = null; this.showAll = null; this.showProperties = null; this.propertiesColumn = null; // alleen nog maar in gebruik voor FIN flexkenmerken detailregels this.addurl = null; this.suppressKeyRepeat = null; this.inline = null; this.lastColKey = -1; // voor suppress (columns) this.urllink = null; this.subtabicon = null; this.rstCheckboxes = null; // multiple resultsets this.rstableCount = 1; this.rstableNr = 1; this.buildHistogram = false; // over *alle* kolommen van de sql! Originele waarden! this.Counter = {}; this.noSetSummary = false; var param; // Neem alle meegegeven parameters mee. for (param in params) this[param] = params[param]; isPlain = ((this.outputmode || 0) == 0); isPrinting = (this.outputmode == 1 || this.outputmode == 5); isExcel = ((this.outputmode == 2 || this.outputmode == 6) && S("excel_mode")==0); isNativeExcel = ((this.outputmode == 2 || this.outputmode == 6 || this.outputmode == 8) && S("excel_mode")==2); isXMLXSL = (this.outputmode == 3); isCSV = ((this.outputmode == 4) || (((this.outputmode == 2 || this.outputmode == 6) && S("excel_mode")==1))); //isCSV2XLSX = (this.outputmode == 8) isZIP = (this.outputmode == 7); isGraph = getQParam("asgraph", 0) == 1; this.printFlex = (this.outputmode == 1 || this.outputmode == 2 || this.showProperties) && this.flexModule != null && this.flexId != null; this.tableClassName = "rstable" + ("nofloating" in params && params.nofloating ? " no-floating" : "") + (!isExcel ? " sortable" : ""); if (isPrinting || isExcel) { this.inlineDetails = null; this.hasInlineDetails = null; this.inlineDetailsChanged = null; } this.columns = new Array(); this.actions = new Array(); this.lastVal = new Array(); // voor suppress (columns) if (this.inline || isExcel) { this.noPrint = true; // Geen printer fuctionaliteit this.noSetSummary = true; // Geen summary zetten in de titelbalk this.noLoading = true; // Geen loading } } ResultsetTable.prototype.processResultset = __rsProcessResultset; ResultsetTable.prototype.startTable = __rsStartTable; ResultsetTable.prototype.makeTableHeader = __rsMakeTableHeader; ResultsetTable.prototype.makeTableRow = __rsMakeTableRow; ResultsetTable.prototype.makeTableFootnote = __rsMakeTableFootnote; ResultsetTable.prototype.endTable = __rsEndTable; ResultsetTable.prototype.addColumn = __rsAddColumn; ResultsetTable.prototype.startPrint = __rsStartPrint; ResultsetTable.prototype.endPrint = __rsEndPrint; ResultsetTable.prototype.addAction = __rsAddAction; ResultsetTable.prototype.rowFilter = function (oRs) { return true }; function __rsAddAction(params) { /* Nu ook inline actions bij PDA (hamburger) if (device.test(device.isTouch) && !params.isDefault) { params.single = false; // touch heeft geen mouseover. Dan alleen de default onclick } */ this.actions.push(params); }; // JGL: O.a. UWVA smoelenboek ResultsetTable.prototype.ProcessAsXMLXSL = function() { var xmlDoc = new ActiveXObject("MSXML2.DOMDocument.6.0"); xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"windows-1252\"")) // MGE: De encoding komt niet in de xml te staan, maar alleen de version: < ?xml version="1.0"? >. MSXML print nooit de encoding. // Kan dit problemen geven? var FCLTElement = xmlDoc.createElement("facilitor"); var FCLTHeader = xmlDoc.createElement("header"); var param; var info = { //ID: this.ID, file: String(Request.ServerVariables("SCRIPT_NAME")).toLowerCase(), dateTime: toDateTimeString(new Date(), true), dateDay: (new Date).getDate(), dateMonth: (new Date).getMonth()+1, dateYear: (new Date).getFullYear(), user: customerId, rapportmode: getQParam("rapportmode", null), // internal abuse only custId: customerId, language: user.lang() // .... } for (param in info) { if (info[param] != null) { var FCLTdata = xmlDoc.createElement(param); FCLTdata.appendChild(xmlDoc.createTextNode(info[param])); FCLTHeader.appendChild(FCLTdata); } } FCLTElement.appendChild(FCLTHeader); var rootElement = xmlDoc.createElement("resultset"); rootElement.setAttribute("id", this.ID); with(this) { var oRs = Oracle.Execute(sql); var theSqlFlex = ""; if (this.printFlex) theSqlFlex = getSqlFlex(flexModule.toUpperCase(), flexId, this.myRs(flexParams, oRs)); for (var cnt = 0; !oRs.EOF; cnt++) { // Vooralsnog geen flex var elementRecord = xmlDoc.createElement("data_row"); for (var i = 0; i < columns.length; i++) { var fieldname; if (columns[i].orgContent instanceof Function) { fieldname = columns[i].orgContent.toString().match(/function\s*(\w*)/)[1]; if (!fieldname) fieldname = columns[i].xmltag; // Bij anonieme contentfunctie moet je xmltag toevoegen if (!fieldname) INTERNAL_ERROR_MISSING_XMLTAG; } else { fieldname = columns[i].orgContent; } var elementField = xmlDoc.createElement(fieldname.toLowerCase() /*"field"*/); try { var val = (columns[i].content != null ? columns[i].content(oRs, outputmode) : ""); } catch (e) { __Log("resultset_table_v2.inc: Probleem met het ophalen van columns[" + i + "]: " + columns[i].caption); throw(e); } var elementFieldText = xmlDoc.createTextNode(val); elementField.appendChild(elementFieldText); elementRecord.appendChild(elementField); } if (this.printFlex) { var flexKey = (!oRs.Fields(flexId).Value ? oRs.Fields("id").Value : oRs.Fields(flexId).Value); // primary key van tabel uit recordset of id uit dataset van api2-model completeSqlFlex = "SELECT * FROM (" + theSqlFlex + ")" + " WHERE flexparentkey = " + flexKey // De flexKey invullen in de sqlFlex query + " ORDER BY volgnummer, omschrijving"; var oRsFlex = Oracle.Execute(completeSqlFlex); while (!oRsFlex.EOF) { if (oRsFlex("waarde").Value) { var elementField = xmlDoc.createElement("kenmerk"); //completeSqlFlex bevat (helaas nog) geen "kenmerk_key" var info = ["omschrijving", "kenmerktype", "nmin", "nmax", "volgnummer", "dimensie", "decimalen"]; for (var param in info) { if (oRsFlex(info[param]).Value) elementField.setAttribute(info[param], oRsFlex(info[param]).Value); } var elementFieldText = xmlDoc.createTextNode(flexValue(oRsFlex)); elementField.appendChild(elementFieldText); elementRecord.appendChild(elementField); } oRsFlex.MoveNext(); } oRsFlex.Close(); } rootElement.appendChild(elementRecord); oRs.MoveNext(); } oRs.close(); FCLTElement.appendChild(rootElement); xmlDoc.appendChild(FCLTElement); Response.ContentType = "text/xml"; Response.Clear(); if (__Logging & 1) { var in_file = shared.tempFolder() + "/"; in_file = in_file + customerId + this.ID + ".xml"; var fs = Server.CreateObject("Scripting.FileSystemObject"); var ts = fs.CreateTextFile(in_file, true); ts.WriteLine (xmlDoc.xml); ts.Close(); } Response.ContentType = "text/html"; var xslfile = Server.MapPath(getCustXsl()); // FSN#39809 var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0"); var xsldoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0"); var xslproc; xsldoc.async = false; xsldoc.setProperty("AllowXsltScript", true); xsldoc.load(xslfile); xsldoc.resolveExternals = true; // XSL kan includes hebben xsldoc.validateOnParse = true; // en moet correct zijn xslt.stylesheet = xsldoc; xslproc = xslt.createProcessor(); xslproc.input = xmlDoc; //xslproc.addParameter("mode", mode); //xslproc.addParameter("srtnotificatiecode", srtnotificatie); xslproc.output = Response; xslproc.transform(); Response.End; } } ResultsetTable.prototype.ProcessAsCSV = function _ProcessAsCSV() { var oRs; if (this.pRs) oRs = this.pRs; else if (this.dataset) oRs = new data_recordset( this.dataset ); else oRs = Oracle.Execute(this.sql); // Header row var safeheader = []; for (var i = 0; i < this.columns.length; i++) safeheader.push(this.columns[i].caption); if (isCSV2XLSX) // dan maken een CSV bestand in de TEMP folder en leveren een JSON op { var fso = new ActiveXObject("Scripting.FileSystemObject") var tmpcsv = "CSV_" + shared.random(16) +".csv" var uitvoerstream = fso.CreateTextFile(shared.tempFolder() + "/" + tmpcsv, true); Session.LCID = 1033; // English(United States) omdat csv2xlsx_386.exe dat verwacht voor floating points } else { var uitvoerstream = Response; } Response.Clear(); // ook voor csv uitvoerstream.Write(safeheader.join(";") + "\r\n"); while (!oRs.EOF) { var saferow = []; for (var i = 0; i < this.columns.length; i++) { try { var val = this.columns[i].content(oRs, this.outputmode); } catch (e) { __Log("resultset_table_v2.inc: Probleem met het ophalen van columns[" + i + "]: " + this.columns[i].caption); throw(e); } saferow.push(safe.csv(val)); } uitvoerstream.Write(saferow.join(";") + "\r\n"); oRs.MoveNext(); } oRs.close(); if (isCSV2XLSX) { uitvoerstream.Close(); Response.ContentType = "application/json"; var result = { "tmpcsv" : tmpcsv, "columns" : this.columns, "colspec" : [] // voor csv2xlsx }; for (var i = 0; i < this.columns.length; i++) { // Type is one of: text|number|integer|currency|date|standard|percent|formula|format var csvtype = "standard"; switch (this.columns[i].datatype) { // let op: format truc werkt alleen voor numbers (waar parseFloat op toegepast kan worden) case "date" : csvtype = "date"; break; // kan dit beter? format:"d-m-jjjj" of zo? case "datetime": csvtype = "date"; break; // kan dit beter? format:"d-m-jjjj uu:mm" of zo? case "time" : csvtype = "standard"; break; // kan dit beter? format:"uu:mm" of zo? case "currency": csvtype = "format:###0.00"; break; case "float" : csvtype = "number"; break; case "number" : csvtype = "integer"; break; case "html" : return val; } result.colspec.push(String(i) + ":" + csvtype); } Response.Write(JSON.stringify(result)); } else { Response.ContentType = "text/csv"; } ASPPAGE_END(); Response.End; } ResultsetTable.prototype.excelTableHeader = function _excelTableHeader(oWs, row, oRs, oRsFlexData) { var maxlengths = []; for (var i = 0; i < this.columns.length; i++) { var caption = this.columns[i].caption; caption = caption.replace(/(<([^>]+)>)/ig,""); // strip html caption = caption.replace(/\ \;/ig, " ");//   naar spatie var len = oWs.write_string(row, i, caption, 1); // 1 = bold maxlengths.push(len); oWs.set_column_width(i, 8.43 /* LXW_DEF_COL_WIDTH */, 1); // Forceer alvast 'wrap' omdat met constant memory het niet achteraf kan } if (this.printFlex) { for (var i_f=0; i_f < oRsFlexData.length; i_f++) { var caption = oRsFlexData[i_f].header; var len = oWs.write_string(row, i + i_f, caption, 1); // 1 = bold maxlengths.push(len); } } return maxlengths; } ResultsetTable.prototype.ProcessAsNativeExcel = function _ProcessAsNativeExcel(formail) { Response.Clear(); // voor de zekerheid var oRs; if (this.pRs) oRs = this.pRs; else if (this.dataset) oRs = new data_recordset( this.dataset ); else oRs = Oracle.Execute(this.sql); var oExcel = new ActiveXObject("SLNKXLSX.Excel"); var tmpxlsx = "XLSX_" + shared.random(16) +".xlsx" var oWb = oExcel.workbook_new(shared.tempFolder() + "/" + tmpxlsx, 1); // 1==constant memory oWb.set_property("author", user.naam()); oWb.set_property("title", this.title); oWb.set_property("comments", "Created with Facilitor v{0}".format(FCLTVersion)); var oWs = oWb.add_worksheet("Sheet1"); var printedFirstHeader = false; // Is de eerste header afgedrukt?. Bij isExcel en isPrinting worden namelijk meerdere headers afgedrukt var printMoreHeaders = false; // Wordt gebruikt bij isExcel en isPrinting om meerdere headers af te drukken, maar dan moet de flexModule en flexId wel gedefineerd zijn // Alleen headers weergeven bij printen naar printer of excel // en indien de flexkenmerkquery, flexid en flexgroupid is meegegeven if (this.printFlex && this.flexGroupId) printMoreHeaders = true; var lastFlexGroupKey = -1; // Wordt gebruikt bij isExcel. Start without a previous flex group, the first one is new. var lastFlexParentGroupKey = -1 // Wordt gebruikt bij isExcel. Start without a previous flex group, the first one is new. var flexGroupChanged = false; var theSqlFlex = ""; if (this.printFlex) theSqlFlex = getSqlFlex(this.flexModule.toUpperCase(), this.flexId, (this.flexParams instanceof Function ? this.flexParams(oRs) : this.flexParams)); var lastHadFlex = false; oWs.freeze_panes(1, 0); // 1e Header row respecteren we maxlength's ook van. var maxlengths = []; // Ik wil altijd de originele waardes hebben. Binnen Excel is toch alles 'safe' safe.html = safe.htmlattr = function (waarde, params) { return waarde || ""; } safe.curr = function (waarde, params) { return waarde; } var rownum = 0; while (!oRs.EOF) { if (!this.rowFilter(oRs)) // Vanuit MJOB en fin { oRs.MoveNext(); continue; } var oRsFlex = null; if (this.printFlex) { var flexKey = (!oRs.Fields(this.flexId).Value ? oRs.Fields("id").Value : oRs.Fields(this.flexId).Value); // primary key van tabel uit recordset of id uit dataset van api2-model var oRsFlexData = getFlexData(theSqlFlex, flexKey, { showProperties: this.showProperties }); // is een JSON if (!oRsFlexData.length) var noFlexResult = true; // Er zijn geen flexkenmerken else var noFlexResult = false; // Er zijn flexkenmerken if (this.flexGroupId) // Is er een flexGroupId meegegeven { var flexGroupKey = this.myRs(this.flexGroupId, oRs); flexGroupChanged = (lastFlexGroupKey != flexGroupKey); // Alleen bij printen naar excel moet er wellicht een nieuwe header boven i.v.m. andere flexkenmerken var flexChanged = flexGroupChanged; lastFlexGroupKey = flexGroupKey; if (this.flexParentGroupId) // Is er een flexParentGroupId meegegeven { var flexParentGroupKey = this.myRs(this.flexParentGroupId, oRs); flexParentGroupChanged = (lastFlexParentGroupKey != flexParentGroupKey); // Alleen bij printen naar excel moet er wellicht een nieuwe header boven i.v.m. andere flexkenmerken if (!flexParentGroupChanged && flexGroupChanged && this.flexChangeNiveau && !noFlexResult && !flexChanged) { // Flexgroep is veranderd maar parentflexgroep niet. Alleen als er op flexgroep niveau flexkenmerken zijn gedefinieerd is er een nieuwe header nodig. flexChanged = false; for (var datai=0; i < oRsFlexData.length; i++) { var rec = oRsFlexData[datai]; var kenmerk_niveau = rec.niveau; if (kenmerk_niveau == this.flexChangeNiveau) { flexChanged = true; break; } } } flexChanged = flexParentGroupChanged || flexChanged; // Als parent group veranderd is zijn er waarchijnlijk ook andere kenmerken. Kan voor meldingen nog scherper i.v.m. nog een niveau (parent) hoger. Maar is in praktijk nog niet echt nodig. lastFlexParentGroupKey = flexParentGroupKey; } } } if (!printedFirstHeader || (printMoreHeaders && flexChanged && (!noFlexResult || (lastHadFlex && noFlexResult)))) { // Header van ResultsetTable var ml = this.excelTableHeader(oWs, rownum++, oRs, oRsFlexData); if (rownum == 1) maxlengths = ml; printedFirstHeader = true; } lastHadFlex = !noFlexResult; var saferow = []; for (var i = 0; i < this.columns.length; i++) { try { if (this.columns[i].orgContent instanceof Function) { var val = this.columns[i].orgContent(oRs, this.outputmode) } else { var val = oRs.Fields(this.columns[i].orgContent).Value; } } catch (e) { __Log("resultset_table_v2.inc: Probleem met het ophalen van columns[" + i + "]: " + this.columns[i].caption); throw(e); } // Zie ook api2_rest.inc function _json2xlsx if (val != null && typeof val != "undefined") { if (typeof val == "object" && "name" in val) { val = val["name"]; this.columns[i].datatype = null; // default string } if (typeof val == "string" && (this.columns[i].orgContent instanceof Function || this.columns[i].datatype == 'html')) { val = val.replace(/(<([^>]+)>)/ig,""); // strip html val = val.replace(/\ \;/ig, " ");//   naar spatie; val = val.replace(/\&\;/ig, "&");// er zijn er nog meer maar dit vind ik genoeg val = val.replace(/\<\;/ig, "<"); val = val.replace(/\>\;/ig, ">"); val = val.replace(/\&apos\;/ig, "'>'"); val = val.replace(/\"\;/ig, "\""); // TODO: andere html-entities ook vertalen? } var len = 0; if (typeof val == "string" && inArray(this.columns[i].datatype, ["date", "datetime", "time", "currency", "float", "number"])) { if (!(this.columns[i].orgContent instanceof Function)) __Log("Vreemd: kolom {0} is string en niet van het type {1}?".format(this.columns[i].caption, this.columns[i].datatype), "#ff0000"); len = oWs.write_string(rownum, i, val); } else switch (this.columns[i].datatype) { case "date" : oWs.write_vardate(rownum, i, new Date(val).getVarDate(), 0); //TODO .midnight() toepassen eindigt in verkeerde tijdzone? break; case "datetime": oWs.write_vardate(rownum, i, new Date(val).getVarDate(), 1); break; case "time" : oWs.write_vardate(rownum, i, new Date(val).getVarDate(), 2); break; case "currency": oWs.write_number(rownum, i, val, 1); break; case "float" : oWs.write_number(rownum, i, val, 1); break; case "number": oWs.write_number(rownum, i, val, 0); break; case "processingtime": if (val["duration"] != null) val = val["duration"] + " " + (val["unit"]=='U'?L("lcl_mld_hours"):L("lcl_mld_days")); else val = ""; len = oWs.write_string(rownum, i, val); break; case "html" : // hij is hierboven al decoded len = oWs.write_string(rownum, i, val); break; default: // Autotypering "datum" if (typeof val == "date" || val instanceof Date) { oWs.write_vardate(rownum, i, new Date(val).getVarDate(), 0); // params.prettydate toepassen? } else { len = oWs.write_string(rownum, i, String(val)); } } if (len > maxlengths[i]) maxlengths[i] = len; } } if (this.printFlex) { // equivalent van html += addFlexKenmerkKolommen(oRsFlexData, this, for (var i_f=0; i_f< oRsFlexData.length; i_f++) { var rec = oRsFlexData[i_f]; var val = rec.value; // altijd string! if (val == null || val === "") // Leeg flexkenmerk is vreemd? continue; // Type 'C','N','D','T','R','X','L','Q','F','M','E','S','l','B','V' // Sommige kunnen we slimmer // Q/L en negatieve volgnummers heeft function getFlexData er al uit gestript switch(rec.type) { case "E": // Encrypted case "F": // Komen nog niet voor/gaan niet goed met kenmerk_niveau vanwege RWSN#78535 var flex_bijlagen = flexProps(this.flexModule, rec.key, rec.kenmerk_key, rec.kenmerk_niveau); if (flex_bijlagen.files.length) oWs.write_string(rownum, i + i_f, flex_bijlagen.files[0].name); break; case "N": // numeriek var fval = parseFloat(val); if (isNaN(fval)) // geeft ongeldige xlsx { __DoLog("NaN, waarde is geen float: " + fval); } if (rec.decimalen) oWs.write_number(rownum, i + i_f, fval, 1); // Altijd 2 decimalen else oWs.write_number(rownum, i + i_f, fval, 0); // geen decimalen break; case "D": // datum var a = /^(\d{2})-(\d{2})-(\d{4})$/.exec(val); // 27-02-2024 if (a) { var dtval = new Date(+a[3], +a[2] - 1, +a[1]); oWs.write_vardate(rownum, i + i_f, dtval.getVarDate(), 0); } break; case "T": // tijd var a = /^(\d{2}):(\d{2})$/.exec(val); // 13:35 if (a) { var dtval = new Date(1970, 0, 1, +a[1], +a[2]); oWs.write_vardate(rownum, i + i_f, dtval.getVarDate(), 2); } break; case "C": // Character case "R": // Referentie case "S": // Suggest case "X": // Bestandsnaam case "V": // checkbox doorvallen naar default? default: oWs.write_string(rownum, i + i_f, String(val)); // Expliciete String } } } rownum++; oRs.MoveNext(); } oRs.close(); for (var i = 0; i < maxlengths.length; i++) { if (maxlengths[i] > 8.43 * 10) // LXW_DEF_COL_WIDTH, 8.43 is de default Excel cell width { oWs.set_column_width(i, 1 + Math.min(maxlengths[i] / 10, 50), 1); // als je (net) te krap instelt wordt de lineheight soms hoger // omdat Excel toch bang is dat er iets wrapt? } } oWb.workbook_close(); if (formail) // Putorders pakt de temp-file verder op { Response.ContentType = "application/json"; var result = { "tmpxlsx" : tmpxlsx, deletefile: __Logging == 0 }; Response.Write(JSON.stringify(result)); } else { var mime = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" var filename = (this.filename ? this.filename : "Facilitor") + " {0}.xlsx".format(toISODateTimeString(new Date())); var pcontentdp = "attachment"; Response.AddHeader("content-disposition", pcontentdp + "; filename= \"" + safe.ContentName(filename) + "\"") StreamFile(shared.tempFolder(), tmpxlsx, { mime: mime , pcontentdp: "none", // geen pcontentdp, dat hebben we zelf gedaan deletefile: __Logging == 0}); } ASPPAGE_END(); Response.End; } // SQL Query moet een veld fac_bijlagen_key bevatten en optioneel fac_bijlagen_zippath ResultsetTable.prototype.ProcessAsZIP = function _ProcessAsZIP() { var oRs; if (this.pRs) oRs = this.pRs; else if (this.dataset) oRs = new data_recordset( this.dataset ); else oRs = Oracle.Execute(this.sql); var has_path = false; for (var i = 0; i < this.columns.length; i++) { if (this.columns[i].name == "fac_bijlagen_zippath") has_path = true;; } var bijlagen_list = []; while (!oRs.EOF) { if (oRs.Fields("fac_bijlagen_key").Value) { var onefile = { fac_bijlagen_key: oRs.Fields("fac_bijlagen_key").Value.id }; if (has_path) onefile.zippath = oRs.Fields("fac_bijlagen_zippath").Value; bijlagen_list.push(onefile); } oRs.MoveNext(); } oRs.close(); zipfacbijlagen("facilitor.zip", bijlagen_list); ASPPAGE_END(); Response.End; } // We bouwen een api2-model van onze recordset // en geven die door aan fac_usrrap_list_graph (zoals onze rapporten ook doen) // Proof of concept, niet in gebruik ResultsetTable.prototype.ProcessAsGraph = function _ProcessAsGraph() { var model = { fields: {} }; var scf_params = { list: { columns: [] }}; var oRs; if (this.pRs) oRs = this.pRs; else if (this.dataset) oRs = new data_recordset( this.dataset ); else oRs = Oracle.Execute(this.sql); // Header row var safeheader = []; for (var i = 0; i < this.columns.length; i++) { var typ = this.columns[i].datatype|| "varchar"; if (typ == "float" || typ == "currency") { this.columns[i].datatype = "number"; typ = "number"; // anders gaat het zo maar naar string } model.fields["col" + i] = { "label": this.columns[i].caption, "typ": typ }; scf_params.list.columns.push("col" + i); // TODO: welke kolommen? } var xxx_array = []; // met data while (!oRs.EOF) { var saferow = {}; for (var i = 0; i < this.columns.length; i++) { try { var val = this.columns[i].content(oRs, this.outputmode); } catch (e) { __Log("resultset_table_v2.inc: Probleem met het ophalen van columns[" + i + "]: " + this.columns[i].caption); throw(e); } saferow["col" + i] = val; } xxx_array.push(saferow); oRs.MoveNext(); } oRs.close(); scf_params.list.columns = getQParamArray("graphcols")// "col3,col4" --> ["col3", "col4"]; //__DoLog(model); //__DoLog(scf_params); //__DoLog(xxx_array); fac_usrrap_list_graph (model, scf_params, xxx_array) Response.End; } ResultsetTable.prototype.countHistogram = function(oRs) { var i, kolomnaam, kolomval, cnt; for (i= 0; i < oRs.Fields.Count; i++) { kolomnaam = oRs.Fields(i).Name; if (kolomnaam.toUpperCase() == this.keyColumn.toUpperCase()) continue; kolomval = oRs.Fields(i).Value; if (!this.Counter[kolomnaam]) this.Counter[kolomnaam] = {}; if (!this.Counter[kolomnaam][kolomval]) this.Counter[kolomnaam][kolomval] = 1; else this.Counter[kolomnaam][kolomval] += 1 } } function __rsProcessResultset(processParams) // processParams wordt blind aan alle callbackfuncties gegevens als tweede parameter { var result = { modified: false }; if (isPlain || isPrinting) { if (this.tabs_code) { result = reorderPerslidCols(this.tabs_code, this.columns); this.columns = result.columns; %> <% if (!this.inline && isPlain) { rs_columns(this.tabs_code, this.columns); } } if (!this.tabs_code || !result.modified) { // Default kolommen for (var i in this.columns) { if (this.columns[i].showDefault === false) { // Onderdruk deze kolommen this.columns[i].hidden = true; } } } } if (this.sql == null && !this.dataset) return; this.processParams = processParams; this.noPrint |= !device.test(device.canPrint); this.noExcel |= !device.test(device.canExcel); if (isXMLXSL) { this.ProcessAsXMLXSL(); return; // die is zo compleet anders.... } if (isCSV || isCSV2XLSX) { this.ProcessAsCSV(); return; // die is zo compleet anders.... } if (isNativeExcel) { this.ProcessAsNativeExcel(this.outputmode == 8); return; // die is zo compleet anders.... } if (isZIP) { this.ProcessAsZIP(); return; // die is zo compleet anders.... } if (isGraph) { this.ProcessAsGraph(); return; // die is zo compleet anders.... } if (this.canBookmark) { if (Request.ServerVariables("REQUEST_METHOD") == "POST") // POST is nog te lastig INTERNAL_ERROR_CANNOT_BOOKMARK_POST; if (book_id || getQParam("bybookmark",0)==1) this.canBookmark = false; } with(this) { if (isPrinting) startPrint(); // Print filter tabel met filterwaarden van het zoekscherm var html_filter = ""; if (isPrinting == true) { if (filterParams) html_filter = getRSFilterTable(filterParams); } Response.Write(html_filter); // class moet hetzelfde zijn zodat summary text overal (incl inline overzichten) hetzelfde uitelijk krijgen // id moet verschillend zijn omdat je meerdere rsSummary divs onafhankelijk van elkaar moet benaderen (vullen) if (isPrinting) { %> <% } else if (isPlain) { if (this.rstableNr == 1) { %> <% } if (this.canBookmark) { %> <% } if (!noPrint) { if (this.rstableNr == 1) { %> <% } } if (this.dataset && this.urllink) { %> <% } var asSavedWidget = getQParamInt("asSavedWidget", 0) == 1; if (asSavedWidget) { %> <% } if (book_id) { this.actions = []; this.buttons = []; } buttons = this.buttons || []; if (this.roundtripCode) { %> <% buttons.push({ icon: "fa-file-import", title: L("lcl_scf_import"), action: "doRoundtrip_" + this.roundtripCode + "_imp()", order: 2 }); buttons.push({ icon: "fa-file-export", title: L("lcl_scf_export"), action: "doRoundtrip_" + this.roundtripCode + "_exp()", order: 3 }); buttons.push({ horizontalRule: true, order: 1 }); // Vanwege vieze CSS truukjes moet deze als laatste gepushed worden } if (!noPrint && Request.ServerVariables("REQUEST_METHOD") == "GET") // Alleen dan auto-refreshknop { var found = false; for (var i=0; i < buttons.length; i++) { if (buttons[i].title == L("lcl_refresh") || buttons[i].action == "FcltMgr.reload()") found = true; } if (!found) buttons.push({ icon: "fa-fclt-refresh", title: L("lcl_refresh"), action: "FcltMgr.reload()", id: "btn_scf_refresh" }); } if (!noPrint) { buttons = buttons.concat([ { icon: "fa-print", title: L("lcl_print_table"), action: "doOutput(1)" } ]); if (!noExcel) { buttons = buttons.concat([ { icon: "fa-table", title: L("lcl_export_to_excel"), action: "doOutput(2)" } ]); } } if (this.advancedprint) { buttons.push({ icon: "fa-address-card", title: advancedprint_title, action: "doOutput(3)" }); // advanced } if (this.canCSV && !noExcel) { buttons.push({ icon: "fa-file", title: L("lcl_export_to_csv"), action: "doOutput(4)" }); // CSV } if (this.canBookmark) buttons.push({ icon: "fa-bookmark", title: L("lcl_fac_bookmark"), action: "createBookmark(window.event, this)" }); if (asSavedWidget) this.buttons.push({ icon: "fa-search-plus", id: "searchBlockToggler", action: "toggleSearchBlock();", tooltip: L("lcl_search") }); if (this.title || buttons.length > 0 || (this.rstCheckBoxes && this.rstCheckBoxes.length > 0) ) IFRAMER_HEADER( this.title || "", buttons, { id: this.rstableNr, inlineId: (this.inline && this.filterParams && this.filterParams.mld_key ? this.filterParams.mld_key : ""), collapsible: this.collapsible }, this.rstCheckBoxes ); if (this.rstableNr == 1) { // collapseblock sluiten we nooit omdat we niet weten of er nog een volgende tabel komen. // Een browser sluit dan vanzelf aan het einde en dan klopt het weer. Niet perfect maar ach.. %>
<% } } // isPlain var html = ""; if (isPlain) { // ========= ACTIONS ========= // == zijn er multi ACTIONS? var anyMultiActions = false; for (var i=0; i"; else val = ""; actionsDiv += val + this.actions[i].caption + ""; } hasInlineActions = aantalInline > 0; html += "\n" + "\n"; } html += startTable(); if (!Response.IsClientConnected) { __Log("Response.IsClientConnected false, Skipping sql query.", "#00FF00"); Response.End; } // read general totals and general averages, if any if (this.sqltotals) { oRs_tot = Oracle.Execute(sqltotals); if (!oRs_tot.EOF) { for (fld in columns) { var field = columns[fld]; if (field.generaltotal) { field.generaltotalsum = oRs_tot(field.name).Value; } else if (field.generalaverage) { field.generaltotalavg = oRs_tot(field.name).Value; } } } oRs_tot.Close(); } // vanuit fac_usrrap_list krijgen we een open recordsset pRs door // hij moest hem zelf al openen om de kolommen te bepalen var oRs; if (this.pRs) oRs = this.pRs; else if (this.dataset) oRs = new data_recordset( this.dataset ); else oRs = Oracle.Execute(sql); if (!Response.IsClientConnected) { // Gebruiker was te ongeduldig. Hoeven we de rest ook niet meer te doen __Log("Response.IsClientConnected false, discarding result.", "#FFFF00"); Response.End; } if (this.subtabicon) { var sti = (subtabicon instanceof Function ? subtabicon(oRs) : subtabicon); if (sti && sti.icon) { var subtabicon = sti.icon; var color = sti.color; %> <% } } if (oRs == null || oRs.EOF) { Response.Write("
"); endTable(); if (isPrinting) endPrint(); if (oRs) oRs.close(); var badgehtml = ""; if (this.required) { badgehtml = "" + I("fa-exclamation-triangle fa-lg", { "fastyle": "fas" }) + "" } if (!this.subtabicon) { %> <% } return -1; } else { %> <% } var printedFirstHeader = false; // Is de eerste header afgedrukt?. Bij isExcel en isPrinting worden namelijk meerdere headers afgedrukt var printMoreHeaders = false; // Wordt gebruikt bij isExcel en isPrinting om meerdere headers af te drukken, maar dan moet de flexModule en flexId wel gedefineerd zijn // Alleen headers weergeven bij printen naar printer of excel // en indien de flexkenmerkquery, flexid en flexgroupid is meegegeven if ((isPrinting || isExcel || this.showProperties) && this.printFlex && this.flexGroupId) printMoreHeaders = true; var lastFlexGroupKey = -1; // Wordt gebruikt bij isExcel. Start without a previous flex group, the first one is new. var lastFlexParentGroupKey = -1 // Wordt gebruikt bij isExcel. Start without a previous flex group, the first one is new. var flexGroupChanged = false; var theSqlFlex = ""; if (this.printFlex) theSqlFlex = getSqlFlex(flexModule.toUpperCase(), flexId, (flexParams instanceof Function ? flexParams(oRs) : flexParams)); var lastHadFlex = false; var nrOutOfFilter = 0; for (var cnt = 0; (cnt < S("qp_maxrows") + nrOutOfFilter || isPrinting || isExcel || showAll || showProperties) && (cnt < S("qp_maxrows2") + nrOutOfFilter || isExcel) && // Naar excel altijd alle regels (meer dan S("qp_maxrows2")) weergeven. !oRs.EOF; cnt++) { if (!Response.IsClientConnected) { __Log("Response.IsClientConnected false, Resultset aborted.", "#00FF00"); Response.End; } if (cnt && cnt % 1000 == 0) __Log("Records: " + cnt, "#E0E0FF"); var oRsFlex = null; if ((isPrinting || isExcel || showProperties) && this.printFlex) { var flexKey = (!oRs.Fields(flexId).Value ? oRs.Fields("id").Value : oRs.Fields(flexId).Value); // primary key van tabel uit recordset of id uit dataset van api2-model var oRsFlexData = getFlexData(theSqlFlex, flexKey, { showProperties: showProperties }); // is een JSON if (!oRsFlexData.length) var noFlexResult = true; // Er zijn geen flexkenmerken else var noFlexResult = false; // Er zijn flexkenmerken if (flexGroupId) // Is er een flexGroupId meegegeven { var flexGroupKey = this.myRs(flexGroupId, oRs); flexGroupChanged = isExcel && (lastFlexGroupKey != flexGroupKey); // Alleen bij printen naar excel moet er wellicht een nieuwe header boven i.v.m. andere flexkenmerken var flexChanged = flexGroupChanged; lastFlexGroupKey = flexGroupKey; if (flexParentGroupId) // Is er een flexParentGroupId meegegeven { var flexParentGroupKey = this.myRs(flexParentGroupId, oRs); flexParentGroupChanged = isExcel && (lastFlexParentGroupKey != flexParentGroupKey); // Alleen bij printen naar excel moet er wellicht een nieuwe header boven i.v.m. andere flexkenmerken if (!flexParentGroupChanged && flexGroupChanged && flexChangeNiveau && !noFlexResult && !flexChanged) { // Flexgroep is veranderd maar parentflexgroep niet. Alleen als er op flexgroep niveau flexkenmerken zijn gedefinieerd is er een nieuwe header nodig. flexChanged = false; for (var datai=0; i < oRsFlexData.length; i++) { var rec = oRsFlexData[datai]; var kenmerk_niveau = rec.niveau; if (kenmerk_niveau == flexChangeNiveau) { flexChanged = true; break; } } } flexChanged = flexParentGroupChanged || flexChanged; // Als parent group veranderd is zijn er waarchijnlijk ook andere kenmerken. Kan voor meldingen nog scherper i.v.m. nog een niveau (parent) hoger. Maar is in praktijk nog niet echt nodig. lastFlexParentGroupKey = flexParentGroupKey; } } } if (!printedFirstHeader || (printMoreHeaders && flexChanged && (!noFlexResult || (lastHadFlex && noFlexResult)))) { // Header van ResultsetTable html += makeTableHeader(oRs, oRsFlexData, anyMultiActions); html += "\n"; printedFirstHeader = true; } lastHadFlex = !noFlexResult; // Een row van ResultsetTable if (rowFilter(oRs)) { html += makeTableRow(oRs, oRsFlexData, rowNum, anyMultiActions, noFlexResult); rowNum = rowNum + 1; if (this.buildHistogram) this.countHistogram(oRs); // Voer berekeningen uit i.v.m. extra info die moet komen in de regel waar ook de print en excel iconen staan if (summaryCalc) summaryCalc(oRs, this.processParams); if (totalCalc) totalCalc(oRs, this.processParams); } else nrOutOfFilter++; if (isExcel) // Excel heeft geen S("qp_maxrows2") bescherming. Extreem grote rapportages leiden { // tot een out-of-memory. Omdat bij Excel verderop toch niets wordt gedaan met html // gooien we die hier alvast naar buiten zodat Response Buffer Exceeded wel ingrijpt. Response.Write(html); html = ""; } oRs.MoveNext(); } html += ""; if ((!oRs.EOF || this.hasMore) && !isPrinting && !isExcel) { var a_element = ""; if (Request.ServerVariables("REQUEST_METHOD") == "POST") { // Inline details met POST methode en meer dan max regels tonen werkt niet. Komt ook niet voor. a_element = ""; } else { a_element = ""; } a_element += L("lcl_qp_maxrows1").format(S("qp_maxrows")) + ""; // Op regel klikken om de overige regels op te halen, boven de tabel html = "
" + (cnt <= S("qp_maxrows") + nrOutOfFilter ? a_element.replace(/&collapsed=1/gi, "") // Als er op deze regel wordt geklikt moet IFRAMER niet meer dichtgeklapt worden, dus &collapsed=1 verwijderen uit de link. : L("lcl_qp_maxrows2").format(S("qp_maxrows2")) ) + "
" + html; } // Footnote van ResultsetTable // Footnote hoort eigenlijk voor de tbody (HTML4.0) maar dan weten we het totaal nog niet. // MGE: TODO: Footnote kan hier nog voor de body gezet worden want Response.Write(html) heeft nog niet plaatsgevonden! // Echter bij (printMoreHeaders && flexGroupChanged) worden er meerdere headers geprint op verschillende plekken. // Dit hoort eigenlijk niet zo. var htmlFoot = ""; if (oRs.EOF) htmlFoot += makeTableFootnote(anyMultiActions, oRsFlexData); if (anyMultiActions && !inline) { appender = "\n
" + safe.html(L("lcl_with_selected").format(0)) + ""; var multiActions = 0; // Geen inline acties, dus ook geen rowEnabler, dus is okformulti ook nog niet bepaald, dan doen we dat hier if (disableInlineActions && multiActionEnabler) { var validateAction = multiActionEnabler(); for (var i=0; i < actions.length; i++) { if (!actions[i].okformulti && // No double check (actions[i].multi && !(actions[i].onlyMulti || actions[i].single === false)) && // No unnecessary check actions[i].enabler && validateAction && validateAction[actions[i].enabler]) // Check { actions[i].okformulti = true; } } } for (var i=0; i < actions.length; i++) { ///// // // Een bulk-actie wordt weergegeven indien: // // - multi = true, EN: // // - okformulti = true (oftewel, de enabler is succesvol) // - OF: het is uitsluitend een multi actie, dan altijd weergeven. Oftewel: (onlyMulti || single === false) // ///// if (actions[i].multi && (actions[i].okformulti || actions[i].onlyMulti || actions[i].single === false)) { multiActions++; appender += ""+(actions[i].icon?I(actions[i].icon):"")+safe.html(actions[i].caption)+""; } } if (multiActions == 0) appender += "" + L("lcl_no_multi_actions") + ""; appender += "
"; var flexColumns = 0; /* Afgekeken van addFlexKenmerkFooter; bepaal het aantal columns dat nodig is voor de kenmerken */ if ((isPrinting || showProperties) && this.printFlex) { flexColumns = 1; } else if (isExcel && this.printFlex) { for (var i=0; i < oRsFlexData.length; i++) { flexColumns++; } } htmlFoot += ""; } if (htmlFoot != "") htmlFoot = "" + htmlFoot + ""; html += htmlFoot; Response.Write(html); endTable(); // 'Klik voor meer' onderaan de tabel if (!oRs.EOF || this.hasMore) { var a_element = ""; if (Request.ServerVariables("REQUEST_METHOD") == "POST") { // Inline details met POST methode en meer dan max regels tonen werkt niet. Komt ook niet voor. a_element = ""; } else { a_element = ""; } a_element += L("lcl_qp_maxrows1").format(S("qp_maxrows")) + ""; // Op regel klikken om de overige regels op te halen, onder de tabel html = "\n
" + (cnt <= S("qp_maxrows") + nrOutOfFilter ? a_element : L("lcl_qp_maxrows2").format(S("qp_maxrows2")) ) + "
"; Response.Write(html); } if ("auditcount" in this && rowNum >= this.auditcount) { shared.registeraction("audit", {info: L("fac_audit_listrequested").format(this.title, rowNum), daily: 0 }); } // default summary text if (rowNum == 1) summaryInfo = L("lcl_nr_lines_resultone"); else summaryInfo = L("lcl_nr_lines_result").format(rowNum); if (summaryShow) { var summaryInfo = ((!oRs.EOF || this.hasMore)? "" + L("lcl_suminfo_incomplete") + " " : "") + (summaryShow(rowNum) || ""); } if (!this.noSetSummary) { %> <% } // Eventueel doortellen tot het einde. Dat doen we maximaal 1 seconde! (zo'n 3200 records) var tmStart = (new Date).getTime(); var teller = 0; while (!oRs.EOF && this.buildHistogram && ((new Date).getTime() - tmStart) < 1000) { teller ++; this.countHistogram(oRs); oRs.MoveNext(); } if (!oRs.EOF && this.buildHistogram) { // Niet gered binnen een seconde __Log("Histogram niet binnen 1000ms klaar. Reset histogram"); this.Counter = {}; } else if (teller > 0) { __Log("Histogram afgerond ("+teller+" extra items) in " + ((new Date).getTime() - tmStart) + "ms"); } oRs.close(); if (endText) { var endTextInfo = (endText instanceof Function ? endText(oRs, this.processParams) : endText); if (endTextInfo != "") { %>
<%=endTextInfo%>
<% } } if (isPrinting) endPrint(); if (this.buildHistogram) return this.Counter; else return rowNum; // simpel return aantal rows } // with(this) } function __rsStartTable() { var html = ""; with (this) { html = "
"; html += "
" + emptySetString + "
" + appender + "
"; } if (useHamburger && hasInlineActions) { html += ""; } if (inlineDetails) { html += ""; } } // ========= COLUMNS/THEADER ========= for (var i=0; i < columns.length; i++) { if (propertiesColumn == i) // Nog kolommen toevoegen voor de flexkenmerken html += addFlexKenmerkHeader(oRsFlexData, this); if ((isPlain && (columns[i].purpose & VIEW_ONLY)) || ((!isPlain || showProperties) && (columns[i].purpose & PRINTING_ONLY))) { if ((isPrinting || showProperties || isExcel || !columns[i].combine) && !(isExcel && columns[i].hidden)) { if (isExcel) { html += ""; } } if (propertiesColumn == null) // Nog header toevoegen voor de flexkenmerken. html += addFlexKenmerkHeader(oRsFlexData, this); html += ""; } return html; } var lastRowKey = -1; // voor suppress function __rsMakeTableRow(oRs, oRsFlexData, cnt, anyMultiActions, noFlexResult) { var html = ""; // Pas op: dit komt voor elke regel terug, dus hou het kort! with(this) { if (beforeEachRow) beforeEachRow(oRs, this.processParams); var thisKey = -1; if (suppressKeyRepeat) thisKey = oRs(suppressKeyRepeat).Value; // HIER START EEN NIEUWE REGEL var appender = ("\n"); // Het start element is nu klaar // ========= COLUMNS ========= if (!isPrinting && !isExcel && anyMultiActions && !inline) // Checkboxje erbij voor 'select all' { var isChecked = this.rowChecked && this.rowChecked(oRs, this.processParams); appender += ""; } if (useHamburger && hasInlineActions) { if (actionbits == noActionBit) // No inline actions { appender += ""; } else { appender += ""; } } if (!isPrinting && !isExcel && inlineDetails) { var ttl = null; if (hasInlineDetails) ttl = hasInlineDetails(oRs, this.processParams); if (!hasInlineDetails || ttl) { var opdr_gewijzigd = (inlineDetailsChanged ? oRs("isGewijzigd").Value == 1 : false); if (typeof ttl == 'string') ttl = " title ='" + safe.htmlattr(ttl) + "'" else ttl = ""; appender += ""; } else appender += ""; } // ========= De echte waarde ========= var colHasVal; for (var i = 0; i < columns.length; i++) { if (propertiesColumn == i) // Nog kolommen toevoegen voor de flexkenmerken appender += addFlexKenmerkKolommen(oRsFlexData, this, { lastRowKey: lastRowKey, thisKey: thisKey }); if ((isPlain && (columns[i].purpose & VIEW_ONLY)) || ((!isPlain || showProperties) && (columns[i].purpose & PRINTING_ONLY))) { if (!columns[i].combine) colHasVal = false; try { var val = (columns[i].content != null ? columns[i].content(oRs, this.processParams) : ""); } catch (e) { __Log("resultset_table_v2.inc: Probleem met het ophalen van columns[" + i + "]: " + columns[i].caption); throw(e); } if (columns[i].image) { var imgval = ""; } if (val == null) val = " "; if (suppressKeyRepeat && lastRowKey == thisKey && !columns[i].keepKeyRepeat) val = " "; // just in case? val = String(val); // Klik actie op de waarde. var urlkey = -1; // urlkey (columns[i].urlkey) is altijd een functie of -1 als er geen functie is gedefinieerd. var urlkey = columns[i].urlkey instanceof Function? columns[i].urlkey(oRs, this.processParams, this) : -1; var clickaction = urlkey == -1? "" : " class='clickaction' OnClick=' clickAction(" + urlkey + ")'"; // Tooltip voor de kolom var tooltip = columns[i].tooltip == null ? null : this.myRs(columns[i].tooltip, oRs); if (!tooltip && columns[i].prettydate) { tooltip = toDateString(oRs(columns[i].orgContent).Value, isExcel, false); } tooltip = (tooltip == null? "" : " title='" + safe.htmlattr(tooltip) + "'"); // Class voor de kolom var columnClass = columns[i].columnClass == null ? (columns[i].tdClass instanceof Function ? columns[i].tdClass(oRs) : columns[i].tdClass) : this.myRs(columns[i].columnClass, oRs); if (i <= lastColKey) { if (lastVal[i] == null || lastVal[i] != val) lastVal[i] = val; else if (val != " " && val !== "") columnClass = (columnClass == null ? "dupe" : columnClass + " dupe"); } columnClass = (columnClass == null ? "" : " class='" + columnClass + "'"); // custom sort key voor de kolom var customSort = columns[i].customSort == null ? null : this.myRs(columns[i].customSort, oRs); if (!customSort && columns[i].prettydate) { customSort = toDateString(oRs(columns[i].orgContent).Value, isExcel, false); } customSort = (customSort == null? "" : " sorttable_customkey='" + customSort + "'"); // pikt sorttable.js vanzelf op // Uitlijning voor de kolom var align = ""; var style = ""; if (columns[i].align) align = " align='" + columns[i].align + "'"; else { if (columns[i].datatype == "currency" || columns[i].datatype == "float" || columns[i].datatype == "number") style += "text-align:right;"; } // Niet zichtbare kolom style += (columns[i].hidden ? " display:none;" : ""); // Prevent wrapping if required var nowrap = columns[i].nowrap ? " class='nowrap'" : ""; // Opbouw cell style = (style ? " style='" + style + "'" : ""); if ((isPrinting || showProperties || isExcel || !columns[i].combine) && !(isExcel && columns[i].hidden)) { if (isExcel) appender += " 0 && val.match(/[0-9]/) && !inArray(columns[i].datatype, ["date", "currency", "datetime", "float", "number"])) { appender += " style='mso-number-format:\"\@\"'"; } appender += (columns[i].classList ? " CLASS='" + columns[i].classList + "'" : "") + ">"; } else { // Combine maar geen
voor lege val if (val != " " && val !== "" && colHasVal) { appender += "
" } else appender = appender.replace(/\ \;$/,"") // "Vorige"   er af strippen } if (!(isExcel && columns[i].hidden)) if (tooltip || clickaction) // show tooltip on field, not on
"; // Hebben we al een echt waarde gehad? colHasVal = colHasVal || (val != " "); // Als totaal van de kolom weergegeven moet worden dan waarden optellen. // amount is altijd een functie if (columns[i].total || columns[i].average) { var amount = (columns[i].amount != null ? columns[i].amount(oRs, this.processParams) : null) if (amount != null && !isNaN(amount)) columns[i].totalsum += amount; } if (columns[i].average) // only on the last iteration is this needed { if (!columns[i].totalRows) columns[i].totalRows = 0; columns[i].totalRows++; } } } html += appender; if (propertiesColumn == null) // Nog kolommen toevoegen voor de flexkenmerken html += addFlexKenmerkKolommen(oRsFlexData, this, { lastRowKey: lastRowKey, thisKey: thisKey }); html += ""; // rowNum = cnt + 1; } lastRowKey = thisKey; return html; } function __rsMakeTableFootnote(anyMultiActions, oRsFlexData) { var html = ""; with(this) { var total = false; var average = false; // Kijk eerst of er een totaalregel toegevoegd moet worden for (var i=0; i < columns.length; i++) { if (columns[i].total || columns[i].generaltotal) total = true; if (columns[i].average || columns[i].generalaverage) average = true; } if ((total || average) && !isExcel) { html += ""; if (!isPrinting && anyMultiActions && !inline) // Kolom i.v.m. checkboxje erbij voor 'select all' html += ""; if (hasInlineDetails && !isPrinting && !isExcel && inlineDetails) html += ""; // Kolom i.v.m. inlinedetails if (useHamburger && hasInlineActions) html += ""; // Ook nog kolom i.v.m. hamburger die er sowieso mogelijk alleen is als er acties zijn var html_f = ""; var once = true; // Indien totalColumnText is gedfinieerd, eenmalig de text van totalColumnText tonen in de kolom voor de eerste totaal kolom. for (var i = 0; i < columns.length; i++) { if ((isPlain && (columns[i].purpose & VIEW_ONLY)) || ((!isPlain || showProperties) && (columns[i].purpose & PRINTING_ONLY))) { if (!columns[i].combine || isPrinting || showProperties || isExcel) // Bij isPrinting, isExcel of showProperties niet combineren. { // Nog kolommen toevoegen voor flexkenmerken if (propertiesColumn == i) html_f += addFlexKenmerkFooter(oRsFlexData, this); html_f += ""; } if (totalColumnText && once && (i + 1) < columns.length && columns[i + 1].total) { once = false; html_f += totalColumnText(); } // Weergeven als integer of als getal met twee decimalen. if (columns[i].total) { if (totalShow) { html_f += totalShow(columns[i], rowNum); } else { html_f += ResultsetTable.formatValue(columns[i].totalsum, columns[i]); } } else if (columns[i].generaltotal) { html_f += ResultsetTable.formatValue(columns[i].generaltotalsum, columns[i]); } else if (columns[i].generalaverage) { html_f += ResultsetTable.formatValue(columns[i].generaltotalavg, {datatype: "float", decimals: 2}); } else if (columns[i].average && columns[i].totalRows > 1) // geen gemiddelde tonen van 1 resultaat html_f += ResultsetTable.formatValue((columns[i].totalsum / columns[i].totalRows), {datatype: "float", decimals: 2}); else html_f += ""; if ((i < columns.length - 1) && !columns[i + 1].combine) html_f += ""; } } // Nog extra kolom headers voor de flexkenmerken // Flexkenmerken tonen bij isPrinting, isExcel of showProperties if (this.printFlex && this.propertiesColumn == null) { html_f += ""; } html_f = balanceCloseTag("td", html_f); html += html_f + ""; } } return html; } function balanceCloseTag(tagname, chtml) { // Als het aantal tag-open groter is dan het aantal tag-close dan een tag-close toevoegen. var tag_open = chtml.toLowerCase().split("<"+tagname.toLowerCase()); var tag_close = chtml.toLowerCase().split("/"+tagname.toLowerCase()+">"); if (tag_open.length > tag_close.length) { chtml += ""; } return chtml; } function __rsEndTable() { Response.Write("\n
"+I("fa-plus-square")+""; } else { if (columns[i].hidden) { html += ""; } else { html += "" } } } if (!(isExcel && columns[i].hidden)) { var combine_caption = columns[i].caption.replace(/^\s+|\s+$/g,""); // trim spaces: functie trim() werkt niet server-side! if (columns[i].combine && combine_caption && !isPrinting) html += "
"; html += columns[i].caption; } // Is de volgende kolom een combine. LET OP!!!: PRINTING_ONLY kolommen niet meerekenen (overslaan) in niet print uitvoer. var combine = false; for (var c = i + 1; c < columns.length; c++) { if (columns[c].purpose != PRINTING_ONLY) { combine = columns[c].combine; break; } } if ((!isPrinting && !isExcel && (i < columns.length - 1) && combine) || (isExcel && columns[i].hidden)) { // html += "
"; } else html += "
" + I("fa-bars fa-lg") + "
" + (opdr_gewijzigd ? I("fa-square-exclamation") : I("fa-plus-square")) + ""+L("lcl_inlinecolumnnone")+" appender += "" + val + ""; else appender += val; // Is de volgende kolom een combine. LET OP!!!: PRINTING_ONLY kolommen niet meerekenen (overslaan) in niet print uitvoer. var combine = false; for (var c = i + 1; c < columns.length; c++) { if (columns[c].purpose != PRINTING_ONLY) { combine = columns[c].combine; break; } } if ((!isPrinting && !isExcel && (i < columns.length - 1) && combine) || (isExcel && columns[i].hidden)) ;/* appender += "
"; */ else appender += "
"); Response.Write("\n
"); } function __rsAddColumn(column) { this.columns.push(column); } function __rsStartPrint() { if (!isPrinting) return; if (getQParamInt("formail", 0) == 1) { var logo_fileName = "cid:" + S("fac_logo_file"); } else { var logo_fileName = custpath + "/" + S("fac_logo_file"); } Response.Write('\n
'); Response.Write('\n'); Response.Write('\n'); Response.Write('\n'); Response.Write('\n'); Response.Write('\n
'); } function __rsEndPrint() { if (isPrinting) { var prtDate = toDateTimeString(new Date()); Response.Write('\n
'); Response.Write('\n'); Response.Write( '\n'); // deze this.title lijkt intussen verloren gegaan Response.Write( '\n'); Response.Write( '\n'); Response.Write('\n
'); if (p_autosortby) { var sortfn = autosortbyrev?"sorttable.doSortRev":"sorttable.doSort"; Response.Write(''); } else Response.Write(''); // Zonder jQuery } } /////////// // Column /////////// var PRINTING_ONLY = 1; var VIEW_ONLY = 2; var PRINT_AND_VIEW = PRINTING_ONLY + VIEW_ONLY; function Column(params) { if (!params) params = {}; this.caption = params.caption; this.title = params.title; this.filter = params.filter; this.content = params.content; this.image = params.image; this.action = params.action; this.tooltip = params.tooltip; this.thClass = params.thClass; this.columnClass = params.columnClass; this.classList = params.classList; this.customSort = params.customSort; this.align = params.align; this.purpose = params.purpose ? params.purpose : PRINT_AND_VIEW; this.hidden = params.hidden; this.showDefault = "showDefault" in params ? params.showDefault : true; this.datatype = params.datatype; this.decimals = params.decimals; this.trimZeros = params.trimZeros; this.total = params.total; this.average = params.average; this.amount = null; // Voor INTERN gebruik: is de integerwaarde van content, indien de kolomwaarden opgeteld moeten worden. this.urlkey = null; // Voor INTERN gebruik: als er een urlkey is meegegeven. this.totalsum = 0; this.average = 0.00; this.generaltotalsum = 0; this.generaltotalavg = 0.00; this.name = params.name; this.nowrap = params.nowrap; this.orgContent = params.content; this.nomidnight = params.nomidnight; this.filename = params.filename; // voor csv/xlsx // Neem alle meegegeven parameters mee. for (param in params) { if (param == "content" && params.content) { if (params.content instanceof Function) { this.content = params.content; this.amount = params.fnAmount || params.content; this.urlkey = params.fnUrlkey || -1; } else { this.content = function (oRs) { return ResultsetTable.formatValue(oRs.Fields(params.content).Value, this) } ; this.amount = function (oRs) { return oRs.Fields(params.content).Value }; this.urlkey = function (oRs, processParams, params) { return params.dataset? ResultsetTable.getUrlKey(oRs.Fields("scf_urlkey").Value, params.content) : -1; }; } } else this[param] = params[param]; } if (!isPlain && this.prettydate) this.prettydate = false; } // Levert een html-safe waarde op ResultsetTable.formatValue = function (val, params) //datatype, decimals) { if (val == null) { if (isXMLXSL || isCSV || isCSV2XLSX) return ""; else return " "; } // Vanuit API2 model if (typeof val == "object" && "name" in val) { val = val["name"]; params.datatype = null; // default string } // Eerst de geforceerde datatypes switch (params.datatype) { case "date" : return toDateString(val, isExcel||isCSV || isCSV2XLSX, params.prettydate); // isExcel-->noDay case "datetime": return toDateTimeString(val, params.withSeconds, isExcel||isCSV || isCSV2XLSX, params.prettydate, params.nomidnight); case "time" : { val = toTimeString(val, params.withSeconds); if (params.datatype == "time" && params.nomidnight && val == "00:00") val = ""; return val; } case "processingtime": { if (val["duration"] == null) val = ""; else val = val["duration"] + " " + (val["unit"]=="U"?L("lcl_mld_hours"):L("lcl_mld_days")); return val; } case "currency": return safe.curr(val); case "float" : return safe.displayfloat(val, params.decimals, params.trimZeros); case "number" : return val; case "html" : return val; } // Autotypering "datum" if (typeof val == "date" || val instanceof Date) return toDateString(val, isExcel, params.prettydate); if (!val) return ""; if (typeof val != "string") { // Je raakt bijvoorbeeld de rechtse uitlijning van number-velden kwijt __Log("Ongespecificeerd datatype van veld '{0}'{1} is {2}, fallback naar string".format(params.caption, typeof params.orgContent=='string'?' (' + params.orgContent + ')':"", typeof val), "#FF0"); val = String(val); } if (params.secret) return "".format(safe.htmlattr(val)) + I("fa-eye fa-lg") + ""; val = shared.stripbbcodes(val); if (isXMLXSL || isCSV || isCSV2XLSX) return val; // DOM lost encoding wel op of we doen safe.csv. // default datatype is "string" val = String(val).replace(/[\n\r]+/g,"\n"); // Compact, geen lege regels tonen var safeval = __rsTruncMore(val, {isPrinting: isPrinting, isExcel: isExcel}); // Zorgt voor het afkappen van de tekst en het toevoegen van ... meer. return safeval; } ResultsetTable.getUrlKey = function (urlval, contenttext) { var urlkey = urlval? urlval[contenttext] || -1 : -1; return urlkey; } ResultsetTable.prototype.truncMore = function __rsTruncMore(pval, pparams) { if (pparams.isExcel) { // Hier geen safe.html omdat we voor Excel de
naar \n vertaling niet kunnen hebben. // Met
krijg je een nieuwe rij in excel. return Server.HTMLEncode(pval); } if (pparams.isPrinting || S("rs_maxchar") < 0 || pval.length < S("rs_maxchar") * 1.20) // 'Meer' moet minstens 20% extra tekst opleveren. return safe.html(pval); // simpelweg hele tekst // Oke, op scherm afkappen na S("rs_maxchar") karakters. // Probeer op de eerste spatie maar die moet wel binnen 20% karakters komen var fullval = pval; var spatie = String(pval).substr(S("rs_maxchar")).indexOf(" "); if (spatie < 0 || spatie > S("rs_maxchar")/5) spatie = 0; pval = fullval.substr(0, S("rs_maxchar") + spatie + 1); // Pas op: pval is al "html-safe" terwijl we dat voor afkappen niet kunnen hebben? // In ieder geval geen safe.htmlattr. var safeval = safe.html(pval) + "" + L("lcl_rs_truncated") + ""; return safeval; } function ResultsetTable.prototype.myRs(fn, oRs) { if (fn instanceof Function) { return fn(oRs, this.processParams); } else { return oRs.Fields(fn).Value; } } %>