2546 lines
98 KiB
PHP
2546 lines
98 KiB
PHP
<% /*
|
||
File: shared/resultset_table_v2.inc
|
||
|
||
$Revision$
|
||
$Id$
|
||
|
||
*/
|
||
%>
|
||
|
||
<!-- #include file="resultset_filter_table.inc" -->
|
||
<!-- #include file="resultset_flex.inc" -->
|
||
<!-- #include file="iface.inc" -->
|
||
<!-- #include file="../api/api.inc" -->
|
||
<!-- #include file="../Shared/rs_columns.inc" -->
|
||
<%
|
||
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);
|
||
}
|
||
|
||
// <form> printform is nodig bij printen reserveringen i.v.m. POST formulier
|
||
// maar <form> mag niet binnen een ander <form> 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 = '<div id=\"postform\">'
|
||
+ '<form id=\"printform\" name=\"printform\" target=\"_blank\" rel=\"noopener noreferrer\" method=\"post\">'
|
||
+ '<input type=\"hidden\" id=\"outputmode\" name=\"outputmode\" value=\"0\">' // input outputmode wordt gezet in doOutput()
|
||
+ '<input type=\"hidden\" id=\"autosortby\" name=\"autosortby\" value=\"0\">' // input autosortby wordt gezet in doOutput()
|
||
+ '<input type=\"hidden\" id=\"showall\" name=\"showall\" value=\"1\">';
|
||
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<6E>ren
|
||
// Een eventuele submit ook niet doorgeven tijdens afdruk.
|
||
if (itemName != "outputmode" && itemName != "showall" && itemName != "do_submit")
|
||
postformHTML += '<input type=\"hidden\" name=\"' + safe.htmlattr(itemName)
|
||
+ '\" value=\"' + safe.htmlattr(Request.Form(itemName)(i)) + '\">';
|
||
}
|
||
items.moveNext();
|
||
}
|
||
postformHTML += '</form>'
|
||
+ '</div>';
|
||
}
|
||
|
||
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;
|
||
%> <!-- 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)
|
||
{
|
||
%>
|
||
<div id="rsSummary<%=summaryId%>" class="rsSummary" style="display:none">
|
||
<span id="rsSummaryInfo<%=summaryId%>" class="rsSummaryInfo"></span>
|
||
</div>
|
||
<script>
|
||
function setSummary(html)
|
||
{
|
||
if (html != "")
|
||
{
|
||
var elm = document.getElementById("rsSummaryInfo<%=summaryId%>");
|
||
elm.innerHTML = html;
|
||
var elm = document.getElementById("rsSummary<%=summaryId%>");
|
||
elm.style.display='block';
|
||
}
|
||
}
|
||
</script>
|
||
<%
|
||
}
|
||
else if (isPlain)
|
||
{
|
||
if (this.rstableNr == 1)
|
||
{
|
||
%>
|
||
<script>
|
||
var postformHTML = '<%=safe.jsstring(postformHTML)%>'; <% /* postformHTML naar javascript voor gebruik in resultset_table_v2.js */ %>
|
||
var /*function*/ setSummary = FcltMgr.setHeaderExtraTitle;
|
||
var result_refresher_url = "<%= safe.jsstring(this.refresher_url) %>";
|
||
var result_refresher_url = <%= (this.refresher_timer||0) %>;
|
||
</script>
|
||
<%
|
||
}
|
||
if (this.canBookmark)
|
||
{
|
||
%>
|
||
<script>
|
||
function saveBookmark($dialog)
|
||
{
|
||
var bmtitel = $dialog.find("#bmtitel").val();
|
||
var data = { path: "<%=safe.jsstring(String(Request.ServerVariables("SCRIPT_NAME")))%>",
|
||
query: "outputmode=" + (<%=this.advancedprint?3:outputmode%>) + "<%=safe.jsstring(transitQS())%>",
|
||
naam: bmtitel
|
||
};
|
||
<% protectRequest.dataToken("data"); %>
|
||
$.post("../shared/create_bookmark.asp",
|
||
data,
|
||
FcltCallback, "json");
|
||
}
|
||
|
||
function createBookmark(evt, deze)
|
||
{
|
||
params = {oktekst: L("lcl_fac_bookmark"),
|
||
title: L("lcl_fac_bookmark"),
|
||
ishtmlsafe: true,
|
||
fncallback: saveBookmark,
|
||
buttons: [{ text: L("lcl_cancel"), icon: "fal fa-fw fa-undo", class: "alertCancel" }]
|
||
};
|
||
var page_content = "<input type='text' id='bmtitel' class='fld' value='<%=safe.htmlattr(this.title)%>'>";
|
||
FcltMgr.mydialog(page_content, params);
|
||
}
|
||
</script>
|
||
<%
|
||
}
|
||
if (!noPrint)
|
||
{
|
||
if (this.rstableNr == 1)
|
||
{
|
||
%>
|
||
<script>
|
||
function doPrint(poutputmode)
|
||
{
|
||
var autosortby = "";
|
||
var xx = $("th.sorttable_sorted,th.sorttable_sorted_reverse");
|
||
if (xx.length)
|
||
{
|
||
if (xx.html().split("<br>").length > 1)
|
||
{
|
||
autosortby = xx.html().split("<br>")[0];// Bij combined alleen de eerste
|
||
}
|
||
else // moeten we complexer strippen
|
||
{
|
||
autosortby = xx.text();
|
||
autosortby = autosortby.substring(0, autosortby.length - 1); // Spatie er af halen. Font Awsome teken is een html <i> tag/element en geen karakter.
|
||
}
|
||
}
|
||
if (xx.hasClass("sorttable_sorted_reverse"))
|
||
{
|
||
autosortby = "-" + autosortby;
|
||
}
|
||
|
||
<% if (Request.ServerVariables("REQUEST_METHOD") == "POST")
|
||
{ %>
|
||
document.printform.autosortby.value = autosortby;
|
||
document.printform.outputmode.value = poutputmode;
|
||
document.printform.submit();
|
||
<% }
|
||
else
|
||
{ %>
|
||
FcltMgr.windowopen("<%=Request.ServerVariables("SCRIPT_NAME")%>?outputmode=" + poutputmode + "&autosortby=" + escape(autosortby) + "<%=safe.jsstring(transitQS())%>");
|
||
<% } %>
|
||
}
|
||
|
||
function doOutput(poutputmode)
|
||
{
|
||
|
||
<% if (Request.ServerVariables("REQUEST_METHOD") == "POST")
|
||
{ %>
|
||
// Alle parameters zijn in een formulier gestopt als request methode POST is.
|
||
if (poutputmode == 0)
|
||
document.printform.target = "_self";
|
||
<% }
|
||
var hasFlex = this.flexModule && this.flexId;
|
||
%>
|
||
if (!<%=hasFlex?"true":"false"%> || !(poutputmode == 1 || (poutputmode == 2 && ("<%=S("excel_mode")%>" == "0" || "<%=S("excel_mode")%>" == "2"))))
|
||
{
|
||
doPrint(poutputmode);
|
||
return;
|
||
}
|
||
params = { oktekst: L("lcl_Yes"), title: L(poutputmode==1?"lcl_print":"lcl_export_to_excel") };
|
||
params.fncallback = function ()
|
||
{
|
||
doPrint(poutputmode); // poutputmode wordt 5 (printer zonder flex) of 6 (excel zonder flex);
|
||
// close gaat vanzelf;
|
||
}
|
||
|
||
params.buttons = [
|
||
{
|
||
text: L("lcl_No"),
|
||
icon: "fal fa-fw fa-times",
|
||
class: 'resultprintno',
|
||
click: function()
|
||
{
|
||
doPrint(poutputmode + 4);
|
||
}
|
||
},
|
||
{
|
||
text: L("lcl_cancel"),
|
||
icon: "fal fa-fw fa-undo",
|
||
class: 'resultprintcancel',
|
||
}];
|
||
FcltMgr.mydialog(L("lcl_print_properties"), params);
|
||
}
|
||
</script>
|
||
<%
|
||
}
|
||
}
|
||
if (this.dataset && this.urllink)
|
||
{
|
||
%>
|
||
<script>
|
||
function clickAction(urlkey, titel)
|
||
{
|
||
FcltMgr.openDetail("<%=safe.htmlattr(urllink)%>" + urlkey, "");
|
||
}
|
||
</script>
|
||
<%
|
||
}
|
||
|
||
var asSavedWidget = getQParamInt("asSavedWidget", 0) == 1;
|
||
if (asSavedWidget)
|
||
{ %>
|
||
<script>
|
||
function _toggleExpandIcon()
|
||
{
|
||
$("#searchBlockToggler > i").toggleClass("fa-search-plus fa-search-minus");
|
||
}
|
||
|
||
function toggleSearchBlock()
|
||
{
|
||
_toggleExpandIcon();
|
||
parent.toggleSearchBlock();
|
||
}
|
||
|
||
$(function() { // Ik zoek opnieuw (of ververs) en het zoekblok is opengeklapt, corrigeer dan het expand-icoontje
|
||
if (!$(parent.document.body).find(".container-fluid.hidden").length)
|
||
_toggleExpandIcon();
|
||
});
|
||
</script>
|
||
<% }
|
||
|
||
if (book_id)
|
||
{
|
||
this.actions = [];
|
||
this.buttons = [];
|
||
}
|
||
|
||
buttons = this.buttons || [];
|
||
if (this.roundtripCode) { %>
|
||
<script>
|
||
function doRoundtrip_<%=this.roundtripCode%>_exp()
|
||
{
|
||
var url = "../fac/fac_roundtrip_exp.asp?app_code=<%=this.roundtripCode%>";
|
||
FcltMgr.windowopen(url);
|
||
}
|
||
|
||
function doRoundtrip_<%=this.roundtripCode%>_imp()
|
||
{
|
||
var url = "appl/fac/fac_roundtrip_imp.asp?app_code=<%=this.roundtripCode%>";
|
||
FcltMgr.openDetail(url, L("lcl_import"));
|
||
}
|
||
</script>
|
||
<% 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..
|
||
%>
|
||
<div id="collapseblock">
|
||
<%
|
||
}
|
||
} // isPlain
|
||
|
||
var html = "";
|
||
|
||
if (isPlain)
|
||
{
|
||
// ========= ACTIONS =========
|
||
// == zijn er multi ACTIONS?
|
||
var anyMultiActions = false;
|
||
for (var i=0; i<this.actions.length; i++)
|
||
{
|
||
anyMultiActions |= this.actions[i].multi;
|
||
}
|
||
|
||
// Eerst: maak <20><>n div met alle acties.
|
||
var hasActionsCol = 0;
|
||
var skip = 0;
|
||
for (var i=0; i < columns.length; i++)
|
||
{
|
||
if (columns[i].combine)
|
||
skip ++;
|
||
if (columns[i].hasActions)
|
||
{
|
||
hasActionsCol = i - skip;
|
||
break;
|
||
}
|
||
}
|
||
if (anyMultiActions)
|
||
hasActionsCol++;
|
||
if (this.inlineDetails)
|
||
hasActionsCol++;
|
||
|
||
// Nu de inline buttons renderen. Ze zijn er <20><>n keer en worden voor alle regels hergebruikt
|
||
var actionsDiv = "";
|
||
var aantalInline = 0;
|
||
for (var i = 0; i < this.actions.length; i++)
|
||
{
|
||
if (disableInlineActions && !this.actions[i].isDefault)
|
||
continue;
|
||
if (this.actions[i].single === false || this.actions[i].onlyMulti) // triple '=' omdat undefined niet false mag zijn
|
||
continue; // niet ook nog inline
|
||
if (!this.actions[i].isDefault)
|
||
aantalInline++;
|
||
var def = (this.actions[i].isDefault? " isdefault='1'" : "")
|
||
+ (this.actions[i].onlyMulti? " onlymulti='1'" : "")
|
||
+ (this.actions[i].isDefault || this.actions[i].onlyMulti? " style='display:none'" : "");
|
||
var tooltip_actions = this.actions[i].tooltip? " title='" + safe.htmlattr(this.actions[i].tooltip) + "'" : "";
|
||
var disp = useHamburger != 0 ? " style='display: block;'" : "";
|
||
if (this.actions[i].multiOnce)
|
||
val = "<span class='ia2' " + def + " onclick='doAm(event, this, \"" + this.actions[i].action + "\")'" + disp + tooltip_actions + ">";
|
||
else
|
||
val = "<span class='ia2' " + def + " onclick='doA(event, this, \"" + this.actions[i].action + "\")'" + disp + tooltip_actions + ">";
|
||
actionsDiv += val + this.actions[i].caption + "</span>";
|
||
}
|
||
hasInlineActions = aantalInline > 0;
|
||
html += "\n<div id='allactions_" + ID + "' class='allactions' style='display:none;z-index:13' hasActionsCol='"+hasActionsCol+"' >" + actionsDiv + "</div>"
|
||
+ "\n<script type='text/javascript'>"
|
||
+ "\n initActions('" + this.ID + "', "+useHamburger+")"
|
||
+ "</script>";
|
||
}
|
||
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;
|
||
%> <script>
|
||
FcltMgr.setSubtabExtra("<span class='subtab-badge-icon' style='color:<%=color%>'>" + I("<%=subtabicon%> fa-lg", { "fastyle": "fas"}) + "</span>");
|
||
</script>
|
||
<% }
|
||
|
||
}
|
||
|
||
if (oRs == null || oRs.EOF)
|
||
{
|
||
Response.Write("<div id='rstable'><table><tr><td class='emptyset'>" + emptySetString + "</td></tr>");
|
||
endTable();
|
||
if (isPrinting)
|
||
endPrint();
|
||
if (oRs)
|
||
oRs.close();
|
||
|
||
var badgehtml = "";
|
||
if (this.required)
|
||
{
|
||
badgehtml = "<span class='subtab-badge-icon subtab-badge-missing'>"
|
||
+ I("fa-exclamation-triangle fa-lg", { "fastyle": "fas" })
|
||
+ "</span>"
|
||
}
|
||
if (!this.subtabicon) {
|
||
%> <script>
|
||
var prevent_badge_reset = false;
|
||
<% if (!badgehtml && this.rstableNr && this.rstableNr > 1)
|
||
{ /* Itereer over alle voorgaande resultsets, als er 1 bestaat hoeven we de spinner niet meer uit de badge te halen,
|
||
want dat is dan al gebeurd, en mogelijk staat er ook al een counter in. */
|
||
%> for (var i = <%=this.rstableNr-1%>; i && !prevent_badge_reset; i--) {
|
||
prevent_badge_reset = $("[id=rstable].rstable" + i).length > 0;
|
||
}
|
||
<% } %>
|
||
if (!prevent_badge_reset) {
|
||
FcltMgr.setSubtabExtra("<%=safe.jsstring(badgehtml)%>");
|
||
}
|
||
</script>
|
||
<% }
|
||
return -1;
|
||
}
|
||
else
|
||
{
|
||
%> <script>
|
||
FcltMgr.setSubtabExtra("");
|
||
</script>
|
||
<% }
|
||
|
||
|
||
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<tbody>";
|
||
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 += "</tbody>";
|
||
|
||
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 = "<a href='javascript:doOutput(0)'>";
|
||
}
|
||
else
|
||
{
|
||
a_element = "<a href='"
|
||
+ (inline // Voor inline details moet niet gehele window vervangen worden omdat je dan ook de hoofd regels kwijt bent (dan alleen de <td> cell vervangen)
|
||
? "javascript:loadInlineDetails(\""
|
||
+ safe.jsstring(Request.ServerVariables("SCRIPT_NAME") + "?showall=1" + transitQS())
|
||
+ "\");"
|
||
: safe.jsstring(Request.ServerVariables("SCRIPT_NAME") + "?showall=1" + transitQS()) + "' target='_self")
|
||
+ "'>";
|
||
}
|
||
a_element += L("lcl_qp_maxrows1").format(S("qp_maxrows")) + "</a>";
|
||
|
||
// Op regel klikken om de overige regels op te halen, boven de tabel
|
||
html = "<div id='rsMaxHistoryB'><span id='rsMaxHistoryInfoB'>"
|
||
+ (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"))
|
||
)
|
||
+ "</span></div>" + 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<div id='multiactiondiv'><span id='multilabel'>" + safe.html(L("lcl_with_selected").format(0)) + "</span>";
|
||
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 += "<span onClick='javascript:doMulti(\"" + this.ID + "\", \"" +
|
||
actions[i].action + "\", \"" +
|
||
safe.jsstring(actions[i].caption) + "\", " +
|
||
actions[i].multiOnce + ");" +
|
||
"FcltMgr.stopPropagation(event);' class='button footerbutton'>"+(actions[i].icon?I(actions[i].icon):"")+safe.html(actions[i].caption)+"</span>";
|
||
}
|
||
}
|
||
if (multiActions == 0)
|
||
appender += "<i style=\"padding-left: 9px\">" + L("lcl_no_multi_actions") + "</i>";
|
||
appender += "</div>";
|
||
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 += "<tr><td class='rsfooter' colspan=" + (columns.length + flexColumns + ((useHamburger && hasInlineActions) ? 1 : 0) + (!isPrinting && !isExcel && anyMultiActions && !inline? 1 : 0) + (inlineDetails? 1 : 0)) + ">" + appender + "</td></tr>";
|
||
}
|
||
|
||
if (htmlFoot != "")
|
||
htmlFoot = "<tfoot>" + htmlFoot + "</tfoot>";
|
||
|
||
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 = "<a href='javascript:doOutput(0)'>";
|
||
}
|
||
else
|
||
{
|
||
a_element = "<a href='"
|
||
+ (inline // Voor inline details moet niet gehele window vervangen worden omdat je dan ook de hoofd regels kwijt bent (dan alleen de <td> cell vervangen)
|
||
? "javascript:loadInlineDetails(\""
|
||
+ safe.jsstring(Request.ServerVariables("SCRIPT_NAME") + "?showall=1" + transitQS())
|
||
+ "\");"
|
||
: safe.jsstring(Request.ServerVariables("SCRIPT_NAME") + "?showall=1" + transitQS()) + "' target='_self")
|
||
+ "'>";
|
||
}
|
||
a_element += L("lcl_qp_maxrows1").format(S("qp_maxrows")) + "</a>";
|
||
|
||
// Op regel klikken om de overige regels op te halen, onder de tabel
|
||
html = "\n<div id='rsMaxHistoryE'><span id='rsMaxHistoryInfoE'>"
|
||
+ (cnt <= S("qp_maxrows") + nrOutOfFilter
|
||
? a_element
|
||
: L("lcl_qp_maxrows2").format(S("qp_maxrows2"))
|
||
)
|
||
+ "</span></div>";
|
||
|
||
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)? "<span class='summaryincomplete'>" + L("lcl_suminfo_incomplete") + "</span> " : "") + (summaryShow(rowNum) || "");
|
||
}
|
||
if (!this.noSetSummary)
|
||
{
|
||
%> <script>
|
||
setSummary("<%=safe.jsstring(summaryInfo)%>");
|
||
var do_sum_lines = false;
|
||
<% if (this.rstableNr && this.rstableNr > 1)
|
||
{ %>
|
||
for (var i = <%=this.rstableNr-1%>; i && !do_sum_lines; i--) {
|
||
do_sum_lines = $("[id=rstable].rstable" + i).length;
|
||
}
|
||
<% } %>
|
||
FcltMgr.setSubtabLines(<%=rowNum%>, { add: do_sum_lines, hasMore: <%=(!oRs.EOF || this.hasMore) ? "true" : "false"%> });
|
||
</script>
|
||
<% }
|
||
|
||
// 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 != "")
|
||
{
|
||
%>
|
||
<div id="rsEndText">
|
||
<span id="rsEndTextInfo"><%=endTextInfo%></span>
|
||
</div>
|
||
</div>
|
||
<%
|
||
}
|
||
}
|
||
|
||
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 = "<div id='rstable' class='rstable" + this.rstableNr + "'>";
|
||
html += "<table cellspacing='0' cellpadding='0' ";
|
||
|
||
if (getQParamInt("noqfilter", 0) == 1)
|
||
html += " noqfilter='1'";
|
||
|
||
if (isPrinting == true) {
|
||
html += " isPrinting='TRUE' ";
|
||
}
|
||
|
||
if (ID != null)
|
||
html += " ID='" + ID + "' ";
|
||
if (tableClassName != null)
|
||
html += " class='" + tableClassName + "' ";
|
||
html += ">";
|
||
|
||
rowNum = 0;
|
||
}
|
||
return html;
|
||
}
|
||
|
||
function __rsMakeTableHeader(oRs, oRsFlexData, anyMultiActions)
|
||
{
|
||
var html = "";
|
||
with(this)
|
||
{
|
||
html += "\n<thead><tr>";
|
||
if (!isPrinting && !isExcel)
|
||
{
|
||
// ========= ACTIONS =========
|
||
// == zijn er multi ACTIONS?
|
||
if (anyMultiActions && !inline)
|
||
{
|
||
html += "<th class='multiselect sorttable_nosort'><input type=checkbox class='master' onclick='checkAll(\"" + ID + "\", this)'></th>";
|
||
}
|
||
if (useHamburger && hasInlineActions)
|
||
{
|
||
html += "<th class='sorttable_nosort'></th>";
|
||
}
|
||
if (inlineDetails)
|
||
{
|
||
html += "<th>"+I("fa-plus-square")+"</th>";
|
||
}
|
||
}
|
||
// ========= 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 += "<th>";
|
||
}
|
||
else
|
||
{
|
||
if (columns[i].hidden)
|
||
{
|
||
html += "<th style='display:none'>";
|
||
}
|
||
else
|
||
{
|
||
html += "<th";
|
||
if (columns[i].caption == p_autosortby)
|
||
{
|
||
html += " id='autosortbyme'";
|
||
}
|
||
var sort_class = "";
|
||
if (columns[i].datatype == "currency" ||
|
||
columns[i].datatype == "float" ||
|
||
columns[i].datatype == "number")
|
||
{
|
||
html += " style='text-align:right;'";
|
||
if (safe.curr(1.5).indexOf(",") == -1)
|
||
sort_class += " sortable_numeric";
|
||
else
|
||
sort_class += " sorttable_numericcomma";
|
||
}
|
||
else if (columns[i].datatype == "varchar" ||
|
||
columns[i].datatype == "html")
|
||
{
|
||
sort_class += " sorttable_alpha";
|
||
}
|
||
if (columns[i].align)
|
||
html += " style='text-align:" + columns[i].align + "'";
|
||
|
||
var theClass = sort_class
|
||
+ (columns[i].thClass ? " " + columns[i].thClass : "")
|
||
+ (columns[i].classList ? " " + columns[i].classList : "");
|
||
|
||
if (theClass != null && theClass != "")
|
||
html += " class='" + theClass + "' ";
|
||
if (inlineDetails)
|
||
html += " preSorttable='hideAllInlineDetails(\""+ID+"\")'";
|
||
var ctitle = columns[i].title == null ? "" : (" title='" + safe.htmlattr(columns[i].title) + "'");
|
||
html += ctitle + ">"
|
||
}
|
||
}
|
||
}
|
||
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 += "<br>";
|
||
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 += "<br>";
|
||
}
|
||
else
|
||
html += "</th>";
|
||
}
|
||
}
|
||
|
||
if (propertiesColumn == null)
|
||
// Nog header toevoegen voor de flexkenmerken.
|
||
html += addFlexKenmerkHeader(oRsFlexData, this);
|
||
|
||
html += "</tr></thead>";
|
||
}
|
||
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<tr");
|
||
|
||
var OddRowClass = ""; // was:(cnt & 1)? "O " : "E "; maar dat kan inmiddels met css clientside beter
|
||
|
||
if (suppressKeyRepeat)
|
||
if (lastRowKey!=thisKey)
|
||
OddRowClass += "firstRow ";
|
||
else
|
||
OddRowClass += "suppressRow ";
|
||
|
||
if (!isExcel)
|
||
{
|
||
if (rowClass)
|
||
appender += " class='" + OddRowClass + rowClass(oRs, this.processParams) + "' ";
|
||
else
|
||
appender += " class='" + OddRowClass + "' ";
|
||
}
|
||
|
||
if (keyColumn != null && !isPrinting && !isExcel)
|
||
{
|
||
appender += " ROWKEY='" + safe.htmlattr(this.myRs(keyColumn, oRs)) + "'";
|
||
}
|
||
if (!isPrinting && !isExcel && rowData != null)
|
||
appender += " ROWDATA='" + safe.htmlattr(rowData(oRs, this.processParams)) + "'";
|
||
|
||
if (!isPrinting && dblClick != null)
|
||
appender += " onDblClick='" + safe.htmlattr(dblClick) + "'";
|
||
|
||
if (!isPrinting && !isExcel && this.actions && this.actions.length)
|
||
{
|
||
if (!keyColumn)
|
||
INTERNAL_ERROR_ACTION_ZONDER_KEYCOLUMN; // dat kan niet echt, we hebben een ROWKEY nodig
|
||
|
||
if (rowActionEnabler)
|
||
var validator = rowActionEnabler(oRs, this.processParams);
|
||
|
||
var actionbits = "";
|
||
var noActionBit = "";
|
||
|
||
for (var i = 0; i < actions.length; i++)
|
||
{
|
||
if (actions[i].single === false || actions[i].onlyMulti) // triple '=' omdat undefined niet false mag zijn
|
||
{
|
||
// die negeren we altijd actionbits += "0";
|
||
continue; // niet ook nog inline
|
||
}
|
||
if (actions[i].enabler && validator && !validator[actions[i].enabler])
|
||
{
|
||
actionbits += "0";
|
||
noActionBit += "0";
|
||
continue; // niet enabled
|
||
}
|
||
actionbits += "1"; // Enabled
|
||
noActionBit += actions[i].isDefault ? "1" : "0";
|
||
actions[i].okformulti = true;
|
||
}
|
||
appender += " ACTIONBITS='" + safe.htmlattr(actionbits) + "'";
|
||
}
|
||
|
||
appender += (">");
|
||
|
||
// Het <TR> 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 += "<td class='multiselect'><input type=checkbox class='multiselect'" + (isChecked?' checked=1':'') + "></td>";
|
||
}
|
||
|
||
if (useHamburger && hasInlineActions)
|
||
{
|
||
|
||
if (actionbits == noActionBit) // No inline actions
|
||
{
|
||
appender += "<td></td>";
|
||
}
|
||
else
|
||
{
|
||
appender += "<td class=\"hambCont\"><div class=\"hamburger\">" + I("fa-bars fa-lg") + "</div></td>";
|
||
}
|
||
}
|
||
|
||
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 += "<td class='inlinedetails closed' onclick='return showInlineDetails(this, \"" + inlineDetails+"\")'" + ttl + ">"
|
||
+ (opdr_gewijzigd ? I("fa-square-exclamation") : I("fa-plus-square")) + "</td>";
|
||
}
|
||
else
|
||
appender += "<td>"+L("lcl_inlinecolumnnone")+"</td>";
|
||
}
|
||
|
||
// ========= 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 = "<img src='" + columns[i].image + "'";
|
||
if (val) imgval += " alt='" + safe.htmlattr(val) + "'";
|
||
val = 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 += "<td";
|
||
else
|
||
appender += "<td" + align + style + columnClass + customSort + nowrap;
|
||
if (isExcel && val != null && val.length > 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 <br> voor lege val
|
||
if (val != " " && val !== "" && colHasVal)
|
||
{
|
||
appender += "<br>"
|
||
}
|
||
else
|
||
appender = appender.replace(/\ \;$/,"") // "Vorige" er af strippen
|
||
}
|
||
|
||
if (!(isExcel && columns[i].hidden))
|
||
if (tooltip || clickaction) // show tooltip on field, not on <td>
|
||
appender += "<span " + tooltip + clickaction + ">" + val + "</span>";
|
||
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 += "<br>"; */
|
||
else
|
||
appender += "</td>";
|
||
|
||
// 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 += "</tr>";
|
||
// 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 += "<tr>";
|
||
if (!isPrinting && anyMultiActions && !inline) // Kolom i.v.m. checkboxje erbij voor 'select all'
|
||
html += "<td></td>";
|
||
if (hasInlineDetails && !isPrinting && !isExcel && inlineDetails)
|
||
html += "<td></td>"; // Kolom i.v.m. inlinedetails
|
||
if (useHamburger && hasInlineActions)
|
||
html += "<td></td>"; // 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 += "<td";
|
||
var sort_class = columns[i].thClass ? " " + columns[i].thClass : "";
|
||
if (sort_class != null)
|
||
html_f += " CLASS='" + sort_class + "' ";
|
||
// Uitlijning voor de kolom
|
||
var style = "";
|
||
var align = "";
|
||
if (totalColumnText && once && (i + 1) < columns.length && columns[i + 1].total)
|
||
style = "text-align: right;";
|
||
else 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;";
|
||
}
|
||
if (columns[i].hidden) style += "display: none;";
|
||
html_f += align + (style ? " style='" + style + "'" : "") + ">";
|
||
}
|
||
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 += "</td>";
|
||
}
|
||
}
|
||
|
||
// Nog extra kolom headers voor de flexkenmerken
|
||
// Flexkenmerken tonen bij isPrinting, isExcel of showProperties
|
||
if (this.printFlex && this.propertiesColumn == null)
|
||
{
|
||
html_f += "<td></td>";
|
||
}
|
||
|
||
html_f = balanceCloseTag("td", html_f);
|
||
|
||
html += html_f + "</tr>";
|
||
}
|
||
}
|
||
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 += "</"+tagname+">";
|
||
}
|
||
return chtml;
|
||
}
|
||
|
||
function __rsEndTable()
|
||
{
|
||
Response.Write("\n</table>");
|
||
Response.Write("\n</div> <!-- for DIV id='rstable' -->");
|
||
}
|
||
|
||
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<div id="printheader">');
|
||
Response.Write('\n<table id="head"><tr>');
|
||
Response.Write('\n<td align="left">');
|
||
Response.Write('<img alt="' + L("lcl_photos") + '" src="' + logo_fileName+ '"></TD>');
|
||
Response.Write('\n<td align="right">');
|
||
Response.Write('\n<table id="right">');
|
||
Response.Write('\n <tr><td colspan="2" id="titel">' + (this.title||"") + '</td></tr>');
|
||
Response.Write('\n <tr><td>' + L("lcl_name") + ' :</td><td>' + safe.html(user.naam()) + ' </td></tr>');
|
||
Response.Write('\n <tr><td>' + L("lcl_date") + ' :</td><td>' + toDateString(new Date()) + ' </td></tr>');
|
||
Response.Write('\n</table>');
|
||
Response.Write('\n</td>');
|
||
Response.Write('\n</tr></table>');
|
||
Response.Write('\n</div>');
|
||
}
|
||
|
||
function __rsEndPrint()
|
||
{
|
||
if (isPrinting)
|
||
{
|
||
var prtDate = toDateTimeString(new Date());
|
||
Response.Write('\n<div id="printfooter">');
|
||
Response.Write('\n<table id="foot"><tr>');
|
||
Response.Write( '\n<td>' + (this.title||"") + '</td>'); // deze this.title lijkt intussen verloren gegaan
|
||
Response.Write( '\n<td align="right">' + toDateTimeString(new Date()) + '</td>');
|
||
Response.Write( '\n</tr></table>');
|
||
Response.Write('\n</div>');
|
||
if (p_autosortby)
|
||
{
|
||
var sortfn = autosortbyrev?"sorttable.doSortRev":"sorttable.doSort";
|
||
Response.Write('<script>$(function () { if ($("#autosortbyme").length) { '+sortfn+'.apply($("#autosortbyme")[0]) };window.print() });</script>');
|
||
}
|
||
else
|
||
Response.Write('<script>window.print();</script>'); // 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 "<span title='{0}'>".format(safe.htmlattr(val)) + I("fa-eye fa-lg") + "</span>";
|
||
|
||
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 <br> naar \n vertaling niet kunnen hebben.
|
||
// Met <br> 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)
|
||
+ "<span class='rsTruncmore' " // Dubbel encoderen hieronder, anders html-injections was achter de Meer... mogelijk
|
||
+ " resttxt='" + safe.htmlattr(safe.html(fullval.substr(S("rs_maxchar") + spatie + 1))) + "'"
|
||
+ " title='" + L("lcl_rs_truncmore") + "'"
|
||
+ " onclick='return expandTruncate(event, this)'"
|
||
+ ">" + L("lcl_rs_truncated") + "</span>";
|
||
return safeval;
|
||
}
|
||
|
||
function ResultsetTable.prototype.myRs(fn, oRs)
|
||
{
|
||
if (fn instanceof Function)
|
||
{
|
||
return fn(oRs, this.processParams);
|
||
}
|
||
else
|
||
{
|
||
return oRs.Fields(fn).Value;
|
||
}
|
||
}
|
||
%>
|