<% /*
     $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;
}
%>