Files
Facilitor/APPL/Shared/kenmerk_common.inc

2086 lines
97 KiB
PHP
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)
TODO: HTML5-achtige zaken toevoegen
- required is ook een attribute met functionaliteit. Tot dusverre zetten we alleen reuired_class
moeten we behalve adt attr toevoegen ook iets met toggle en zo?
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"], js: ["jquery-ui.js", "date.js"]})
var requiredGroupUsed = new Array(); // Array zorgt voor eenmalige initiele aanroep van checkRequiredGroup(groep) per groep
function parseDocumentPath(kenmerk_val)
{
// kenmerk_val is een padnaam naar een document
// Als het document begint met <S("image_path_local")> dan halen we
// dat er af voordat het de database in gaat.
// We maken van back-slashes (alleen) dan altijd forward slashes
// Bij presenteren plakken we er mettertijd S("image_path_virtual") voor
// de check S("image_path_local") != "\\" is nog historisch om problemen te voorkomen
var localpath = S("image_path_local").replace(/\//g,"\\");
var newval = String(kenmerk_val).replace(/\//g,"\\");
__Log("newval: " + newval);
if (S("image_path_local") != "\\" && newval.indexOf(localpath) == 0)
return newval.substring(localpath.length);
else if (S("image_path_local_regexp") && newval.match(S("image_path_local_regexp")))
{
__Log("regexp match!");
return newval.substring(RegExp.lastIndex);
}
else
return kenmerk_val; // Origineel ongewijzigd
}
function kenmerk_write(s)
{
Response.Write(s);
}
// Tel/ zoek de bijlagen in een folder
// Resultaat: array met bijlage namen
function BijlagenList(pModule, pNiveau, pKey, pKenmerk_key, otherKenmerk_path)
{
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 = [];
var fso = Server.CreateObject("Scripting.FileSystemObject")
if (vAttachPath)
__Log("Tellen in folder: " + vAttachPath);
if (vAttachPath && fso.FolderExists(vAttachPath))
{
var fso, f, f1, fc, s;
fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.GetFolder(vAttachPath);
fc = new Enumerator(f.files);
for (; !fc.atEnd(); fc.moveNext())
{
lijst.push(fc.item().Name);
}
}
return lijst;
}
function BijlagenButton(pModule, pNiveau, pKey, tmpfolder, pKenmerk_key,
pReadonly, pRequired, kdim, pregexp, otherKenmerk_path, identify, label, params)
{
// Lever code op voor een BijlagenButton type M (map)
// Let op: F (file) gebeurt verderop in de code
// Module is 'R' voor ruimte, 'M' voor melding enz
// key is de object key
// Parameter otherKenmerk_path 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] */
var lijst = BijlagenList(pModule, pNiveau, pKey, pKenmerk_key, otherKenmerk_path);
if (pReadonly)
{ // Indien readonly en lijst.length = 0 dan hoeft het kenmerk (net als bij andere kenmerken) helemaal niet getoond te worden.
var filehtmlarr = [];
for (var file in lijst)
{
if (kdim == 'xxx')
var href = protectQS.create(OpenFlexFile(pModule, pNiveau, pKey, pKenmerk_key, lijst[file], { mime_type: "image/png", contentdp: "inline" }));
else
var href = protectQS.create(OpenFlexFile(pModule, pNiveau, pKey, pKenmerk_key, lijst[file]));
//var html = "<a href='" + safe.htmlattr(href) + "' target='_new'>" + safe.html(lijst[file]) + "</a>";
var html = '<span class="details fldflexM" " readonly=1'
+ ' onclick=\'FcltMgr.windowopen("' + safe.jsstring(href) + '")\'>' + safe.html(lijst[file]) + '</span>';
filehtmlarr.push(html);
}
var res = filehtmlarr.join("</br>");;
}
else
{
if (otherKenmerk_path && lijst.length > 0)
var res = L("lcl_flex_autocopy");
else // pf: op 1 regel tbv mijn syntaxhiliting
{
var res ="<input type='button' isBijlage='1' nBijlagen='" + lijst.length + "'" + identify + " class='bijlage button " + pRequired + "' value='" + label.format(lijst.length) + "'";
var url = "../shared/BijlagenForm.asp?module=" + pModule
+ "&key=" + pKey
+ (pNiveau != ""? "&niveau=" + pNiveau : "")
+ "&kenmerk_key=" + pKenmerk_key
+ (params.kenmerk_module? "&kenmerk_module=" + params.kenmerk_module : "");
if (pKey < 0)
{
url += "&tmpfolder=" + tmpfolder;
}
if (pReadonly) url += "&reado=1";
url += "&multi=1";
if (kdim) url += "&extFilter=" + escape(kdim);
if (pregexp) url += "&pregexp=" + escape(pregexp); // P800x600 voor foto van 800x600
var blg = "onBijlagen('" + safe.jsstring(protectQS.create(url)) + "'"
+ ",''" // geen saveUrl
+ ", true" // multi
+ ", this)"
res += " onClick='" + safe.htmlattr(blg) + "'"
+ (!pReadonly ? " onChange='checkKenmerk(this, false,\"M\",0,0,0,0)'" : "")
res += ">";
res += "<i class='fa fa-folder-open fa-fw hasIcon bijlage' onClick='this.previousSibling.click()'></i>";
}
}
return {html: res, count: lijst.length};
}
// Params kan bevatten
// mime_type: "image/png"
// contentdp: "attachment"
function OpenFlexFile(Module, Niveau, Key, Kenmerk_key, fname, params)
{
params = params || {}
// Lever code op voor tonen van een bepaalde flexfile streaming
var s = "../shared/BijlagenStream.asp"
s += "?module=" + Module
+ "&key=" + Key
+ (Niveau? "&niveau=" + Niveau : "")
+ "&kenmerk_key=" + Kenmerk_key
+ "&filename=" + Server.URLencode(fname);
if (params.mime_type)
s += "&mime=" + params.mime_type;
if (params.contentdp)
s += "&contentdp=" + params.contentdp;
return s;
}
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;
}
// ================================================================================================
// 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
// 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
// fnpre en fnpost: functies die voor en na genereren worden aangroepen *mits er kenmerken zijn*
// wfbuilder: toon ook flex-colname :f123 (voor workflow expression builder)
// }
// ================================================================================================
function listKenmerk(sql, module, key, props)
{
var flexcolumns = props.flexcolumns;
var kenmerk_search = props.kenmerk_search;
var kenmerk_colspan = props.kenmerk_colspan;
var kenmerk_extraTD = props.kenmerk_extraTD;
var multiMode = props.multiMode; // TODO: support this!
var hideVervallen = props.hideVervallen;
var prs_key = props.prs_key || props.reqId; // Oude obsolete reqId nog even ondersteunen
var cont_key = props.cont_key;
var nameprefix = props.nameprefix || "k";
var extraserie = props.extraserie || false;
var niveau = props.niveau || "";
var srtdeel_key = props.srtdeelKey;
var requiredbyfield = props.requiredbyfield;
var serie = props.serie || 0;
var parent_list = props.parent_list; // Maak voor deze keys ook bijlagen knop
var formobile = props.mobile;
var notr = props.notr; // Geen tr's toevoegen.
var nolabel = props.nolabel; // Geen labels toevoegen.
var flexstart = props.flexstart || 1; // De kenmerken vanaf de flexstart-ste element tonen {flexstart >= 1 indien meegegeven).
var flexend = props.flexend || -1; // De kenmerken tot het flexend-ste element tonen {flexend >= 1 indien meegegeven}.
var hasfilter = props.hasfilter || false; // De kenmerken kunnen op naam gefilterd worden.
var tmpfolder = props.tmpfolder || "";
var predone = false;
var colCount = 0; // Even/oneven zodat we weten of we links of rechts zitten
var forceNewLine = false; // Bij labels en grote text velden
var val_seperator = '';
var val_label = '';
var idCounter = 1; // We maken alleen name/id-s voor de velden die ook echt bewerkt kunnen worden
var clabelCounter = 0; // Het aantal collapsable labels
var anyDate = false;
var anyTextarea = false;
var kenmerkidref = new Array(); // Bijhouden welk kenmerk welke id referentie mee heeft gekregen
var dpYearRanges = []; // te gebruiker jaren voor datepicker vastleggen.
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 = (flexcolumns >= 2); // 2 kolommnen voor flexkenmerken als aantal kolommen ingevuld 2 of meer is.
if (module == "INS" && niveau == "S")
{ // Sleutelmodule werkt met srtdeel_key
if (srtdeel_key > 0)
key = srtdeel_key;
}
// Zitten er expressie kenmerken tussen?
var flexExprIncluded = false;
var oRs = Oracle.Execute(sql);
while (!oRs.eof)
{
var kdefault = oRs("kenmerk_default").Value;
if (kdefault && kdefault.match('##EXPR##') != null)
{
flexExprIncluded = true;
break;
}
oRs.MoveNext();
}
oRs.Close();
// Opnieuw dezelfde query is niet supperefficient maar een MoveFirst is problematisch (FSN#39008)
var oRs = Oracle.Execute(sql);
// ============================================================================================
// Doorloop alle flexkenmerken
if (key < 0 && tmpfolder == "")
tmpfolder = shared.random(32); // voor als nog geen key en wel bijlagen
var prssql = false;
for (i = 1; !oRs.eof; i++)
{
var val = null;
val_seperator = ':';
var def_val = oRs("kenmerk_default").Value;
var isExpression = false;
if (!kenmerk_search && !multiMode)
{
// In multiMode no filling of default values
val = oRs("kenmerk_waarde").value;
if (def_val && def_val.match('##EXPR##') != null)
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 (val != null)
{ //__Log("val:"+val);
if (val == def_val && val.match('##SQL##') != null)
{
//__Log("val match");
prssql = true;
val = val.substr(val.indexOf('##SQL##') + 7);
var sql2 = val.replace("##PRS_PERSLID_KEY##", prs_key).replace("##PRS_CONTACTPERSOON_KEY##", cont_key);
oRsPerslid = Oracle.Execute(sql2);
if (!oRsPerslid.eof)
val = oRsPerslid(0).value;
else
val = '';
oRsPerslid.Close();
}
else if (def_val && val == def_val && def_val.match('##EXPR##') != null)
{
val = "";
}
}
}
// 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")
{
val = xx;
if (oRs("kenmerk_kenmerktype").value == "C" || oRs("kenmerk_kenmerktype").value == "N" || oRs("kenmerk_kenmerktype").value == "B")
val = val.substr(0, oRs("kenmerk_lengte").value); // Kap de waarde op de maximale lengte af
}
}
// De weer te geven waarde is nu bepaald
var kkey = oRs("kenmerk_key").value;
val_label = Server.HTMLEncode(oRs("kenmerk_omschrijving").value? oRs("kenmerk_omschrijving").value : ""); // Omschrijving kan leeg gelaten zijn
var ktype = oRs("kenmerk_kenmerktype").value;
var klen = oRs("kenmerk_lengte").value;
if (!klen) klen = 4000;
var kdec = oRs("kenmerk_dec").value;
var kmin = oRs("kenmerk_nmin").value;
var kmax = oRs("kenmerk_nmax").value;
var kvolgnr = "" + oRs("kenmerk_volgnr").value;
var kdim = oRs("kenmerk_dimensie").value; // beperkt bij uploads de extensie
var hint = oRs("kenmerk_hint").value;
var kregexp = oRs("kenmerk_regexp").value;
var kdomein_key = oRs("kenmerkdomein_key").value;
// if (hint == null) hint = "";
// PF vindt van niet if (def_val == null) def_val = "&nbsp;";
var required = oRs("kenmerk_verplicht").value;
if ((props.sqldefaultnotrequired && def_val && def_val.match('##SQL##')) || props.ignorerequired)
required = false;
var reqgroup = oRs("kenmerk_groep").value;
var otherPath = oRs("otherpath").value; // otherKenmerkPath, alleen voor meldingen en facturen (tbv kopieren)
//
// forceReadonly kan gezet zijn: dan is het veld *altijd* readonly en kan alleen
// ingevuld raken doordat een extern proces (importjob?) dat doet of het wordt
// gevuld door de default waarde.
var forceReadonly = oRs("kenmerk_toonbaar").value == 1;
// Velden die de gebruiker niet mag zien zijn we h<><68>l snel klaar mee
// Ook velden waar je niet op kunt zoeken 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 ((!kenmerk_search && props.fnIsInvisible && props.fnIsInvisible(kvolgnr, ktype, oRs)) ||
(kenmerk_search && (ktype == 'L' || ktype == 'l' || ktype == 'Q' || ktype == 'M' || ktype == 'F' || ktype == 'E') || kvolgnr < 0) ||
(!kenmerk_search && (ktype == 'L' || ktype == 'l') && forceReadonly && props.fnIsReadonly && props.fnIsReadonly(kvolgnr, oRs))
)
{
oRs.MoveNext();
continue; // Onzichtbaar
}
//kenmerk_write( "<!--YY:"+colCount+":"+val_label+"-->");
//kenmerk_write( "<!--YY:"+idCounter+":"+val_label+"-->");
var readonlyfield = forceReadonly; // startwaarde
if (!readonlyfield && !kenmerk_search && props.fnIsReadonly) // Zoeken is natuurlijk nooit readonly
readonlyfield = props.fnIsReadonly(kvolgnr, oRs)
if (readonlyfield || kenmerk_search)
required = false;
var required_class = "";
var required_group = "";
if (required)
{
required_class = " required";
// Indien required afhankelijk is van een gewoon veld dan requiredgroup gebruiken met groep >= 10
if (requiredbyfield && required == 1)
{
required = 10;
}
if (required > 1)
{
if (required == 2)
required_group = reqgroup + "S" + parseInt(serie, 10);
else
required_group = required + "S" + parseInt(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_<%=nameprefix + idCounter%>" style="display:none"></span>
<script type="text/javascript">
jQuery(document).ready(function()
{
<% if (required > 9)
{ // Gewone veld ook dezelfde requiredgroup class geven
%>
$("#<%=requiredbyfield%>").addClass("<%=required_class%>");
<% } %>
checkRequiredGroup("<%=required_group%>");
$("#requiredgeg_<%=nameprefix + idCounter%>").remove(); // Na het uitvoeren kan de ready functie weer weg zodat deze niet
});
</script>
<% }
}
}
// 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 (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 kd1.fac_kenmerkdomein_key = " + 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 (kenmerk_search) readonlyfield = false;
}
oRs2.close();
}
// 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)
if (readonlyfield && !isParent && ktype != 'L' && ktype != 'l' && ktype != 'M' && (!val || val=="") &&
(!kenmerk_search && (ktype == 'C' || ktype == 'N' || ktype == 'B' || ktype == 'D' || ktype == 'R' || ktype == 'S')) ) // Als geavanceerd dan maakt het niet uit of het readonly is. Dan moet je het kenmerk gewoon tonen.
{
oRs.MoveNext();
continue;
}
// Als geavanceerd dan maakt het niet uit of het readonly is. Dan moet je het kenmerk gewoon tonen.
if (kenmerk_search && readonlyfield && (ktype == 'C' || ktype == 'N' || ktype == 'B' || ktype == 'D' || ktype == 'R' || ktype == 'S'))
readonlyfield = false;
colCount++; // Nu pas ophogen.
// De kenmerken vanaf de flexstart-ste element tonen.
// De kenmerken tot het flexend-ste element tonen.
if (flexstart > colCount || (flexend >= 0 && flexend < colCount))
{
oRs.MoveNext();
idCounter++;
continue;
}
if( ktype == 'L' || ktype == 'l' )
{
forceNewLine = true;
colCount = 2; // Forceer 'even'
if (inMobileBlock)
kenmerk_write("</div>");
}
else
forceNewLine = false;
if (kenmerk_search || val != null && val != "")
allCollapsable = false;
// Eerst de simpele datatypes ('C', 'D' en 'N'). De complexere overrulen kv mogelijk later nog wel.
// De classes-conventie is:
// fldflex+[ktype] voor edit/show en fldSflex+[ktype] voor searchmode
// waarbij type niet perse hoeft als er geen onderscheid is.
// Extra is er nog C50 ipv C voor lange C kenmerken
// Ook class number/float (of currency) toevoegen
var kv = ""; // Het in te voegen veld in HTML, zonder label
var onchangeExp = "";
// Een flexkenmerk wordt altijd weergegeven volgens het volgende format:
// <tr><td class="label"><label>LABEL</label>:</td><td><input type="text" value='XX'></td></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
// KENMERKTYPE C (Karakter) =================================================================
if (ktype == 'C')
{
if (flexExprIncluded && !isExpression)
onchangeExp = ";if (fvalid) calculateFlexExpressions(this"
+ ", \"" + module + "\""
+ ", " + key
+ ", \"" + (props.kenmerk_module || "") + "\""
+ ", \"" + nameprefix + "\""
+ ", \"" + extraserie + "\""
+ ");";
if (klen > 50 && !kenmerk_search)
{
// Groot text veld wordt automatisch textarea
if (readonlyfield)
{
if (formobile)
{
kv = "<textarea class='fldflexC50 ' rows=3 readonly tabindex=-1 maxlength='"+klen+"'>" + safe.textarea(val) + "</textarea>";
}
else
{
kv = "<div class='readonly fldflexC50'>"
+ safe.html(val)
+ "</div>";
}
}
else
{
anyTextarea = true; // straks autogrow code
kv = "<textarea "
+ (kregexp ? " regexp='" + kregexp + "' " : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")"
+ onchangeExp
+ "'"
+ " onBlur='checkKenmerk(this, true,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")'"
+ " class='fldflexC50 "
+ (required ? required_class : "")
+ (isExpression? " expression " : "")
+ "'"
+ (required ? " required='required' " : "")
+ (isExpression ? " readonly " : "")
+ " rows=3 "
+ " maxlength='"+klen+"'"
+ " name='" + nameprefix + idCounter + "val' id='" + nameprefix + idCounter + "val' "
//+ "placeholder='"+val_label+"'"
+ ">"
+ safe.textarea(val)
+ "</textarea>";
}
} else { // klein input veld
if (readonlyfield)
{
if (formobile)
{
kv = "<input type='text' class='fldflexC ' readonly tabindex=-1 value='"+ safe.html(val) +"'>";
}
else
{
kv = "<span"
+ " class='readonly "
+ (kenmerk_search ? "fldSflexC " : "fldflexC ")
+ "'>" + safe.htmlattr(val) + "</span>";
}
}
else
{
kv = "<input type='text'"
+ (kregexp ? " regexp='" + kregexp + "' " : "")
+ " onChange='fvalid=checkKenmerk(this, false,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")"
+ onchangeExp
+ "'"
+ " onBlur='checkKenmerk(this, true,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")'"
+ " id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val'"
+ " class='"
+ (kenmerk_search ? "fldSflexC " : "fldflexC ")
+ (required ? required_class : "")
+ (isExpression? " expression " : "")
+ "'"
+ (required ? " required='required' " : "")
+ (isExpression ? " readonly " : "")
//+ " placeholder='"+val_label+"'"
+ " value='" + safe.htmlattr(val) + "'"
+ " maxlength='" + klen + "'"
+ ">";
}
}
} // C
// Bijhouden welk kenmerk welke id referentie mee heeft gekregen
function idref(idname, waarde)
{
this.idname = idname;
this.waarde = waarde;
}
// 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[nameprefix + kkey] = new idref(nameprefix + idCounter, val);
var parentkenmerkid = "";
var parentkenmerk_key = -1;
var parentkenmerkwaarde;
if (!readonlyfield && (ktype == 'S' || ktype == '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"
+ " FROM fac_usrtab ut1"
+ " , fac_usrtab ut2"
+ " , fac_kenmerkdomein kd1"
+ " , fac_kenmerkdomein kd2"
+ " , (" + sql + ") tfin"
+ " WHERE kd1.fac_kenmerkdomein_key = " + 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(ktype)
var oRs2 = Oracle.Execute(sqlDep);
if (!oRs2.eof)
{ // Er is een afhankelijkheid met een ander kenmerk
parentkenmerk_key = oRs2("kenmerk_key").value;
parentkenmerkid = kenmerkidref[nameprefix + parentkenmerk_key].idname;
parentkenmerkwaarde = kenmerkidref[nameprefix + parentkenmerk_key].waarde;
}
oRs2.close();
}
// KENMERKTYPE R/S (Referentie/Suggest) =====================================================
if (ktype == 'R' || (readonlyfield && ktype == 'S')) // Referentie naar andere tabel (listboxje)
{
var wheres = [];
var dsql = "SELECT 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 = " + kdomein_key;
var oRs_d = Oracle.Execute(dsql);
var xmlnode = oRs_d("fac_kenmerkdomein_xmlnode").value;
var vervalkolom = oRs_d("fac_kenmerkdomein_verval").value;
if (!readonlyfield && parentkenmerkid != "")
{
if (parentkenmerkwaarde != null)
wheres.push("fac_usrdata_parentkey = " + parentkenmerkwaarde);
else // Parent heeft geen waarde geselecteerd.
wheres.push("fac_usrdata_parentkey IS NOT NULL");
}
if (val !== null && String(oRs_d("fac_kenmerkdomein_kolomnaam").value).match(/\_key$/i))
{
var vv = parseInt(val, 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
__DoLog("Ongeldige referentie waarde <em>{0}</em> voor kolom {1}.{2}".format(val,
oRs_d("fac_kenmerkdomein_objectnaam").value,
oRs_d("fac_kenmerkdomein_kolomnaam").value), "#ff0000");
val = "-1";
}
else
val = String(vv);
}
if (oRs_d("fac_kenmerkdomein_objectnaam").value == "FAC_USRDATA" && oRs_d("fac_usrtab_key").value)
{
// Deze kunnen we standaard localisen!
var fsql = "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"
+ " FROM fac_usrdata ";
wheres.push("fac_usrtab_key=" + oRs_d("fac_usrtab_key").value);
if (!readonlyfield)
wheres.push("fac_usrdata_verwijder IS NULL"); // bij readonly tonen we ook verwijderde oude waarden
if (hideVervallen)
wheres.push("(fac_usrdata_vervaldatum IS NULL OR fac_usrdata_vervaldatum > SYSDATE)");
}
else
{
var fsql = "SELECT " + oRs_d("fac_kenmerkdomein_kolomnaam").value
+ "," + oRs_d("fac_kenmerkdomein_kolomtxt").value
+ (vervalkolom
? " || CASE WHEN " + vervalkolom + " < SYSDATE THEN " + safe.quoted_sql(L("lcl_inactive_data_suffix")) + " END"
: ""
) + " fac_kenmerkdomein_omschr"
+ "," + (vervalkolom
? vervalkolom
: "NULL"
) + " x"
+ " FROM " + oRs_d("fac_kenmerkdomein_objectnaam").value;
if ((!readonlyfield || hideVervallen) && vervalkolom)
wheres.push("("+vervalkolom+" IS NULL OR "+vervalkolom+" > SYSDATE)");
}
if (readonlyfield)
wheres.push(oRs_d("fac_kenmerkdomein_kolomnaam").value + " = " + safe.quoted_sql(val));
if (wheres.length)
fsql += " WHERE " + wheres.join(" AND ");
fsql += (oRs_d("fac_kenmerkdomein_objectnaam").value == "FAC_USRDATA")
? " ORDER BY fac_usrdata_volgnr, 2"
: " ORDER BY 2, 1";
oRs_d.close();
var oRs2 = Oracle.Execute(fsql);
var c0 = "";
var c1 = "";
var inactiveval = false;
if (!oRs2.eof)
{
c0 = oRs2(0); // for performance this is better, it seems (-JGL).
c1 = oRs2(1);
inactiveval = (oRs2(2).value != null && oRs2(2).value<new Date());
}
// 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)
{
if (readonlyfield)
{
if (c0.value == val)
{
kvv = c1.value;
break; // Rap klaar. Kan efficienter met een WHERE?
}
}
else
{
if (c1.value != null && String(c1.value.length) > maxLen)
maxLen = String(c1.value).length;
appender = '<option value="' + c0.value + '"'
+ (c0.value == val?' selected' : '') + '>' + safe.html(c1.value) + '</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.
oRs2.close();
if (!readonlyfield)
{ // is dus impliciet ook type R
if (flexExprIncluded && !isExpression)
onchangeExp = "calculateFlexExpressions(this"
+ ", \"" + module + "\""
+ ", " + key
+ ", \"" + (props.kenmerk_module || "") + "\""
+ ", \"" + nameprefix + "\""
+ ", \"" + extraserie + "\""
+ ");";
kv = "<select id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val'"
+ " class='"
+ (kenmerk_search ? "fldSflexR " : "fldflexR ")
+ (required ? required_class : "")
+ "'"
//+ " placeholder='"+val_label+"'"
+ (required ? " required='required' " : "")
+ (required > 1
? " onChange='checkRequiredGroup(\"" + required_group + "\");" + onchangeExp + "'"
: (flexExprIncluded && !isExpression? " onChange='" + onchangeExp + "'" : ""))
+ ">"
+ "<option value='-1' " + (required? " class='" + required_class + "'" : "") + "><!--lege waarde--></option>"
+ kvv
+ "</select>";
if (required) // wrapper voor rode streepje, IE-only. Wat vind je Jos (ik vind het te lelijk in chrome/safari)
kv = "<!--[if lt IE 8]><div id='req_" + nameprefix + idCounter + "val' class='fldflexR " + required_class + "'><![endif]-->" + kv + "<!--[if lt IE 8]></div><![endif]-->";
}
else
{
var showdetail = (formobile ? "" : (xmlnode? ' details' : '') );
var clickdetail = (formobile ? "" : (xmlnode? ' onClick="xmlNodeDetails(' + val + ', \'' + xmlnode + '\')"' : '') );
if (ktype == "R")
kv = '<input class="fldflexR'
+ showdetail
+ (inactiveval? ' inactive' : '')
+ '" type="text" readonly tabindex=-1 value="' + safe.htmlattr(kvv) + '"'
+ clickdetail
+ '>';
else
kv = '<input class="fldflexS'
+ showdetail
+ (inactiveval ? ' inactive' : '')
+ '" type="text" readonly tabindex=-1 value="' + safe.htmlattr(kvv) + '"'
+ clickdetail
+ '>';
}
if (!readonlyfield && parentkenmerkid != "")
{ %>
<script type="text/javascript">
function onChangeRKenmerkParent<%=parentkenmerkid%>()
{ // Functie wordt aangeroepen door een eventuele parent waarvan deze listbox afhankelijk is
var className = $("#<%=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 = $("#<%=parentkenmerkid%>val")[0].className.match(/required\d*S\d*/g)[0].substr(8);
checkRequiredGroup(group);
}
$("#<%=nameprefix + idCounter%>val").
load("../Shared/loadRKenmerk.asp",
{ init_key: $("#<%=nameprefix + idCounter%>val").val(),
kdomein_key: <%=kdomein_key%>,
parent_key: $("#<%=parentkenmerkid%>val").val(),
required: <%=required? required : 0%>,
hideVervallen: <%=hideVervallen? 1 : 0%> });
}
jQuery(document).ready(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.
$("#<%=parentkenmerkid%>val")[0].onchange = function() {onChangeRKenmerkParent<%=parentkenmerkid%>();}
})
</script>
<% }
}
// KENMERKTYPE F/E (File) ===================================================================
var MasF = false; // M behandelen als F?
if ((ktype == 'F' || ktype == 'E' || ktype == 'M') && formobile)
{
var lijst = BijlagenList(module, niveau, key, kkey, otherPath); // die hebben we dan nodig
}
if (ktype == 'M' && formobile && !lijst.length)
MasF = true; // Een M zonder files doen we als F zodat je tenminste <20><>n betand kunt toevoegen
if (ktype == 'F' || ktype == 'E' || MasF) // single File of Encrypted
{
if (formobile && lijst.length)
readonlyfield = true;
// Bedoeling is: toon de filenaam in een inputfield.
// In showmode/readonly kun je er op klikken als-ie bestaat, in editmode
// moet je de change button gebruiken om te wijzigen en is niet klikbaar.
// De echte waarde bewaren we in een hidden veld. Die wordt dan ook gesubmit
var fld = nameprefix + idCounter + "val";
// Er is redundantie: de bestandsnaam zit in de database en staat in de folder
// door bijvoorbeeld niet op Ok te drukken na vervanging van het bestand
// kan er inconstistentie ontstaan. Lastig tegen te gaan dus maar detecteren en melden.
var missing = false;
if (val && ktype != 'M')
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
if (otherPath)
var vAttachPath = S("flexFilesPath") + "/" + otherPath;
else
{
// JGL: Zou dit niet moeten/ kunnen via bijvoorbeeld iets als flexProps(module, key, String(kkey), niveau).AttachPath + "/";
var vAttachPath = S("flexFilesPath") + "/" + module + "/" + subfolderKey(bepaalNiveau(module, niveau), key) + "/" + kkey;
}
missing = !fso.FileExists(vAttachPath + "/" + val);
if (missing)
__Log(vAttachPath + "/" + val + " is missing");
}
// Mobile heeft een compleet eigen BijlagenForm.asp
if (kdim == 'xxx')
var url = "../shared/BijlagenSignature.asp"
else if (formobile)
var url = "../pda/BijlagenForm.asp"
else
var url = "../shared/BijlagenForm.asp"
url += "?module=" + module
+ "&key=" + key
+ (niveau != ""? "&niveau=" + niveau : "")
+ "&kenmerk_key=" + kkey
+ "&mobile=" + (formobile ? 1 : 0)
+ (props.kenmerk_module? "&kenmerk_module=" + props.kenmerk_module : "");
// nooit if (pReadonly) url += "&reado=1";
// nooit url += "&multi=1";
if (kdim) url += "&extFilter=" + escape(kdim);
if (kregexp) url += "&pregexp=" + escape(kregexp); // P800x600 voor foto van 800x600
if (ktype == "E") url += "&encrypt=1";
if (key < 0)
url += "&tmpfolder=" + tmpfolder;
var saveUrl = "";
if (props.parentKey > 0 && ktype != 'M')
{
// Voor de zekerheid slaan we wijziging van de bestandsnaam direct op.
// op het filesysteem is het namelijk ook al 'gecommit'
var saveUrl="../shared/AjaxSaveFlex.asp";
if (module=="MLD" && niveau == "O")
saveUrl += "?module=OPDR";
else if (module=="FIN" && niveau == "R")
saveUrl += "?module=FINR";
else
saveUrl += "?module="+module;
saveUrl += "&parentKey="+props.parentKey;
saveUrl += "&kenmerkKey=" + kkey;
if (props.kenmerk_module)
saveUrl += "&kenmerk_module="+props.kenmerk_module;
};
var func = "onBijlagen";
if (formobile)
func = "onBijlagenMobile";
var blg = func + "('" + safe.jsstring(protectQS.create(url)) + "'"
+ ",'" + (saveUrl?safe.jsstring(protectQS.create(saveUrl)):"") + "'"
+ ", false"
+ ", $('#" + fld + "')[0]"
+ ")";
if (!readonlyfield || val)
{
kv = "<input type='text'"
+ (readonlyfield
? " readonly tabindex=-1 "
: " id='" + fld + "' name='" + fld + "' ")
+ "class='"
+ (kenmerk_search
? "fldSflex" + ktype + " "
: "fldflex" + ktype + " ")
+ (missing ? " missing " : " details ")
+ "'"
+ (required ? " required='required' " : "")
+ (required > 1
? " onChange='checkRequiredGroup(\"" + required_group + "\")'"
: "")
//+ " placeholder='"+val_label+"'"
+ " value='" + safe.htmlattr(val) + "' "
+ (!val?" style=display:none":"");
// + ">"; //komt later
var kvClick="";
if (otherPath) // Even niet klikbaar
kvClick = " title='" + L("lcl_flex_autocopy") +"' ";
else if (readonlyfield && val && !missing) // rechtstreeks openen
{
if (kdim == 'xxx')
var fnclick = "parent.FcltMgr.windowopen('" + protectQS.create(OpenFlexFile(module, niveau, key, kkey, val, { mime_type: "image/png", contentdp: "inline" })) + "')";
else
var fnclick = "parent.FcltMgr.windowopen('" + protectQS.create(OpenFlexFile(module, niveau, key, kkey, val)) + "')";
kvClick = " onclick='" + safe.htmlattr(fnclick) + "'";
}
else if (readonlyfield && val && missing) // Waarschuwen
kvClick = " title='" + safe.htmlattr(L("lcl_flex_filenotfoundRO")) + "'";
else
{
kvClick = " onClick='" + safe.htmlattr(blg) + "'"; // klik altijd naar bijlagenform
if (missing)
{
kvClick += " title='" + safe.htmlattr(L("lcl_flex_filenotfound")) + "'";
}
else
kvClick += " title='" + L("lcl_change") + "'";
}
// Om te saven doet de gebruiker maar rightclick/Saveas
kv += kvClick + ">"; // hier tag afsluiten
}
if (!readonlyfield && !otherPath) // Altijd aanwezig
{
kv += "<input type='button' "
+ "class='bijlage1 button " + (required? required_class : "") + "' "
+ "isBijlage='1' nBijlagen='"+(val?1:0)+"' "
+ "value='" + L("lcl_add") + "'"
+ (val?" style='display:none' ": " ")
+ "onClick=\"" + blg + "\""
+">";
}
if (kdim == 'xxx')
{
if (!missing && val)
kv += "<img class='kenmerk' src=' " + protectQS.create(OpenFlexFile(module, niveau, key, kkey, val, { mime_type: "image/png", contentdp: "inline" })) + "'>";
else
kv += "<img class='kenmerk' style='display:none'>";
}
}
// KENMERKTYPE M (Map) ======================================================================
// Mobiel hebben we hem al bij 'F' gedaan
if (ktype == 'M' && !MasF) // Map met bestanden is altijd heel simpel
{
var requiredfield = (required ? required_class : "");
var identify = " id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val'";
var res = BijlagenButton(module, niveau, key, tmpfolder, kkey, readonlyfield || formobile, // Mobile altijd readonly
requiredfield, kdim, kregexp, otherPath, identify, L("lcl_appendixes_teller"), props)
kv = res.html;
if (res.count > 0)
allCollapsable = false;
if (parent_list)
{
for (pp in parent_list)
{ // JGL: parent_list is alleen bij workflowmeldingen in *show*mode.
// Meeste parameters hieronder zullen dan ook don't care zijn
var res = BijlagenButton(parent_list[pp].module, niveau, parent_list[pp].key,
tmpfolder, kkey, readonlyfield, requiredfield, kdim, kregexp, otherPath, identify, parent_list[pp].label, props)
if (res.count > 0)
{
allCollapsable = false;
kv = res.html + "<br/>" + kv; // parent komt ervoor
}
}
}
}
var makeCheckbox = false;
if ((ktype == 'N' || ktype == 'B') && klen == 1 && kmin == 0 && kmax == 1 && (kdec == 0 || !kdec))
{
makeCheckbox = true;
if (formobile) // Daar staat de tekst achter het vinkje
val_seperator = '';
}
// ===========================================================================
// De uitzonderingen hebben we nu gehad, alle overige types beginnen hetzelfde
// ===========================================================================
// JGL: Wat zijn de overige types nog van CNDRSXFEMLlQB ?
// Volgens mij NDXLlQB waarbij L en l nog overruled worden.
if (kv == "" && ktype != "M" && ktype != "F" && ktype != "E" && !makeCheckbox)
{ // Ook lege folders met bestanden en een enkele bestandsnaam krijgen we via de query mee. Maar deze niet tonen.
// Ooit meer HTML-types toepassen (number, float)
if (flexExprIncluded && (ktype == "N" || ktype == "D" || ktype == "S") && !isExpression)
onchangeExp = ";if (fvalid) calculateFlexExpressions(this"
+ ", \"" + module + "\""
+ ", " + key
+ ", \"" + (props.kenmerk_module || "") + "\""
+ ", \"" + nameprefix + "\""
+ ", \"" + extraserie + "\""
+ ");";
kv = "<input type='text'"
+ (!readonlyfield && kregexp ? " regexp='" + kregexp + "' " : "")
+ (!readonlyfield
? " onChange='fvalid=checkKenmerk(this, false,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")"
+ onchangeExp
+ "' "
: "")
+ (!readonlyfield ? " onBlur='checkKenmerk(this, true,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")' " : "")
+ (readonlyfield? " readonly tabindex=-1 "
: " id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val' ");
}
//
// LET OP: kv is nu een "OPEN" variabele, die nog minstens een sluithaak nodig heeft!
//
// KENMERKTYPE N (Numeriek) of B (Berekening) ===============================================
if (ktype == 'N' || ktype == 'B')
{ // Checkbox of numeriek/berekening input veld.
if (makeCheckbox) // deze doen we compleet hier
{
if (readonlyfield || ktype == 'B') // Berekening input veld is altijd readonly.
{
if (formobile)
{
kv = "<input type='text' class='fldflexc ' readonly tabindex=-1 value='" + (val == 1? L("lcl_check_1") : L("lcl_check_0")) + "'>";
}
else
{
kv = "<span"
+ " class='readonly "
+ (kenmerk_search ? "fldSflexC" : "fldflexC") // Is nu tekstveld
+ "'>" + (val == 1? L("lcl_check_1") : L("lcl_check_0")) + "</span>";
}
}
else
kv = "<input type='checkbox' class='"
+ (kenmerk_search
? "fldCSflexN "
: "fldCflexN ")
+ (required ? required_class : "")
+ "'"
+ " onChange='checkKenmerk(this, false,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")' "
+ " onBlur='checkKenmerk(this, true,\"" + ktype + "\"," + klen + "," + kdec + "," + kmin + "," + kmax + ")' "
+ (val == 1
? " checked"
: "")
+ " id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val' "
+ ">"
+ "<input type='hidden' id='has_" + nameprefix + idCounter + "val' name='has_" + nameprefix + idCounter + "val' value='1'>";
}
else
kv += " class='"
+ (kenmerk_search
? "fldSflexN "
: "fldflexN ")
+ (required ? required_class : "")
+ (kdec > 0 ? " float " : " number ")
+ (isExpression? " expression " : "")
+ "'"
+ (required ? " required='required' " : "")
+ (isExpression ? " readonly " : "")
//+ " placeholder='"+val_label+"'"
+ " value='" + (kdec > 0 && val? safe.displayfloat(parseFloat(val), kdec) : safe.html(val)) + "'"
+ " maxlength='" + ((kmin >= 0? 0 : 1) + (kdec > 0? 1 : 0) + klen) + "'"
+ ">";
}
// KENMERKTYPE D (Date) =================================================================
if (ktype == 'D')
{
kv += " class='"
+ (kenmerk_search
? "fldSflexD "
: "fldflexD ")
+ (required ? required_class : "")
+ (isExpression? " expression " : "")
+ "'"
+ (required ? " required='required' " : "")
+ (isExpression? " readonly " : "")
+ " value='" + safe.htmlattr(val) + "'"
+ ">";
if (!readonlyfield && !isExpression)
kv += "<i class=\"fa fa-calendar fa-fw dateklikker\" onclick=\"$('#"
+ nameprefix + idCounter + "val').datepicker('show')\"></i>";
// Als er voor een datumveld geen kmin en kmax 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 (kmin || kmax)
{
range_val = (kmin ? ((Math.abs(kmin)<1000) ? "c"+(kmin>0?"+"+kmin:kmin) : Math.abs(kmin)) : "c-10") + ":"
+ (kmax ? ((Math.abs(kmax)<1000) ? "c"+(kmax>0?"+"+kmax:kmax) : Math.abs(kmax)) : "c+10");
field_id = nameprefix + idCounter + "val";
dpYearRanges.push({id: field_id, range: range_val});
}
anyDate |= !readonlyfield;
}
// KENMERKTYPE X (Bestandsnaam/url) =========================================================
if (ktype == 'X')
{
if (S("flex_X_is_URL")==0)
var viewpath = S("image_path_virtual") + val;
else
var viewpath = val;
if (readonlyfield) // Je mag er wel op klikken
if (val)
kv = '<input class="details fldflexX" onclick=\'openDoc("' + safe.jsstring(viewpath) + '")\' value="' + safe.htmlattr(val) + '">';
else
kv = "";
else if (val) // Tekstveld met 'view' button er achter plakken
kv += " class='fldflexX"
+ (required ? required_class : "")
+ "'"
+ " value='" + safe.htmlattr(val) + "'"
+ (required ? " required='required' " : "")
+ "><i class='fileopen details fa fa fa-folder-open' "
+ " onClick='openDoc(\"" + safe.jsstring(viewpath) + "\");'></i>";
else if (!kenmerk_search) // !val // Browse button for new er achter plakken
kv = "<input class='fldflexX"
+ (required ? required_class : "")
+ "'"
+ (required ? " required='required' " : "")
+ (required > 1
? " onChange='checkRequiredGroup(\"" + required_group + "\")'"
: "")
+ " type='"
+ (S("flex_X_is_URL") == 0
? 'file'
: 'text')
+ "' "
+ ((S("flex_X_is_URL")==0) && kregexp
? " regexp='" + kregexp + "' "
: "")
+ "name='" + nameprefix + idCounter + "val' "
+ "value='" + safe.htmlattr(val) + "'"
+ ">";
else
kv += ">";
}
// KENMERKTYPE S (Suggest) ==================================================================
// readonlyfield is bij "R" al meegenomen
if (ktype == 'S' && !readonlyfield) // Referentie naar andere tabel (suggest box)
{
// Huidige waarde opzoeken
var dsql = "SELECT fac_kenmerkdomein_objectnaam "
+ ", fac_kenmerkdomein_kolomnaam "
+ ", fac_kenmerkdomein_kolomtxt "
+ ", fac_usrtab_key "
+ "FROM fac_kenmerkdomein "
+ "WHERE fac_kenmerkdomein_key = " + kdomein_key;
var oRs_d = Oracle.Execute(dsql);
var suggestval = getDatatypeValue(oRs_d("fac_kenmerkdomein_objectnaam").value, oRs_d("fac_kenmerkdomein_kolomnaam").value, val);
if (oRs_d("fac_kenmerkdomein_objectnaam").value == "FAC_USRDATA" && oRs_d("fac_usrtab_key").value)
{
var fsql = "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"
+ " FROM fac_usrdata "
+ " WHERE " + oRs_d("fac_kenmerkdomein_kolomnaam").value + " = " + suggestval;
fsql += " AND fac_usrtab_key = " + oRs_d("fac_usrtab_key").value
+ " AND fac_usrdata_verwijder IS NULL"
} else {
var fsql = "SELECT " + oRs_d("fac_kenmerkdomein_kolomnaam").value
+ "," + oRs_d("fac_kenmerkdomein_kolomtxt").value
+ ", NULL x"
+ " FROM " + oRs_d("fac_kenmerkdomein_objectnaam").value
+ " WHERE " + oRs_d("fac_kenmerkdomein_kolomnaam").value + " = " + suggestval;
}
oRs_d.close();
var oRs2 = Oracle.Execute(fsql);
var currval = "";
//var inactiveval = false;
if (!oRs2.eof)
{
currval = oRs2(1).value;
//inactiveval = (oRs2(2).value != null); // zie opmerking hieronder
}
oRs2.close();
%> <script type="text/javascript">
<% if (parentkenmerkid != "")
{ %>
function onChangeSKenmerkParent<%=parentkenmerkid%>(parentkey, parenttxt)
{ // Functie wordt aangeroepen door een eventuele parent waarvan deze suggest afhankelijk is
// setValue(key, txt, doonChange, checkExist, extraParam, lastTry)
var presentkey = $("#<%=nameprefix + idCounter%>val").val();
var presenttxt = $("#Suggest<%=nameprefix + idCounter%>_show").val()
Suggest<%=nameprefix + idCounter%>.setValue(presentkey, presenttxt, false, true, null, true);
// Indien suggestbox verplicht is en maar <20><>n mogelijke waarde heeft, dan deze selecteren
if ($("#Suggest<%=nameprefix + idCounter%>_show").hasClass("required")) Suggest<%=nameprefix + idCounter%>.CheckJustOne();
var className = $("#Suggest<%=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<%=parentkenmerkid%>_show")[0].className.match(/required\d*S\d*/g)[0].substr(8);
checkRequiredGroup(group);
}
}
<% } %>
<% if (required)
{ %>
function onChangeSKenmerk<%=nameprefix + idCounter%>(parentkey, txt)
{
checkRequiredGroup("<%=required_group%>");
}
<% } %>
jQuery(document).ready(function()
{
if ($("#execDone<%=nameprefix + 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<%=nameprefix + idCounter%> = new Suggest({objectName: "Suggest<%=nameprefix + idCounter%>",
queryField: $("#Suggest<%=nameprefix + idCounter%>_show")[0],
queryUrl: "../shared/Suggest/SuggestKenmerkDomein.asp?kenmerkdomein_key=<%=kdomein_key%><%=(hideVervallen?'&filtcode=A':'')%>",
initKey: '<%=val%>',
keyField: $("#<%=nameprefix + idCounter%>val")[0],
fieldReadonly: <%=readonlyfield? "true" : "false"%>
<% if (parentkenmerkid != "")
{ %>
,urlAdd: [{ urlParam: "parent_key", field: "<%=parentkenmerkid%>val" }]
<% } %>
});
<% if (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<%=parentkenmerkid%>_show").attr("sgonChange", "onChangeSKenmerkParent<%=parentkenmerkid%>");
<% } %>
$("#execDone<%=nameprefix + idCounter%>").val(1); // Het is nu 1 keer uitgevoerd. Nu niet meer uitvoeren.
}
})
</script><%
kv = "<input type='text' "
+ (kregexp ? " regexp='" + kregexp + "' " : "")
+ "id='Suggest" + nameprefix + idCounter + "_show' "
+ "name='Suggest" + nameprefix + idCounter + "_show' "
+ "value='" + safe.htmlattr(currval) + "' "
+ "class='" + (kenmerk_search ? "fldflexS" : "fldSflexS")
+ (required ? required_class : "") + "'"
// zo wordt het veld rood, ongeacht de waarde, wat verwarrend is, dus niet + (inactiveval ? " inactive " : "")
+ (required ? " required='required' " : "")
+ (required > 1
? " sgonChange='onChangeSKenmerk" + nameprefix + idCounter + "'"
: "")
+ ">"
+ "<input type='hidden' id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val'>"
+ "<input type='hidden' id='execDone" + nameprefix + idCounter + "' name='execDone" + nameprefix + idCounter + "' value='0'>";
}
// KENMERKTYPE L (Label) ====================================================================
if (ktype == 'L' || ktype == 'l')
{ // Label line
allCollapsable = (ktype == 'l'); // opnieuw beginnen met zoeken
inMobileBlock = (formobile && ktype == 'l'); // op dit moment zitten we in een mobile-collapse-content-block
val_label = oRs("kenmerk_omschrijving").Value; // was: 1
clabelCounter++;
val_seperator = '';
kv = def_val;
// suggestie voor UWVA#20007: if required then collapsable
}
// ==========================================================================================
// Alles bepaald, nu positioneren enzo
// ==========================================================================================
if (!predone && props.fnpre && (kv || (ktype == 'L' || ktype == 'l')))
{
predone = true;
props.fnpre();
}
// KENMERKTYPE Q (spacer) ===================================================================
// Alleen echt nuttig bij 2-koloms layout
if (ktype == 'Q')
{
// PF: deze implementatie lijkt me discutabel; is forceNewLine niet beter?
if (((colCount&1) || !kenmerk_2col) && !formobile && !notr)
kenmerk_write('<tr>');
else if (!((colCount&1) && kenmerk_2col) && !formobile && !notr)
kenmerk_write('</tr>');
oRs.MoveNext();
continue; // Teller is wel opgehoogd: volgende komt vanzelf op nieuwe regel
}
if (kv != '')
{
// Schrijf eventueel een tabelregel begin
if (((colCount&1) || forceNewLine || !kenmerk_2col) && !formobile && !notr)
kenmerk_write('<tr' + (ktype == 'L' || ktype == 'l'? ' id="'+nameprefix+'clabel' + clabelCounter + '"' : '')
+ ' class="trlabel ' + (ktype == 'L' || ktype == 'l'? 'flexlabel' : '') + (ktype == 'l' && !readonlyfield? ' flexcollapsable' : '') + '"'
+ (ktype == 'l'? ' onclick="$(\'#'+nameprefix+'clabel' + clabelCounter + '\').nextUntil($(\'#'+nameprefix+'clabel' + (clabelCounter + 1) + '\')).toggle();'
+ '$(this).toggleClass(\'flexcollapsed\');'
+ 'FcltMgr.resized(window);"'
: '')
+ '>'); // Nu altijd zichtbaar in popup dmodal scherm
// Schrijf een tabelcell met het label
if (makeCheckbox && formobile) // Zie commentaar iets verderop
props.label_colspan = 2;
if (props.wfbuilder) // Workflow Expression Builder
kenmerk_write("<td>:flex{0}</td>".format(kkey));
if (!formobile && !nolabel)
kenmerk_write('<td class="label' + (ktype == 'L' || ktype == 'l'? ' flexlabel' : '')+ (kenmerk_search? ' flexsearch' : '') + '"'
+ (props.label_colspan? ' colspan=' + props.label_colspan : '') + '>');
if (!nolabel)
kenmerk_write((formobile && ktype == 'l'? '<div data-role="collapsible" data-theme="c" data-content-theme="c"><h3 id="collLabel'+clabelCounter+'">' : '')
+ '<label for="' + nameprefix + idCounter + 'val" class="label' + (ktype == 'L' || ktype == 'l'? ' flexlabellabel' : '')
+ (isExpression ? ' expression' : '') + '">' + '<span title="' + safe.htmlattr(hint) + '">'
+ val_label + ((kdim != null && kdim != "xxx")? ' [' + kdim + ']' : '') + val_seperator + '</span></label>'+(formobile && ktype == 'l' ? '</h3>' : ''));
// labelwaardes (vaak invulinstructie) in apart te stylen span
if (formobile && (ktype == 'L' || ktype == 'l') && kv) {
kv = '<span class="flexlabelvalue">' + kv + '</span>';
}
// 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 ((!makeCheckbox || !formobile) && !formobile)
{
if (!nolabel)
kenmerk_write('</td>');
kenmerk_write('<td ' + (ktype == 'L' || ktype == 'l'? ' class="flexlabel lhint"' : (readonlyfield ? ' class="readonly flexvalue"' : ' class="flexvalue"')));
if (kenmerk_search && (ktype != 'L' && ktype != 'l'))
{
kenmerk_write('>');
kenmerk_write(Operand(idCounter));
}
else
{
if ( ktype == 'L' || ktype == 'l' )
if (typeof kenmerk_extraTD != "undefined" && kenmerk_extraTD)
kenmerk_write(' colspan=4>'); // MLD_OPDR heeft TD-tje extra
else
kenmerk_write(' colspan=3>');
else
kenmerk_write(">");
}
if (nolabel)
kenmerk_write('<label for="' + nameprefix + idCounter + 'val">'
+ '<span title="' + safe.htmlattr(hint) + '">'
+ '</span></label>');
}
// Schrijf vervolgens nu het echte veld
kenmerk_write(kv);
if (typeof kenmerk_extraTD != "undefined" && kenmerk_extraTD && !formobile)
kenmerk_write('</td><td>') // Extra leeg celletje voor layout MLD_OPDR
if (val && forceReadonly && ktype != "M" && ktype != 'L' && ktype != 'l')
{ // hidden veld met de *echt* waardes zodat ze wel worden opgeslagen
kenmerk_write("<input type=hidden id='" + nameprefix + idCounter + "val' name='" + nameprefix + idCounter + "val' value='" + safe.htmlattr(val) + "'>")
}
if ((kenmerk_search || !readonlyfield || (val && forceReadonly)) && ktype != "M" && ktype != 'L' && ktype != 'l')
{ // Alleen dan hidden name-velden er bij
%> <input type=hidden name='<%=nameprefix + idCounter%>key' id='<%=nameprefix + idCounter%>key' value='<%=kkey%>'>
<input type=hidden name='<%=nameprefix + idCounter%>t' id='<%=nameprefix + idCounter%>t' value='<%=ktype%>'>
<% if (isExpression)
{ %>
<input type=hidden name='<%=nameprefix + idCounter%>e' id='<%=nameprefix + idCounter%>e' value='1'>
<% } %>
<% }
idCounter++; // Nu ophogen
if (!formobile)
{
kenmerk_write('</td>');
if (!((colCount&1) && kenmerk_2col) && !notr)
kenmerk_write('</tr>');
}
}
oRs.MoveNext();
// Collapse code er achteraan als de *volgende* een ander label is
if ((inMobileBlock || (!formobile && allCollapsable)) && (oRs.Eof || oRs("kenmerk_kenmerktype").value.toUpperCase() == 'L')) // einde huidige label
{
if (formobile)
{
kenmerk_write('</div>');
inMobileBlock = false;
if (!allCollapsable) // the current collapseBlock should be expanded
kenmerk_write('<script> $(document).ready(function(){ $("#collLabel'+clabelCounter+'").trigger("click"); });</script>');
}
else
kenmerk_write('<script>$(document).ready(function(){$("#' + nameprefix + 'clabel' + clabelCounter + '").addClass("flexcollapsed").nextUntil($("#' + nameprefix + 'clabel' + (clabelCounter + 1) + '")).hide();})</script>');
allCollapsable = false;
}
}
oRs.close();
if (inMobileBlock || (!formobile && allCollapsable)) // allerlaatste ook nog
{
if (formobile)
{
kenmerk_write('</div>');
if (!allCollapsable) // the current collapseBlock should be expanded
kenmerk_write('<script> $(document).ready(function(){ $("#collLabel'+clabelCounter+'").trigger("click"); });</script>');
}
else
kenmerk_write('<script>$(document).ready(function(){$("#' + nameprefix + 'clabel' + clabelCounter + '").addClass("flexcollapsed").nextUntil($("#' + nameprefix + 'clabel' + (clabelCounter + 1) + '")).hide();})</script>');
}
var counterName = (extraserie? nameprefix + "_all" : "k_all");
if (!formobile)
{
if (!notr)
kenmerk_write('<tr>');
kenmerk_write('<td>');
}
if (key < 0)
kenmerk_write("<input type='hidden' name='ktmpfolder" + serie + "' id='ktmpfolder" + serie + "' value='" + tmpfolder + "'>");
kenmerk_write('<input type="hidden" id="' + counterName + '" name="' + counterName + '" value="' + (idCounter - 1) + '">');
kenmerk_write('<input type="hidden" id="k_flexsql" name="k_flexsql" value="' + (prssql? 1 : 0) + '">');
if (!formobile)
{
kenmerk_write('</td>');
if (!notr)
kenmerk_write('</tr>');
}
if (predone && props.fnpost)
props.fnpost();
// Eventuele scripts moeten buiten de </table>
if (anyTextarea && !kenmerk_search)
{
%><script type="text/javascript">
jQuery(document).ready( function()
{
$('textarea').resize(function () { FcltMgr.resized(window) } );
if ($.fn.autogrow) // Niet bij mobile
$('textarea').autogrow();
});
</script><%
}
// Bij kenmerk_search doen de load_kenmerk's geen FCLTHeader.Generate en dus hebben
// we date.js niet gegarandeerd. .fldSflexD werd echter hieronder toch al niet
// meegenomen dus komen we er mee weg gewoon hier geen kalenders te doen
if (anyDate && !kenmerk_search)
{
// FCLTHeader.Requires is hier te laat
%><script type="text/javascript">
// Zie ook calendar.inc. Delen code was iets te lastig
jQuery(document).ready( function()
{
if ($.datepicker) // Is er niet mobile
{
$(".fldflexD").not("[readonly]").datepicker({
// buttonImage: "../pictures/calendar2.png",
// buttonImageOnly: true,
showOn: "none",
duration: 'fast',
dateFormat: 'dd-mm-yy', // zo verwacht de flex-code het.
changeYear: true,
changeMonth: true,
duration: 'fast',
beforeShow: function(input, inst) { setTimeout("FcltMgr.resized(window)", 100) },
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%>");
<%
}
%>
}
});
</script><%
}
if (hasfilter)
{
%>
<script>
$(document).ready(function () {
$("#insFlex2 .fcltblockhead").append("<input id='autofilter' type='text' placeholder='"+L("lcl_autofilter")+"'>");
$("#autofilter")
.click(function(e) {e.stopPropagation()})
.keyup(function(e) {
if (e.which == 27) {
$("#autofilter").val("");
}
delayed(200, doFilter);
})
});
function delayed(delay, fn)
{
if (window.timerID)
clearTimeout(window.timerID);
window.timerID = setTimeout(fn, delay);
}
function doFilter(deze)
{
var deze = $("#autofilter");
var valThis = deze.val().toLowerCase();
$('#insFlex2List table.fcltblocktab>tbody>tr.trlabel').each(function() {
var text = $(this).find("td.flexsearch>label>span").text().toLowerCase();
$(this).toggle(text.indexOf(valThis) > -1);
});
}
</script>
<%
}
if (formobile && clabelCounter)
{ %>
<script>
$(document).ready(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.getTmpfolder)
return tmpfolder;
}
// Ondersteunende filehandlingfuncties ============================================================
// Hernoem folders onder basepath
// Flexsql levert twee velden op: oude key en nieuwe key
function RenameFlexFolders(basepath, flexsql)
{
var basepath = S("flexFilesPath") + "/" + basepath + "/";
var oRs = Oracle.Execute(flexsql);
while (!oRs.Eof)
{
var vAttachPath = basepath + oRs(0).value;
var vAttachPath2 = basepath + oRs(1).value;
MoveFlexfiles(vAttachPath, vAttachPath2);
oRs.MoveNext();
}
}
// Kopieer folders van oldbasepath naar newbasepath
// Flexsql levert twee velden op: oude key en nieuwe key
function CopyFlexFolders(oldbasepath, newbasepath, flexsql)
{
var fso = Server.CreateObject("Scripting.FileSystemObject")
var oldbasepath = S("flexFilesPath") + "\\" + oldbasepath + "\\";
var newbasepath = S("flexFilesPath") + "\\" + newbasepath + "\\";
var oRs = Oracle.Execute(flexsql);
while (!oRs.Eof)
{
vAttachPath = oldbasepath + oRs(0).value;
vAttachPath2 = newbasepath + oRs(1).value;
__Log("Kopie " + vAttachPath + " Naar " + vAttachPath2);
try
{
if (fso.FolderExists(vAttachPath))
{
__Log("xAbout to copy " + vAttachPath + "\\*.* to " + vAttachPath2 + "\\");
CreateFullPath(vAttachPath2);
fso.CopyFile(vAttachPath+"\\*.*", vAttachPath2, false); // Don't overwrite
}
}
catch(ee)
{
__SafeDoLog("Copying files from " + vAttachPath + "<br>to " + vAttachPath2 + " failed:<br>" + ee.description, "#FFFF00");
}
oRs.MoveNext();
}
fso = null;
}
// ================================================================================================
// Save de kenmerken die we met listKenmerk hebben aangemaakt
// Verondersteld POST formulier (we doen een Request.Form)
// 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 kenmerk_omschrijving en
// srtkenmerk_key (zie melding_save)
// - 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. kkn en kvn zullen er dan ook altijd beide zijn
// ================================================================================================
// Let op: de voorkeur is het gebruik van saveFlexKenmerken(parentKey, params)
// voor backward compatibilitiet 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, 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,
currentKenmerkenSQL: currentKenmerkenSQL,
requestQF: RequestQ?Request.QueryString:Request.Form,
moduleName: moduleName, moduleVal: moduleVal,
isNew: isNew, flexPath: flexPath,
multiMode: multiMode
}
}
var flexdata = kenmerkParams.flexdata;
if (!flexdata)
{
// Maak alsnog het flexdata object: backwards compatible!
var params = {};
if (kenmerkParams.extraserie) params.extraserie = kenmerkParams.extraserie;
if (kenmerkParams.nameprefix) params.nameprefix = kenmerkParams.nameprefix;
flexdata = flexkenmerken2jsondata(params);
}
return _saveFlexKenmerken(parentKey, kenmerkParams, flexdata);
}
function _saveFlexKenmerken(parentKey, params, flexdata) // TODO: support multiMode!
{
var kenmerk_keys = new Array(); // 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 onstaan 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)
{
kenmerk_keys[oRs(params.kenmerkKey).value] = oRs(params.kenmerkWaarde).value; // kenmerkwaarde moet oldval bevatten
oRs.MoveNext();
}
oRs.Close();
}
if (params.isNew && !params.noAttachments)
{
var ktmpfolder = getFParam("ktmpfolder" + (params.tmpfolderNum? params.tmpfolderNum : 0), "");
if (ktmpfolder)
{
var tmp_folder = "__NEW__" + user_key + "_" + safe.filename(ktmpfolder);
vAttachPath = S("flexFilesPath") + "/" + params.flexPath + tmp_folder;
var flexPathArray = params.flexPath.split("/"); // MLD/M => MLD (0) en M (1)
vAttachPath2 = S("flexFilesPath") + "/" + flexPathArray[0] + "/" + subfolderKey(bepaalNiveau(params.moduleName, flexPathArray[1]), parentKey);
// 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);
fso.DeleteFolder(vAttachPath);
}
catch (ee)
{
__DoLog("MoveFolder " + vAttachPath + " naar " + vAttachPath2 + " nog mislukt: " + ee.description);
}
}
fso = null;
}
}
var trackarray = []; // eventuele tracking
var hasExpression = false;
for (kenmerkkey in flexdata)
{
var flex = flexdata[kenmerkkey];
var vold = kenmerk_keys[flex.id]? kenmerk_keys[flex.id] : "";
hasExpression = hasExpression || flex.expr == 1;
var vnew = flex.value || "";
// tracking?
if (!params.isNew && params.tracking)
{
if (vold != vnew)
{
var oRsk = Oracle.Execute(params.allKenmerkenSQL + flex.id);
var label = oRsk("kenmerk_omschrijving").Value;
var kdomein_key = oRsk("fac_kenmerkdomein_key").Value;
oRsk.Close();
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 = oRsd("domeinwaarde").Value;
oRsd.Close();
}
if (vnew != "")
{
var oRsd = Oracle.Execute("SELECT fac.getdomeinwaarde(" + kdomein_key + ", " + safe.quoted_sql(vnew) + ") domeinwaarde FROM DUAL");
vnew = oRsd("domeinwaarde").Value;
oRsd.Close();
}
}
trackarray.push(label + ": " + buildTrackText("varchar", vold, vnew, {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.type == "X" && S("flex_X_is_URL") == 0)
flex.value = parseDocumentPath(flex.value);
if (( flex.value == "" || flex.value == "undefined"))
{
if (kenmerk_keys[flex.id] && !params.multiMode)
{
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);
evaluateflexexpressions(module, parentKey, true);
//removekenmerkwaarden(module, parentKey);
}
return trackarray;
}
function savekenmerkwaarden(module, refkey, kenmerkniveau, flexdata)
{
for (kenmerkkey in flexdata)
{
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_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].expr
+ " , " + user_key
+ " )";
Oracle.Execute(sql);
}
}
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;
__DoLog(message);
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");
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 kv = getFParam(flex + "val", ""); // kenmerk waarde
var ke = Request.Form(flex + "e").Count; // Flexkenmerk is een expressie.
// 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")
{
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.
// 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".
}
}
// 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,
value: kv,
expr: (ke? 1 : 0),
kfieldid: flex
};
}
}
return jsondata;
}
%>