Files
Facilitor/APPL/Shared/kenmerk_common.inc
Jos Groot Lipman 762ec4d0f4 Merge 2023.2 Gold A changes
svn path=/Website/trunk/; revision=61137
2023-07-11 11:45:25 +00:00

3869 lines
188 KiB
HTML
Raw Blame History

<% /*
$Revision$
$Id$
File: kenmerk_common.inc
Description:
Context: Used by /XX/kenmerk.inc
Note: Writes flex-props html edit/view code to Response object
Usage: listKenmerk must be called once with an SQL-statement that
fetches all kenmerk-information
The structure of tha SQL should match the predefined structure (column names)
*/
// FlexFiles.inc functie bepaalNiveau is altijd nodig dus FlexFiles.inc erbij
%><!-- #include file="../shared/FlexFiles.inc" -->
<%
// "jquery-ui.js" en "date.js" zijn alleen nodig als er een datumkenmerk is.
// meestal is die er toch al wel in het hoofdscherm dus voor het gemak doen
// we het hier ook maar voor overige schermen.
if (!this.JSON_Result)
FCLTHeader.Requires({ plugins:["jQuery", "kenmerk", "suggest"],
js: ["multi.js"] })
var requiredGroupUsed = new Array(); // Array zorgt voor eenmalige initiele aanroep van checkRequiredGroup(groep) per groep
var addPreview = false; // moet deze global?
var __insideblock = 0;
var clabelCounter = 0; // Het aantal collapsable labels (niet zeker of nog noodzakelijk)
var show_label_expr = {};
// Public function: read the kenmerk_key in case of <kenmerk> with refcode or value
function getKenmerkKeyByRef(kenmerkdomein_key, kenmerk_ref, kenmerk_waarde)
{
var kenmerk_key = parseInt(kenmerk_waarde, 10);
var fac_omschr_code;
var udf_omschr_code;
var ksql = "SELECT fac_kenmerkdomein_objectnaam, fac_kenmerkdomein_kolomnaam, fac_kenmerkdomein_kolomtxt, fac_kenmerkdomein_verval, fac_usrtab_key"
+ " FROM fac_kenmerkdomein"
+ " WHERE fac_kenmerkdomein_key = " + kenmerkdomein_key
+ " AND fac_kenmerkdomein_verwijder IS NULL";
var oRs_kd = Oracle.Execute(ksql);
if (!oRs_kd.eof)
{
switch (kenmerk_ref)
{
case "value":
udf_omschr_code = " WHERE UPPER(" + oRs_kd("fac_kenmerkdomein_kolomtxt").Value + ") = " + safe.quoted_sql_upper(kenmerk_waarde);
fac_omschr_code = " AND UPPER(fac_usrdata_omschr) = " + safe.quoted_sql_upper(kenmerk_waarde);
break;
case "code":
udf_omschr_code = " WHERE UPPER(" + oRs_kd("fac_kenmerkdomein_objectnaam").Value + "_CODE) = " + safe.quoted_sql_upper(kenmerk_waarde);
fac_omschr_code = " AND UPPER(fac_usrdata_code) = " + safe.quoted_sql_upper(kenmerk_waarde);
break;
default:
oRs_kd.Close();
return kenmerk_key;
}
var kenmerkdomein_verval = oRs_kd("fac_kenmerkdomein_verval").Value;
if (oRs_kd("fac_kenmerkdomein_objectnaam").Value == "FAC_USRDATA" && oRs_kd("fac_usrtab_key").Value)
{
ksql = "SELECT fac_usrdata_key"
+ " FROM fac_usrdata"
+ " WHERE fac_usrtab_key = " + oRs_kd("fac_usrtab_key").Value
+ fac_omschr_code
+ " AND (fac_usrdata_vervaldatum IS NULL OR fac_usrdata_vervaldatum > SYSDATE)"
+ " AND fac_usrdata_verwijder IS NULL";
}
else
{
ksql = "SELECT " + oRs_kd("fac_kenmerkdomein_kolomnaam").Value + " fac_usrdata_key"
+ " FROM " + oRs_kd("fac_kenmerkdomein_objectnaam").Value
+ udf_omschr_code
+ (kenmerkdomein_verval != null ? " AND ( " + kenmerkdomein_verval + " IS NULL OR " + kenmerkdomein_verval + " > SYSDATE)" : "");
}
}
var oRs_ud = Oracle.Execute(ksql);
if (!oRs_ud.eof)
kenmerk_key = String(oRs_ud("fac_usrdata_key").Value);
oRs_ud.Close();
oRs_kd.Close();
return kenmerk_key;
}
//
// Internal functions:
//
function kenmerk_write(s)
{
Response.Write(s);
}
// links aanvullen met 0
function pad(val, len)
{
if (typeof val != "string")
return val;
while (val.length < len)
val = "0" + val;
return val;
}
// levert .. eeh..
function get_kenmerkpath_params(path)
{
var path_params = {};
var path_arr = path.split("/");
if (path_arr.length > 2)
{
path_params.module = path_arr[0];
path_params.niveau = path_arr[1].replace(/\d+/g, "").replace(/_/g, "");
path_params.refkey = path_arr[2].replace(/\D/g,"");
if (path_arr[3])
path_params.kenmerkkey = path_arr[3];
}
return path_params;
}
// Tel/ zoek de bijlagen in een folder
// Resultaat: array met bijlagenamen
function BijlagenList(pModule, pNiveau, pKey, pKenmerk_key, otherKenmerk_path, pSortFilename)
{
if (pKey == -1 && otherKenmerk_path)
{
var kp_params = get_kenmerkpath_params(otherKenmerk_path);
pKenmerk_key = kp_params.kenmerkkey;
pKey = kp_params.refkey;
}
var from_table = true;
var lijst = ( from_table
? BijlagenListFromTable(pModule, pNiveau, pKey, pKenmerk_key, pSortFilename)
: BijlagenListFromPath(pModule, pNiveau, pKey, pKenmerk_key, otherKenmerk_path)
);
return lijst;
}
function BijlagenListFromPath(pModule, pNiveau, pKey, pKenmerk_key, otherKenmerk_path)
{
function listFromPath(pAttachPath)
{
var fso = Server.CreateObject("Scripting.FileSystemObject")
var vLijst = [];
if (pAttachPath)
__Log("Tellen in folder: " + pAttachPath);
if (pAttachPath && fso.FolderExists(pAttachPath))
{
var fso, f, f1, fc, s;
fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.GetFolder(pAttachPath);
fc = new Enumerator(f.files);
for (; !fc.atEnd(); fc.moveNext())
{
vLijst.push({ "name": fc.item().Name, "date": new Date(fc.item().DateLastModified), "size": fc.item().Size });
}
}
return vLijst;
}
function arrayUnique(a, b)
{ // Voeg 2 arrays samen en ontdubbel op basis van het veld name.
var c = a.concat(b);
for (var i=0; i<c.length; ++i)
{
for(var j=i+1; j<c.length; ++j)
{
if (c[i].name == c[j].name)
c.splice(j--, 1);
}
}
return c;
}
if (otherKenmerk_path)
{
var vAttachPath = S("flexFilesPath") + "/" + otherKenmerk_path + "/";
}
else
{
if (pKey > 0) // anders valt er niets te tellen
var vAttachPath = flexProps(pModule, pKey, String(pKenmerk_key), pNiveau).AttachPath + "/";
}
var lijst_1 = listFromPath(vAttachPath);
if (vAttachPath)
{
__Log("{0} bestanden gevonden in Path {1}.".format(lijst_1.length, vAttachPath));
}
// Zoek ook in de root (via fac_bijlagen)
var r_bijlagen = get_bijlagen(pModule, pKey, pKenmerk_key);
var lijst_2 = [];
if (r_bijlagen.length)
{
var vAttachPath = flexProps(pModule, r_bijlagen[0].refkey, String(r_bijlagen[0].kmkey), r_bijlagen[0].niveau).AttachPath + "/";
lijst_2 = listFromPath(vAttachPath);
__Log("{0} bestanden gevonden in Path {1}.".format(lijst_2.length, vAttachPath));
}
// Verwijder dubbele bestanden.
var lijst = arrayUnique(lijst_1, lijst_2);
__Log("{0} bestanden gevonden in Path.".format(lijst.length));
return lijst;
}
function BijlagenListFromTable(pModule, pNiveau, pKey, pKenmerk_key, pSortFilename)
{
function compareValue(order_by_filename)
{
return function innerSort(a,b)
{
if (order_by_filename)
{
var c = 0;
if (a.name.toUpperCase() > b.name.toUpperCase())
c = 1;
else if (a.name.toUpperCase() < b.name.toUpperCase())
c = -1;
return c;
}
else
{
return new Date(a.date) - new Date(b.date);
}
}
}
var lijst = [];
if (pKey > 0)
{
lijst = get_bijlagen(pModule, pKey, pKenmerk_key, null, pNiveau);
lijst.sort(compareValue(pSortFilename));
__Log("{0} bestanden gevonden in Table.".format(lijst.length));
}
return lijst;
}
// debug functie die vergelijkt wat op schijf staat versus in fac_bijlagen
function match_fac_bijlagen(pModule, pKey, pKenmerk_key, pNiveau, otherKenmerk_path)
{
// if (Application("JGL") != "1" || (!pKey > 0))
// return "";
var JGLerrors = [];
var filesystem_lijst = BijlagenListFromPath(pModule, pNiveau, pKey, pKenmerk_key, otherKenmerk_path);
if (pKey == -1 && otherKenmerk_path)
{ // Bij kopieren van melding naar opdracht moeten de bestanden bij de melding worden gezocht.
var kp_params = get_kenmerkpath_params(otherKenmerk_path);
pKenmerk_key = kp_params.kenmerkkey;
pKey = kp_params.refkey;
}
var lijst2 = BijlagenListFromTable(pModule, pNiveau, pKey, pKenmerk_key); // Deze kijkt welke bijlagen in de tabel fac_bijlagen staan
for (var i = 0; i < filesystem_lijst.length; i++)
{
var name = filesystem_lijst[i].name;
for (var j = 0; j < lijst2.length; j++)
{
if (lijst2[j].name == filesystem_lijst[i].name)
{
lijst2[j].name = null;
break;
}
}
if (j == lijst2.length)
JGLerrors.push(L("lcl_fac_bijlagen_notregistered").format(filesystem_lijst[i].name))
}
for (var j = 0; j < lijst2.length; j++)
{
if (lijst2[j].name)
{
JGLerrors.push(L("lcl_fac_bijlagen_notfound").format(lijst2[j].name))
}
}
if (JGLerrors.length)
{
__Log(">>>MATCH_FAC_BIJLAGEN");
var msg = "Errors (LOG only) m:{0} N:{1} K:{2} KK:{3}".format(pModule, pNiveau, pKey, pKenmerk_key);
__Log(msg);
__Log(JGLerrors.join("\n"));
__Log("<<<");
return JGLerrors.join("<br>");
}
else
return "";
}
function BijlagenButton(tfield, tprops, tparams)
{ // Module is 'R' voor ruimte, 'M' voor melding enz
// key is de object key
// Parameter tfield.otherPath is null of bevat het pad van het kenmerk waarvan we
// in een veel later stadium (saveFlexKenmerken) de folder kopieren (order onder melding)
// of moven (wijzigen type stdmelding of type opdracht)
// Als die is meegegeven en er zitten bestanden in de folder dan wordt de knop
// vooralsnog read-only
/* Bestanden zijn nu te vinden in ...cust/X/flexfiles/[module]/[key]/[kenmerk_key] */
// verschillende situaties voor kopieren van bijlagen van melding naar opdracht, opdracht naar opdracht en melding/opdracht naar meerdere opdrachten
// #63784 en #63771
var lijst = [];
var kenmerk_key = tfield.kkey;
if (tparams.module == "MLD")
{
if (tprops.copy)
{ // De uitzonderingen zitten in meldingen en opdrachten.
// Voor andere modules kan er 1 op 1 gekopieerd worden.
if (tprops.niveau == "M")
{ // Melding naar melding
lijst = BijlagenList(tparams.module, tprops.niveau, tparams.pkey, kenmerk_key, tfield.otherPath, tprops.sortFilename);
}
else if (tfield.otherPath) // tprops.niveau == "O"
{ // Opdracht naar opdracht
var sql = "SELECT mld_typeopdr_key"
+ " FROM mld_opdr"
+ " WHERE mld_opdr_key = " + tprops.parentKey;
var oRs = Oracle.Execute(sql);
var old_typeopdr_key = oRs("mld_typeopdr_key").Value;
oRs.Close();
var actual_kenmerk_key = kenmerk_key; /* Deze is mogelijk anders als we van opdr-type wijzigen */
if (old_typeopdr_key != tprops.opdr_type)
{
sql = "SELECT k2.mld_kenmerk_key"
+ " FROM mld_kenmerk k1,"
+ " mld_kenmerk k2,"
+ " mld_srtkenmerk sk1,"
+ " mld_srtkenmerk sk2"
+ " WHERE k1.mld_srtkenmerk_key = k2.mld_srtkenmerk_key"
+ " AND k1.mld_srtkenmerk_key = sk1.mld_srtkenmerk_key"
+ " AND k2.mld_srtkenmerk_key = sk2.mld_srtkenmerk_key"
+ " AND COALESCE (k1.mld_kenmerk_omschrijving, sk1.mld_srtkenmerk_omschrijving) ="
+ " COALESCE (k2.mld_kenmerk_omschrijving, sk2.mld_srtkenmerk_omschrijving)"
+ " AND sk1.mld_srtkenmerk_kenmerktype = sk2.mld_srtkenmerk_kenmerktype" // Toch wel op z'n minst
+ " AND k1.mld_kenmerk_key = " + kenmerk_key
+ " AND k1.mld_typeopdr_key = " + tprops.opdr_type
+ " AND k2.mld_typeopdr_key = " + old_typeopdr_key;
var oRs = Oracle.Execute(sql);
if (oRs.EoF)
actual_kenmerk_key = -1; // Dan weet ik het ook niet
else
{
actual_kenmerk_key = oRs("mld_kenmerk_key").Value;
oRs.MoveNext();
if (!oRs.EoF) // Dan hebben we schijnbaar geen unieke gevonden -> foute configuratie
actual_kenmerk_key = -1;
}
oRs.Close();
}
if (actual_kenmerk_key > 0)
lijst = BijlagenList(tparams.module, tprops.niveau, tparams.pkey, actual_kenmerk_key, tfield.otherPath, tprops.sortFilename);
}
}
else if (tprops.srtkm_list && tprops.srtkm_list.length > 0)
{
for (var i=0; i<tprops.srtkm_list.length; i++)
{
var v_srtkm = tprops.srtkm_list[i];
var mld_parent_lijst = BijlagenList(tparams.module, tprops.niveau, v_srtkm.mld_key, [v_srtkm.km_key], tfield.otherPath);
lijst = lijst.concat(mld_parent_lijst);
}
}
else
{ // Melding naar opdracht
// Alleen de mappen met bijlagen toevoegen die we nog niet eerder hebben toegevoegd.
if (tfield.kenmerktype != "M" || !tfield.otherPath || !inArray(tfield.otherPath, tparams.attach_km_list))
{ // In workflow ook alle bijlage kenmerken ophalen van voorgaande meldingen,
// voor zover deze gewenst zijn.
var km_arr = [kenmerk_key];
if (tprops.parent_list && tprops.parent_list.length > 0)
{
for (var i=0; i<tprops.parent_list.length; i++)
{
var v_parent = tprops.parent_list[i];
if (v_parent.km_key && v_parent.km_key.length > 0)
{
for (var j=0; j<v_parent.km_key.length; j++)
{
km_arr.push(v_parent.km_key[j]);
}
}
}
}
lijst = BijlagenList(tparams.module, tprops.niveau, tparams.pkey, km_arr, tfield.otherPath);
}
}
}
else // Voor alle andere modules
{ // Bij kopieren van bijlagen bij opdracht niet naar specifieke kenmerk zoeken.
kenmerk_key = ((tfield.kkenmerktype == "M" && tprops.copy) ? -1 : tfield.kkey);
lijst = BijlagenList(tparams.module, tprops.niveau, tparams.pkey, kenmerk_key, tfield.otherPath, tprops.sortFilename);
}
// var mismatchtekst = match_fac_bijlagen(tparams.module, tparams.pkey, kenmerk_key, tprops.niveau, tfield.otherPath);
var mismatchtekst = "";
var anyPreview = false;
var fileChecked = ( tparams.pkey == -1 ? S("mld_copy_order_attachment_from_call") : true);
var requiredfield = (tfield.required ? tparams.required_class : "");
if (tfield.readonlyfield || (tfield.otherPath && lijst.length > 0))
{ // Indien readonly en lijst.length = 0 dan hoeft het kenmerk (net als bij andere kenmerken) helemaal niet getoond te worden.
var filehtmlarr = [];
var max_attach = S("fac_max_initial_attachments");
var regex = new RegExp(S("flexPreviewExt"), 'i');
if (tfield.otherPath) {
var otherKenmerk_arr = tfield.otherPath.split("/");
var otherKenmerk_key = otherKenmerk_arr.length ? otherKenmerk_arr[otherKenmerk_arr.length - 1] : -1;
}
var attach_counter = 0;
for (var file in lijst)
{
++attach_counter;
if (tfield.kkenmerktype == "M") {
var kmCode = function(text, no_file) { return tprops.nameprefix + tfield.idCounter + text + (no_file? "" : file); }
var km_val = kmCode('val', true);
} else {
var kmCode = function(text) { return tprops.nameprefix + tfield.idCounter + text; }
var km_val = kmCode('val');
}
var html = (tfield.otherPath
? '<input type="checkbox" class="fldCflexN" '
+ (fileChecked ? " checked" : "")
+ (tfield.readonlyfield ? " disabled" : "" )
+' controlgroup="'+kenmerk_key+'" id="' + kmCode('val') + '" name="' + kmCode('val') + '">'
+ '<label for="' + kmCode('val') + '">'+safe.html(lijst[file].name)+'</label>'
+ (tfield.kkenmerktype == "M"
? '<input type="hidden" id="has_' + kmCode('val') + '" name="has_' + kmCode('val') + '" value="1">'
+ '<input type="hidden" id="' + kmCode('file') + '" name="' + kmCode('file') + '" value="' + safe.html(lijst[file].name) + '">'
: '')
: '');
//var html = "<a href='" + safe.htmlattr(href) + "' target='_new'>" + safe.html(lijst[file]) + "</a>";
if (tfield.readonlyfield && !tfield.otherPath)
{
if (tfield.kdimensie == "xxx")
{
var href = protectQS.create(OpenFlexFile(tparams.module, lijst[file].key, { mime_type: "image/png", contentdp: "inline" }));
html += "<img alt='" + safe.htmlattr(L("lcl_flex_preview")) + "' class='preview kenmerk' src='" + safe.htmlattr(href) + "'"
+ " onclick='FcltMgr.windowopen(\"" + safe.jsstring(href) + "\")'>"
+ "<span class='flexsize'>{0}</span>".format(toDateTimeString(lijst[file].date));
}
else
{
var href = protectQS.create(OpenFlexFile(tparams.module, lijst[file].key));
html += '<span class="details ' + (max_attach > 0 && attach_counter > max_attach? km_val + " hide-more hidden" : "") + '" readonly=1 title="{0} kB"'.format(Math.round(lijst[file].size / 1024))
+ ' onclick=\'FcltMgr.windowopen("' + safe.jsstring(href) + '", "File")\'>' + safe.html(lijst[file].name) + '</span>'
+ ' <span class="flexsize ' + (max_attach > 0 && attach_counter > max_attach? km_val + " hide-more hidden" : "") + '">{0}</span>'.format(toDateTimeString(lijst[file].date));
}
if (regex.test(lijst[file].name)) {
anyPreview = true;
}
}
filehtmlarr.push(html);
}
function checkCheckbox(event) {
$("#has_" + $(event.target).attr("id")).val($(event.target).is(":checked") ? "1" : "0");
if ($(event.target).closest("div").hasClass("required"))
{
$("[controlgroup=" + $(event.target).attr("controlgroup") + "]").attr("disabled", false);
var arr = $("[controlgroup=" + $(event.target).attr("controlgroup") + "]:checked");
if (arr.length == 1)
{
event.preventDefault();
$(arr[0]).attr("disabled", true);
$(arr[0]).attr("checked", true);
}
}
}
var frm = '';
var res = '';
if (filehtmlarr.length)
{
var res = "<div>" + filehtmlarr.join("<br>")
if (max_attach > 0)
{
res += '<div class="' + km_val + ' show-more-container" style="display: none">'
+ ' <div class="' + km_val + ' show-more"><span class="details">'+L("lcl_more")+'</span></div>'
+ ' <div class="' + km_val + ' show-less hidden"><span class="details">'+L("lcl_less")+'</span></div>'
+ '<script>$(function(){ '
+ ' $("span.' + km_val + '.hide-more").next("br").toggleClass("hidden invisible");'
+ ' $("div.' + km_val + '.show-more-container").toggle(' + lijst.length + ' > ' + max_attach + ');'
+ (lijst.length > max_attach ? 'FcltMgr.resized(window);' : '') /* Want ik heb zojuist getoggled */
+ ' $("div.' + km_val + '.show-more, div.' + km_val + '.show-less").off().on("click", function() { '
+ ' $("div.' + km_val + '.show-more, div.' + km_val + '.show-less, span.' + km_val + '.hide-more").toggleClass("hidden");'
+ ' $("span.' + km_val + '.hide-more").next("br").toggleClass("hidden");'
+ ' FcltMgr.resized(window);'
+ ' });'
+ ' });'
+ '</script>';
}
res += "</div>";
if (tfield.otherPath)
{
res += '<input type="hidden" name="' + tprops.nameprefix + tfield.idCounter + 'key" id="' + tprops.nameprefix + tfield.idCounter + 'key" value="' + kenmerk_key + '">'
+ '<input type="hidden" name="' + tprops.nameprefix + tfield.idCounter + 'other_key" id="' + tprops.nameprefix + tfield.idCounter + 'other_key" value="' + (otherKenmerk_key || -1) + '">'
+ '<input type="hidden" name="' + tprops.nameprefix + tfield.idCounter + 't" id="' + tprops.nameprefix + tfield.idCounter + 't" value="' + tfield.kkenmerktype + '">';
}
res += "</div>";
if (tfield.otherPath)
res += '<script>$(function(){ $("[controlgroup='+kenmerk_key+']").on("change", '+checkCheckbox+').change();});</script>';
}
if (mismatchtekst)
{
var msg = "";
res += "<div style='color:red'>{0}<br>{1}</div>".format(msg, mismatchtekst);
}
}
else
{ // De formUrl
if (tfield.kdimensie == "xxx")
var url = rooturl + "/appl/" + (tprops.mobile ? "pda" : "shared") + "/BijlagenSignature.asp"
else
var url = rooturl + "/appl/shared/BijlagenForm.asp"
url += "?module=" + tparams.module
+ "&key=" + tparams.pkey
+ (tprops.niveau != ""? "&niveau=" + tprops.niveau : "")
+ "&kenmerk_key=" + tfield.kkey
+ (tprops.kenmerk_module? "&kenmerk_module=" + tprops.kenmerk_module : "");
if (tfield.kdimensie)
url += "&extFilter=" + escape(tfield.kdimensie);
if (tfield.kregexp)
url += "&pregexp=" + escape(tfield.kregexp); // P800x600 voor foto van 800x600
if (tfield.kkenmerktype == "E")
url += "&encrypt=1";
if (tprops.copy || tparams.pkey < 0)
url += "&tmpfolder=" + tprops.tmpfolder;
if (tfield.kkenmerktype == "M") {
if (tfield.kdimensie != "xxx") {
url += "&multi=1";
}
if (tfield.readonlyfield) {
url += "&reado=1";
}
}
// De saveUrl
if (tprops.parentKey > 0 && tfield.kkenmerktype != "M") // ![M]ap, dus [E]ncrypted of [F]ile
{ // Voor de zekerheid slaan we wijziging van de bestandsnaam direct op.
// op het filesysteem is het namelijk ook al 'gecommit'
tfield.saveUrl = rooturl + "/appl/shared/AjaxSaveFlex.asp";
if (tparams.module=="MLD" && tprops.niveau == "O")
tfield.saveUrl += "?module=OPDR";
else if (tparams.module=="FIN" && tprops.niveau == "R")
tfield.saveUrl += "?module=FINR";
else if (tparams.module=="RES" && tprops.extraserie) // Verbruiksartikelkenmerken
tfield.saveUrl += "?module=RESA";
else
tfield.saveUrl += "?module=" + tparams.module;
tfield.saveUrl += "&parentKey=" + tprops.parentKey;
tfield.saveUrl += "&kenmerkKey=" + tfield.kkey;
if (tprops.kenmerk_module)
tfield.saveUrl += "&kenmerk_module=" + tprops.kenmerk_module;
}
// De aan te roepen functie incl. argumenten
var func = tprops.mobile ? "onBijlagenMobile" : "onBijlagen"
var blg = func + "('" + safe.jsstring(protectQS.create(url)) + "'"
+ ",'" + (tfield.saveUrl ? safe.jsstring(protectQS.create(tfield.saveUrl)) : "") + "'"
+ ", " + (tfield.kkenmerktype == "M" ? "true" : "false") // multi
+ ", $('#" + tprops.nameprefix + tfield.idCounter + "val')[0]"
+ ");";
var res = "";
// Handtekening plaatje
if (tfield.kdimensie == "xxx") {
res += "<img alt='" + safe.htmlattr(L("lcl_flex_preview")) + "' class='preview kenmerk'"
+ " onClick='" + safe.htmlattr(blg) + "'";
if (lijst.length) {
res += " src=' " + protectQS.create(OpenFlexFile(tparams.module, lijst[0].key, { mime_type: "image/png", contentdp: "inline" }));
}
res += "'>";
}
// Tekst op de button
var btn_descr = L("lcl_add");
if (tfield.kkenmerktype == "M") {
btn_descr = L("lcl_appendixes_teller").format(lijst.length);
} else if (tfield.kdimensie != "xxx" && lijst.length) {
btn_descr = lijst[0].name;
if (btn_descr.length > 28) { // Dit past zo'n beetje
btn_descr = btn_descr.slice(0, 12)
+ "..."
+ btn_descr.slice(-12);
}
}
// Icoontje op de button
var btn_icon;
if (tfield.kdimensie == "xxx") {
btn_icon = I("fa-file-signature");
} else if (tfield.kkenmerktype == "M") {
btn_icon = I("fa-folder-open");
} else if (tfield.kkenmerktype == "F") {
btn_icon = I("fa-file");
} else if (tfield.kkenmerktype == "E") {
btn_icon = I("fa-file-lock");
}
// De button
if (tprops.mobile) { // Alleen handtekening doen we hier, andere mobile bijlagen gaan via mobileBijlagen()
var cls = "bijlage1 button signature";
cls += (tfield.isSqlExpr ? " flexsql" : "")
cls += (tfield.isExpression ? " expression " + (tfield.isShowExpr ? "flexshow" : "flexexpr") : "")
cls += (tfield.required ? tparams.required_class : "");
res += BUTTON_HTML(btn_descr, {
"dataicon": "fa fa-file-signature",
"id": tprops.nameprefix + tfield.idCounter + "val",
"cls": cls,
"click": blg,
"attributes": {
"isBijlage": "1",
"nBijlagen": lijst.length
}
});
res = "<div>" + res + "</div>"; // Wrap in divje om conditionele zichtbaarheid makkelijker te kunnen togglen
} else {
res += "<span class='flex-bijlage button-icon-wrapper'>"
+ "<input type='button' isBijlage='1' nBijlagen='" + lijst.length + "' "
+ " id='" + tprops.nameprefix + tfield.idCounter + "val'"
+ " class='button " + (tfield.isExpression? " expression " + (tfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ (tfield.kdimensie == "xxx" ? " signature" : "") + " " + requiredfield + "'"
+ " value='" + safe.htmlattr(btn_descr) + "'"
+ " onClick='" + safe.htmlattr(blg) + "'"
+ (!tfield.readonlyfield ? " onChange='checkKenmerk(this, false,\"" + tfield.kkenmerktype + "\",0,0,0,0)'" : "") // Bij bijlage button heb je geen requiredbyemptyval nodig.
+ ">"
+ "<span class='endicon'>" + btn_icon + "</span>"
+ "</span>";
}
// Hidden field to store filename in kenmerk-table (F/E only)
if (!tfield.saveUrl && tfield.kkenmerktype != "M") { // saveUrl doet dit zelf al
res += "<input type='hidden' name='" + tprops.nameprefix + tfield.idCounter + "val' value='" + (lijst.length ? lijst[0].name : "") + "'>";
}
}
return { html: res, count: lijst.length, addPreview: anyPreview, kotherkey: (lijst.length ? lijst[0].kmkey : -1) };
}
function Operand(n)
{
ret_str = "<select class='operand' id='ko" + n + "' name='ko" + n + "'>"
+"<option value='='>=</option> "
+"<option value='&lt;&gt;'>&lt;&gt;</option> "
+"<option value='&lt;'>&lt;</option>"
+"<option value='&gt;'>&gt;</option>"
+"<option value='&lt;='>&lt;=</option>"
+"<option value='&gt;='>&gt;=</option>"
+"<option value='LIKE'>"+L("lcl_operand_like")+"</option>"
+"<option value='NOT LIKE'>"+L("lcl_operand_notlike")+"</option>"
+"<option value='IS NOT NULL'>"+L("lcl_operand_notnull")+"</option>"
+"<option value='IS NULL'>"+L("lcl_operand_null")+"</option>"
+"</select>";
return ret_str;
}
function getDatatypeValue(table, column, checkval)
{
var tsql = "SELECT data_type"
+ ", data_length"
+ ", data_precision"
+ ", data_scale"
+ " FROM user_tab_columns"
+ " WHERE table_name = " + safe.quoted_sql_upper(table)
+ " AND column_name = " + safe.quoted_sql_upper(column);
var oRs_t = Oracle.Execute(tsql);
if (oRs_t("data_type").Value == "NUMBER")
{
if (!oRs_t("data_scale").Value || oRs_t("data_scale").Value > 0)
suggestval = parseFloat(checkval) || 0;
else
suggestval = parseInt(checkval) || 0;
}
else if (oRs_t("data_type").Value == "VARCHAR2")
{
suggestval = safe.quoted_sql(checkval);
}
else
{
suggestval = safe.quoted_sql(checkval);
}
oRs_t.close();
return suggestval;
}
// evaluate an expression, returns evaluation outcome
// [table] can be "melding" or "opdr"
var evaluateExpression = function (key, value, table)
{
var index;
var arr_match;
var evaluation;
var arr_flexfields;
var arr_words;
var arr_expression = [];
if (!!value && value.indexOf("##SHOW## ") != -1)
{
arr_expression = value.split("##SHOW## ");
}
else if(!!value && value.indexOf("##EXPR## ") != -1)
{
arr_expression = value.split("##EXPR## ");
}
// no expression present
if (arr_expression.length == 0) {
return true;
}
// a length other then 2 is false
if (arr_expression.length != 2)
{
return false;
}
// split the expression by :flex
arr_flexfields = arr_expression[1].split(":flex");
for (index=1; index < arr_flexfields.length; index++)
{
// replace the :flex pointer with a select statement
arr_match = arr_flexfields[index].match(/[^0-9]/);
if (arr_match)
{
arr_words = arr_flexfields[index].split(arr_match[0]);
}
// flex key value only
else
{
arr_words = [arr_flexfields[index]];
}
arr_words[0] = "(SELECT mld_kenmerk" + table + "_waarde"
+ " FROM mld_kenmerk" + table
+ " WHERE mld_" + table + "_key = " + key
+ " AND mld_kenmerk_key = " + arr_words[0] + ")";
// recombine the condition where each flex pointer is replaced with a SELECT statement(s)
if (arr_match)
{
arr_flexfields[index] = arr_words.join(arr_match[0]);
}
else
{
arr_flexfields[index] = arr_words[0];
}
}
var oRs_flex = Oracle.Execute("SELECT (" + arr_flexfields.join("") + ") value FROM dual");
if (oRs_flex.Eof)
{
oRs_flex.Close();
return false;
}
evaluation = oRs_flex("value").Value;
oRs_flex.Close();
return evaluation;
}
// evaluate an OPDR expression, returns evaluation outcome
var evaluateOpdrExpression = function (key, value)
{
return evaluateExpression(key, value, "opdr");
}
// evaluate a show expression, returns evaluation outcome which can be interpreted as a truthy/falsy value
var showIsVisible = function (key, value, table)
{
var exprOutcome = evaluateExpression(key, value, (table || "melding"));
if (typeof exprOutcome == "date") { // Een Oracle date evalueert naar 'falsy', dat is voor ons doel onterecht
exprOutcome = true; // Een javascript datum is trouwens van type 'object' en [new Date() instanceof Date === true]
}
return exprOutcome;
}
// Formatteert de bepaalde flexwaarde tot een html-fragment
// ik wil eigenlijk een structuur die het mobile ook net zo doet, of minstens goed nadenken en hier beschrijven wat de structuren zijn
function kv2html(pfield, pparams)
{
var kvhtml = "";
// Bloktitel's en Nieuwe secties doen we niks meer aan, die zijn goed zoals ze zijn.
if (pfield.kkenmerktype == "l" || pfield.kkenmerktype == "Q")
// hidden when ishidden
return (pfield.ishidden ? '<div class="hidden"></div>' : pparams.kv);
if (pparams.kv != "")
{
// Schrijf eventueel een tabelregel begin
if (((pparams.colCount&1) || pparams.forceNewLine || !pparams.kenmerk_2col) && !pparams.props.mobile && !pparams.props.notr)
{
var cls = "trlabel {0}flex{1} ".format(pparams.module, pfield.kvolgnr);
if (pfield.kkenmerktype == "L")
cls += "flexlabel";
if (pfield.ishidden ||
(pparams.isParent && pparams.props.reado && (!pfield.kwaarde || pfield.kwaarde == ""))) // Hide een leeg parent kenmerk in de show mode (RWSN#68678).
cls += " hidden";
kvhtml += ("<tr" + (pfield.kkenmerktype == "L"
? ' id="'+pparams.props.nameprefix+'clabel' + pparams.clabelCounter + '"'
: ''
)
+ ' class="' + cls + '"'
+ ">"); // Nu altijd zichtbaar in popup dmodal scherm
}
// Schrijf een tabelcell met het label
if (pparams.makeCheckbox && pparams.props.mobile) // Zie commentaar iets verderop
pparams.props.label_colspan = 2;
if (pparams.props.wfbuilder) // Workflow Expression Builder
kvhtml += ("<td>:flex{0}</td>".format(pfield.kkey));
var hashint = (pfield.khint ? " hashint" : "");
var haspreview = (pparams.addPreview ? " haspreview" : "");
var nohint = (pfield.kdefault ? "" : " nohint");
if (!pparams.props.mobile && !pparams.props.nolabel)
kvhtml += ('\n <td class="label' + hashint + haspreview + nohint
+ (pfield.kkenmerktype == 'L' ? ' flexlabel' : '')
+ ((pfield.kkenmerktype == 'C' && pfield.klengte > 50 && !pparams.props.kenmerk_search && !pfield.maskeren) ? ' textarea' : '') // readonly mag van mij ook wel
+ (pparams.props.kenmerk_search? ' flexsearch' : '') + '"'
+ (pparams.props.label_colspan? ' colspan=' + pparams.props.label_colspan : '') + '>');
if (pparams.props.mobile && pfield.kkenmerktype == 'L')
kvhtml += '<div class="fldflexl ui-bar">';
if (!pparams.props.nolabel && !pfield.ishidden)
{
if (S("fac_html_strictness") == 0)
var safe_oms = pfield.komschrijving;
else
var safe_oms = safe.html(pfield.komschrijving); // strict mode
if (pparams.props.mobile && pfield.kkenmerktype == 'L') safe_oms = "<h2>"+safe_oms+"</h2>";
kvhtml += ('\n <label for="' + pparams.props.nameprefix + pfield.idCounter + 'val" >' + safe_oms + (pparams.label_ext ? " "+pparams.label_ext : "") + pfield.separator
+ ( (pfield.kdimensie != null && pfield.kdimensie != "xxx")
? " [" + pfield.kdimensie + "]"
: ""
)
+ (pparams.props.mobile ? '' : '</label>') // info and preview icon inside label for mobile
+ '<span class="'
+ (pparams.addPreview ? 'labelextra details' : '')
+ (pfield.kkenmerktype == 'L' ? ' flexlabellabel' : '')
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression ? ' expression ' + (pfield.isShowExpr ? "flexshow" : "flexexpr") : '') + '">'
+ (pparams.addPreview ? '<span class="preview" id="p'+pfield.idCounter+'" title="'+L("lcl_flex_preview")+'">' + I("fa-image fa-lg") + '</span>' : '')
+ (pfield.khint == null ? '' : '<span class="hint" '
+ (pparams.props.mobile ? 'onClick="FcltMgr.alert(\'' + safe.jsstring(pfield.khint) + '\')"' : 'data-title="' + safe.htmlattr(pfield.khint) + '"') + '>' + I("fa-question-circle") + '</span>')
+ '</span>'
+ (pparams.props.mobile ? '</label>' : '')); // info and preview icon inside label for mobile
}
// labelwaardes (vaak invulinstructie) in apart te stylen span
if (!pfield.ishidden && pparams.props.mobile && pfield.kkenmerktype == "L" && pparams.kv)
{
kvhtml += '\n <span class="flexlabelvalue">' + pparams.kv + '</span>';
}
if (pparams.props.mobile && pfield.kkenmerktype == 'L')
kvhtml += '</div>';
// Bij mobile willen we de checkbox en zijn label in dezelfde ene TD hebben met colspan=2.
// jQuery voegt ze namelijk samen tot een enkel interface element en dat past niet altijd
// in de ene TD anders
if ((!pparams.makeCheckbox || !pparams.props.mobile) && !pparams.props.mobile) /* !pparams.makeCheckbox doet hier precies niets .. */
{
if (!pparams.props.nolabel)
kvhtml += ('</td>');
if (pparams.props.kenmerk_search && pfield.kkenmerktype != "L")
{
kvhtml += ('<td class="operand_td">');
kvhtml += (Operand(pfield.idCounter));
kvhtml += ('</td>');
}
kvhtml += ('\n <td ' + (pfield.kkenmerktype == "L"
? ' class="flexlabel lhint"'
: (pfield.readonlyfield ? ' class="readonly tabindex=-1 flexvalue"' : ' class="flexvalue"')
));
if (!pparams.props.kenmerk_search && pfield.kkenmerktype == "L"
&& typeof pparams.props.kenmerk_extraTD != "undefined" && pparams.props.kenmerk_extraTD)
kvhtml += (' colspan="2">'); // MLD_OPDR heeft TD-tje extra
else
kvhtml += (">");
if (pparams.props.nolabel && !pfield.ishidden)
kvhtml += ('\n <label for="' + pparams.props.nameprefix + pfield.idCounter + 'val">'
+ '<span title="' + safe.htmlattr(pfield.khint) + '">'
+ '</span></label>');
}
// Nu het eerder bepaalde waarde veld, zo nodig onderdrukt bij confidential-situatie
if (!pfield.ishidden && pfield.maskeren)
{ // nu verstop ik alles wat we hierboven bepaald hebben. Dat is wat lomp.
kvhtml += ("<span class='confidential'>"+ /* c_maskmarker + */ L("lcl_confidential")+"</span>");
if (pfield.kwaarde && (pfield.kkenmerktype == "F" || pfield.kkenmerktype == "E"))
kvhtml += "<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"val' id='"+pparams.props.nameprefix + pfield.idCounter+"val' value='" + safe.htmlattr(pfield.kwaarde) + "'>";
}
else if (pparams.props.mobile && pfield.ishidden)
{
kvhtml += ("<span style='display: none'>" + pparams.kv + "</span>") || "";
}
else
kvhtml += (pparams.props.mobile && pfield.kkenmerktype == "L") ? "" : pparams.kv || "";
if (typeof pparams.props.kenmerk_extraTD != "undefined" && pparams.props.kenmerk_extraTD && !pparams.props.mobile)
kvhtml += '\n </td><td>'; // Extra leeg celletje voor layout MLD_OPDR
if (pfield.kkenmerktype != "M" && pfield.kkenmerktype != "L" &&
((!pfield.maskeren && pfield.kwaarde && pfield.forceReadonly) || /* ik denk dat readonlyfield ipv forceReadonly gebruikt moet worden */
(!pfield.maskeren && pparams.hasAnyFlexExpr && !pparams.makeCheckbox && pfield.readonlyfield))) // in case the field triggers ##SHOW## expressions (checkbox excluded).
{
// hidden veld met de *echte* waardes zodat ze wel worden opgeslagen
kvhtml += "\n <input type='hidden' id='" + pparams.props.nameprefix + pfield.idCounter + "val' name='" + pparams.props.nameprefix + pfield.idCounter + "val' value='" + safe.htmlattr(pfield.kwaarde) + "'>";
}
if ((!pfield.maskeren &&
(pparams.props.kenmerk_search || !pfield.readonlyfield || (pfield.kwaarde && pfield.forceReadonly))) || /* ik denk dat readonlyfield ipv forceReadonly gebruikt moet worden */
(!pfield.maskeren && pparams.hasAnyFlexExpr && !pparams.makeCheckbox && pfield.readonlyfield)) // in case the field triggers ##SHOW## expressions (checkbox excluded)
{
// Alleen dan hidden name-velden er bij (Die van bloktitel worden in de functie zelf toegevoegd)
kvhtml += "\n<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"key' id='"+pparams.props.nameprefix + pfield.idCounter+"key' value='"+pfield.kkey+"'>";
kvhtml += "\n<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"count' id='"+pparams.props.nameprefix + pfield.idCounter+"count' value='"+pparams.kcount+"'>";
if (pparams.kcount > 1)
kvhtml += "\n<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"omsch' id='"+pparams.props.nameprefix + pfield.idCounter+"omsch' value='"+pfield.komschrijving+"'>";
kvhtml += "\n<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"t' id='"+pparams.props.nameprefix + pfield.idCounter+"t' value='"+pfield.kkenmerktype+"'>";
if (pfield.kkenmerktype == "F" || pfield.kkenmerktype == "E")
{
kvhtml += "\n<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"other_key' id='"+pparams.props.nameprefix + pfield.idCounter+"other_key' value='"+(pparams.kotherkey || -1)+"'>";
}
if (pfield.kkenmerktype == "C" || pfield.kkenmerktype == "N" || pfield.kkenmerktype == "B" || pfield.kkenmerktype == "V")
{
kvhtml += "<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"p' id='"+pparams.props.nameprefix + pfield.idCounter+"p' value='"+pfield.klengte+"'>";
if (pfield.kkenmerktype == "N" || pfield.kkenmerktype == "B" || pfield.kkenmerktype == "V")
{
kvhtml += "<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"d' id='"+pparams.props.nameprefix + pfield.idCounter+"d' value='"+pfield.kdec+"'>";
}
}
if (pfield.isExpression)
{
kvhtml += "<input type='hidden' name='"+pparams.props.nameprefix + pfield.idCounter+"e' id='"+pparams.props.nameprefix + pfield.idCounter+"e' value='"+ (pfield.isShowExpr ? 2 : 1) +"'>";
}
}
if (!pparams.props.mobile)
{
kvhtml += '</td>';
if (!((pparams.colCount&1) && pparams.kenmerk_2col) && !pparams.props.notr)
kvhtml += '\n</tr>';
}
/* Verplicht bij (sub)status afgerond moeten we clientside kunnen togglen */
if (pfield.reqbystatus == "52" && !inArray(pfield.kkenmerktype, ["B", "l", "L", "Q"]) && !pfield.readonlyfield && !pfield.maskeren)
{
var jQuery_selector = "#" + (pfield.kkenmerktype == "S" ? "Suggest" : "")
+ pparams.props.nameprefix + pfield.idCounter
+ (pfield.kkenmerktype == "S" ? "_show" : "val");
kvhtml += '<script>$("' + jQuery_selector + '").attr("data-required-completed", 1);</script>';
}
}
return kvhtml;
}
// libraryfunctie
function refvaluessql (tfield, tparams)
{
// The result is *the SQL statement* with 4 columns to optain:
// - the list of all (current) values, or
// - the current value
// in column order rkey, romschr, rvervaldatum, rxmlnode
// the rsxmlnode column is a convenient way to pass the knowledge to teh caller
var fsql ="";
var wheres = [];
var dsql = "SELECT fac_kenmerkdomein_omschrijving"
+ " , fac_kenmerkdomein_objectnaam"
+ " , fac_kenmerkdomein_kolomnaam"
+ " , fac_kenmerkdomein_kolomtxt"
+ " , fac_kenmerkdomein_xmlnode"
+ " , fac_kenmerkdomein_verval"
+ " , fac_usrtab_key"
+ " FROM fac_kenmerkdomein"
+ " WHERE fac_kenmerkdomein_key = " + tfield.kdomein_key;
var oRs_d = Oracle.Execute(dsql);
var xmlnode = oRs_d("fac_kenmerkdomein_xmlnode").Value;
var vervalkolom = oRs_d("fac_kenmerkdomein_verval").Value;
//@@TODO deze wheres worden volgens mij niet gebruikt! Zou dat wel moeten??
if (tparams.parentkenmerkid != "")
{
if (tparams.parentkenmerkwaarde != null)
wheres.push("fac_usrdata_parentkey = " + tparams.parentkenmerkwaarde);
else // Parent heeft geen waarde geselecteerd.
wheres.push("fac_usrdata_parentkey IS NOT NULL");
}
var lflexkenmerkwaarde = tfield.kwaarde;
if (lflexkenmerkwaarde !== null && String(oRs_d("fac_kenmerkdomein_kolomnaam").Value).match(/\_key$/i))
{
var vv = parseInt(lflexkenmerkwaarde, 10);
if (isNaN(vv))
{ // Kan gebeuren als van een text-kenmerk *achteraf* een referentiekenmerk wordt gemaakt
// Ook: als je bij een referentie kenmerk een foutieve default-waarde (textueel) invult
// We negeren het gewoon stil, het vervuilt mij de logging te veel
__Log("Ongeldige referentie waarde <em>{0}</em> voor kolom {1}.{2}".format(tfield.kwaarde,
oRs_d("fac_kenmerkdomein_objectnaam").Value,
oRs_d("fac_kenmerkdomein_kolomnaam").Value), "#ff0000");
lflexkenmerkwaarde = "-1";
}
else
lflexkenmerkwaarde = String(vv);
}
if (oRs_d("fac_kenmerkdomein_objectnaam").Value == "FAC_USRDATA" && !oRs_d("fac_usrtab_key").Value)
{
shared.internal_error("Missing usertable for '{0}' {1}".format(L("lcl_kenmerkdomein"), oRs_d("fac_kenmerkdomein_omschrijving").Value));
}
if (oRs_d("fac_kenmerkdomein_objectnaam").Value == "FAC_USRDATA")
{
// Een verwijzing uit een usertabel
// Deze kunnen we standaard localisen!
fsql = "SELECT fac_usrdata_key rkey"
+ " , " + lcl.xsql('fac_usrdata_omschr', 'fac_usrdata_key') + " romschr"
+ " , fac_usrdata_vervaldatum rvervaldatum"
+ ", " + (xmlnode ? safe.quoted_sql(xmlnode) : "NULL") + " rxmlnode"
+ " , fac_usrdata_volgnr"
+ " FROM fac_usrdata "
+ " WHERE fac_usrtab_key=" + oRs_d("fac_usrtab_key").Value
+ (!tfield.readonlyfield
? " AND fac_usrdata_verwijder IS NULL"
: " AND fac_usrdata_key = " + lflexkenmerkwaarde)
+ " AND (fac_usrdata_vervaldatum IS NULL OR fac_usrdata_vervaldatum > SYSDATE)"
+ (tfield.kregexp?" AND fac_usrdata_key IN ({0})".format(safe.int_array(tfield.kregexp.split(",")).join(",")):"")
+ " UNION "
+ "SELECT fac_usrdata_key"
+ " , " + lcl.xsql('fac_usrdata_omschr', 'fac_usrdata_key') + " ||"
+ " CASE"
+ " WHEN fac_usrdata_vervaldatum < SYSDATE"
+ " THEN " + safe.quoted_sql(L("lcl_inactive_data_suffix"))
+ " END fac_usrdata_omschr"
+ " , fac_usrdata_vervaldatum"
+ ", " + (xmlnode ? safe.quoted_sql(xmlnode) : "NULL") + " rxmlnode"
+ " , fac_usrdata_volgnr"
+ " FROM fac_usrdata "
+ " WHERE fac_usrtab_key = " + oRs_d("fac_usrtab_key").Value
+ " AND fac_usrdata_key = " + lflexkenmerkwaarde;
}
else
{
// Een verwijzing uit een andere view of tabel
// var wheres = []; // DIT LIJKT ME STERK. Het wist de afhankelijkheid van parentwaarden
if (vervalkolom)
wheres.push("(" + vervalkolom + " IS NULL OR " + vervalkolom + " > SYSDATE)");
if (tfield.readonlyfield)
wheres.push(oRs_d("fac_kenmerkdomein_kolomnaam").Value + " = " + safe.quoted_sql(tfield.kwaarde)); // niet die lflexkenmerkwaarde?
fsql = "SELECT " + oRs_d("fac_kenmerkdomein_kolomnaam").Value + " rkey, "
+ oRs_d("fac_kenmerkdomein_kolomtxt").Value + " romschr,"
+ (vervalkolom ? vervalkolom : "NULL") + " rvervaldatum,"
+ (xmlnode ? safe.quoted_sql(xmlnode) : "NULL") + " rxmlnode"
+ " FROM " + oRs_d("fac_kenmerkdomein_objectnaam").Value
+ (wheres.length?" WHERE " + wheres.join(" AND "):"")
+ " UNION " // De huidige waarde altijd. Doordat hier *geen* UNION ALL staat ontstaan er geen dubbelen
+ "SELECT " + oRs_d("fac_kenmerkdomein_kolomnaam").Value + " rkey, "
+ oRs_d("fac_kenmerkdomein_kolomtxt").Value
+ (vervalkolom
? " || CASE WHEN " + vervalkolom + " < SYSDATE THEN " + safe.quoted_sql(L("lcl_inactive_data_suffix")) + " END"
: ""
) + " romschr, "
+ (vervalkolom ? vervalkolom : "NULL") + " rvervaldatum,"
+ (xmlnode ? safe.quoted_sql(xmlnode) : "NULL") + " rxmlnode"
+ " FROM " + oRs_d("fac_kenmerkdomein_objectnaam").Value
+ " WHERE " + oRs_d("fac_kenmerkdomein_kolomnaam").Value + " = " + safe.quoted_sql(lflexkenmerkwaarde);
}
fsql += (oRs_d("fac_kenmerkdomein_objectnaam").Value == "FAC_USRDATA")
? " ORDER BY fac_usrdata_volgnr, 2"
: " ORDER BY 2, 1";
oRs_d.close();
return fsql;
}
// ==========================================================================================
// The functions to return the value-html for each field type
// ==========================================================================================
// ==========================================================================================
function kenmerktype_text (pfield, pprops, pparams)
{
var lkv = "";
if (pfield.klengte > 50 && !pprops.kenmerk_search)
{
// Groot text veld wordt automatisch textarea
if (pfield.readonlyfield || pfield.maskeren)
{
if (pprops.mobile)
{
lkv = "<textarea rows=3 readonly tabindex=-1 maxlength='"+pfield.klengte+"'>" + safe.textarea(pfield.kwaarde) + "</textarea>";
}
else
{
lkv = "<div class='readonly'>" + safe.html(pfield.kwaarde) + "</div>";
}
}
else
{
lkv = "<textarea "
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "' " : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")"
+ (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExpValid : "")
+ "'"
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")'"
+ " class='fldtxt fldflexC "
+ (pfield.required ? pparams.required_class : "")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ (pfield.required ? " required='required' " : "")
+ (pfield.isReadonly ? " readonly tabindex=-1 " : "")
+ " rows=3 "
+ " maxlength='"+pfield.klengte+"'"
+ " name='" + pprops.nameprefix + pfield.idCounter + "val' id='" + pprops.nameprefix + pfield.idCounter + "val' "
//+ "placeholder='"+pfield.komschrijving+"'"
+ ">"
+ safe.textarea(pfield.kwaarde)
+ "</textarea>";
}
}
else
{ // klein input veld
if (pfield.readonlyfield || pfield.maskeren)
{
if (pprops.mobile)
{
lkv = "<input type='text' readonly tabindex=-1 value='"+ safe.html(pfield.kwaarde) +"'>";
}
else
{
lkv = "<span>" + safe.htmlattr(pfield.kwaarde) + "</span>";
}
}
else
{
lkv = "<input type='text'"
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "' " : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")"
+ (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExpValid : "")
+ "'"
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")'"
+ " id='" + pprops.nameprefix + pfield.idCounter + "val' name='" + pprops.nameprefix + pfield.idCounter + "val'"
+ " class='fld fldflexC "
+ (pfield.required ? pparams.required_class : "")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ (pfield.required ? " required='required' " : "")
+ (pfield.isReadonly ? " readonly tabindex=-1 " : "")
//+ " placeholder='"+pfield.komschrijving+"'"
+ " value='" + safe.htmlattr(pfield.kwaarde) + "'"
+ " maxlength='" + pfield.klengte + "'"
+ ">";
}
}
return lkv;
}
// ==========================================================================================
function kenmerktype_listbox (pfield, pprops, pparams)
{
var lkv = "";
var xmlnode;
// Bepaal key, omschrijving, vervaldatum en evt xmlnode van de domeinwaarde(n)
var fsql = refvaluessql(pfield, pparams);
var oRs2 = Oracle.Execute(fsql);
var refkeyfield = "";
var refvaluefield = "";
var inactiveval = false;
var xmlnode;
if (!oRs2.eof)
{
refkeyfield = oRs2("rkey").Value;
refvaluefield = oRs2("romschr").Value;
inactiveval = (oRs2("rvervaldatum").Value != null && oRs2("rvervaldatum").Value < new Date());
xmlnode = oRs2("rxmlnode").Value;
}
if (pfield.readonlyfield || pfield.maskeren)
{
if (pprops.mobile)
lkv = '<input class="fld fldflexR'
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ (inactiveval? ' inactive' : '')
+ '" type="text" readonly tabindex=-1'
+ ' value="' + safe.htmlattr(refvaluefield) + '"></input>';
else
lkv = '<span class="fld fldflexR'
+ ((xmlnode && !pprops.mobile) ? ' details' : '')
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ (inactiveval? ' inactive' : '')
+ '" type="text" readonly tabindex=-1'
+ (xmlnode && !pprops.mobile? ' onClick="xmlNodeDetails(' + pfield.kwaarde + ', \'' + xmlnode + '\')"' : '')
+ '>' + safe.html(refvaluefield) + "</span>";
}
else
{
// Performance optimalisation: Instead of building the string by appending
// we build it in an array first and finally 'join' it.
var builder = new Array();
var maxLen = 0;
var kvv = "";
while (!oRs2.eof)
{
refkeyfield = oRs2("rkey").Value;
refvaluefield = oRs2("romschr").Value;
if (pfield.readonlyfield)
{
if (refkeyfield == pfield.kwaarde)
{
kvv = refvaluefield;
break; // Rap klaar. Kan efficienter met een WHERE?
}
}
else
{
if (refvaluefield != null && String(refvaluefield.length) > maxLen)
maxLen = String(refvaluefield).length;
appender = '<option value="' + refkeyfield + '"'
+ (refkeyfield == pfield.kwaarde?' selected' : '') + '>' + safe.html(refvaluefield) + '</option>';
builder[builder.length] = appender;
}
oRs2.MoveNext();
}
if (kvv == '') kvv += builder.join(' ');
if (kvv == '') kvv = ' '; // Zodat readonly/print in ieder geval het label getoond wordt.
//kvv is nu een waarde of een reeks opties voor een select
if (pfield.readonlyfield || pfield.maskeren)
{
}
else
{
// is dus impliciet ook type R
lkv = "<select id='" + pprops.nameprefix + pfield.idCounter + "val' name='" + pprops.nameprefix + pfield.idCounter + "val'"
+ " class='fld fldflexR "
+ (pfield.required ? pparams.required_class : "")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ (pprops.kenmerk_search ? " advmulti=1 " : "")
+ (pfield.required ? " required='required' " : "")
+ (pfield.required > 1
? " onChange='checkRequiredGroup(\"" + pparams.required_group + "\", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ");" + (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "") + "'"
: (pparams.hasAnyFlexExpr ? " onChange='" + (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "") + "'" : ""))
+ " data-icon='fa fa-chevron-down'"
+ ">"
+ "<option value='-1' " + (pfield.required? " class='" + pparams.required_class + "'" : "") + "><!--lege waarde--></option>"
+ kvv
+ "</select>";
}
if (!pfield.readonlyfield && pparams.parentkenmerkid != "" && !pfield.maskeren)
{ %>
<script type="text/javascript">
function onChangeRKenmerkParent<%=pparams.parentkenmerkid%>()
{ // Functie wordt aangeroepen door een eventuele parent waarvan deze listbox afhankelijk is
var className = $("#<%=pparams.parentkenmerkid%>val")[0].className;
if (className.match(/required\d/g) && className.match(/required\d/g).length > 0)
{ // Select hoort binnen een required groep.
var group = $("#<%=pparams.parentkenmerkid%>val")[0].className.match(/required\d*S\d*/g)[0].substr(8);
checkRequiredGroup(group, <%=(pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null")%>);
}
$("#<%=pprops.nameprefix + pfield.idCounter%>val").
load(rooturl + "/appl/Shared/loadRKenmerk.asp?" + serializeObj(
{ init_key: $("#<%=pprops.nameprefix + pfield.idCounter%>val").val() || -1,
kdomein_key: <%=pfield.kdomein_key%>,
parent_key: $("#<%=pparams.parentkenmerkid%>val").val() || -1,
required: <%=pfield.required? pfield.required : 0%>,
hideVervallen: <%=pprops.hideVervallen? 1 : 0%> })
);
}
$(function()
{
// Op de onChange van de parent moet deze listbox opnieuw gevuld worden.
// onchange van de parent koppelen aan de functie die deze actie uitvoert.
if ($("#<%=pparams.parentkenmerkid%>val").length)
{
$("#<%=pparams.parentkenmerkid%>val").change(function() { onChangeRKenmerkParent<%=pparams.parentkenmerkid%>(); });
$("#<%=pparams.parentkenmerkid%>val").change();
}
});
</script><%
}
}
oRs2.close();
return lkv;
}
// ==========================================================================================
function kenmerktype_suggest (pfield, pprops, pparams)
{
var lkv = "";
var lkenmerkwaarde = "";
if (pfield.kwaarde)
{
var rsql = "SELECT flx.getdomeinwaarde("+pfield.kdomein_key+","+safe.quoted_sql(pfield.kwaarde)+") refwaarde FROM DUAL";
var rORs = Oracle.Execute(rsql);
if (!rORs.eof)
{
lkenmerkwaarde = rORs("refwaarde").value;
}
else
{
lkenmerkwaarde = "???"; //error
}
rORs.close();
}
if (pfield.readonlyfield)
{
var xmlnode, refkeyfield;
if (!pprops.mobile)
{
var fsql = refvaluessql(pfield, pparams);
var oRs2 = Oracle.Execute(fsql);
if (!oRs2.eof)
{
refkeyfield = oRs2("rkey").Value;
lkenmerkwaarde = oRs2("romschr").Value;
xmlnode = oRs2("rxmlnode").Value;
}
oRs2.Close();
lkv = "<span" + ((xmlnode && !pprops.mobile) ? " class='details'" : "")
+ ((xmlnode && !pprops.mobile) ? ' onClick="xmlNodeDetails(' + refkeyfield + ', \'' + xmlnode + '\')"' : '')
+ ">" + safe.html(lkenmerkwaarde) + "</span>";
}
else
lkv = "<input type='text' class='fld' readonly tabindex=-1"
+ " value='" + safe.htmlattr(lkenmerkwaarde) + "'></input>";
}
else
{
%> <script type="text/javascript">
<% if (pparams.parentkenmerkid != "")
{
%>
function onChangeSKenmerkParent<%=pparams.parentkenmerkid%>(parentkey, parenttxt)
{ // Functie wordt aangeroepen door een eventuele parent waarvan deze suggest afhankelijk is
// setValue(key, txt, doonChange, checkExist, extraParam, lastTry)
var presentkey = $("#<%=pprops.nameprefix + pfield.idCounter%>val").val();
var presenttxt = $("#Suggest<%=pprops.nameprefix + pfield.idCounter%>_show").val()
Suggest<%=pprops.nameprefix + pfield.idCounter%>.setValue(presentkey, presenttxt, false, true, null, true);
// Indien suggestbox verplicht is en maar <20><>n mogelijke waarde heeft, dan deze selecteren
if ($("#Suggest<%=pprops.nameprefix + pfield.idCounter%>_show").hasClass("required")) Suggest<%=pprops.nameprefix + pfield.idCounter%>.CheckJustOne();
var className = $("#Suggest<%=pparams.parentkenmerkid%>_show")[0].className;
if (className.match(/required\d/g) && className.match(/required\d/g).length > 0)
{ // Suggest hoort binnen een required groep.
var group = $("#Suggest<%=pparams.parentkenmerkid%>_show")[0].className.match(/required\d*S\d*/g)[0].substr(8);
checkRequiredGroup(group, <%=(pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null")%>);
}
}
<% }
if (pfield.required)
{
%>
function onChangeSKenmerk<%=pprops.nameprefix + pfield.idCounter%>(parentkey, txt)
{
checkRequiredGroup("<%=pparams.required_group%>", <%=(pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null")%>);
}
<% }
%>
$(function()
{
if ($("#execDone<%=pprops.nameprefix + pfield.idCounter%>").val() == 0)
{ // Alleen initieel uitvoeren. Niet bij overzichten als "Geavanceerd" kenmerken worden gekopieerd naar div binnen form. Want waarde kan veranderd/ingevuld zijn.
Suggest<%=pprops.nameprefix + pfield.idCounter%> =
new Suggest({objectName: "Suggest<%=pprops.nameprefix + pfield.idCounter%>",
<%=(pprops.kenmerk_search ? "multitoggle: \"advanced\", " : "")%>
queryField: $("#Suggest<%=pprops.nameprefix + pfield.idCounter%>_show")[0],
queryUrl: rooturl + "/appl/shared/Suggest/SuggestKenmerkDomein.asp?kenmerkdomein_key=<%=pfield.kdomein_key%>",
initKey: '<%=pfield.kwaarde%>',
keyField: $("#<%=pprops.nameprefix + pfield.idCounter%>val")[0],
fieldReadonly: false
<% if (typeof mobile != "undefined" && typeof modal != "undefined" && modal == 1) // mobile en popup en kenmerken?
{ %> // Dat komt alleen voor bij de 'reserveer werkplek' pagina,
, embedded: true // waar we een PDA pagina in een desktop popup gebruiken
<% }
if (pparams.parentkenmerkid != "")
{ %>
, urlAdd: [{ urlParam: "parent_key", field: "<%=pparams.parentkenmerkid%>val" }]
<% } %>
});
<% if (pparams.parentkenmerkid != "")
{
// Op de onChange van de parent moet deze suggestbox geleegd worden.
// sgonchange van de parent koppelen aan de functie die deze actie uitvoert.
%>
$("#Suggest<%=pparams.parentkenmerkid%>_show").attr("sgonChange", "onChangeSKenmerkParent<%=pparams.parentkenmerkid%>");
<% }
%>
$("#execDone<%=pprops.nameprefix + pfield.idCounter%>").val(1); // Het is nu 1 keer uitgevoerd. Nu niet meer uitvoeren.
<% if (pparams.hasAnyFlexExpr)
{
%>
$("#Suggest<%=pprops.nameprefix+pfield.idCounter%>_show").attr("onblur", '<%=(sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "")%>');
<% }
%>
}
});
</script>
<%
lkv = "<input type='text' "
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "' " : "")
+ "id='Suggest" + pprops.nameprefix + pfield.idCounter + "_show' "
+ "name='Suggest" + pprops.nameprefix + pfield.idCounter + "_show' "
+ "value='" + safe.htmlattr(lkenmerkwaarde) + "' "
+ "class='fld fldflexS "
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? "expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ (pfield.required ? " " + pparams.required_class : "") + "'"
// zo wordt het veld rood, ongeacht de waarde, wat verwarrend is, dus niet + (inactiveval ? " inactive " : "")
+ (pfield.required ? " required='required' " : "")
+ (pfield.required > 1
? " sgonChange='onChangeSKenmerk" + pprops.nameprefix + pfield.idCounter + "'"
: "")
+ ">"
+ "<input type='hidden' id='" + pprops.nameprefix + pfield.idCounter + "val' name='" + pprops.nameprefix + pfield.idCounter + "val'>"
+ "<input type='hidden' id='execDone" + pprops.nameprefix + pfield.idCounter + "' name='execDone" + pprops.nameprefix + pfield.idCounter + "' value='0'>";
}
return lkv;
}
// ==========================================================================================
function kenmerktype_date (pfield, pprops, pparams, dpYearRanges)
{
var lkv = "";
if (pfield.readonlyfield)
{
if (pprops.mobile)
lkv = "<input type='text' class='fld' readonly tabindex=-1 value='" + safe.htmlattr(pfield.kwaarde) + "'></input>";
else
lkv = "<span>" + safe.html(pfield.kwaarde) + "</span>";
}
else
{
lkv = "<span class='input-icon-wrapper'>";
lkv += "<input type='text'"
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "'" : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", "
+ (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")" + (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "") + "'"
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")'"
+ " id='" + pprops.nameprefix + pfield.idCounter + "val'"
+ " name='" + pprops.nameprefix + pfield.idCounter + "val' ";
lkv += " class='flddate " /* deze bepaalt ook dat er een dateselector op komt */
+ (pfield.required ? " " + pparams.required_class : "")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ (pfield.required ? " required='required' " : "")
+ " onChange='" + (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "") + "' "
+ " value='" + safe.htmlattr(pfield.kwaarde) + "'"
+ " autocomplete=\"off\""
+ ">";
if ((!pfield.isExpression || pfield.isShowExpr) && !pfield.maskeren)
lkv += "<span class=\"dateklikker\" onclick=\"$('#" + pprops.nameprefix + pfield.idCounter + "val').datepicker('show')\"> " + I("fa-calendar") + "</span>";
lkv += "</span>";
// Als er voor een datumveld geen knmin en knmax is ingevuld dan is de yearRange default -10 tot +10 jaar vanaf geselecteerd jaar.
// Is een van beiden ingevuld dan wordt de andere op 10 jaar vanaf geselecteerde jaar gezet (deze verschuift met selectie).
// Een opgegeven waarde is het aantal jaren voor of na het huidige jaar (waarde < 1000), of een jaartal (waarde > 1000).
if (pfield.knmin || pfield.knmax)
{
range_val = (pfield.knmin ? ((Math.abs(pfield.knmin)<1000) ? "c"+(pfield.knmin>0?"+"+pfield.knmin:pfield.knmin) : Math.abs(pfield.knmin)) : "c-10") + ":"
+ (pfield.knmax ? ((Math.abs(pfield.knmax)<1000) ? "c"+(pfield.knmax>0?"+"+pfield.knmax:pfield.knmax) : Math.abs(pfield.knmax)) : "c+10");
field_id = pprops.nameprefix + pfield.idCounter + "val";
dpYearRanges.push({id: field_id, range: range_val});
}
}
return lkv;
}
// ==========================================================================================
function kenmerktype_time (pfield, pprops, pparams)
{
var lkv= "";
if (pfield.readonlyfield)
{
if (pprops.mobile)
lkv = "<input type='text' class='fld' readonly tabindex=-1 value='" + safe.htmlattr(pfield.kwaarde) + "'></input>";
else
lkv = "<span>" + safe.html(pfield.kwaarde) + "</span>";
}
else
{ // Defaults
var lkmin = "0";
var lkmax = "23.99"; // Not 23.75 because you want to be able to manually enter 23:59
if (pfield.knmin !== null)
lkmin = Math.max(0, (Math.round(pfield.knmin * 4) / 4)).toFixed(2); // Rounded to nearest quarter
if (pfield.knmax !== null)
lkmax = Math.min(23.99, (Math.round(pfield.knmax * 4) / 4)).toFixed(2); // Rounded to nearest quarter
var kminH = Math.floor(lkmin);
var kminM = Math.round(lkmin * 60 % 60, 10);
var kmaxH = Math.floor(lkmax);
var kmaxM = Math.round(lkmax * 60 % 60, 10);
lkmin = pad(String(kminH), 2) + ":" + pad(String(kminM), 2);
lkmax = pad(String(kmaxH), 2) + ":" + pad(String(kmaxM), 2);
/*global*/minMax.push({namePrefix: pprops.nameprefix, id: pfield.idCounter, kmin: lkmin, kmax: lkmax});
lkv = "<span class='input-icon-wrapper'>";
lkv += "<input type='text'"
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "' " : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + ",\"" + lkmin + "\",\"" + lkmax + "\", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")"
+ (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExpValid : "") + "' "
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + ",\"" + lkmin + "\",\"" + lkmax + "\", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")'"
+ (!pfield.maskeren
? " id='" + pprops.nameprefix + pfield.idCounter + "val' name='" + pprops.nameprefix + pfield.idCounter + "val' "
: "")
+ " class='fldtime " /* deze bepaalt ook dat er een timeselector op komt */
+ (pfield.required ? " " + pparams.required_class : "")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ (pfield.required ? " required='required' " : "")
+ " size=\"5\""
+ " value='" + safe.htmlattr(pfield.kwaarde) + "'"
+ " autocomplete=\"off\""
+ ">";
if (!pfield.maskeren)
lkv += "<span class=\"flex timeklikker\" onclick=\"$('#" + pprops.nameprefix + pfield.idCounter + "val').click(); event.stopPropagation()\">" + I("fa-clock") + "</span>";
lkv += "</span>";
}
return lkv;
}
// ==========================================================================================
function kenmerktype_checkbox (pfield, pprops, pparams)
{
var lkv = "";
if (pfield.readonlyfield || pfield.kkenmerktype == "B" || pfield.maskeren) // Berekening input veld is altijd readonly.
{
if (pprops.mobile)
{
lkv = "<input type='text' class='fld' readonly tabindex=-1 value='" + (pfield.kwaarde == 1? L("lcl_check_1") : L("lcl_check_0")) + "'>";
// Wat doen we hier mee?
//if (pprops.mobile) // Daar staat de tekst achter het vinkje
//thisfield.separator = '';
}
else
{
lkv = "<span class='fldcheck'>"
+ (pfield.kwaarde == 1? L("lcl_check_1") : L("lcl_check_0"))
+ "</span>";
}
}
else
{
lkv = "<input type='checkbox' class='fldshort "
+ (pfield.required ? " " + pparams.required_class : "")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")"
+ (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExpValid : "")
+ "' "
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")' "
+ (pfield.kwaarde == 1 ? " checked" : "")
+ " id='" + pprops.nameprefix + pfield.idCounter + "val'"
+ " name='" + pprops.nameprefix + pfield.idCounter + "val'"
+ ">"
+ "<input type='hidden' id='has_" + pprops.nameprefix + pfield.idCounter + "val' name='has_" + pprops.nameprefix + pfield.idCounter + "val' value='1'>";
}
return lkv;
}
// ==========================================================================================
function kenmerktype_number (pfield, pprops, pparams)
{
var lkv = "";
if (pfield.readonlyfield || pfield.kkenmerktype == "B" || pfield.maskeren) // Berekening input veld is altijd readonly.
{
if (pfield.kdec > 0 && pfield.kwaarde)
var safeformattedvalue = safe.showFloat(pfield.kwaarde, pfield.kdec);
else
var safeformattedvalue = safe.html(pfield.kwaarde);
if (pprops.mobile)
lkv = "<input type='text' class='fldshort' readonly tabindex=-1 value='"+ safeformattedvalue +"'>";
else
lkv = "<span>" + safeformattedvalue + "</span>";
}
else
{
lkv = "<input type='text'"
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "'" : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", "
+ (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")" + (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExpValid : "") + "'"
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")'"
+ " id='" + pprops.nameprefix + pfield.idCounter + "val'"
+ " name='" + pprops.nameprefix + pfield.idCounter + "val' ";
lkv += " class='fldshort "
+ (pfield.required ? pparams.required_class : "")
+ (pfield.kdec > 0 ? " float " : " number ")
+ (pfield.isSqlExpr ? ' flexsql' : '')
+ (pfield.isExpression? " expression " + (pfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ "'"
+ (pfield.required ? " required='required' " : "")
+ (pfield.isReadonly ? " readonly tabindex=-1 " : "")
+ " value='" + (pfield.kdec > 0 && pfield.kwaarde? safe.displayfloat(parseFloat(pfield.kwaarde), pfield.kdec) : safe.htmlattr(pfield.kwaarde)) + "'"
+ " maxlength='" + ((pfield.knmin >= 0? 0 : 1) + (pfield.kdec > 0? 1 : 0) + pfield.klengte) + "'"
+ ">";
}
return lkv;
}
// ==========================================================================================
function kenmerktype_xref (pfield, pprops, pparams)
{
var lkv = "";
if (pfield.readonlyfield || pfield.maskeren)
{
if (pfield.kwaarde)
lkv = '<span class="details" onclick=\'openDoc("' + safe.jsstring(pfield.kwaarde) + '")\'>'+safe.htmlattr(pfield.kwaarde)+"</span>";
}
else
{
lkv = "<input type='text'"
+ (pfield.kregexp ? " regexp='" + pfield.kregexp + "'" : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", "
+ (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")" + (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "") + "'"
+ " onBlur='checkKenmerk(this, true,\"" + pfield.kkenmerktype + "\"," + pfield.klengte + "," + pfield.kdec + "," + pfield.knmin + "," + pfield.knmax + ", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ")'"
+ " id='" + pprops.nameprefix + pfield.idCounter + "val'"
+ " name='" + pprops.nameprefix + pfield.idCounter + "val' ";
if (pfield.kwaarde) // Tekstveld met 'view' button er achter plakken
{
lkv += " class='fld fldflexX "
+ (pfield.required ? pparams.required_class : "")
+ "'"
+ " value='" + safe.htmlattr(pfield.kwaarde) + "'"
+ (pfield.required ? " required='required' " : "")
+ "><span class='fileopen details' "
+ " onClick='openDoc(\"" + safe.jsstring(pfield.kwaarde) + "\");'>" + I("fa-folder-open") + "</span>";
}
else if (!pprops.kenmerk_search) // !pfield.kwaarde // Browse button for new er achter plakken
lkv = "<input class='fld fldflexX "
+ (pfield.required ? pparams.required_class : "")
+ "'"
+ (pfield.required ? " required='required' " : "")
+ " onChange='"
+ (pfield.required > 1
? "checkRequiredGroup(\"" + pparams.required_group + "\", " + (pprops.requiredbyemptyval != null? "{emptyvalue: " + pprops.requiredbyemptyval + "}" : "null") + ");"
: "")
+ (sharedIndexOf(pfield.kkey, pparams.kenmerkUsedInExpr) > -1 ? pparams.onchangeExp : "") + "'"
+ " type='text' "
+ "name='" + pprops.nameprefix + pfield.idCounter + "val' " + "id='" + pprops.nameprefix + pfield.idCounter + "val' "
+ "value='" + safe.htmlattr(pfield.kwaarde) + "'"
+ ">";
else
lkv += "class='fld fldflexX'>";
}
return lkv;
}
// ==========================================================================================
function kenmerktype_label (pfield, pprops, pparams)
{
// Een label is geen echt veld, maar een infoblock
// De 'waarde' van een label is de defaultwaarde van het kenmerk
var lkv = "";
if (S("fac_html_strictness") == 0)
var safe_default = pfield.kdefault
else
var safe_default = safe.html(pfield.kdefault);
lkv = "<span class='flexlabel'>"+(safe_default || "")+"</span>";
return lkv;
}
// KENMERKTYPE l (kleine letter L) = blokheader (voorheen collapsible label) ===============
// ==========================================================================================
function kenmerktype_blocktitel (pfield, pprops, pparams)
{
// Wordt aangeroepen als er (zeker) een block_start met komen
// Het label zelf bestaat uit een icon + label-tekst
// Het icon staat bij de default waarde van het kenmerk
// De label-tekst wordt gedefinieerd bij de benaming van het kenmerk
var lkv = "";
if (!pprops.kenmerk_search)
{
// Schrijf eventueel een block-begin; je mag (nog) niet nesten, dus nieuw block betekent einde vorige block
// Blocks worden gemarkeerd met een collapsible label, ktype = kleine-letter-l
// Deze zijn echter optioneel, dus als die er niet zijn, moeten we zelf een (1) blokbegin verzinnen
if (/*global*/__insideblock > 0) {
lkv += BLOCK_END_HTML();
__insideblock = 0; // of -1 om ooit nesting te kunnen ;-)
}
// Gelijk aan suppress_label, een blok moet je nog wel printen omdat alle velden er in ook hidden moeten worden
var hide_block = show_label_expr[pfield.kkey] == 0 ||
(pprops.reado && pfield.kshow_expr && pparams.module == 'MLD' && pparams.pkey && !showIsVisible(pparams.pkey, pfield.kshow_expr, (pparams.flexPath == "MLD/O" ? "opdr" : "")));
var block_params = { "flexblock": true,
"icon": "fa-info-square",
"isShowExpr": pfield.isShowExpr,
"hidden": hide_block,
"collapsible": !pprops.reado && pfield.forceReadonly
};
var mobile_block_params = { "pId": "flx_" + pprops.nameprefix + pfield.idCounter,
"safe": true,
"title": (pfield.komschrijving ? pfield.komschrijving : L("lcl_flexblok")),
"collapsed": !pprops.reado && pfield.forceReadonly
};
if (pfield.kdefault && pfield.kdefault.match(/^fa-/))
block_params.icon = pfield.kdefault;
if (pfield.kregexp && pfield.kregexp.match(/(100|100%)/) != null)
block_params.wide = true;
lkv += ( pprops.mobile
? BLOCK_START_HTML(mobile_block_params) // pda/iface.inc
: BLOCK_START_HTML("flx_" + pprops.nameprefix + pfield.idCounter, (pfield.komschrijving ? pfield.komschrijving : L("lcl_flexblok")), block_params) // shared/iface.inc
);
if (pfield.kkey && pparams.hasAnyFlexExpr)
{
lkv += "\n<input type='hidden' name='"+pprops.nameprefix + pfield.idCounter+"key' id='"+pprops.nameprefix + pfield.idCounter+"key' value='"+pfield.kkey+"'>";
lkv += "\n<input type='hidden' name='"+pprops.nameprefix + pfield.idCounter+"val' id='"+pprops.nameprefix + pfield.idCounter+"val' value=''>";
lkv += "\n<input type='hidden' name='"+pprops.nameprefix + pfield.idCounter+"count' id='"+pprops.nameprefix + pfield.idCounter+"count' value='"+pfield.kkeycount+"'>";
lkv += "\n<input type='hidden' name='"+pprops.nameprefix + pfield.idCounter+"t' id='"+pprops.nameprefix + pfield.idCounter+"t' value='"+pfield.kkenmerktype+"'>";
if (pfield.isExpression)
{
lkv += "\n<input type='hidden' name='"+pprops.nameprefix + pfield.idCounter+"e' id='"+pprops.nameprefix + pfield.idCounter+"e' value='"+(pfield.isShowExpr ? 2: 1) +"'>";
}
}
/*global*/__insideblock = 1;
/*global*/allCollapsable = true; // opnieuw beginnen met zoeken
/*global*/inMobileBlock = pprops.mobile; // op dit moment zitten we in een mobile-collapse-content-block
/*global*/clabelCounter++;
}
return lkv;
}
// ==========================================================================================
function kenmerktype_spacer (pfield, pprops, pparams)
{
// Een spacer is geen echt veld maar een horizontale streep om de verticale uitlijning van opvolgende blokken te resetten
var lkv = "";
if (pprops.mobile)
return lkv;
if (/*global*/__insideblock > 0)
lkv += BLOCK_END_HTML();
lkv += SIMPLE_BLOCK_START_HTML({ extraclass: "flexspacer" });
lkv += SIMPLE_BLOCK_END_HTML();
__insideblock = 0;
return lkv;
}
function kenmerktype_attachment_by_srtkenmerk(pfield, pprops, pparams)
{
var res;
if (pprops.parent_list)
{
var sql_p = "SELECT mld_srtkenmerk_key"
+ " FROM mld_kenmerk"
+ " WHERE mld_kenmerk_key = " + pfield.kkey;
var oRs_p = Oracle.Execute(sql_p);
var srtkm_key = oRs_p("mld_srtkenmerk_key").Value;
oRs_p.Close();
var btn_kenmerken = [];
for (pp in pprops.parent_list)
{
var v_parent = pprops.parent_list[pp];
var v_kenmerken = v_parent.kenmerken;
for (var j=0; j<v_kenmerken.length; j++)
{
if (v_kenmerken[j].srtkm_key == srtkm_key)
{
btn_kenmerken.push({mld_key: v_parent.key, km_key: v_kenmerken[j].km_key});
}
}
}
if (btn_kenmerken.length > 0)
{
pprops.srtkm_list = btn_kenmerken;
res = BijlagenButton(pfield, pprops, pparams); ///@@@ ik heb hier pprops.parent_list[pp].label weggemoffeld. Erg?
res.addPreview = res.addPreview && !pprops.nolabel && !pfield.maskeren && pfield.readonlyfield;
pprops.srtkm_list = [];
}
}
return res;
}
// ==========================================================================================
function kenmerktype_bijlage (pfield, pprops, pparams)
{
var lkv = "";
var previewParams = [];
var addPreview = false;
var kotherkey = null;
var flexbijlagen_key = -1;
var fld = pprops.nameprefix + pfield.idCounter + "val";
if (pprops.mobile && pfield.kdimensie != 'xxx')
{
lkv = mobileBijlagen(pfield, pprops, pparams);
var km_data = { lkv: lkv };
}
else
{ // Bedoeling is: toon de filenaam op een button
// In showmode/readonly kun je op een <span> klikken als-ie bestaat, in editmode
// moet je de change button gebruiken om te wijzigen
// De echte waarde bewaren we in een hidden veld. Die wordt dan ook gesubmit
// (mobile) Handtekeningen gaan ook via BijlagenButton met een eigen mechanisme waar afgewisseld wordt tussen;
// <Leeg> => 'Toevoegen' knop, of gevuld => klikbaar plaatje vd tekening
var res = BijlagenButton(pfield, pprops, pparams);
lkv = res.html;
addPreview = res.addPreview;
kotherkey = res.kotherkey || -1;
res = kenmerktype_attachment_by_srtkenmerk(pfield, pprops, pparams);
if (res)
{
if (res.addPreview)
{
addPreview = true;
}
lkv += res.html;
if (res.count > 0)
{
allCollapsable = false;
}
}
// Add preview links for bijlagen
if (addPreview && !pprops.kenmerk_search)
{
var previewUrl = protectQS.create("../Shared/BijlagenPreview.asp?key="+pparams.pkey+"&kenmerk_key="+pfield.kkey+"&module="+pparams.module+"&niveau="+pprops.niveau);
%> <script>
$(function() {
$("span.preview#p<%=pfield.idCounter%>").on("click", function() { FcltMgr.openModalDetail("<%=previewUrl%>", L("lcl_flex_preview")) });
});
</script>
<% }
var km_data = { lkv: lkv, addPreview: addPreview, kotherkey: kotherkey };
}
return km_data;
}
// ==========================================================================================
function kenmerktype_folder (pfield, pprops, pparams)
{
var lkv = "";
var addPreview = false;
var previewLink = { keys: [],
kkey: pfield.kkey,
module: pparams.module,
niveau: pprops.niveau };
if (pprops.mobile && pfield.kdimensie != 'xxx')
{
lkv = mobileBijlagen(pfield, pprops, pparams);
var km_data = { lkv: lkv };
return km_data;
}
var res = BijlagenButton(pfield, pprops, pparams);
addPreview = res.addPreview && !pprops.nolabel && !pfield.maskeren && pfield.readonlyfield;
if (addPreview)
previewLink.keys.push(pparams.pkey);
lkv = res.html;
if (res.count > 0)
allCollapsable = false;
// If the 'child' was not preview-able, then start extending the Id count with -1 instead of 0
res = kenmerktype_attachment_by_srtkenmerk(pfield, pprops, pparams);
if (res)
{
if (res.addPreview)
{
previewLink.keys.push(pprops.parentKey);
addPreview = true;
}
lkv += res.html;
if (res.count > 0)
allCollapsable = false;
}
if (pfield.Classname && lkv=="")
{
lkv = "<div class='readonly'></div>";
}
// Add preview links for folders
if (addPreview && previewLink.keys.length && !pprops.kenmerk_search)
{
var previewUrl = protectQS.create("../Shared/BijlagenPreview.asp?key="+previewLink.keys.join(",")+"&kenmerk_key="+previewLink.kkey+"&module="+previewLink.module+"&niveau="+previewLink.niveau);
%><script>
$(function()
{
$("span.preview#p<%=pfield.idCounter%>").on("click", function() { FcltMgr.openModalDetail("<%=previewUrl%>", L("lcl_flex_preview")) });
});
</script><%
}
var km_data = { lkv: lkv, addPreview: addPreview };
return km_data;
}
// Mobiel tonen we de bijlagen heel anders
function mobileBijlagen (tpfield, tpprops, tpparams)
{
var tkv = "";
var flex_bijlagen = flexProps(tpparams.module, tpparams.pkey, String(tpfield.kkey), tpprops.niveau);
var lijst = flex_bijlagen.files;
var filehtmlarr = [];
for (var i = 0; i < lijst.length; i++)
{
var previewClass = '';
if (new RegExp(S("flexPreviewExt"),"i").test(lijst[i].name)) {
previewClass = 'previewext';
}
var idval = "kid{0}_{1}".format(tpfield.idCounter, i);
var href = protectQS.create(OpenFlexFile(tpparams.module, lijst[i].key, { name: lijst[i].name }));
var delete_function = "DeleteFile('" + safe.html(lijst[i].name) + "', '" + safe.jsstring(protectQS.create("Bijlagenform_delete.asp?DoDelete=" + Server.URLEncode(lijst[i].name) + "&key=" + lijst[i].refkey + "&module=" + tpparams.module + "&niveau=" + lijst[i].niveau + "&kenmerk_key=" + lijst[i].kmkey + "&multi=1")) + "', $(this).closest('div'))";
var html = '<div class="flex-nowrap">'
+ ' <a id="'+idval+'" class="details pda-bijlage '+previewClass+'" data-role="button"'
+ ' href=\"' + safe.htmlattr(href) + '" ' + (device.isapp()? '' : 'target="_blank"') + ' data-ajax="false">'
+ /*FCLT#64193*/ '<span class="dont-break-out">' + safe.html(lijst[i].name) + '</span></a>'
+ (tpfield.readonlyfield || ("canDeleteAttachment" in tpprops && !tpprops.canDeleteAttachment) ? '' : '<a id="'+idval+'" href="#" onclick="' + delete_function + '" class="ui-btn ui-btn-inline ui-icon-fa fa-trash-alt ui-btn-icon-notext" title="' + L("lcl_filedelete") + '"></a>')
// kenmerktype = 'M' heeft dit veld niet nodig, als deze er wel staat wordt de bestandsnaam via mobile in de kenmerktabel opgeslagen, en dat moet niet (#71024)
+ (tpfield.kkenmerktype == 'M' ? '' : '<input type="hidden" class="icon icon-attachment filename readonly" name="'+tpprops.nameprefix + tpfield.idCounter + "val"+'" value="'+safe.html(lijst[i].name)+'">')
+ '</div>';
filehtmlarr.push(html);
}
if (!tpfield.readonlyfield) {
var btn_icon = "fa fa-file"; // [F]ile
if (tpfield.kkenmerktype == "M") { // [M]ap
btn_icon = "fa fa-folder-open";
} else if (tpfield.kkenmerktype == "E") { // [E]ncrypted
btn_icon = "fa fa-file-lock";
}
tkv += '<div class="attachment-wrapper">';
tkv += ' <span class="attachments_form">';
tkv += ' <span class="attachments_fields">';
tkv += filehtmlarr.join("");
tkv += '</span>'; // Geen spaties in deze <span> (!)
tkv += ' <span class="' + (tpfield.kkenmerktype == 'M' ? '' : 'single ') + 'add_attachment">';
tkv += BUTTON_HTML(L("lcl_select_file_mobile") + (tpfield.kdimensie ? " (" + safe.html(tpfield.kdimensie) + ")" : ""), {
"id": tpprops.nameprefix + tpfield.idCounter + "val",
"cls": (tpfield.isSqlExpr ? " flexsql" : "") + (tpfield.isExpression ? " expression " + (tpfield.isShowExpr ? "flexshow" : "flexexpr") : "")
+ " ui-link ui-btn ui-btn-b ui-icon-" + btn_icon + " ui-btn-icon-left ui-shadow ui-corner-all ui-mini", /* Dynamsch herladen voegt deze classes niet in */
"dataicon": btn_icon,
"click": "FcltMgr.stopPropagation(); $('#attachments"+tpfield.kkey+"').trigger('click')"
});
tkv += ' <input type="file"';
tkv += ' name="attachments'+tpfield.kkey+'"';
tkv += ' id="attachments'+tpfield.kkey+'"';
tkv += ' class="file_selector filedrop"';
tkv += (tpfield.kkenmerktype == 'M' ? ' multiple="multiple"' : '');
tkv += ' onchange="addInputFiles(this);"';
// tkv += ' data-max-file-size="5242880"';
// tkv += ' data-max-file-size-message="This file cannot be uploaded because it exceeds the maximum allowed file size (5 MB)"';
tkv += ' data-max-concurrent-uploads="2"';
tkv += ' data-upload-path="{0}/api2/{1}/{2}/attachments/{3}/"'.format(rooturl, tpparams.api2name, tpparams.pkey<0?0:tpparams.pkey, tpfield.kkey);
tkv += ' data-role="none"'; // zorg dat jQuery er verder af blijft, hij wordt toch hidden
tkv += ' data-param="attachments"';
tkv += ' data-description="true"';
// tkv += ' data-description-placeholder="Optional description"';
// tkv += ' (Maximum size: 5 MB)';
tkv += ' >';
tkv += ' </span>';
tkv += ' </span>';
tkv += '</div>';
} else {
tkv += filehtmlarr.join("");
}
return tkv;
}
var minMax = []; // te gebruiken uren voor timepicker vastleggen.
// ================================================================================================
// listKenmerk
// Genereer code voor flexkenmerken
//
// Genereer code voor flexkenmerken. Vrij kale code
// <tr><td>lbl1:</td><td>flex1</td><td>lbl2:</td><td>flex2</td></tr> en dat dan herhaald
// (Alleen!) voor bewerkbare velden voegen we ook name's toe die met het formulier gesubmit worden
// params: sql: moet een query met de goede :-) velden bevatten
// sinds kort worden deze By Name gebruikt ipv By volgorde
// module, key: alleen gebruikt voor flexkenmerk 'F' (file) 'E' (encrypted file) en 'M' (map)
// props { fnIsInvisible: optioneel function (volgnr, type) - true betekent onzichtbaar
// fnIsReadonly: optioneel function (volgnr) - true betekent readonly
// fnIsHidden: optioneel function (volgnr, default) - true betekent hidden (onzichtbaar maar wel aanwezig i.v.m. opslaan)
// fnClassname: optioneel function() - geeft een class of lege string terug
// parentKey: optioneel om flexkenmerken onder op te slaan
// kenmerk_module: optioneel bij ALG: "L", "G", "R" etc.
// multiMode
// hideVervallen: om alleen nu nog geldige waarden te tonen
// defaults { bsn: "12345678", plaats: "Enschede", postcode:"1234AB" } altijd lowercase namen
// prs_key (of obsolete reqId) - key om bij defaultwaarde in ##PRS_PERSLID_KEY## te substitueren
// wfbuilder: toon ook flex-colname :f123 (voor workflow expression builder)
// showConfidential: als true mogen vertrouwelijke waarden getoond worden, anders gemaskeerd
// sortFilename: optioneel - true betekent bestandenlijst wordt op naam gesorteerd, anders op datum.
// }
// Qua confidential-maskeren zijn er 2 aspecten:
// 1. zorgen dat de echt waarden niet getoond worden, dat kan lomp als allereerste actie
// maar ik verwacht dat men ooit bv wel de bijlagenaam wil tonen maar dan onklikbaar
// 2. zorgen dat de gemaskeerde waarden niet gesubmit worden, dan dus geen submitvelden opnemen
//
// ================================================================================================
function listKenmerk(sql, module, pkey, props)
{
//props.kenmerk_search; // zoekmode of niet
//props.multiMode; // TODO: support this!?!
//props.hideVervallen; // voor list/suggest
props.prs_key = props.prs_key || props.reqId; // voor persoonsafhankelijke kenmerkformule; Oude obsolete reqId nog even ondersteunen
//props.cont_key; // voor contactpersoonsafhankelijke kenmerkfomule
props.nameprefix = props.nameprefix || "k"; //
props.extraserie = props.extraserie || false; //
props.niveau = props.niveau || ""; //
//props.opdr_type; // voor bijlagen
//props.srtdeelKey; // alternatieve key voor sleutelmodule
//props.requiredbyfield; // ??
//props.requiredbyemptyval; // ??
props.serie = props.serie || 0; //
//props.parent_list; // Maak voor deze keys ook bijlagen knop
//props.mobile; // mobiele GUI
//props.kenmerk_extraTD; // mwoah
//props.notr; // Geen tr's toevoegen.
//props.nolabel; // Geen labels toevoegen.
props.flexstart = props.flexstart || 1; // De kenmerken vanaf de flexstart-ste element tonen (flexstart >= 1 indien meegegeven).
props.flexend = props.flexend || -1; // De kenmerken tot het flexend-ste element tonen {flexend >= 1 indien meegegeven}.
props.hasfilter = props.hasfilter || false; // De kenmerken kunnen op naam gefilterd worden.
props.tmpfolder = props.tmpfolder || ""; //
//props.copy // Bij het kopieren of vervolgen van een opdracht.
//props.getTmpfolder // indien true, dan levert deze functie de (onderweg bepaalde) tmpfolder op(??)
//props.showConfidential; //
//props.forceRequired; // In case only status dependent characteristics are shown (close confirm/...etc)
props.force_default_when_null = props.force_default_when_null || false; //
props.inline = props.inline || false; // tijdelijk misschien, om blockheader te voorkomen
// Ik moet de API2 name weten voor de bestandskenmerken-mobiel. Hier nog iets beters voor verzinnen...?
if (props.mobile)
{
var api2name = { "ALG": { "L": "locations",
"G": "buildings",
"R": "rooms"
},
"BES": "INTERNAL_ERROR_INVALID_API2NAME", // wel via mobile, maar readonly dus geen api2name nodig
"BEZ": "visitors",
"CNT": "INTERNAL_ERROR_INVALID_API2NAME", // wel via mobile, maar readonly dus geen api2name nodig
"FIN": "INTERNAL_ERROR_INVALID_API2NAME", // wel via mobile, maar readonly dus geen api2name nodig
"MLD": { "M": "issues",
"O": "orders2"
},
"PRS": { "P": "persons",
"A": "departments",
"B": "companies"
},
"INS": { "I": "inspections",
"D": "objects"
// "S": "sleutels"?
},
"RES": "reservations"
}[module] // niveau
if (api2name && typeof api2name == 'object')
api2name = api2name[props.kenmerk_module || props.niveau || "D"]; // kenmerk_module voor ALG, niveau voor INS
if (!api2name)
{
__DoLog(props);
__DoLog("What should api2name be for {0} and {1}?".format(module, props.kenmerk_module));
INTERNAL_ERROR_UNDEFINED_API2NAME;
}
}
var vars = {};
var c_maskmarker = "<em style='cursor:auto'>" + I("fa-ban") + "</em>" // prefix, niet klikbaar
var colCount = 0; // Even/oneven zodat we weten of we links of rechts zitten
var forceNewLine = false; // Bij labels en grote text velden
var idCounter = 1; // We maken alleen name/id-s voor de velden die ook echt bewerkt kunnen worden
var anyDate = false;
var anyTime = false;
var anyTextarea = false;
var anySelect = false;
var anyCollapsible = false;
var anyHint = false;
var blockId = 0;
var blockShow = [];
var kenmerkidref = new Array(); // Bijhouden welk kenmerk welke id referentie mee heeft gekregen
var dpYearRanges = []; // te gebruiken jaren voor datepicker vastleggen.
var attach_km_list = []; // Bijhouden welke bijlagen mappen al zijn gelezen (voor toevoegen van opdracht bij melding)
var kotherkey = null; // Wordt voor type 'E' en 'F' gevuld met de kenmerkkey waar deze bijlage vandaan komt
var allCollapsable = false; // true bij eerste 'l'-label
var inMobileBlock = false; // true van begin mobile-collapse-content tot eind mobile-collapse-content
//var kenmerk_2col = (props.flexcolumns >= 2); // 2 kolommnen voor flexkenmerken als aantal kolommen ingevuld 2 of meer is.
var kenmerk_2col = false; // DEPRECATED?
if (module == "INS" && props.niveau == "S")
{ // Sleutelmodule werkt met srtdeel_key
if (props.srtdeelKey > 0)
pkey = props.srtdeelKey;
}
// Zitten er expressie kenmerken tussen?
var hasAnyFlexExpr = false;
var hasAnyShowExpr = false;
var kenmerkUsedInExpr = []; // Neem hier de kenmerken op die een effect kunnen hebben op de waarde/zichtbaarheid van andere kenmerken
var matchedKeys;
var flexpregex = /:flex(\d+)/gi;
var oRs = Oracle.Execute(sql); // De hoofdquery, eerste keer
var hasAnyKenmerk = !oRs.EOF; // dan hoeft de twee keer niet
// Komt er uberhaupt iets moeilijks voor? Meestal niet namelijk
while (!oRs.eof) {
var kdefault = oRs("kenmerk_default").Value;
var kshowexpr = oRs("kenmerk_show_expr").Value;
if ((kdefault && (kdefault.match('##EXPR##') != null)) ||
(kshowexpr && kshowexpr.match('##SHOW##') != null))
{
hasAnyFlexExpr = true; // Omvat zowel ##EXPR## als ##SHOW##
if (kdefault && (kdefault.match('##EXPR##') != null)) {
while (matchedKeys = flexpregex.exec(kdefault)) {
if (sharedIndexOf(matchedKeys[1], kenmerkUsedInExpr) === -1) { // Alleen unieke waardes pushen
kenmerkUsedInExpr.push(matchedKeys[1]);
}
}
}
if (kshowexpr && kshowexpr.match('##SHOW##') != null) {
hasAnyShowExpr = true;
while (matchedKeys = flexpregex.exec(kshowexpr)) {
if (sharedIndexOf(matchedKeys[1], kenmerkUsedInExpr) === -1) { // Alleen unieke waardes pushen
kenmerkUsedInExpr.push(matchedKeys[1]);
}
}
}
}
oRs.MoveNext();
}
oRs.Close();
matchedKeys = null;
flexpregex = null;
kdefault = null;
kshowexpr = null;
// Labels with ##show## expression in SHOW mode must be suppressed when the fac_kenmwaarden_exprwaarde = 0
// because labels always have a value they will always show, even when they have a ##show## expression
// PF: ik begrijp niet zomaar waarom je dat niet bij het label regelt? Omdat je dan per label moet querien?
if (pkey > -1 && (props.reado || false) == true)
{
var label_sql = "SELECT fac_kenmwaarden_kenmerk_key, fac_kenmwaarden_exprwaarde "
+ " FROM fac_kenmwaarden "
+ " WHERE fac_kenmwaarden_module = '" + module + "'"
+ " AND fac_kenmwaarden_refkey = " + pkey
+ " AND fac_kenmwaarden_kenmerktype IN ('L','l')"
+ " AND fac_kenmwaarden_isexpr = '1'";
var label_oRs = Oracle.Execute(label_sql);
while (!label_oRs.eof)
{
show_label_expr[label_oRs("fac_kenmwaarden_kenmerk_key").Value] = label_oRs("fac_kenmwaarden_exprwaarde").Value;
label_oRs.MoveNext();
}
label_oRs.Close();
}
if (hasAnyKenmerk)
{
__Log("Opnieuw dezelfde query is niet supperefficient maar een MoveFirst is problematisch (FSN#39008)");
var oRs = Oracle.Execute(sql);
}
if ((pkey < 0 || props.copy) && props.tmpfolder == "")
props.tmpfolder = shared.random(32); // voor als nog geen key en wel bijlagen
var prssql = false;
// ============================================================================================
// Doorloop alle flexkenmerken
if (props.kenmerk_search)
kenmerk_write("<table class='fcltblocktab'>");
else if (!props.reado) { // Leave a marker for dynamic (re)loading of kenmerken
kenmerk_write("<flex-marker></flex-marker>"); // Custom elementje
}
var hasfilter_cnt = 0;
for (i = 1; hasAnyKenmerk && !oRs.eof; i++)
{
var thisfield = {};
thisfield.idCounter = idCounter;
kotherkey = null;
thisfield.separator = ''; //standaard
thisfield.kkenmerktype = oRs("kenmerk_kenmerktype").Value;
thisfield.kdefault = oRs("kenmerk_default").Value;
thisfield.kshow_expr = oRs("kenmerk_show_expr").Value;
thisfield.isExpression = false;
thisfield.isReadonly = false;
thisfield.isShowExpr = false;
thisfield.isSqlExpr = false;
thisfield.Classname = (props.fnClassname ? props.fnClassname(oRs) : "");
//ExpressionClass= (params.isShowExpr ? "flexshow" : "flexexpr")
addPreview = false;
if (!props.kenmerk_search && !props.multiMode)
{
// In multiMode no default values
thisfield.kwaarde = oRs("kenmerk_waarde").Value;
try // Het kenmerk wissen staat niet in alle kenmerk-queries!
{ thisfield.wissen = oRs("kenmerk_wissen").Value == 1; }
catch(e)
{ thisfield.wissen = false; }
thisfield.isExpression = (thisfield.kdefault && thisfield.kdefault.match('##EXPR##') != null);
if (thisfield.isExpression)
thisfield.isReadonly = true;
thisfield.isSqlExpr = (thisfield.kdefault && thisfield.kdefault.match('##SQL##') != null);
thisfield.isShowExpr = (thisfield.kshow_expr && thisfield.kshow_expr.match('##SHOW##') != null);
if (thisfield.isShowExpr)
thisfield.isExpression = true;
// For a new value, this default is used. It could be a primitive value (string, number or key) or
// it is suggested to support (later)
// a more sophisticated value, using ##asp-variable## and/or SQL:SELECT in the string.
if (thisfield.kwaarde == null && props.force_default_when_null && thisfield.kdefault)
thisfield.kwaarde = thisfield.kdefault;
if (thisfield.kwaarde != null)
{
if (thisfield.kwaarde == thisfield.kdefault && thisfield.kwaarde.match('##SQL##') != null)
{
prssql = true;
thisfield.kwaarde = thisfield.kwaarde.substr(thisfield.kwaarde.indexOf('##SQL##') + 7);
var sql2 = thisfield.kwaarde.replace("##PRS_PERSLID_KEY##", props.prs_key).replace("##PRS_CONTACTPERSOON_KEY##", props.cont_key);
var oRsPerslid = Oracle.Execute("SELECT ({0}) FROM DUAL".format(sql2)); // forceer 'SELECT' statements
if (oRsPerslid(0).Value != null)
thisfield.kwaarde = String(oRsPerslid(0).Value);
else
thisfield.kwaarde = '';
oRsPerslid.Close();
}
else if (thisfield.kdefault && thisfield.kwaarde == thisfield.kdefault && thisfield.kdefault.match('##EXPR##') != null)
{
thisfield.kwaarde = "";
}
}
}
// Meegegeven default verwerken (UWVA Pacta o.a.)
if (props.defaults && oRs("kenmerk_omschrijving").Value)
{
var xx = props.defaults[oRs("kenmerk_omschrijving").Value.toLowerCase()];
if (typeof xx != "undefined")
{
thisfield.kwaarde = xx;
if (oRs("kenmerk_kenmerktype").Value == "C" || oRs("kenmerk_kenmerktype").Value == "N" || oRs("kenmerk_kenmerktype").Value == "B" || oRs("kenmerk_kenmerktype").Value == "V")
thisfield.kwaarde = thisfield.kwaarde.substr(0, oRs("kenmerk_kenmerktype").Value == "V"? 1 : oRs("kenmerk_lengte").Value); // Kap de waarde op de maximale lengte af
}
}
if (oRs("kenmerk_key_count").Value > 1) {
thisfield.kkey = oRs("srtkenmerk_key").Value;
} else {
thisfield.kkey = oRs("kenmerk_key").Value;
}
thisfield.kkeycount = oRs("kenmerk_key_count").Value;
thisfield.komschrijving = (oRs("kenmerk_omschrijving").Value ? oRs("kenmerk_omschrijving").Value : "");
thisfield.klengte = oRs("kenmerk_lengte").Value;
if (!thisfield.klengte)
thisfield.klengte = 4000;
thisfield.kdec = oRs("kenmerk_dec").Value;
thisfield.knmin = oRs("kenmerk_nmin").Value;
thisfield.knmax = oRs("kenmerk_nmax").Value;
thisfield.ksysteem = oRs("kenmerk_systeem").Value;
thisfield.kvolgnr = "" + oRs("kenmerk_volgnr").Value;
thisfield.kdimensie = oRs("kenmerk_dimensie").Value; // beperkt bij uploads de extensie
thisfield.khint = oRs("kenmerk_hint").Value;
thisfield.kregexp = oRs("kenmerk_regexp").Value;
thisfield.kdomein_key = oRs("kenmerkdomein_key").Value;
thisfield.required = oRs("kenmerk_verplicht").Value; // dit is een integer, geen boolean
thisfield.reqbystatus = module == "MLD" && !props.kenmerk_search ? oRs("kenmerk_verplicht_status").Value : -1;
thisfield.reqgroup = oRs("kenmerk_groep").Value;
thisfield.otherPath = oRs("otherpath").Value; // otherKenmerkPath, alleen voor meldingen en facturen (tbv kopieren)
thisfield.functie_key = oRs("fac_functie_key").Value; // Extra Autorisatie rechten.
if (thisfield.functie_key)
thisfield.additAuthrights = user.checkAutorisation(thisfield.functie_key, true); // Additional Authorization rights.
// afgeleide veldeigenschappen
thisfield.maskeren = !props.showConfidential && (thisfield.ksysteem&4);
// Checkbox is een -verder compatible- type met voorheen N(1) met min 0 en max 1
// Door die oude voorkomens hier direct om te zetten hoeven we die oude variant verder
// niet meer te erkennen (zou kunnen dat die B nog anders is?)
if ( (thisfield.kkenmerktype == "N" || thisfield.kkenmerktype == "B") && thisfield.klengte == 1 && thisfield.knmin == 0 && thisfield.knmax == 1 && (thisfield.kdec == 0 || !thisfield.kdec))
thisfield.kkenmerktype=="V";
thisfield.required = props.forceRequired || thisfield.Classname ? 1 : thisfield.required;
if ((props.sqldefaultnotrequired && thisfield.kdefault && thisfield.kdefault.match("##SQL##")) || props.ignorerequired)
thisfield.required = 0; // false
// forceReadonly kan gezet zijn: dan is het veld *altijd* readonly en kan alleen ingevuld zijn
// doordat een extern proces (importjob?) dat doet of het wordt gevuld door de default waarde.
// Als er extra autorisatie is gezet en je hebt hiervan alleen lees rechten, dan ook readonly forceren.
thisfield.forceReadonly = oRs("kenmerk_toonbaar").Value == 1 ||
(thisfield.additAuthrights && thisfield.additAuthrights.ALGreadlevel < 9 && thisfield.additAuthrights.PRSreadlevel < 9 &&
thisfield.additAuthrights.ALGwritelevel > 5 && thisfield.additAuthrights.PRSwritelevel > 5);
// Velden die de gebruiker niet mag zien zijn we h<><68>l snel klaar mee
// Ook velden waar je niet op kunt zoeken (bv vertrouwelijke) slaan we direct over in zoekmode
// En labels met een readonly-kenmerk tonen we niet als readonly, om invulinstructies in showmode weg te laten
if ( (!props.kenmerk_search && props.fnIsInvisible && props.fnIsInvisible(thisfield.kvolgnr, thisfield.kkenmerktype, oRs))
|| (props.kenmerk_search && (thisfield.kkenmerktype == "L" || thisfield.kkenmerktype == "l" || thisfield.kkenmerktype == "Q" || thisfield.kkenmerktype == "M" || thisfield.kkenmerktype == "F" || thisfield.kkenmerktype == "E") || thisfield.kvolgnr < 0)
|| (!props.kenmerk_search && thisfield.kkenmerktype == "L" && thisfield.forceReadonly && props.fnIsReadonly && props.fnIsReadonly(thisfield.kvolgnr, oRs))
|| (props.kenmerk_search && (thisfield.ksysteem&4)
|| (thisfield.functie_key && !thisfield.additAuthrights)) // Als er geen rechten zijn op de extra autorisatie, dan het kenmerk niet tonen.
)
{
oRs.MoveNext();
continue; // Onzichtbaar
}
//kenmerk_write( "<!--YY:"+thisfield.idCounter+":"+thisfield.komschrijving+"-->");
thisfield.readonlyfield = thisfield.forceReadonly; // startwaarde
if (!thisfield.readonlyfield && !props.kenmerk_search && props.fnIsReadonly) // Zoeken is natuurlijk nooit readonly
thisfield.readonlyfield = props.fnIsReadonly(thisfield.kvolgnr, oRs);
if (thisfield.readonlyfield || props.kenmerk_search)
thisfield.required = 0; //false
var required_class = "";
var required_group = "";
if (thisfield.required != 0)
{
required_class = (thisfield.Classname? thisfield.Classname : " required");
// Indien required afhankelijk is van een gewoon veld dan requiredgroup gebruiken met groep >= 10
if (props.requiredbyfield && thisfield.required == 1)
{
thisfield.required = 10;
}
if (thisfield.required > 1)
{
if (thisfield.required == 2)
required_group = thisfield.reqgroup + "S" + parseInt(props.serie, 10);
else
required_group = thisfield.required + "S" + parseInt(props.serie, 10);
required_class += required_group;
if (!requiredGroupUsed[required_group]) // Array requiredGroupUsed[] zorgt voor eenmalige initiele aanroep van checkRequiredGroup(groep) per groep
{
requiredGroupUsed[required_group] = true;
%> <span id="requiredgeg_<%=props.nameprefix + thisfield.idCounter%>" style="display:none">
<script type="text/javascript">
$(function()
{
<% if (thisfield.required > 9)
{ // Gewone veld ook dezelfde requiredgroup class geven
%>
$("#<%=props.requiredbyfield%>").addClass("<%=required_class%>");
<% } %>
checkRequiredGroup("<%=required_group%>", <%=(props.requiredbyemptyval != null? "{emptyvalue: " + props.requiredbyemptyval + "}" : "null")%>);
$("#requiredgeg_<%=props.nameprefix + thisfield.idCounter%>").remove(); // Na het uitvoeren kan de ready functie weer weg zodat deze niet
});
</script>
</span>
<% }
}
}
// Als een parent kenmerk niet toonbaar is (vinkje "Niet te wijzigen" is gezet) en een lege waarde heeft,
// dan moet het parent kenmerk toch getoond worden i.v.m. de afhankelijkheid.
// en het child kenmerk is toonbaar (vinkje "Niet te wijzigen" is niet gezet)
// Afhankelijke child-parent kenmerken kunnen niet beide "niet toonbaar" zijn.
// Dan heeft de afhankelijkheid ook geen zin. Dus daarop ga ik niet controleren. Dat is een configuratie fout.
// Alleen controle of parent niet toonbaar is bij een toonbare child.
var isParent = false;
if (thisfield.kdomein_key)
{
sqlP = "SELECT ut2.fac_usrtab_parentkey"
+ " FROM fac_kenmerkdomein kd1"
+ " , fac_usrtab ut1"
+ " , fac_usrtab ut2"
+ " WHERE kd1.fac_usrtab_key = ut1.fac_usrtab_key"
+ " AND ut1.fac_usrtab_key = ut2.fac_usrtab_parentkey" // Kenmerk 1 is een parent van een ander kenmerk 2.
+ " AND ut2.fac_usrtab_verwijder IS NULL"
+ " AND kd1.fac_kenmerkdomein_key = " + thisfield.kdomein_key;
var oRs2 = Oracle.Execute(sqlP);
if (!oRs2.eof)
{
isParent = true; // Er is minstens 1 child kenmerk.
// In zoekscherm hoeft de parent dan ook niet readonly te zijn. Je mag er mee zoeken
if (props.kenmerk_search) thisfield.readonlyfield = false;
}
oRs2.close();
}
// We kijken wanneer we dit veld direct sowieso kunnen skippen
// In het geval van readonly laten we velden zonder waarde helemaal niet zien,
// met uitzondering van Labels.
// Parent kenmerken laten we altijd zien.
// PF vraagt zich af: heeft dit ook gevolg voor print en excel?
// En: voor type M is het altijd nu nog leeg, en die komen dus readonly nooit!
// Voorlopig laat ik die dan altijd maar zien (TODO: evt niet als er 0 bestanden zijn)
// Als geavanceerd dan maakt het niet uit of het readonly is. Dan moet je het kenmerk gewoon tonen.
// @@TODO: dit ziet er niet helemaal scherp uit met die kenmerk_search, DeMorgan?
if (thisfield.readonlyfield
&& ((!thisfield.kwaarde || thisfield.kwaarde=="") && thisfield.Classname=="")
&& !isParent
&& thisfield.kkenmerktype != "L"
&& thisfield.kkenmerktype != "l"
&& thisfield.kkenmerktype != "M"
&& (!props.kenmerk_search &&
(thisfield.kkenmerktype == "C" ||
thisfield.kkenmerktype == "N" ||
thisfield.kkenmerktype == "V" ||
thisfield.kkenmerktype == "B" ||
thisfield.kkenmerktype == "D" ||
thisfield.kkenmerktype == "T" ||
thisfield.kkenmerktype == "R" ||
thisfield.kkenmerktype == "S"))
)
{
oRs.MoveNext();
continue;
}
// Bijhouden van kenmerken. Later kan blijken dat ze parent kenmerken zijn.
// Kenmerkkey alleen is niet uniek bij meerdere bezoekers of factuurregels.
// Daarom nameprefix meenemen want die is per bezoeker of factuurregel wel uniek.
kenmerkidref[props.nameprefix + thisfield.kkey] = new idref(props.nameprefix + thisfield.idCounter, thisfield.kwaarde);
var parentkenmerkid = "";
var parentkenmerk_key = -1;
var parentkenmerkwaarde;
// Als er bij kenmerk_search meerdere afhankelijke (=children) kenmerken zijn, dan hoeft deze check ook niet
if (!thisfield.readonlyfield && !(thisfield.kkeycount > 1 && props.kenmerk_search) && (thisfield.kkenmerktype == 'S' || thisfield.kkenmerktype == 'R'))
{
// Aannames die tot nu toe zijn gemaakt:
// 1) Een kenmerk kan alleen afhankelijk zijn van een kenmerk van hetzelfde type.
// M.a.w. een suggest box kan nu nog alleen afhankelijk zijn van een andere suggestbox (idem geldt voor listbox).
// Als een suggestbox namelijk dezelfde kenmerkdomein gebruikt als een listbox en ze worden beide gelijktijdig gebruikt geeft dat anders problemen.
// 2) Afhankelijke suggestboxen met hetzelfde kenmerkdomein mogen niet voorkomen. Anders kun je niet de juiste afhankelijke suggestbox bepalen.
// Idem geldt dit voor listboxen.
// 3) Als een kenmerk afhankelijk is van een ander kenmerk dan moet de afhankelijke kenmerk een hoger volgnummer hebben (later worden getoond)
// dan het kenmerk waarvan het afhankelijk is.
// 4) Afhankelijkheid van kenmerken werkt alleen voor eigen tabellen (fac_usrtab, fac_usrdata)
// Is er een afhankelijkheid met een ander kenmerk (met een lager volgnummer)?
var sqlDep = "SELECT tfin.kenmerk_key"
+ " , tfin.kenmerk_key_count"
+ " , tfin.kenmerk_volgnr"
+ " FROM fac_usrtab ut1"
+ " , fac_usrtab ut2"
+ " , fac_kenmerkdomein kd1"
+ " , fac_kenmerkdomein kd2"
+ " , (" + sql + ") tfin"
+ " WHERE kd1.fac_kenmerkdomein_key = " + thisfield.kdomein_key
+ " AND kd1.fac_usrtab_key = ut1.fac_usrtab_key"
+ " AND ut1.fac_usrtab_parentkey = ut2.fac_usrtab_key"
+ " AND ut2.fac_usrtab_key = kd2.fac_usrtab_key"
+ " AND kd2.fac_kenmerkdomein_key = tfin.kenmerkdomein_key"
+ " AND tfin.kenmerk_kenmerktype = " + safe.quoted_sql(thisfield.kkenmerktype)
+ " ORDER BY tfin.kenmerk_volgnr"
var oRs2 = Oracle.Execute(sqlDep);
// Indien kenmerk_key_count > 1, dan zijn er meerdere (gegroepeerde) parents gevonden, dan geen dependency check bij kenmerk_search
if (!oRs2.eof && !(oRs2("kenmerk_key_count").Value > 1 && props.kenmerk_search))
{ // Er is een afhankelijkheid met een ander kenmerk
var volgnummer = oRs2("kenmerk_volgnr").Value;
var temp_parentkenmerk_key = oRs2("kenmerk_key").Value;
oRs2.MoveNext();
if (oRs2.eof) // Er is maar 1 parent gevonden -> doe de dependency check
{
if (thisfield.kvolgnr < volgnummer)
{
__DoLog("INTERNAL_ERROR: kenmerk {0}, kenmerkkey {1}".format(thisfield.komschrijving, thisfield.kkey));
_AiAi("INTERNAL_ERROR: Parent property not found in front of dependent property with key " + thisfield.kkey);
}
else
{
parentkenmerk_key = temp_parentkenmerk_key;
parentkenmerkid = kenmerkidref[props.nameprefix + parentkenmerk_key].idname;
parentkenmerkwaarde = kenmerkidref[props.nameprefix + parentkenmerk_key].waarde;
}
}
else
{
__DoLog("kenmerk {0} (key {1}) is afhankelijk van TWEE parents (key {2} en {3}).\nDat is een inrichtingsfout. Afhankelijkheid wordt genegeerd"
.format(thisfield.komschrijving, thisfield.kkey, temp_parentkenmerk_key, oRs2("kenmerk_key").Value), "#FFFF00");
}
}
oRs2.close();
}
// Als geavanceerd dan maakt het niet uit of het readonly is. Dan moet je het kenmerk gewoon tonen.
if (props.kenmerk_search && thisfield.readonlyfield)
thisfield.readonlyfield = false;
colCount++; // Nu pas ophogen.
// De kenmerken vanaf de flexstart-ste element tonen.
// De kenmerken tot het flexend-ste element tonen.
if (props.flexstart > colCount || (props.flexend >= 0 && props.flexend < colCount))
{
oRs.MoveNext();
idCounter++;
continue;
}
if( thisfield.kkenmerktype == 'L' || thisfield.kkenmerktype == 'l' )
{
forceNewLine = true;
colCount = 2; // Forceer 'even'
if (inMobileBlock)
kenmerk_write("</div>");
}
else
forceNewLine = false;
if (props.kenmerk_search || thisfield.kwaarde != null && thisfield.kwaarde != "")
allCollapsable = false;
var kv = ""; // Het in te voegen veld in HTML, zonder label
var kv_arr = [];
var onchangeExp = "";
var onchangeExpValid = "";
// Een editable flexkenmerk wordt altijd weergegeven volgens het volgende format:
// <tr><td class="label"><label>LABEL</label></td><td><input type="text" value='XX'></td></tr>
// Een readonly flexkenmerk wordt altijd weergegeven volgens het volgende format:
// <tr><td class="label"><label>LABEL</label></td><td><span>XX</span></tr>
// Eventueel met 2 kolommen in een rij.
// Er zijn 2 uitzonderingen:
// - een lange tekst wordt een textarea
// - een R wordt een select
// We doen eerst die uitzonderingen
// Als er expresssies in het spel zijn, dan berekenen we bij het verlaten met deze functie
// die we dan voor de clientside toevoegen aan de betrokken velden
// PAS OP: deze codestrings bevatten DUBBELE quotes, en moeten bij gebruik dus in ENKELE quotes gezet worden
// (nog uitzoeken of de if fvalid versie niet gewoon altijd kan)
if (hasAnyFlexExpr)
{
onchangeExp = ";calculateFlexExpressions(this);";
onchangeExpValid = ";if (fvalid) calculateFlexExpressions(this);";
}
// Bijhouden welk kenmerk welke id referentie mee heeft gekregen
function idref(idname, waarde)
{
this.idname = idname;
this.waarde = waarde;
}
// we hebben nu 3 groepen:
// thisfield met veldeigenschappen
// props met flexblokeigenschappen
// en nu ook params om afgeleid bepaalde zaken mee te geven
params= {
pkey: pkey,
module: module,
hasAnyFlexExpr: hasAnyFlexExpr,
kenmerkUsedInExpr: kenmerkUsedInExpr,
parentkenmerkid: parentkenmerkid,
parentkenmerkwaarde: parentkenmerkwaarde,
required_class: required_class,
required_group: required_group,
onchangeExp: onchangeExp,
onchangeExpValid: onchangeExpValid,
api2name: api2name
};
// Auto-Add generieke BLOCK_START als het eerste veld geen bloktitel is
if (__insideblock == 0 // kenmerk buiten BLOCK (mag niet, m.u.v. Nieuwe sectie 'Q')
&& !props.kenmerk_search // Tenzij in kenmerkfilter
&& thisfield.kkenmerktype != 'l' // geen collapsible block (die komt automatisch zelf met een blocktitel)
&& thisfield.kkenmerktype != 'Q' // geen blok bij een nieuwe sectie (die is op block-niveau)
&& !props.inline // inline moet geen blocktitel
&& !props.noblock)
{
// Een blok verzinnen. De field-eigenschappen gelden niet.
// Dus conceptueel eigenlijk even /* thisfield = {idCounter: idCounter, kkenmerktype: 'l' }; */
thisfield_auto = { idCounter: idCounter
, kkey: 0
, kkeycount: 0
, kkenmerktype: "l"
, isShowExpr: false
}
kv = kenmerktype_blocktitel(thisfield_auto, props, params);
blockId = idCounter;
blockShow["flx_" + props.nameprefix + blockId] = 0;
// Om er een veld van te maken zou je kv2html(..) doen,
// maar ik weet dat die voor blokken gewoon de parameter teruggeeft
kenmerk_write(kv);
}
switch (thisfield.kkenmerktype)
{
case 'C':
kv = kenmerktype_text(thisfield, props, params);
anyTextarea = anyTextarea || (thisfield.klengte > 50 && !props.kenmerk_search && !thisfield.readonlyfield && !thisfield.maskeren);
break;
case 'D':
kv = kenmerktype_date(thisfield, props, params, dpYearRanges);
anyDate = anyDate || !thisfield.maskeren;
break;
case 'T':
kv = kenmerktype_time(thisfield, props, params);
anyTime = anyTime || !thisfield.maskeren;
break;
case 'R':
kv = kenmerktype_listbox(thisfield, props, params);
anySelect = anySelect || (!thisfield.readonlyfield && !thisfield.maskeren);
break;
case 'S':
kv = kenmerktype_suggest(thisfield, props, params);
break;
case 'V':
kv = kenmerktype_checkbox(thisfield, props, params);
thisfield.separator = "";
break;
case 'N':
case 'B':
kv = kenmerktype_number(thisfield, props, params);
break;
case 'X':
kv = kenmerktype_xref(thisfield, props, params);
break;
case 'L':
kv = kenmerktype_label(thisfield, props, params);
thisfield.separator = "";
break;
case 'l':
if (!props.noblock)
{
kv = kenmerktype_blocktitel(thisfield, props, params);
anyCollapsible = anyCollapsible || (!props.reado && thisfield.forceReadonly)
blockId = thisfield.idCounter;
blockShow["flx_" + props.nameprefix + blockId] = 0;
}
break;
case 'F':
case 'E':
kv_data = kenmerktype_bijlage(thisfield, props, params);
kv = kv_data.lkv;
addPreview = props.reado && kv_data.addPreview;
kotherkey = kv_data.kotherkey;
break;
case 'M':
params.attach_km_list = attach_km_list;
kv_data = kenmerktype_folder(thisfield, props, params);
if (thisfield.otherPath && !inArray(thisfield.otherPath, attach_km_list)) // Voeg een bijlagenmap alleen toe als deze nog niet in het array zit.
attach_km_list.push(thisfield.otherPath); // Ja, en wel NA aanroep van kenmerk_folder. Anders gaat het huidige pad toch mee in params.attach_km_list!
kv = kv_data.lkv;
addPreview = props.reado && kv_data.addPreview;
break;
case 'Q':
kv = kenmerktype_spacer(thisfield, props, params);
break;
}
anyHint = anyHint || (thisfield.kkenmerktype != 'l' && thisfield.kkenmerktype != 'Q' && kv && thisfield.khint != null && !thisfield.ishidden && !props.nolabel);
if (thisfield.kkenmerktype != "l" && kv.length > 0)
{ // Verhoog het aantal ingevulde kenmerken in een blok.
blockShow["flx_" + props.nameprefix + blockId]++;
}
// vangnet: verbergen ondanks alles (kan ook vooraf, is slimmer)
thisfield.komschrijving = (thisfield.maskeren ? c_maskmarker + "&nbsp;" + thisfield.komschrijving : thisfield.komschrijving);
thisfield.ishidden = (props.fnIsHidden && props.fnIsHidden(thisfield.kvolgnr, thisfield.kdefault));
// deze nog wegmanagen TODO
var makeCheckbox = (((thisfield.kkenmerktype == "N" || thisfield.kkenmerktype == "B") && thisfield.klengte == 1 && thisfield.knmin == 0 && thisfield.knmax == 1 && (thisfield.kdec == 0 || !thisfield.kdec)) || thisfield.kkenmerktype=="V");
// ==========================================================================================
// Alles bepaald, te tonen waarde/veld in kv, nu positioneren enzo in kvhtml
// ==========================================================================================
kenmerk_write("\n<!-- Kenmerk {0}:{1} '{2}' -->\n".format(thisfield.kkey, thisfield.kkenmerktype, thisfield.komschrijving));
// Voor een multi-value waarde maken we een array, denk aan 3 bestandsnamen,
kv_arr.push({label: ""/*geen toevoeging aan het label*/, waarde: kv});
var kvhtml = "00"; // hierin bouwen we de html op
for(kv_i=0; kv_i< kv_arr.length; kv_i++)
{
var kvparams = { kcount: thisfield.kkeycount
, forceNewLine: forceNewLine
, colCount: colCount
, kenmerk_2col: kenmerk_2col
, props: props /* de rest zeg maar */
, module: module
, kotherkey: kotherkey
, clabelCounter: clabelCounter
, makeCheckbox: makeCheckbox
, addPreview: addPreview
, kv: kv_arr[kv_i].waarde
, label_ext: kv_arr[kv_i].label
, hasAnyFlexExpr: hasAnyFlexExpr
, isParent: isParent
};
kvhtml = kv2html(thisfield, kvparams);
hasfilter_cnt = hasfilter_cnt + (kvhtml == "" ? 0 : 1);
//kvhtml = "<tr><td>"+thisfield.kkey+"/"+thisfield.komschrijving+"</td><td>"+kv_arr[kv_i].waarde+"</td></tr>"; //testshortcut
// En hier schrijven we het hele veld dan naar de pagina
// suppress label in SHOW mode when the label has a ##show## expression and the exprwaarde == false
var suppress_label = show_label_expr[thisfield.kkey] == 0 ||
(props.reado && thisfield.kshow_expr && module == 'MLD' && pkey && (thisfield.kkenmerktype == "L" || (thisfield.kkenmerktype != "l" && thisfield.kdefault)) && !showIsVisible(pkey, thisfield.kshow_expr, (props.niveau == "O" ? "opdr" : "")));
if (!suppress_label)
kenmerk_write (kvhtml);
idCounter++; // Nu ophogen
}
oRs.MoveNext();
// Collapse code er achteraan als de *volgende* een ander label is @@TODO
if (!thisfield.ishidden && (inMobileBlock || (!props.mobile && allCollapsable)) && (oRs.Eof || oRs("kenmerk_kenmerktype").Value.toUpperCase() == 'L')) // einde huidige label
{
if (props.mobile)
{
kenmerk_write('</div>');
inMobileBlock = false;
if (!allCollapsable) // the current collapseBlock should be expanded
kenmerk_write('<script> $(function(){ $("#collLabel'+clabelCounter+'").trigger("click"); });</script>');
}
else
kenmerk_write('<script>$(function(){$("#' + props.nameprefix + 'clabel' + clabelCounter + '").addClass("flexcollapsed").nextUntil($("#' + props.nameprefix + 'clabel' + (clabelCounter + 1) + '")).hide();})</script>');
allCollapsable = false;
}
}
// Alle i flexkenmerken doorlopen.
// ============================================================================================
if (hasAnyKenmerk)
oRs.close();
// All fields are done here
if (props.kenmerk_search)
{
if (hasfilter_cnt == 0)
{
kenmerk_write("<tr><td>" + L("lcl_shared_advanced_none") + "</td></tr>");
}
kenmerk_write("</table>");
}
// Maak kenmerkblokken die geen gegevens bevatten onzichtbaar.
for (sb in blockShow)
{
if (blockShow[sb] == 0)
{ %>
<script>
$("#<%=sb%>").hide();
</script>
<% }
}
if (/*!thisfield.ishidden && PF:deze bestaat hier niet meer */ inMobileBlock || (!props.mobile && allCollapsable)) // allerlaatste ook nog
{
if (props.mobile)
{
kenmerk_write('</div>');
if (!allCollapsable) // the current collapseBlock should be expanded
kenmerk_write('<script> $(function(){ $("#collLabel'+clabelCounter+'").trigger("click"); });</script>');
}
else
kenmerk_write('<script>$(function(){$("#' + props.nameprefix + 'clabel' + clabelCounter + '").addClass("flexcollapsed").nextUntil($("#' + props.nameprefix + 'clabel' + (clabelCounter + 1) + '")).hide();})</script>');
}
var counterName = (props.extraserie? props.nameprefix + "_all" : "k_all");
var flexsqlName = (props.extraserie? props.nameprefix + "_flexsql": "k_flexsql");
if (!props.mobile)
{
if (!props.notr)
kenmerk_write('<tr>');
kenmerk_write('<td>');
}
if (hasAnyKenmerk && props.flexstart == 1) // Deze hoeft maar 1 keer.
{ // Toelichting: In bez_edit_bezoekers.inc wordt load_kenmerk.asp twee keer achter elkaar aangeroepen.
// Een keer voor kenmerken die men achter de bezoeker op dezelfde regel wil hebben staan
// en een keer voor de rest van de kenmerken die in een <div> onder de bezoeker komen te staan.
// Om te voorkomen dat beide keren de id's k_all, k_flexsql en ktmpfolder worden aangemaakt alleen de eerste keer deze aanmaken.
if (pkey < 0 || props.copy)
kenmerk_write("<input type='hidden' name='ktmpfolder" + props.serie + "' id='ktmpfolder" + props.serie + "' value='" + props.tmpfolder + "'>");
kenmerk_write('<input type="hidden" id="' + counterName + '" name="' + counterName + '" value="' + (idCounter - 1) + '">');
kenmerk_write('<input type="hidden" id="' + flexsqlName + '" name="' + flexsqlName + '" value="' + (prssql? 1 : 0) + '">');
kenmerk_write('<input type="hidden" name="nameprefix" value="' + props.nameprefix + '">');
}
if (!props.mobile)
{
kenmerk_write('</td>');
if (!props.notr)
kenmerk_write('\n</tr>');
}
// Wat 'globale' data voor calculateFlexExpressions()
if (hasAnyFlexExpr) { %>
<input type="hidden" id="<%=props.nameprefix%>_data"
data-any-show="<%=hasAnyShowExpr ? 1 : 0%>"
data-module="<%=module%>"
data-refkey="<%=pkey%>"
data-niveau="<%=props.kenmerk_module%>"
data-extraserie="<%=props.extraserie ? props.extraserie : 0%>">
<% }
if (__insideblock > 0) {
kenmerk_write(BLOCK_END_HTML());
__insideblock = 0;
}
// Eventuele scripts moeten buiten de </table>
if (anyCollapsible && !props.mobile && !props.kenmerk_search)
{
%><script>
$(function() {
$(".card[id^=flx_<%=props.nameprefix%>] > [data-toggle=collapse]").on("click", function () {
let $target = $($(this).data("target"));
$(this).attr("aria-expanded", ($(this).attr("aria-expanded") == "false" ? "true" : "false"));
$target.toggle().promise().done(() => {
FcltMgr.resized();
$target[0].scrollIntoView({ block: "nearest", behavior: "smooth" });
});
});
});
</script><%
}
if (anyTextarea && !props.kenmerk_search)
{
%><script>
$(function()
{
$("textarea[name^=<%=props.nameprefix%>]").on("resize", function () { FcltMgr.resized(window); });
if (<%=(props.mobile ? 0 /* Niet bij mobile */ : 1)%> && $.fn.autogrow)
$("textarea[name^=<%=props.nameprefix%>]").autogrow();
});
</script><%
}
if (anySelect && props.kenmerk_search)
{
%><script>
$(function()
{
$("select[name^=<%=props.nameprefix%>][advmulti=1]").multiSelectToggle({advanced: true});
});
</script><%
}
if (anyHint)
{
%><script>
$(function() {
if (Modernizr.pointerevents || Modernizr.touchevents) {
$("label[for^=<%=props.nameprefix%>]").parent("td.hashint").find("span.hint").on("contextmenu", function (e) { e.preventDefault(); })
.on("touchstart", () => {});
}
});
</script><%
}
if (props.kenmerk_search)
{
%><script>
$(function()
{
$("select.operand").each(function() {
$(this).change(function() {
var isIs = $(this).val() == "<>" || $(this).val() == "=";
var $advDiv = $(this).next("div.advmultitoggle:has(> select[multiple])"); // open multiToggle
if (!isIs && $advDiv.length)
$advDiv.find("span.multi_select_toggle, span.multi_suggest_toggle").click(); // close open multiToggle
$(this).next("div.advmultitoggle")
.find("span.multi_select_toggle, span.multi_suggest_toggle")
.toggleClass("disabled", !isIs);
});
});
});
</script><%
}
// Bij kenmerk_search doen de load_kenmerk's geen FCLTHeader.Generate en dus hebben
// we date.js niet gegarandeerd. Dates werd echter hieronder toch al niet
// meegenomen dus komen we er mee weg gewoon hier geen kalenders te doen
if (anyDate && !props.kenmerk_search)
{
// FCLTHeader.Requires is hier te laat
// Zie ook calendar.inc. Delen code was iets te lastig
%><script type="text/javascript">
$(function()
{
<% /* Onderstaande staat ook in kenmerk_js.asp */ %>
var touchdevice = (typeof window.orientation !== "undefined") || (typeof window.ontouchstart !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
if ((typeof Modernizr == "undefined" || !Modernizr.inputtypes.date || !touchdevice) && $.datepicker)
{
$.datepicker._gotoToday = function(id) {
$(id).datepicker("setDate", new Date()).datepicker("hide").trigger("change").blur();
};
// jQuery datepicker
$("input[name^=<%=props.nameprefix%>].flddate").not("[readonly]").datepicker({
showOn: "none",
showButtonPanel: true,
currentText: L("lcl_date_today"),
closeText: L("lcl_cancel"),
duration: 'fast',
dateFormat: 'dd-mm-yy', // zo verwacht de flex-code het.
changeYear: true,
changeMonth: true,
beforeShow: function(input, inst) { setTimeout("FcltMgr.resized(window)", 100) },
onUpdateDatepicker: function() { $(".ui-datepicker-current").removeClass("ui-priority-secondary").addClass("ui-priority-primary"); },
dayNames: calendar_names.days,
dayNamesMin: calendar_names.daysMin,
dayNamesShort: calendar_names.daysMin,
firstDay: 1,
monthNamesShort: calendar_names.monthsShort,
monthNames: calendar_names.months,
showWeek: true
});
<%
for (i=0; i < dpYearRanges.length; i++)
{
fld_id = dpYearRanges[i].id;
fld_val = dpYearRanges[i].range;
%>
$("#<%=fld_id%>").datepicker("option", "yearRange", "<%=fld_val%>");
<%
}
%>
}
else
{
// Native date input field
$("input[name^=<%=props.nameprefix%>].flddate").not("[readonly]").each(function() {
// Native, so change date format from [DD-MM-YYYY] -> [YYYY-MM-DD] (native format)
$(this).val($(this).attr("value").split("-").reverse().join("-"));
// Make this a native datepicker
$(this).attr("type", "date");
// Change hidden type field from 'D' to 'DN'
var nativeId = $(this).attr("id").slice(0, -3);
$("input:hidden#"+nativeId+"t").val("DN");
});
}
});
</script><%
}
if (anyTime && !props.kenmerk_search)
{
// FCLTHeader.Requires is hier te laat
%><script type="text/javascript">
var minMax = minMax || {};
$(function()
{
var touchdevice = (typeof window.orientation !== "undefined") || (typeof window.ontouchstart !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
if (typeof Modernizr == "undefined" || !Modernizr.inputtypes.time || !touchdevice)
{
<% for (i = 0; i < minMax.length; i++)
{ %>
$.extend(minMax, {"<%=minMax[i].namePrefix + minMax[i].id%>": {"instantiated": false, "startTime": "<%=minMax[i].kmin%>", "endTime": "<%=minMax[i].kmax%>"}} );
<% } %>
var entry;
$("input[name^=<%=props.nameprefix%>].fldtime").not("[readonly]").each(function()
{
entry = $(this).attr("id").slice(0, -3);
if (entry in minMax && !minMax[entry].instantiated)
{
$(this).timePicker({
step: 15,
startTime : minMax[entry].startTime,
endTime : minMax[entry].endTime,
columns : <%=S("timepickercolumns")%>,
onChange : function () {
$timeInput = $(this).parents("div.time-holder").prev("input[name^=<%=props.nameprefix%>].fldtime")
$timeInput.removeClass("bad");
$timeInput.trigger("change");
}
});
minMax[entry].instantiated = true;
}
});
}
else
{
// Native timepicker
$("input[name^=<%=props.nameprefix%>].fldtime").not("[readonly]").each(function() {
// Make this a native timepicker
$(this).attr("type", "time");
});
}
});
</script><%
}
if (props.hasfilter && hasfilter_cnt > 5)
{
%>
<script>
$(function ()
{
$(".fcltblocktab").eq(0).before("<div class='advanced-header'><span class='advanced-header-text'>" + L("lcl_flexible_properties") + "</span><input id='autofilter' class='autofilter_<%=props.nameprefix%>' type='text' placeholder='"+safe.htmlattr(L("lcl_autofilter"))+"'></div>");
$(".autofilter_<%=props.nameprefix%>")
.click(function(e) {e.stopPropagation()})
.keyup(function(e) {
if (e.which == 27) {
$(".autofilter_<%=props.nameprefix%>").val("");
}
delayed(200, doFilter.bind(null, $(".autofilter_<%=props.nameprefix%>")), "<%=props.nameprefix%>");
});
});
function delayed(delay, fn, nameprefix)
{
if (window["timerID_" + nameprefix])
clearTimeout(window["timerID_" + nameprefix]);
window["timerID_" + nameprefix] = setTimeout(fn, delay);
}
function doFilter(deze)
{
var valThis = deze.val().toLowerCase();
var $flex_table = deze.closest(".advanced-header").next(".fcltblocktab");
$flex_table.find(":not(.times) > tr").each(function () {
var text = $(this).find("td.label > label").text().toLowerCase();
$(this).toggle(text.indexOf(valThis) > -1);
});
}
</script>
<%
}
if (props.mobile && clabelCounter)
{ %>
<script>
$(function ()
{
for (var i = 0; i <= <%=clabelCounter%>; i++)
{
if ($("h3#collLabel"+i).next("div.ui-collapsible-content") &&
$("h3#collLabel"+i).next("div.ui-collapsible-content").children().length == 0)
{
// Change empty collapsable mobile labels back to regular labels
$("h3#collLabel"+i).unwrap()
.contents().unwrap();
}
}
});
</script>
<% } if (props.multiMode)
{ %>
<script type="text/javascript">
$(function()
{
init_multi_flex();
});
</script>
<% }
// remove fac_kenmwerkwaarden to keep the file clean
if (hasAnyKenmerk)
removekenmerkwaarden(module, pkey);
if (props.getTmpfolder)
return props.tmpfolder; // ik vind dit best een eigenaardige returnvalue
}
// Ondersteunende filehandlingfuncties ============================================================
// Hernoem folders onder basepath
// Flexsql levert twee velden op: oude kenmerk key en nieuwe key
function RenameFlexFolders(flexsql, pModule, pNiveau, pKey)
{
var basepath = pModule + "/" + subfolderKey(pNiveau, pKey)
var oRs = Oracle.Execute(flexsql);
while (!oRs.Eof)
{
var basepath_old = basepath + "/" + oRs(0).Value;
var basepath_new = basepath + "/" + oRs(1).Value;
var vAttachPath = S("flexFilesPath") + "/" + basepath_old;
var vAttachPath2 = S("flexFilesPath") + "/" + basepath_new;
MoveFlexfiles(vAttachPath, vAttachPath2);
//
// fac_bijlagen tabel bijwerken.
var sql_u = "UPDATE fac_bijlagen"
+ " SET fac_bijlagen_disk_directory = " + safe.quoted_sql(basepath_new)
+ " , fac_bijlagen_kenmerk_key = " + oRs(1).Value
+ " WHERE fac_bijlagen_module = " + safe.quoted_sql(pModule)
+ " AND fac_bijlagen_refkey = " + pKey
+ " AND fac_bijlagen_kenmerk_key = " + oRs(0).Value;
Oracle.Execute(sql_u);
oRs.MoveNext();
}
}
// Copy selected files from oldbasepath to newbasepath
// Flexsql levert twee velden op: oude kenmerkkey en nieuwe kenmerkkey
function CopyFlexFiles(pmodule, poldniveau, poldkey, pnewniveau, pnewkey, flexsql, filter)
{
var oRs = Oracle.Execute(flexsql);
// Only one from kenmerk_key and one to kenmerk_key combination is expected
if (!oRs.Eof)
{
var old_km_key = oRs(0).Value;
var new_km_key = oRs(1).Value;
vAttachPath = S("flexFilesPath") + "/" + pmodule + "/" + subfolderKey(poldniveau, poldkey) + "/" + old_km_key;
vAttachPath2 = S("flexFilesPath") + "/" + pmodule + "/" + subfolderKey(pnewniveau, pnewkey) + "/" + new_km_key;
__Log("Kopie files " + vAttachPath + " Naar " + vAttachPath2);
var sql_c = "SELECT r.fac_bijlagen_key"
+ " , r.fac_bijlagen_disk_directory"
+ " FROM fac_bijlagen c"
+ " , fac_bijlagen r"
+ " WHERE c.fac_bijlagen_root_key = r.fac_bijlagen_key"
+ " AND c.fac_bijlagen_verwijder IS NULL"
+ " AND c.fac_bijlagen_refkey = " + poldkey
+ " AND c.fac_bijlagen_kenmerk_key = " + old_km_key
+ " AND c.fac_bijlagen_module = " + safe.quoted_sql(pmodule);
if (filter.length)
{
sql_c += " AND c.fac_bijlagen_filename IN (" + safe.quoted_sql_join(filter) + ")";
}
var oRs_c = Oracle.Execute(sql_c);
while (!oRs_c.eof)
{
var vAttachPath0 = S("flexFilesPath") + "/" + oRs_c("fac_bijlagen_disk_directory").Value;
if (vAttachPath0 != vAttachPath)
{
__Log("kopie via verwijzing van: " + vAttachPath0);
}
var sql = "BEGIN "
+ " flx.copyflexbijlage(" + safe.quoted_sql(pmodule) + ", " + pnewkey + ", " + new_km_key + ", " + oRs_c("fac_bijlagen_key").Value + ");"
+ " END;";
var err = Oracle.Execute(sql, true);
if (err.friendlyMsg)
{
__SafeDoLog("Copying files from " + vAttachPath0 + "<br>to " + vAttachPath2 + " failed:<br>" + err.friendlyMsg, "#FFFF00");
}
oRs_c.MoveNext();
}
oRs_c.Close();
}
oRs.Close();
}
// Kopieer folders van oldbasepath naar newbasepath
// Flexsql levert twee velden op: oude key en nieuwe key
function CopyFlexFolders(pmodule, poldniveau, poldkey, pnewniveau, pnewkey, flexsql)
{ // Bestanden worden niet echt gekopieerd maar er wordt een entry met referentie (root_key) naar het oorpronkelijke bestand gemaakt.
//"FIN/" + subfolderKey("F", copyfin_key), "FIN/" + subfolderKey("F", fin_key)
var oRs = Oracle.Execute(flexsql);
while (!oRs.Eof)
{
var old_km_key = oRs(0).Value;
var new_km_key = oRs(1).Value;
vAttachPath = S("flexFilesPath") + "/" + pmodule + "/" + subfolderKey(poldniveau, poldkey) + "/" + old_km_key;
vAttachPath2 = S("flexFilesPath") + "/" + pmodule + "/" + subfolderKey(pnewniveau, pnewkey) + "/" + new_km_key;
__Log("Kopie map " + vAttachPath + " Naar " + vAttachPath2);
var sql_c = "SELECT r.fac_bijlagen_key"
+ " , r.fac_bijlagen_disk_directory"
+ " FROM fac_bijlagen c"
+ " , fac_bijlagen r"
+ " WHERE c.fac_bijlagen_root_key = r.fac_bijlagen_key"
+ " AND c.fac_bijlagen_verwijder IS NULL"
+ " AND c.fac_bijlagen_refkey = " + poldkey
+ " AND c.fac_bijlagen_kenmerk_key = " + old_km_key
+ " AND c.fac_bijlagen_module = " + safe.quoted_sql(pmodule);
var oRs_c = Oracle.Execute(sql_c);
while (!oRs_c.eof)
{
var vAttachPath0 = S("flexFilesPath") + "/" + oRs_c("fac_bijlagen_disk_directory").Value;
if (vAttachPath0 != vAttachPath)
{
__Log("kopie via verwijzing van: " + vAttachPath0);
}
var sql = "BEGIN "
+ " flx.copyflexbijlage(" + safe.quoted_sql(pmodule) + ", " + pnewkey + ", " + new_km_key + ", " + oRs_c("fac_bijlagen_key").Value + ");"
+ " END;";
var err = Oracle.Execute(sql, true);
if (err.friendlyMsg)
{
__SafeDoLog("Copying files from " + vAttachPath0 + "<br>to " + vAttachPath2 + " failed:<br>" + err.friendlyMsg, "#FFFF00");
}
oRs_c.MoveNext();
}
oRs_c.Close();
oRs.MoveNext();
}
oRs.Close();
}
// ================================================================================================
// Save de kenmerken die we met listKenmerk hebben aangemaakt
//
// kenmerkTable : "mld_kenmerkopdr"
// kenmerkParentKey : "mld_opdr_key"
// kenmerkWaarde : "mld_kenmerkopdr_waarde"
// kenmerkKey : "mld_kenmerk_key"
// currentKenmerkenSQL : Voor maken array met kenmerk_keys die voor dit object al in de database waren
// als tracking dan moet ook tweede parameter de oude waarde opleveren
// RequestQ : true voor QueryString, false voor Form
// moduleName : optional "ALG_ONRGOED_NIVEAU"
// moduleVal : optional "R"
// isNew : optional, true als het object nieuw is
// flexPath : die gebruiken we dan om tijdelijke folder te hernoemen bijv. "ALG/R"
// tracking : optional, dan tracken we als !isNew
// - allKenmerkenSQL is dan ook verplicht met strak-gedefinieerde kolommen
// - module is dan ook verplicht
//
// In listKenmerk hebben we al gezorgd dat er alleen waarden gesubmit worden van velden die we
// ook echt mochten wijzigen. kk en kv zullen er dan ook altijd beide zijn
// Nieuw is dat we af moeten blijven van confidential kenmerken, dat zijn kenmerken die
// vertrouwelijk zijn (systeem&4) gedefinieerd en voor deze user afgeschermd zijn (confidential)
// ================================================================================================
// Let op: de voorkeur is het gebruik van saveFlexKenmerken(parentKey, params)
// voor backward compatibiliteit mag je het nog uitschrijven.
// bez_edit_bezoekers_save, cnt_contract_save en mld_opdr_save gebruiken al de nieuwe methode
function saveFlexKenmerken(parentKey, kenmerkTable /* eigenlijk: Params */,
// deprecated: */
kenmerkParentKey,
kenmerkWaarde,
kenmerkKey,
kenmerkToonbaar,
currentKenmerkenSQL,
RequestQ,
moduleName, moduleVal,
isNew, flexPath,
multiMode) // TODO: support multiMode!
{
if (typeof kenmerkTable == "object")
{
var kenmerkParams = kenmerkTable;
}
else // oldstyle
{
var kenmerkParams = { kenmerkTable: kenmerkTable,
kenmerkParentKey : kenmerkParentKey,
kenmerkWaarde: kenmerkWaarde,
kenmerkKey: kenmerkKey,
kenmerkToonbaar: kenmerkToonbaar,
currentKenmerkenSQL: currentKenmerkenSQL,
requestQF: RequestQ?Request.QueryString:Request.Form,
moduleName: moduleName,
moduleVal: moduleVal,
isNew: isNew,
flexPath: flexPath,
multiMode: multiMode //waar komt deze vandaan>
}
}
var flexdata = kenmerkParams.flexdata;
if (!flexdata)
{
// Maak alsnog het flexdata object: backwards compatible!
var params = {};
if (kenmerkParams.allKenmerkenSQL) params.allKenmerkenSQL = kenmerkParams.allKenmerkenSQL;
if (kenmerkParams.extraserie) params.extraserie = kenmerkParams.extraserie;
if (kenmerkParams.nameprefix) params.nameprefix = kenmerkParams.nameprefix;
if (kenmerkParams.multiMode) params.multiMode = kenmerkParams.multiMode;
if (kenmerkParams.flexPath) params.flexPath = kenmerkParams.flexPath;
flexdata = flexkenmerken2jsondata(params);
}
return _saveFlexKenmerken(parentKey, kenmerkParams, flexdata);
}
function _saveFlexKenmerken(parentKey, params, flexdata) // TODO: support multiMode!
{
if (parentKey <= 0) return; // Er moet wel een geldige parentKey meegegeven zijn.
var kenmerk_keys = {}; // kenmerk table is used to check whether a kenmerk already exists or not.
if (params.currentKenmerkenSQL) // JGL: Is volgens mij altijd wel aanwezig
{
// FSN#18613/ PNBR#22893 Foute kenmerken opruimen
// Kunnen met name ontstaan als iemand bijvoorbeeld de stdmelding wijzigt van een melding,
// srtactiviteit van een reservering etc.
// params.currentKenmerkenSQL bevat alle geldige kenmerkwaarden (ongeacht autorisatie)
if (!params.noFlexCleanup)
{
var sqldelete = "DELETE FROM " + params.kenmerkTable
+ " WHERE " + params.kenmerkParentKey + " = " + parentKey
+ " AND " + params.kenmerkKey + " NOT IN (SELECT " + params.kenmerkKey + " FROM (" + params.currentKenmerkenSQL + "))";
if (params.moduleName) // voorzichtig
sqldelete += " AND " + params.moduleName + " = " + safe.quoted_sql(params.moduleVal);
Oracle.Execute(sqldelete);
}
// Nu oude kenmerken verzamelen in kenmerk_keys
var oRs = Oracle.Execute(params.currentKenmerkenSQL);
while (!oRs.eof)
{
var fac_functie_key = oRs("fac_functie_key").Value;
var forceReadonly = false;
if (fac_functie_key)
{ // Er is een extra autorisatie ingesteld die nodig is om het kenmerk te kunnen lezen en/of schrijven.
var additAuthrights = user.checkAutorisation(fac_functie_key, true); // Additional Authorization rights.
forceReadonly = !additAuthrights || (additAuthrights && additAuthrights.ALGwritelevel > 5 && additAuthrights.PRSwritelevel > 5); // Zijn er schrijfrechten op de extra autorisatie?
}
kenmerk_keys[oRs(params.kenmerkKey).Value] = { waarde: oRs(params.kenmerkWaarde).Value, // kenmerkwaarde moet oldval bevatten
readonly: oRs(params.kenmerkToonbaar).Value == 1 || forceReadonly }; // Kenmerk is "Niet te wijzigen": 1=Niet te wijzigen, NULL=Te wijzigen.
oRs.MoveNext();
}
oRs.Close();
}
if (params.isNew && !params.noAttachments) // uploads oude stijl (mld_edit_melding_save.asp en consorten)
{
var ktmpfolder = getFParam("ktmpfolder" + (params.tmpfolderNum? params.tmpfolderNum : 0), "");
if (ktmpfolder)
{
var tmp_folder = "__NEW__" + user_key + "_" + safe.filename(ktmpfolder);
vAttachPath = shared.tempFolder() + "/" + params.flexPath + tmp_folder;
var flexPathArray = params.flexPath.split("/"); // MLD/M => MLD (0) en M (1)
var newfolder = flexPathArray[0] + "/" + subfolderKey(bepaalNiveau(params.moduleName, flexPathArray[1]), parentKey);
vAttachPath2 = S("flexFilesPath") + "/" + newfolder;
// Niet van toepassing: we doen altijd een hele folder hieronder.
// MoveFlexfiles(vAttachPath, vAttachPath2)
var fso = Server.CreateObject("Scripting.FileSystemObject");
if (fso.FolderExists(vAttachPath))
{
__Log("Hernoem " + vAttachPath + " naar " + vAttachPath2);
CreateFullPath(vAttachPath2); // het 1000-tal was er misschien nog niet.
try
{
// fso.MoveFolder(vAttachPath + "/*.*", vAttachPath2);
// MoveFolder werkt niet als flexfilespath op een andere drive of zelfs share staat
// Daarom maar in een loopje stuk voor stuk moven. We weten dat de folder exact
// <20><>n niveau diep zijn
var tempfolder = fso.GetFolder(vAttachPath);
var fc = new Enumerator(tempfolder.SubFolders);
for (; !fc.atEnd(); fc.moveNext())
{
var folder = fc.item();
__Log("Moving: " + folder.Name);
CreateFullPath(vAttachPath2 + "\\" + folder.Name);
fso.MoveFile(vAttachPath + "\\" + folder.Name + "\\*.*", vAttachPath2 + "\\" + folder.Name);
}
// Definitieve foldernaam en refkey voor fac_bijlagen bijwerken
var sql = "UPDATE fac_bijlagen"
+ " SET fac_bijlagen_refkey = " + parentKey
+ " , fac_bijlagen_disk_directory = REPLACE(fac_bijlagen_disk_directory, {0}, {1})"
.format(safe.quoted_sql(params.flexPath + tmp_folder), safe.quoted_sql(newfolder))
+ " WHERE fac_bijlagen_refkey = -1"
+ " AND fac_bijlagen_disk_directory LIKE " + safe.quoted_sql(params.flexPath + tmp_folder + "%");
Oracle.Execute(sql);
fso.DeleteFolder(vAttachPath);
}
catch (ee)
{
__DoLog("Move files uit Folder " + vAttachPath + " naar " + vAttachPath2 + " nog mislukt: " + ee.description);
}
}
fso = null;
}
}
// Uploads nieuwe stijl (pda die via API2 geeft geupload)
if (params.isNew)
{
for (var i = 1; i < 100; i++)
{
if (getFParam("attachments[" + i + "][filename]", "")) // de originele filenaam, doen we niets mee
{
// elk nieuw bestand zit in een eigen flexfiles\MLD\M__NEW__81968_mG5Yj9duWAwuK16XYYbKwoS3RfJOYCL6\2961
var ktmpfolder = getFParam("attachments[" + i + "][token]", "");
if (ktmpfolder)
{
var tmp_folder = "__NEW__" + user_key + "_" + safe.filename(ktmpfolder);
var vAttachPathSource = shared.tempFolder() + "/" + params.flexPath + tmp_folder;
var flexPathArray = params.flexPath.split("/"); // MLD/M => MLD (0) en M (1)
var vAttachSubPath = flexPathArray[0] + "/"
+ subfolderKey(bepaalNiveau(params.moduleName, flexPathArray[1]), parentKey);
var vAttachPathTarget = S("flexFilesPath") + "/" + vAttachSubPath;
var fso = Server.CreateObject("Scripting.FileSystemObject");
if (fso.FolderExists(vAttachPathSource))
{
if (!fso.FolderExists(vAttachPathTarget)) // nieuwe hoofdfolder is er nog niet
CreateFullPath(vAttachPathTarget); // het 1000-tal was er misschien ook nog niet.
// nu bestaat voor een melding 1021481 de folder flexfiles\MLD\M1021___\M1021481
// Misschien bestaat flexfiles\MLD\M1021___\M1021481\2803 ook al
try
{
var oFolder = fso.GetFolder(vAttachPathSource); // Doorloop de kenmerk keys (zal er *eentje* zijn)
var fc1 = new Enumerator(oFolder.SubFolders);
for (; !fc1.atEnd(); fc1.moveNext())
{
var folder = fc1.item(); // folder.Name is eigenlijk kenmerk_key
var fromFolder = vAttachPathSource + "/" + folder.Name;
var toFolder = vAttachPathTarget + "/" + folder.Name;
if (!fso.FolderExists(toFolder)) // kenmerkfolder is er nog niet
CreateFullPath(toFolder);
__Log("Verplaats inhoud " + fromFolder + "/*.* naar " + toFolder + "/");
fso.MoveFile (fromFolder + "/*.*", toFolder + "/");
var sql = "UPDATE fac_bijlagen"
+ " SET fac_bijlagen_refkey = " + parentKey
+ " , fac_bijlagen_disk_directory = REPLACE(fac_bijlagen_disk_directory, {0}, {1})"
.format(safe.quoted_sql(params.flexPath + tmp_folder), safe.quoted_sql(vAttachSubPath))
+ " WHERE fac_bijlagen_refkey = -1"
+ " AND fac_bijlagen_disk_directory LIKE " + safe.quoted_sql(params.flexPath + tmp_folder + "%");
Oracle.Execute(sql);
}
fso.DeleteFolder(vAttachPathSource);
}
catch (ee)
{
__DoLog("MoveFlexfiles " + vAttachPathSource + " naar " + vAttachPathTarget + " mislukt: " + ee.description);
}
}
fso = null;
}
}
}
}
var trackarray = []; // eventuele tracking
var hasExpression = false;
for (kenmerkkey in flexdata)
{
var flex = flexdata[kenmerkkey];
if (kenmerk_keys[flex.id])
if ( flex.type == "M" || // Die zijn al lang geregistreerd in UploadForm_save.asp
(!params.isNew && (flex.type == "F" || flex.type == "E")) || // Deze zijn al geregistreerd via AjaxSaveFlex.asp
kenmerk_keys[flex.id] && kenmerk_keys[flex.id].readonly) // Alleen wijzigbare flexkenmerken kunnen opgeslagen worden.
continue;
var vold = (kenmerk_keys[flex.id] && !!kenmerk_keys[flex.id].waarde)? kenmerk_keys[flex.id].waarde : "";
hasExpression = hasExpression || flex.expr == 1;
var vnew = flex.value || "";
// tracking?
if (!params.isNew && params.tracking)
{
if (vold != vnew)
{
// allKenmerkenSQL levert nu deze kolommen (deels future use):
// kenmerk_omschrijving
// kenmerk_kenmerktype
// kenmerk_systeem
// kenmerk_readonly
// kenmerk_uniek
// fac_kenmerkdomein_key
var oRsk = Oracle.Execute(params.allKenmerkenSQL + flex.id);
var label = oRsk("kenmerk_omschrijving").Value;
var kdomein_key = oRsk("fac_kenmerkdomein_key").Value;
var confidential= oRsk("kenmerk_systeem").Value&4;
oRsk.Close();
var vold_track = vold; // De waarde die bij tracking getoond wordt kan wijzigen tov de waare die in de tabel moet worden opgeslagen.
var vnew_track = vnew; // Gebruik daarom voor de tracking tekst nieuwe variabelen!
if (confidential)
{
vold_track = vnew_track = L("lcl_confidential_mask");
}
else
{
if (flex.type == "S" || flex.type == "R")
{
if (vold != "")
{
var oRsd = Oracle.Execute("SELECT fac.getdomeinwaarde(" + kdomein_key + ", " + safe.quoted_sql(vold) + ") domeinwaarde FROM DUAL");
vold_track = oRsd("domeinwaarde").Value;
oRsd.Close();
}
if (vnew != "")
{
var oRsd = Oracle.Execute("SELECT fac.getdomeinwaarde(" + kdomein_key + ", " + safe.quoted_sql(vnew) + ") domeinwaarde FROM DUAL");
vnew_track = oRsd("domeinwaarde").Value;
oRsd.Close();
}
}
}
trackarray.push(label + ": " + buildTrackText("varchar", vold_track, vnew_track, {nodiff: (flex.type != "C"? true : null)}));
}
}
// Bepaal of het hier gaat om een flexkemerk verbruiksmeter. Dan moet historie behouden blijven
var verbruiksmeter = false;
if (params.kenmerkKey == "ins_kenmerk_key")
{ // Het gaat om een INS flexkenemerk.
// Controleren of het hier om een verbruiksmeter gaat.
var sql2 = "SELECT ins_kenmerk_meetwaarde"
+ " FROM ins_kenmerk"
+ " WHERE ins_kenmerk_key = " + flex.id;
oRs = Oracle.Execute(sql2);
verbruiksmeter = oRs("ins_kenmerk_meetwaarde").Value == 1;
oRs.Close();
}
// A real kenmerk value exists
if (flex.value == "" || flex.value == "undefined")
{
if (kenmerk_keys[flex.id])
{
if (verbruiksmeter)
{ // Zet de sysdate zodat de historie behouden blijft
sql = "UPDATE ins_kenmerkdeel"
+ " SET ins_kenmerkdeel_verwijder = " + "SYSDATE"
+ " WHERE ins_deel_key = " + parentKey
+ " AND ins_kenmerk_key = " + flex.id
+ " AND ins_kenmerkdeel_verwijder IS NULL";
Oracle.Execute(sql);
}
else
{ // Delete;
// Zelf zetten we niet de verwijderdatum maar als een ander proces dat
// heeft gedaan (BONS#21991) dan blijven wij wel van die records af.
sql = "DELETE FROM " + params.kenmerkTable
+ " WHERE " + params.kenmerkParentKey + " = " + parentKey
+ " AND " + params.kenmerkKey + " = " + flex.id
+ " AND " + params.kenmerkTable + "_VERWIJDER IS NULL";
Oracle.Execute(sql);
}
}
continue;
}
if (flex.id in kenmerk_keys) // Kenmerk komt in de kenmerkTable voor. Desnoods met waarde null (wat eigenlijk niet zou mogen).
{ // update
// Alleen een update als de waarde veranderd is
if (vold != vnew)
{ // Alleen een update/insert als de waarde veranderd of toegevoegd is
if (verbruiksmeter)
{ // Bij de verbruiksmeters moet de historie behouden blijven
// Bij verbruiksmeter gaat het over ins kenmerken
sql = "UPDATE ins_kenmerkdeel"
+ " SET ins_kenmerkdeel_verwijder = " + "SYSDATE"
+ " WHERE ins_deel_key = " + parentKey
+ " AND ins_kenmerk_key = " + flex.id
+ " AND ins_kenmerkdeel_verwijder IS NULL";
Oracle.Execute(sql);
sql = "INSERT INTO ins_kenmerkdeel "
+ " (ins_kenmerkdeel_waarde, ins_deel_key, ins_kenmerk_key)"
+ " VALUES "
+ " (" + safe.quoted_sql(flex.value) + ", " + parentKey + ", " + flex.id + ")";
Oracle.Execute(sql);
}
else
{ // Gewone flexkenmerken
// Zelf zetten we niet de verwijderdatum maar als een ander proces dat
// heeft gedaan (BONS#21991) dan blijven wij wel van die records af.
sql = "UPDATE " + params.kenmerkTable + " SET " + params.kenmerkWaarde + " = " + safe.quoted_sql(flex.value)
+ " WHERE " + params.kenmerkParentKey + " = " + parentKey
+ " AND " + params.kenmerkKey + " = " + flex.id
+ " AND " + params.kenmerkTable + "_verwijder IS NULL";
Oracle.Execute(sql);
}
}
}
else
{ // Insert
if (( flex.value != "" && flex.value != "undefined"))
{
sql = "INSERT INTO " + params.kenmerkTable
+ "(" + params.kenmerkParentKey
+ "," + params.kenmerkKey
+ "," + params.kenmerkWaarde
+ (params.moduleName? "," + params.moduleName : "")
+ ")"
+ " VALUES "
+ "(" + parentKey
+ "," + flex.id
+ "," + safe.quoted_sql(flex.value)
+ (params.moduleName? "," + safe.quoted_sql(params.moduleVal): "")
+ ")";
Oracle.Execute(sql);
}
}
}
if (hasExpression)
{
if (params.module == "MLD")
{
if (params.flexPath == "MLD/O")
module = "OPD"
else
module = "MLD"
}
else
module = params.module;
// Tabel fac_kenmwaarden vullen, expressies berekenen en tabel fac_kenmwaarden weer leeg maken.
// Vorige waarden verwijderen.
removekenmerkwaarden(module, parentKey);
savekenmerkwaarden(module, parentKey, params.moduleVal, flexdata, true);
evaluateflexexpressions(module, parentKey, true);
//removekenmerkwaarden(module, parentKey);
}
return trackarray;
}
function savekenmerkwaarden(module, refkey, kenmerkniveau, flexdata, savetodb)
{
if (isEmptyObject(flexdata)) {
return;
}
Oracle.Transaction(); // V<EFBFBD><EFBFBD>l sneller bij heel veel flexkenmerken
for (var kenmerkkey in flexdata)
{
var expr = flexdata[kenmerkkey].expr || 0;
if (expr == 2)
{
if (savetodb) // show-expressies met savetodb niet uitrekenen
expr = 0; // DB37 slaat ze dan foutief ook op
else
expr = 1; // gewoon uitrekenen
}
var sql = "INSERT INTO fac_kenmwaarden"
+ " (fac_kenmwaarden_module"
+ " , fac_kenmwaarden_refkey"
+ (kenmerkniveau
? " , fac_kenmwaarden_niveau"
: "")
+ " , fac_kenmwaarden_kenmerk_key"
+ " , fac_kenmwaarden_waarde"
+ " , fac_kenmwaarden_kenmerktype"
+ " , fac_kenmwaarden_kenmerklen"
+ " , fac_kenmwaarden_kenmerkdec"
+ " , fac_kenmwaarden_isexpr"
+ " , prs_perslid_key"
+ " )"
+ " VALUES (" + safe.quoted_sql(module)
+ " , " + refkey
+ (kenmerkniveau
? " , " + safe.quoted_sql(kenmerkniveau)
: "")
+ " , " + flexdata[kenmerkkey].id
+ " , " + safe.quoted_sql(flexdata[kenmerkkey].value)
+ " , " + safe.quoted_sql(flexdata[kenmerkkey].type)
+ " , " + (flexdata[kenmerkkey].len ? flexdata[kenmerkkey].len : "NULL")
+ " , " + (flexdata[kenmerkkey].dec ? flexdata[kenmerkkey].dec : "NULL")
+ " , " + expr
+ " , " + user_key
+ " )";
Oracle.Execute(sql);
}
Oracle.Commit();
}
function evaluateflexexpressions(module, refkey, savetodb)
{ // Berekening van de expressie kenmerken.
var sql = "BEGIN flx.evaluateflexexpressions(" + safe.quoted_sql(module) + ", " + refkey + ", " + user_key + ", " + (savetodb? 1 : 0) + "); END;";
var err = Oracle.Execute(sql, true);
if (err.friendlyMsg)
{
var message = "kenmerk_common.inc (evaluateflexexpressions): Error writing flex expression\n" + err.friendlyMsg;
abort_with_warning(err.friendlyMsg);
}
}
function removekenmerkwaarden(module, refkey)
{
var sql = "DELETE FROM fac_kenmwaarden"
+ " WHERE fac_kenmwaarden_module = " + safe.quoted_sql(module)
+ " AND fac_kenmwaarden_refkey = " + refkey
+ " AND prs_perslid_key = " + user_key;
Oracle.Execute(sql);
}
function flexkenmerken2jsondata(params)
{
// Lees de Form parameters van flexkenmerken en zet ze in een json-object.
var jsondata = {};
var namePrefix = params.nameprefix || "k";
var counterName = (params.extraserie ? namePrefix + "_all" : "k_all");
var multiMode = params.multiMode;
var as_array = (params.returnArray ? params.returnArray : false);
if (Request.Form(counterName).count > 0)
var kall = Request.Form(counterName)(1); // bij bezoekers komt counterName (k_all) meerdere keren voor maar wel altijd identiek
else
{ // JGL: komt normaal nooit voor, alleen als edit-scherm flexkenmerken niet goed heeft kunnen laden, bijv. AKZA#21569
// Normaal laten we zoiets gewoon gebeuren maar
// Error: File /facilitor5iwork/appl/shared/kenmerk_common.inc Line 1246 Index out of range. An array index is out of range.
// in de eventvwr(!) wil ik echt niet hebben
var kall = 0;
}
for (var kenmerk=1; kenmerk<=kall; kenmerk++)
{
var flex = namePrefix + kenmerk;
var kkn = Request.Form(flex + "key").Count;
var ktn = Request.Form(flex + "t").Count;
if (kkn && ktn)
{
var kk = getFParamInt(flex + "key"); // kenmerk key
var kt = getFParam(flex + "t", ""); // Type letter
var kp = getFParam(flex + "p", ""); // lengte veld (alleen voor type C en N)
var kd = getFParam(flex + "d", ""); // aantal decimalen (alleen voor type N)
var kv = getFParam(flex + "val", ""); // kenmerk waarde
var ke = getFParamInt(flex + "e", 0); // Flexkenmerk is een expressie.
var checkVal = "check_" + flex + "val";
if (kt == "S" && getFParam("check_suggest" + flex, false)) // suggest with [check_suggest_k9] name
checkVal = "check_suggest" + flex;
// Uitzondering "ALG/R" is tijdelijke oplossing voor "FCLT#52926: Multi wijzigen van ruimtes werkt niet" zodat de kenmerken i.i.g. opgeslagen worden.
// TODO voor 2018.1: "Multi wijzigen" m.b.v. vinkjes mogelijk maken.
if (multiMode && getFParam(checkVal, "off") != "on" && kt != "F")
{
continue;
}
// Hier is iets mis (YKPN#53546 & YKPN#56907)
// Er wordt (schijnbaar) als suggest_value een "x" meegegeven ipv een key
// Even loggen en proberen te achterhalen hoe dit nou komt.
if (kt == "S" && kv != "" && params.flexPath == "BEZ/B" && params.allKenmerkenSQL && isNaN(parseInt(kv, 10)))
{
var sql = "SELECT fac_kenmerkdomein_kolomnaam"
+ " FROM fac_kenmerkdomein, (" + params.allKenmerkenSQL + kk + ") bez_k"
+ " WHERE fac_kenmerkdomein.fac_kenmerkdomein_key = bez_k.fac_kenmerkdomein_key"
+ " AND fac_kenmerkdomein_verwijder IS NULL"
+ " AND fac_kenmerkdomein_module = 'BEZ'";
var oRs = Oracle.Execute(sql);
if (String(oRs("fac_kenmerkdomein_kolomnaam").Value).match(/\_key$/i))
{
__DoLog("Ongeldige suggest waarde \"" + kv + "\" ingevuld voor flexveld met key " + kk);
__DoLogForm();
kv = "";
}
oRs.Close();
}
// Native datepicker
if (kt == "DN")
{
kt = "D";
// Change format from [YYYY-MM-DD] -> [DD-MM-YYYY] for Oracle
// It's format is already checked by checkKenmerk()
kv = kv.split("-").reverse().join("-");
}
// ATTENTIE: Als het een numeriek/decimaal veld is, kan het zijn dat er een komma in voorkomt die eigenlijk een punt moet zijn.
// Als het een numeriek/decimaal veld is, kan het ook een checkbox zijn
if (kt == "N" || kt == "V")
{
// Kijken of het een checkbox is
var isCheckbox = getFParamInt("has_" + flex + "val", 0) == 1;
if (isCheckbox)
{
var isChecked = Request.Form(flex + "val").Count;
kv = (isChecked ? "1" : ""); // Een niet aangevinkte checkbox hoeft niet opgeslagen te worden als de waarde "0".
}
else
{
kv = kv.replace(",", "."); // We slaan altijd op met punten
if (kv.substr(0, 2) == "0.") // leading zero er af. Doet de database trigger ook en nu
{
if (kv.length == 2 || kv.substr(3) == " ")
kv = "0";
else
kv = kv.substr(1); // krijgen we geen ongewenste tracking.
}
}
}
// Suggest kenmerken moeten ook gedelete worden als ze leeg zijn. Dus voor delete actie leeg maken.
// Ook nodig voor correctere tracking
if ((kt == "S" || kt == "R") && kv == "-1") kv = ""; // anders zouden we '-1' opslaan
jsondata[kk] = { id: kk,
//name: "",
type: kt,
len: kp,
dec: kd,
value: kv,
expr: ke,
kfieldid: flex
};
}
}
var json_result = (as_array ? [] : jsondata);
if (as_array)
{ // Converteer object naar array.
for (kenmerkkey in jsondata)
{
json_result.push(jsondata[kenmerkkey]);
}
}
return json_result;
}
%>