Files
Facilitor/APPL/Shared/selector.inc
Erik Groener 1522d72f30 PROR#89199 Per melding slechts één object selecteren
svn path=/Website/trunk/; revision=70558
2025-10-07 13:13:49 +00:00

370 lines
17 KiB
PHP

<% /*
$Revision$
$Id$
File: selector.inc
Description: Algemene interface functie om een selectveld te maken
Deze moet je kunnen includen en aanroepen.
Resulteert dan uiteindelijk in een selectbox aangemaakt die gevuld wordt door een query.
Het resultaat heeft de vorm "[<td>label</td><td>]selectveld[</td>]"
of voor mobile "[<label>label</label>]selectveld"
of [<td>label</td><td>]inputveld[</td>].
Indien geen initiële waarde is meegegeven, dan wordt standaard -1 genomen.
parameters: fieldName: veldnaam van het selectveld. Dit veld wordt gesubmit.
sql: sql query die zorg voor de inhoud van het selectveld. (SELECT key, omschrijving FROM ... WHERE ...)
params: object met meegegeven parameters.
initKey: initiële key waarde van de select die ingevuld moet worden.
label: label dat voor het selectveld wordt weergegeven.
onChange: onchange op het selectveld.
readonly: geeft aan of het selectveld readonly weergegeven moet worden (true|false(default)).
multi multi selectveld
sgRelType: De onderliggende multiSelect-type die afhankelijk is van deze FCLTselector. Voor nu alleen ondersteuning voor 1 afhankelijke.
Uitbereiding naar afhankelijkheid van meerdere select boxen kan wel tegen de tijd dat het nodig is.
trclass: wordt ook op de <tr> gezet
size handig bij multi selectveld
moreinfo: geeft een extra informatie button achter het selectveld. Klikken hierop geeft informatie over de geselecteerde waarde
extraParamValue: Voegt een extra value parameter toe aan de waarden (<option>)
extraParamValueInit: Initiele waarden voor de extra value parameters
emptyKey: De key voor de emptyOption (default -1)
emptyOption: De tekst voor een lege waarde bovenaan in de lijst
?Bij 'multi' doet hij dat alleen bij een lege listbox
selectjustone Als er 1 waarde in de lijst is, selecteer deze dan en voeg geen lege waarde toe
initEmpty Moet de lege waarde altijd geselecteerd zijn (meestal voor filters) of kies een single optie altijd gelijk
required Voegt de class 'required' toe aan het veld
mobile Format for HTML5
titleCol kolom waarin de tooltip tekst voor de option staat
tooltipsql als titleCol bestaat, kan er nog een opsomming van gegevens volgens deze sql worden toegevoegd aan de tooltip
maxrows Maximum aantal regels dat wordt opgehaald in tooltipsql
action Om nog een extra actie voor deze waarde uit te kunnen voeren, bijvoorbeeld het openen van een scherm voor het op een andere manier selecteren van gegevens.
Hierbij horen extra parameters: onclick (aan te roepen functie), title (hint tekst) en icon (zelf te definieren icon voor de actie).
Resultaat: { justone: true // als dat zo is
initKey: 1234, // als justone
initText: "sdfsd" // als justone
}
Note: de combinatie van readonly en multi is (nog) niet ondersteund
*/ %>
<%
FCLTHeader.Requires({ plugins: ["jQuery"] });
// Functie kijkt of de waarde pvalue voorkomt in de array parray
function valueInArray(parray, pvalue, pmulti, pemptyIsRealValue)
{
// TODO return $.inArray()
var vvalue = (pemptyIsRealValue && pvalue == null ? "" : pvalue);
if (pmulti && parray.length > 1) // parray is nu een array met waarden
{
for (i = 0; i < parray.length; i++)
{
if (parray[i] == vvalue) return true;
}
}
else
{
return (parray[0] == vvalue)
}
return false
}
function FCLTselector(fieldName, sql, params)
{
Response.Write(FCLTselector_HTML(fieldName, sql, params));
}
function FCLTselector_HTML(fieldName, sql, params)
{
var resultstr = "";
var result = {};
if (!(params.initKey && params.initKey > 0) && params.readonly && params.suppressEmpty) return;
if (typeof params == "undefined") params = {};
var isMobile = ("mobile" in params) ? params.mobile : (typeof mobile != "undefined");
params.id = params.id || fieldName;
if (params.multi) { // Zet bij multi de default size op 4 regels.
if (!params.size) {
params.size = 4;
}
}
if (params.label)
{
if (!isMobile) { // mobile zit niet in een table
resultstr += "<tr" + (params.trclass? " class='" + params.trclass + "'" : "") + "><td class='label'>";
}
resultstr += "<label class='selector' for='" + fieldName + (params.readonly? "_ro" : "") + "'>" + params.label + "</label>"
+ (params.moreinfo ? "<span class='labelextra details' onclick='" + params.moreinfo + "'>" + I("fa-info-circle") + "</span>" : "")
+ ( params.action && params.action.onclick
? "<span class='labelextra default-clickable-icon' onclick='" + params.action.onclick + "'"
+ (params.action.title ? " title='" + safe.htmlattr(params.action.title) + "'" : "")
+ ">"
+ I( (params.action.icon ? params.action.icon : "fa-star") )
+ "</span>"
: ""
);
if (!isMobile) { // mobile zit niet in een table
resultstr += "</td><td>";
}
}
if ("flag" in params && isNaN(parseInt(params.flag, 10))) /* Wel meegegeven, maar ongeldig (bijv. undefined) */
params.flag = 0;
if (!isMobile && "flag" in params && !isNaN(parseInt(params.flag, 10)))
{
resultstr += "<script type='text/javascript'>"
+ "$(function()"
+ "{"
+ " $('#" + fieldName + "').on('change',"
+ " function () {"
+ " var flagkey = $('#" + fieldName + " option:selected').val();"
+ " $('#flag-icon').html((flagkey == 0? \"" + I("fa-fclt-flag0") + "\" : \"" + I("fa-fclt-flag") + "\"))"
+ " .attr('class', '" + fieldName + "' + flagkey);"
+ " }"
+ " );"
+ "});"
+ "</script>"
+ "<span id='flag-icon' class='" + fieldName + params.flag + "'>"
+ I("fa-fclt-flag" + (params.flag == 0? "0" : ""))
+ "</span>";
}
if (params.sgRelType)
{
resultstr += "<script type='text/javascript'>"
+ " function toggle" + params.sgRelType + "()"
+ " {"
+ " if ($('#" + params.id + "').attr('multiple') == 'multiple')"
+ " $('#discmulti').closest('tr').hide();"
+ " else"
+ " $('#discmulti').closest('tr').show();"
+ " $('#discmulti').val(-1);"
+ " }"
+ " $(function()"
+ " { // Na het klikken op de dubbele >> voor de multi uitvoering van de selectbox moet eerst selectbox uitklappen.\n"
+ " // Daartoe is een onclick gezet op alle elementen met de class 'multi_select_toggle'. Dit is gebeurt in fcltJquery.js.\n"
+ " // Dit bestand wordt later geladen en dus wordt ook de onclick later uitgevoerd, dus staat [multiple] hier al in de juiste stand\n"
+ " $(document).on('click', '[fcltfor=" + params.id + "].multi_select_toggle', function () { toggle" + params.sgRelType + "(); });"
+ " FcltMgr.resized();"
+ " });"
+ "</script>";
}
if (!params.readonly)
{ // TODO: class van fld overnemen voor de width is niet helemaal jofel
var startmulti = params.startmulti;
if (params.multi && params.initKey && String(params.initKey).split(",").length>1)
startmulti = true;
if (params.multi && !params.initKey && params.initKey != "" && !params.emptyOption && params.emptyOption != "")
startmulti = true;
var result = FCLTselectorOptions_HTML(sql, params);
resultstr += "<select class='fld"
+ (params.startmulti ? "multi" : "")
+ (params.required ? " required" + (result.hasEmpty || !result.n_records? "" : " no-empty-option") : "")
+ (isMobile ? MOBILE_UI_CLASSES.select : "")
+ (params.extraclass? " " + params.extraclass : "")
+ "'"
+ " name='" + fieldName + "'"
+ " id='" + params.id + "'"
+ (startmulti? " multiple" : "")
+ (startmulti? " size=" + params.size : "")
+ ((!params.startmulti && params.showasmulti && params.size)? " size=" + params.size : "")
+ (params.multi && (params.size || 2) > 1? " fcltmulti=1" : "")
+ (params.formid? " form='" + params.formid + "'" : "")
+ (params.disable? " disabled" : "")
+ (params.onChange? " onchange='" + safe.htmlattr(params.onChange) + "'" : "")
+ (params.onDblClick? " onDblClick='" + safe.htmlattr(params.onDblClick) + "'" : "");
if (params.data) {
for (var i in params.data) {
if (params.data.hasOwnProperty(i)) {
resultstr += " data-" + i + "='" + safe.htmlattr(params.data[i]) + "'";
}
}
}
resultstr += ">"
+ result.html
+ "</select>"
}
else
{ // we moeten hier wat ingewikkeld doen omdat we wel de key hebben van de te tonen waarde, maar niet de waarde zelf
// NB: in het geval van een readonly/multi listbox toont-ie maar 1 waarde.
var initstr = "";
if (sql && sql != "")
{
var oRs = Oracle.Execute(sql);
while (!oRs.eof)
{
var v_value = ((params.emptyIsRealValue && (oRs(0).value == null)) ? "" : oRs(0).value);
if (params.initKey == v_value)
{
if (v_value == "")
initstr = (params.emptyIsRealValue ? oRs(1).value : (params.emptyOption ? params.emptyOption : ""));
else
initstr = oRs(1).value;
}
oRs.MoveNext();
}
oRs.close();
}
if (initstr == "" && params.emptyIsRealValue && params.emptyOption) {
initstr = params.emptyOption;
}
resultstr += "<span id='" + fieldName + "_ro' class='readonly fld" + fieldName + "'>" + safe.html(initstr) + "</span>";
}
if (params.moreinfo && !params.label) {
resultstr += "<span class='details' onclick='" + params.moreinfo + "'>" + I("fa-info-circle") + "</span>";
}
if (params.label && !isMobile)
{
resultstr += "</td></tr>";
} else if (isMobile && !params.readonly) {
resultstr = "<div>" + resultstr + "</div>";
}
return resultstr;
}
function FCLTselectorOptions(sql, params) {
var result = FCLTselectorOptions_HTML(sql, params);
Response.Write(result.html);
return result;
}
// Levert alleen de <options> van de selector op
function FCLTselectorOptions_HTML(sql, params)
{
var result = { n_records: 0, html: "" };
if (typeof params.required == "boolean" && params.required)
params.required = 1;
else if (typeof params.required == "boolean" && !params.required)
params.required = 0;
// Else aanroep vanuit Shared/loadRKenmerk.asp waar params.required een number is
var required_class = "";
if (params.required)
{
required_class = " required";
if (params.required > 1)
required_class += params.required; // checkRequiredGroup() hoeft hier niet. wordt alleen gebruikt bij kenmerken
}
if (!("emptyKey" in params))
params.emptyKey = -1;
// Indien geen initiële waarde is meegegeven, dan wordt standaard -1 genomen.
if (typeof params.initKey == "undefined") // pas op: activiteit_key is wel eens 0
params.initKey = params.emptyKey;
// Indien multi dan kan initKey een string van waarden bevatten
// Maak daarom van initKey een array met waarden
params.initKey = String("" + params.initKey);
params.initKey = params.initKey.split(",");
var hasEmpty = false;
if (sql && sql != "")
{
var oRs = Oracle.Execute(sql);
// Check of er slechts 1 resultaat is: dan wil ik die automatisch gekozen hebben in plaats van een evt. lege waarde
var justone = false;
var noresults = false;
if (!oRs.eof)
{
if (params.multi && params.selectfirstone)
params.initKey[0] = oRs(0).value;
oRs.MoveNext();
if (oRs.eof)
justone = true;
oRs.MoveFirst();
}
else
noresults = true;
result.justone = justone;
if (params.extraParamValue)
{
var extraPV = params.extraParamValue.split(",");
if (params.extraParamValueInit)
var extraPVI = params.extraParamValueInit.split(",");
}
// TODO: als required en initKey dan hoeft emptyOption er natuurlijk niet bij zou ik zeggen
if ((((params.emptyOption || params.emptyOption == "") && !(justone && params.required == 1)) || params.initEmpty) && !(params.selectjustone && justone))
{
var hasEmpty = true; // afgeleide var voor het gemak
result.html += '<option value="' + params.emptyKey + '" '
+ (params.required ? ' class="' + required_class + '"' : '')
+ (valueInArray(params.initKey, params.emptyKey, params.multi) ? ' selected' : '')
if (params.extraParamValue && params.extraParamValueInit)
{
for (var i = 0; i < extraPV.length; i++)
{
result.html += ' ' + extraPV[i].replace(/^\s+|\s+$/g,"") + '="' + safe.htmlattr(extraPVI[i] ? extraPVI[i].replace(/^\s+|\s+$/g, '') : '') + '"'; /* replace is to trim spaces */
}
}
result.html += '>'
+ ((!noresults || params.emptyIsRealValue) && params.emptyOption ? safe.html(params.emptyOption) : '&nbsp;')
+ '</option>';
}
if (params.placeholder) // Voor mobile: het label komt dan in de listbox te staan als er geen waarde gekozen is.
{
result.html += "<option disabled selected hidden class='placeholder'>" + params.label + "</option>";
}
while (!oRs.eof)
{
result.n_records ++;
if (justone && !hasEmpty)
{
result.initKey = oRs(0).value;
result.initText = oRs(1).value;
}
if (oRs(0).value === "##DISABLED##") {
result.html += '<option disabled ';
} else {
result.html += '<option value="' + safe.htmlattr(oRs(0).value) + '" ' + (valueInArray(params.initKey, oRs(0).value, params.multi, params.emptyIsRealValue) || (justone && !hasEmpty) ? ' selected ' : '');
}
if (params.titleCol)
{
title = oRs(params.titleCol).value;
if (params.tooltipsql)
{
var ttsql = params.tooltipsql + oRs(0).value + " ORDER BY 2"; // de key voor deze option waarop aanvullende gegevens van toepassing zijn
if (params.maxrows)
{
ttsql = "SELECT * FROM (" + ttsql + ") WHERE ROWNUM <= " + params.maxrows;
}
var oRst = Oracle.Execute(ttsql);
while (!oRst.eof)
{
title += "\n" + oRst(0).value; // elk gevonden record op een nieuwe regel
oRst.MoveNext();
}
oRst.close();
}
result.html += ' title="' + safe.htmlattr(title) + '"';
}
if (params.intervals) {
result.html += " intervals='" + (oRs(params.intervals).Value ? safe.htmlattr(oRs(params.intervals).Value) : "") + "'";
}
if (params.extraParamValue)
{
for (var i = 0; i < extraPV.length; i++)
{
result.html += extraPV[i].replace(/^\s+|\s+$/g,"") + '="' + safe.htmlattr(oRs(extraPV[i].replace(/^\s+|\s+$/g,"")).value) + '"'; /* replace is for trim spaces */
}
}
result.html += '>'
+ safe.html(oRs(1).value)
+ '</option>';
oRs.MoveNext();
}
oRs.close();
}
result.hasEmpty = hasEmpty;
return result;
}
%>