1261 lines
54 KiB
JavaScript
1261 lines
54 KiB
JavaScript
/*
|
||
$Revision$
|
||
$Id$
|
||
|
||
File: Suggest.js
|
||
Description:
|
||
Parameters: params.objectName,
|
||
params.queryField,
|
||
params.queryUrl,
|
||
params.initKey,
|
||
params.initExtraParam,
|
||
params.keyField,
|
||
params.fieldReadonly,
|
||
params.urlAdd,
|
||
params.extraParamField,
|
||
params.isBad,
|
||
params.highlightDescript,
|
||
params.noJustOne,
|
||
params.suppressJustOne
|
||
params.JSONP
|
||
params.multitoggle (true|false voor alle, of [0-6] voor plaatsselector, t/m alg_level #multitoggle
|
||
params.addfixedoption Voegt een vaste optie toe, meegegeven als {key, txt, desc}
|
||
params.embedded Kijk nooit naar het parent document (embedded)
|
||
Context:
|
||
Note: Pas op met gebruiken functies uit andere modules. Dit bestand
|
||
wordt ook bij vinder/vanuit API\phonebook_js.asp gebruikt en dan
|
||
heb je die andere bestanden niet.
|
||
|
||
*/
|
||
|
||
var $suggestbusy;
|
||
var suggesttimer;
|
||
|
||
function Suggest(inParams) {
|
||
// Genereer een enkel stukje busy-html die voor alle suggests in deze pagina hergebruiken
|
||
if (!$suggestbusy)
|
||
$suggestbusy = $("<i class='fas fa-cog fa-spin suggestbusy'></i>").appendTo($("body"));
|
||
var params = inParams;
|
||
|
||
var storeKeyField; // = inStoreKeyField; // use function withKeyField() to assign field
|
||
var storeExtraParamField; // = instoreExtraParamField; // use function withExtraParamField() to assign field
|
||
var _completeDiv = null;
|
||
var _comboDiv = null;
|
||
|
||
//thisdoc.onclick = function(){debugger;};
|
||
// Kopie uit FcltJquery.js. Die hebben we niet vanuit API\phonebook_js.asp
|
||
var myEncode = function(s) {
|
||
return unescape(encodeURIComponent(escape(s))).replace(/\+/g, "%2B");
|
||
}
|
||
|
||
var req;
|
||
var suggestionValues = [];
|
||
var resultsObj;
|
||
var selected = -1;
|
||
var latestServerQuery = "";
|
||
var THROTTLE_PERIOD = 250;
|
||
var timerID = null;
|
||
var lastHighlight = null;
|
||
var divWidth = 500;
|
||
var doAction = true;
|
||
|
||
var emptyKey = ("emptyKey" in params) ? params.emptyKey : -1;
|
||
var emptyText = "";
|
||
var currentKey = -1;
|
||
var currentText = null;
|
||
var currentExtraParam = null;
|
||
var $currentField = $(params.queryField); // Either the INPUT or the SELECT field
|
||
// De this. functies zijn zo extern ook beschikbaar
|
||
this.makeReadOnly = makeReadOnly;
|
||
this.undoReadOnly = undoReadOnly;
|
||
this.isReadOnly = isReadOnly;
|
||
this.makeHidden = makeHidden;
|
||
this.undoHidden = undoHidden;
|
||
this.isHidden = isHidden;
|
||
this.getKeyField = getKeyField;
|
||
this.getValue = getValue;
|
||
this.setValue = setValue;
|
||
this.sgType = params.sgType;
|
||
this.isMulti = isMulti;
|
||
this.toggleSelect = toggleSelect;
|
||
this.updateMultiSuggest = updateMultiSuggest;
|
||
this.CheckJustOne = CheckJustOne;
|
||
this.reloadUrlAdd = reloadUrlAdd;
|
||
this.editUrlAdd = editUrlAdd;
|
||
this.changeQueryUrl = changeQueryUrl;
|
||
this.sendQuery = sendQuery;
|
||
thisdoc = document; // Hier wordt de AutocompleteDiv aan gehangen
|
||
|
||
function updateMultiSuggest() {
|
||
// Niet mooi, wel effectief
|
||
toggleSelect();
|
||
toggleSelect();
|
||
}
|
||
|
||
function isMulti() {
|
||
return $currentField.prop("tagName") == "SELECT";
|
||
}
|
||
|
||
function getKeyField() {
|
||
return params.keyField;
|
||
}
|
||
|
||
function multiToggle($fld, adv) {
|
||
$fld.addClass(adv ? "advMultiSuggest" : "multiSuggest");
|
||
var $lbl = $("<span fcltfor='" + $fld.attr("id") + "' class='multi_suggest_toggle'></span>").on("click", function() { toggleSelect(this); }).html(I("fa-angle-double-down"));
|
||
var $div = $("<div></div>").addClass(adv ? "advmultitoggle" : "multitoggle");
|
||
$fld.add($fld.next(".suggestklikker")).wrapAll($div);
|
||
$fld.before($lbl);
|
||
}
|
||
|
||
// TODO: Controleren of parent wel in hetzelfde domein zit?
|
||
if (!params.embedded && self != top && window.name != "fclttop" && document.body.id != "searchbody") {
|
||
thisdoc = parent.document; // We gaan de AutocompleteDiv aan de parent hangen, uit het frame breken
|
||
|
||
// Mogelijke fix voor PNBR#22301
|
||
if (FcltMgr._pageManager.name == 'defaultManager' && parent.window.name != "fclttop" && parent.FcltMgr && !parent.FcltMgr.IsTheManager)
|
||
thisdoc = parent.parent.document; // Nog eentje hoger
|
||
|
||
if (!window.name || window.name == "") {
|
||
// FcltMgr.alert("Internal error. " + document.referrer + " heeft een IFRAME zonder 'name' en 'id' voor " + window.location.pathname);
|
||
thisdoc = document;
|
||
//debugger;
|
||
}
|
||
/* Sommige mobile/3G proxies embedden de CSS 'netjes' zodat het bestand niet te vinden is
|
||
var cssfound = false;
|
||
for (i = 0; i < thisdoc.styleSheets.length; i++)
|
||
{
|
||
try
|
||
{ // TODO faalt op FF?
|
||
if (thisdoc.styleSheets[i].href.match(/suggest.css/i))
|
||
cssfound = true;
|
||
}
|
||
catch(e){};
|
||
}
|
||
if (!cssfound)
|
||
{
|
||
FcltMgr.alert("Internal error. " + document.referrer + " moet suggest.css ook includen!");
|
||
// debugger;
|
||
}
|
||
*/
|
||
}
|
||
var icon = inParams.icon || "fa-asterisk";
|
||
if (params.embedded && params.site) {
|
||
suggesticon = params.suggesticon || (params.site + "/appl/shared/suggest/suggest.png");
|
||
var $klikker = $("<div class='suggestklikker' style='cursor:pointer'><img alt='" + L("mgt_srtkenmerk_referentie_s") + "' src='" + suggesticon + "'></div>");
|
||
} else
|
||
var $klikker = $("<div class='suggestklikker'><i class='fal fa-fw " + icon + " suggestklikker'></i></div>");
|
||
$(params.queryField).after($klikker);
|
||
|
||
params.queryField.setAttribute("sgKey", params.initKey);
|
||
|
||
if (params.multitoggle)
|
||
multiToggle($(params.queryField), params.multitoggle == "advanced");
|
||
|
||
// IE6 en IE7 hebben functie hasAttribute niet
|
||
if (!params.queryField.hasAttribute)
|
||
params.queryField.hasAttribute = function(attr) { return !!params.queryField.getAttribute(attr) };
|
||
|
||
if (params.keyField) {
|
||
storeKeyField = params.keyField;
|
||
//storeKeyField.value = params.queryField.getAttribute("sgKey");
|
||
storeKeyField.value = params.keyField.value;
|
||
} else
|
||
this.withKeyField = function(inStoreKeyField) {
|
||
storeKeyField = inStoreKeyField;
|
||
//storeKeyField.value = params.queryField.getAttribute("sgKey");
|
||
storeKeyField.value = params.keyField.value;
|
||
return this;
|
||
}
|
||
|
||
if (params.extraParamField) {
|
||
storeExtraParamField = params.extraParamField;
|
||
if (params.queryField.hasAttribute("sgExtraParam"))
|
||
storeExtraParamField.value = params.queryField.getAttribute("sgExtraParam");
|
||
} else
|
||
this.withExtraParamField = function(instoreExtraParamField) {
|
||
storeExtraParamField = instoreExtraParamField;
|
||
if (params.queryField.hasAttribute("sgExtraParam"))
|
||
storeExtraParamField.value = params.queryField.getAttribute("sgExtraParam");
|
||
return this;
|
||
}
|
||
|
||
// Kan verwijderd worden. Kan ook bereikt worden door initi<74>le waarde -1 mee te geven
|
||
this.withEmpty = function(eKey, eText) {
|
||
emptyText = eText ? eText : "";
|
||
emptyKey = eKey;
|
||
return this;
|
||
}
|
||
|
||
// Niet extern bedoeld maar noodzakekelijk voor setTimeout
|
||
|
||
this.requestLoop = requestLoop;
|
||
|
||
//if (params.objectName == "sgPerson") FcltMgr.alert("initKey = " + params.initKey);
|
||
//if (params.initKey == -1) FcltMgr.alert(params.objectName + " " + params.initKey);
|
||
// Alleen als verplicht
|
||
if ((params.initKey == -1 || params.suppressJustOne) && !params.noJustOne && $(params.queryField).hasClass("required"))
|
||
CheckJustOne();
|
||
|
||
if (params.fieldReadonly) {
|
||
params.queryField.readOnly = true;
|
||
setClass("suggestReadOnly");
|
||
} else
|
||
startup();
|
||
|
||
if (params.isBad) {
|
||
setValue(emptyKey, null, true, false, emptyText);
|
||
setClass("suggestBad");
|
||
} else
|
||
this.isBad = function() {
|
||
setValue(emptyKey, null, true, false, emptyText);
|
||
setClass("suggestBad");
|
||
}
|
||
|
||
// Geavanceerd scherm waarvan een suggest geladen wordt met meerdere waarden automatisch uitklappen,
|
||
// indien maar 1 waarde aanwezig, dan met setValue de sgKey en sgCurrentvalue setten.
|
||
if (params.multitoggle == "advanced") {
|
||
var storedVars = $(params.queryField).val().split(",");
|
||
if (storedVars.length == 1 && storedVars[0] != "")
|
||
setValue(params.keyField.value, storedVars[0]);
|
||
else if (storedVars.length > 1 && params.keyField.value == storedVars)
|
||
toggleSelect();
|
||
}
|
||
|
||
/**
|
||
*
|
||
* It all starts here!
|
||
*
|
||
*/
|
||
|
||
function startup() {
|
||
createAutocompletDiv();
|
||
hideAutocompleteDiv();
|
||
params.queryField.autocomplete = "off";
|
||
params.queryField.title = L("lcl_shared_suggest_hint");
|
||
params.queryField.onkeydown = keypressHandler;
|
||
params.queryField.onkeyup = keyupHandler;
|
||
params.queryField.onblur = function() {
|
||
if (document.activeElement &&
|
||
typeof thisdoc.activeElement != "unknown" &&
|
||
(document.activeElement == params.queryField ||
|
||
thisdoc.activeElement == _completeDiv ||
|
||
document.activeElement == _comboDiv ||
|
||
document.activeElement == $suggestbusy[0] ||
|
||
document.activeElement == $klikker[0] ||
|
||
$("body").hasClass("modal") || // Zou anders in IE9 sluiten bij klikken op scrollbar
|
||
thisdoc.activeElement.parentElement == _completeDiv))
|
||
return;
|
||
if (isAutocompleteDivVisible()) {
|
||
if ($(_completeDiv).is(":hover")) // IE 11 bug, klik op scrollbar hide de dropdown
|
||
{
|
||
$(params.queryField).focus(); // reset focus want die is er al afgehaald.
|
||
return;
|
||
}
|
||
|
||
if (params.queryField.getAttribute("sgCurrentValue") == null)
|
||
setValues(true);
|
||
else //houden we de huidige waarde
|
||
setValue(params.queryField.getAttribute("sgKey"),
|
||
params.queryField.getAttribute("sgCurrentValue"), false, false,
|
||
params.queryField.getAttribute("sgExtraParam"));
|
||
|
||
hideAutocompleteDiv();
|
||
}
|
||
};
|
||
|
||
// http://stackoverflow.com/questions/3380458/looking-for-a-better-workaround-to-chrome-select-on-focus-bug
|
||
$(params.queryField).focus(function() {
|
||
$(params.queryField).select().mouseup(function(e) {
|
||
e.preventDefault();
|
||
$(this).unbind("mouseup");
|
||
});
|
||
if (!timerID)
|
||
timerID = setTimeout(params.objectName + '.requestLoop(-1);', THROTTLE_PERIOD);
|
||
});
|
||
|
||
$klikker.click(function(e) {
|
||
if (!isReadOnly()) {
|
||
// Als je op vergrootglas hebt gedrukt moet checkExist altijd false zijn want je wilt een lijst.
|
||
// Anders krijg je ook het verschijnsel dat je 2 keer moet klikken voordat je de lijst krijgt.
|
||
params.queryField.removeAttribute("checkExist");
|
||
doAction = false; // Voorkomt focus handler op dit veld
|
||
$(params.queryField).focus(); // zodat anderen door onblur verbergen
|
||
if (!isAutocompleteDivVisible()) {
|
||
autoOpen();
|
||
} else {
|
||
setValue(params.queryField.getAttribute("sgKey"),
|
||
params.queryField.getAttribute("sgCurrentValue"), false, false,
|
||
params.queryField.getAttribute("sgExtraParam"));
|
||
hideAutocompleteDiv();
|
||
}
|
||
return;
|
||
}
|
||
});
|
||
|
||
params.queryField.onmousemove = function(evt) {
|
||
if (!isReadOnly()) {
|
||
evt = evt || window.event;
|
||
var offX = evt.offsetX || evt.layerX; // layerX is FireFox
|
||
if (params.queryField.clientWidth - offX < 20) // op de 'combodiv' geklikt
|
||
params.queryField.style.cursor = "pointer";
|
||
else
|
||
params.queryField.style.cursor = "auto";
|
||
}
|
||
};
|
||
|
||
params.queryField.setAttribute("sgCurrentValue", params.queryField.defaultValue);
|
||
requestLoop(0);
|
||
}
|
||
|
||
function toggleSelect(label) {
|
||
var $suggestField; // The suggest field, INPUT or SELECT
|
||
if (!label) // Interne call van sgXxx.toggleSelect(), use $currentField
|
||
{
|
||
$suggestField = $currentField;
|
||
label = $suggestField.prev("span.multi_suggest_toggle");
|
||
} else
|
||
$suggestField = $(label).next(".multiSuggest, .advMultiSuggest");
|
||
|
||
if ($(label).hasClass("disabled"))
|
||
return;
|
||
|
||
var isMultiSuggest = $suggestField.prop("tagName") == "SELECT";
|
||
var multiClass = $suggestField.hasClass("multiSuggest") ? "multiSuggest" : "advMultiSuggest";
|
||
|
||
// toggle label between v and ^
|
||
$(label).html(isMultiSuggest ? I("fa-angle-double-down") : I("fa-angle-up"));
|
||
|
||
// toggle suggestklikker Icon
|
||
$suggestField.next(".suggestklikker").toggle();
|
||
|
||
// toggle subsequent plaatsselector levels
|
||
var sgType = $suggestField.attr("sgType");
|
||
|
||
// sgType: type Suggest, dit is het gedeelte tussen 'FCLT' en 'selector' (bijvoorbeeld plaats of stdmelding)
|
||
// params.sgRelType: Relevante Suggest types die bij een multitoggle moeten inklappen in een string gescheiden door een komma
|
||
// sgRelTypeArray: Deze zelfde relevante Suggests maar dan in een Array
|
||
var sgRel = []; // Een array van alle opvolgende Suggest-objecten die moeten inklappen bij een multitoggle (van hetzelfde sgType of met een sgType in sgRelType)
|
||
var thisSgObj = null; // Het 'togglende' element, pas als deze gevonden is gaan we (alleen onder dit element dus) relevante Suggests zoeken.
|
||
var sgRelTypeArray = [];
|
||
if (typeof params.sgRelType != "undefined") // van String naar Array
|
||
sgRelTypeArray = params.sgRelType.split(/\s*,\s*/); // Regex: komma met 0 of meerdere spaties eromheen
|
||
|
||
for (var key in window) {
|
||
if (window[key] instanceof Suggest) { // Er kunnen meerdere afhankelijke suggest velden zijn.
|
||
|
||
if (thisSgObj != null && // De 'togglende' Suggest is al gevonden
|
||
window[key].sgType && // De gevonden Suggest heeft een sgType (altijd, maar voor de zekerheid)
|
||
(window[key].sgType === sgType || // De gevonden Suggest is: (1) van hetzelfde sgType (bijvoorbeeld; alle Suggests met sgType = 'plaats')
|
||
sgRelTypeArray.indexOf(window[key].sgType) != -1)) // of (2) heeft een sgType die te vinden is in de sgRelType (gerelateerde types) van de 'togglende' Suggest
|
||
{
|
||
sgRel.push(window[key]);
|
||
}
|
||
|
||
// thisSgObj = de 'togglende' Suggest
|
||
if (window[key].getKeyField() === params.keyField) // keyField used as unique identifier
|
||
thisSgObj = window[key];
|
||
}
|
||
}
|
||
|
||
// Itereer door alle Suggest's die moeten toggelen bij deze multitoggle
|
||
for (var key in sgRel) {
|
||
if (isMultiSuggest)
|
||
sgRel[key].undoHidden();
|
||
else
|
||
sgRel[key].makeHidden();
|
||
|
||
// Alle afhankelijke multi SELECT boxen weer tonen als SUGGEST input velden als deze zichtbaar worden.
|
||
if (isMultiSuggest && sgRel[key].isMulti())
|
||
// Toggelen naar SUGGEST.
|
||
sgRel[key].toggleSelect();
|
||
|
||
// SUGGEST veld altijd leeg maken want bovenliggende veld kunnen aangepast zijn waardoor de waarden niet meer geldig kan zijn.
|
||
sgRel[key].setValue(-1, "");
|
||
}
|
||
FcltMgr.resized();
|
||
|
||
if (isMultiSuggest) // Replace multi-suggest back to single-suggest with new or empty value.
|
||
{
|
||
var sgKey = $suggestField.find(":selected").eq(0).val() || -1;
|
||
var sgDesc = $suggestField.find(":selected").eq(0).text() || "";
|
||
$suggestField.replaceWith($(params.queryField));
|
||
$currentField = $(params.queryField);
|
||
thisSgObj.setValue(sgKey, sgDesc);
|
||
} else // if (!isMultiSuggest)
|
||
{
|
||
// Make multi-SELECT
|
||
var url = params.queryUrl + _urlAddParams(params.urlAdd) + "&SuggestAll=1&k=*";
|
||
$.getJSON(url, function(data, textStatus) {
|
||
if (data) {
|
||
var sgKey = $currentField[0].getAttribute("sgKey");
|
||
var $sel = $("<select size=\"5\" multiple=\"1\" class=\"" + multiClass + "\">").attr("id", $currentField.attr("id"))
|
||
.attr("name", params.keyField.id)
|
||
.attr("sgType", sgType);
|
||
if (data.hasMore)
|
||
$sel.append($("<option>").attr("disabled", true)
|
||
.attr("title", L("lcl_shared_suggest_toomany_multi"))
|
||
.text(L("lcl_shared_suggest_toomany_multi")));
|
||
var $option;
|
||
if (params.addfixedoption && "key" in params.addfixedoption && "desc" in params.addfixedoption && "txt" in params.addfixedoption) { // Add fixed option to the resultset
|
||
data.result.unshift(params.addfixedoption);
|
||
}
|
||
|
||
var keys_arr = $suggestField.val().split(",");
|
||
for (var i = 0; i < data.result.length; i++) {
|
||
$option = $("<option>").attr("value", data.result[i].key)
|
||
.attr("title", data.result[i].desc)
|
||
.text(data.result[i].txt);
|
||
if (sgKey == data.result[i].key || (keys_arr.length > 1 && $.inArray(String(data.result[i].key), keys_arr) > -1)) {
|
||
$option.attr("selected", true);
|
||
}
|
||
$sel.append($option);
|
||
}
|
||
$suggestField.replaceWith($sel);
|
||
$currentField = $sel;
|
||
if (thisSgObj)
|
||
thisSgObj.setValue(-1, "");
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
function setClass(oneClass) {
|
||
$(params.queryField).removeClass("suggest suggestBad suggestBusy suggestReadOnly");
|
||
$(params.queryField).addClass(oneClass);
|
||
}
|
||
|
||
function makeReadOnly() {
|
||
params.queryField.readOnly = true;
|
||
setClass("suggestReadOnly");
|
||
params.queryField.title = "";
|
||
}
|
||
|
||
function undoReadOnly() {
|
||
params.queryField.readOnly = false;
|
||
setClass("suggest");
|
||
params.queryField.title = L("lcl_shared_suggest_hint");
|
||
}
|
||
|
||
function isReadOnly() {
|
||
return params.queryField.readOnly;
|
||
}
|
||
|
||
function makeHidden() {
|
||
if (!$currentField.isHidden) {
|
||
if (typeof mobile == "undefined")
|
||
$currentField.parents("tr").eq(0).addClass("hidden");
|
||
else {
|
||
var $parent = $currentField.parents("div");
|
||
$parent = ($parent.parent("nobr").length ? $parent.parent("nobr") : $parent);
|
||
$parent.hide()
|
||
.prev("label").hide();
|
||
}
|
||
}
|
||
}
|
||
|
||
function undoHidden() {
|
||
if (typeof mobile == "undefined")
|
||
$currentField.parents("tr").eq(0).removeClass("hidden");
|
||
else {
|
||
var $parent = $currentField.parents("div");
|
||
$parent = ($parent.parent("nobr").length ? $parent.parent("nobr") : $parent);
|
||
$parent.show()
|
||
.prev("label").show();
|
||
}
|
||
}
|
||
|
||
function isHidden() {
|
||
return (typeof mobile == "undefined" ?
|
||
$currentField.parents("tr").eq(0).hasClass("hidden") :
|
||
$currentField.parent("div").eq(0).hasClass("hidden"));
|
||
}
|
||
|
||
function setValue(key, txt, doonChange, checkExist, extraParam, lastTry) {
|
||
// Onthoudt de huidige waarde als je checkt of de te zetten waarde bestaat.
|
||
// Als de nieuwe waarde niet voorkomt in de query en niet kan worden gezet
|
||
// dan wordt geprobeerd om de huidige waarde weer opnieuw te zetten.
|
||
// In dat laatste geval is dan lastTry == true. Indien ook de huidige waarde niet
|
||
// meer aanwezig is in de query, dan wordt de suggestbox leeg gemaakt.
|
||
// Als alleen de nieuwe waarde moet worden geprobeerd,
|
||
// kan ook direct voor lastTry de waarde true worden meegegeven.
|
||
if (checkExist && !lastTry) {
|
||
currentKey = params.queryField.getAttribute("sgKey");
|
||
currentText = params.queryField.value;
|
||
currentExtraParam = params.queryField.getAttribute("sgExtraParam");
|
||
}
|
||
if (params.queryField) {
|
||
// Afhankelijk van het readonly zijn de suggest class zetten zodat de suggestBusy wordt vervangen.
|
||
// De suggest class toont het vergrootglas in beeld.
|
||
if (!isReadOnly())
|
||
setClass("suggest");
|
||
params.queryField.setAttribute("sgKey", key);
|
||
if (storeKeyField) storeKeyField.value = key;
|
||
if (extraParam != null) // De waarde 0 moet niet als false worden opgevat.
|
||
{
|
||
params.queryField.setAttribute("sgExtraParam", extraParam);
|
||
if (storeExtraParamField) storeExtraParamField.value = extraParam;
|
||
} else {
|
||
if (storeExtraParamField) storeExtraParamField.value = ""; // Als storeExtraParamField bestaat dan leeg maken (vullen met "")
|
||
}
|
||
if (!checkExist && txt != null) {
|
||
params.queryField.value = txt;
|
||
params.queryField.setAttribute("sgCurrentValue", txt);
|
||
//latestServerQuery = txt.toLowerCase();
|
||
if (txt != "" &&
|
||
(document.activeElement && (typeof thisdoc.activeElement != "unknown") &&
|
||
(document.activeElement == params.queryField ||
|
||
thisdoc.activeElement == _completeDiv ||
|
||
thisdoc.activeElement == _comboDiv ||
|
||
thisdoc.activeElement.parentElement == _completeDiv
|
||
)
|
||
)
|
||
)
|
||
// selectRange zou focus stelen
|
||
// Alleen focus stelen als element al focus had (activeElement)
|
||
selectRange(0, 0);
|
||
}
|
||
// bij 'checkExist' hoeven we nu nog geen onChange te doen: die komt later nog wel
|
||
if (!checkExist && doonChange && params.queryField.getAttribute("sgonChange")) {
|
||
eval(params.queryField.getAttribute("sgonChange")).call(null, key, txt, { suggestid: params.queryField.id });
|
||
|
||
// Update related multiSuggests (related = zelfde sgType of een sgType uit params.sgRelType)
|
||
var sgRelTypeArray = [params.sgType]; // In ieder geval die van hetzelfde sgType
|
||
if (typeof params.sgRelType != "undefined") // van String naar Array
|
||
sgRelTypeArray = params.sgRelType.split(/\s*,\s*/); // Regex: komma met 0 of meerdere spaties eromheen
|
||
|
||
for (var i = 0; i < sgRelTypeArray.length; i++) {
|
||
$(params.queryField).closest(".suggest-wrapper").nextAll(".suggest-wrapper").each(function() { // Voor elke volgende suggest rij;
|
||
|
||
// We zoeken op 'select' dus we vinden alleen de 'isMulti'
|
||
var $multiSuggestToggle = $(this).find("select.multiSuggest[sgType=\"" + sgRelTypeArray[i] + "\"]").prev("span.multi_suggest_toggle");
|
||
$multiSuggestToggle.click();
|
||
$multiSuggestToggle.click();
|
||
});
|
||
}
|
||
}
|
||
if (checkExist)
|
||
params.queryField.setAttribute("checkExist", true);
|
||
else
|
||
params.queryField.removeAttribute("checkExist");
|
||
|
||
if (doonChange)
|
||
params.queryField.setAttribute("doonChange", doonChange);
|
||
else
|
||
params.queryField.removeAttribute("doonChange");
|
||
if (checkExist) {
|
||
sendQuery(txt, false, checkExist);
|
||
}
|
||
}
|
||
}
|
||
|
||
function getValue() {
|
||
return (params.queryField.getAttribute("sgKey"));
|
||
}
|
||
|
||
function process_one_choice_info(data, textStatus) {
|
||
if (textStatus == "success") {
|
||
// setValue(key, txt, doonChange, checkExist, extraParam, lastTry)
|
||
if (data && data.result.length == 1) {
|
||
var txt = data.result[0].txt;
|
||
var key = data.result[0].key;
|
||
var extraParam = data.result[0].extra;
|
||
setValue(key, txt, true, false, extraParam);
|
||
if (params.suppressJustOne)
|
||
makeHidden();
|
||
}
|
||
// initiele waarden worden met initkey gezet
|
||
//else
|
||
//setValue(emptyKey, emptyText, true, false, emptyText); // Er zijn geen waarden. Suggestbox leeg maken.
|
||
} else
|
||
FcltMgr.alert("process_one_choice_info: " + textStatus);
|
||
}
|
||
|
||
// Een urlAdd kan zijn meegegeven als val, field of jqfield
|
||
function _urlAddParams(urlAdd) {
|
||
if (!urlAdd)
|
||
return "";
|
||
|
||
var urlAddParams = "";
|
||
for (var i = 0; i < urlAdd.length; i++) { // Url parameter aan link toevoegen
|
||
urlAddParams += "&" + urlAdd[i].urlParam + "=";
|
||
var theVal = urlAdd[i].val;
|
||
if (typeof theVal == "undefined") {
|
||
var selector = urlAdd[i].jqfield;
|
||
var hasselector = "";
|
||
if (!selector || selector == "") // JQuery selector, handig voor radio
|
||
{
|
||
selector = "#" + urlAdd[i].field;
|
||
hasselector = "#has_" + urlAdd[i].field;
|
||
}
|
||
// Is het misschien een checkbox? Dan is de waarde niet belangrijk maar of deze is aangevinkt.
|
||
if (hasselector != "" && $(hasselector).length > 0) { // Het is een checkbox. Controleer of de checkbox is aangevinkt.
|
||
theVal = $(selector).prop("checked") ? 1 : 0; // Wel (1) of niet (0) aangevinkt.
|
||
} else
|
||
theVal = $(selector).val() ? $(selector).val() : -1; // Indien niets geselecteerd dan -1;
|
||
}
|
||
urlAddParams += theVal;
|
||
}
|
||
return urlAddParams;
|
||
}
|
||
|
||
function CheckJustOne() {
|
||
var isMultiSuggest = $currentField.prop("tagName") == "SELECT";
|
||
if (!isMultiSuggest) {
|
||
var url = params.queryUrl + _urlAddParams(params.urlAdd) + "&k=*";
|
||
// eerste 10 is m<><6D>r dan genoeg url += "&SuggestAll=1&";
|
||
|
||
$.getJSON(url, process_one_choice_info);
|
||
}
|
||
}
|
||
|
||
function reloadUrlAdd(newUrlAdd) {
|
||
params.urlAdd = newUrlAdd;
|
||
}
|
||
|
||
function editUrlAdd(thisUrlParam, newField, newJqfield, newVal) {
|
||
if ("urlAdd" in params)
|
||
for (var i = 0; i < params.urlAdd.length; i++) {
|
||
if (params.urlAdd[i].urlParam == thisUrlParam) {
|
||
if (newField) params.urlAdd[i].field = newField;
|
||
if (newJqfield) params.urlAdd[i].jqfield = newJqfield;
|
||
if (newVal) params.urlAdd[i].val = newVal;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
function changeQueryUrl(new_inQueryUrl) {
|
||
params.queryUrl = new_inQueryUrl;
|
||
latestServerQuery = null;
|
||
// gaat mis bij kostenplaats fe res setValue(-1, ""); // TODO: vriendelijk via checkExist?
|
||
}
|
||
|
||
function calculateOffsetLeft(r) {
|
||
return SumAttr(r, "offsetLeft")
|
||
}
|
||
|
||
function calculateOffsetTop(r) {
|
||
return SumAttr(r, "offsetTop")
|
||
}
|
||
|
||
function SumAttr(r, attr) {
|
||
var kb = 0;
|
||
while (r) {
|
||
kb += r[attr];
|
||
r = r.offsetParent
|
||
}
|
||
return kb
|
||
}
|
||
|
||
function createAutocompletDiv() {
|
||
//_completeDiv=$(thisdoc).find("div#"+params.objectName+"completeDiv")[0];
|
||
// if (true||!_completeDiv)
|
||
{
|
||
_completeDiv = thisdoc.createElement("DIV");
|
||
|
||
_completeDiv.id = params.objectName + "completeDiv";
|
||
_completeDiv.className = "suggestautocompleteContainer";
|
||
|
||
_completeDiv.onblur = function() { params.queryField.onblur(); }
|
||
_completeDiv.style.zIndex = "2199"; // JQuery dialog begint bij 1000, daar zitten we ruim boven
|
||
|
||
thisdoc.body.appendChild(_completeDiv);
|
||
//_completeDiv.appendChild(thisdoc.createTextNode("DIVVERtje"));
|
||
}
|
||
// pas bij echt openen afmetingen zetten setCompleteDivSize();
|
||
}
|
||
|
||
function setCompleteDivSize() {
|
||
var _inputField = params.queryField;
|
||
if (_inputField && _completeDiv) {
|
||
var inputWidth = parseFloat($(_inputField).css("width"));
|
||
var newdivWidth = Math.min(Math.max(divWidth, inputWidth), thisdoc.body.offsetWidth); // Voor Mobile
|
||
var newLeft = calculateOffsetLeft(_inputField);
|
||
var newTop = calculateOffsetTop(_inputField) + _inputField.offsetHeight - 1;
|
||
if (thisdoc != document) {
|
||
newTop += calculateOffsetTop(thisdoc.getElementById(window.name)) + 2;
|
||
|
||
newLeft += calculateOffsetLeft(thisdoc.getElementById(window.name)) + 2;
|
||
if (typeof mobile === "undefined") // Voor niet-Mobile
|
||
{
|
||
newTop -= $(document).scrollTop();
|
||
}
|
||
}
|
||
|
||
if (newLeft + newdivWidth > thisdoc.body.offsetWidth) { // Wel in beeld houden
|
||
newLeft = Math.max(0, thisdoc.body.offsetWidth - newdivWidth - 20); // ook speling voor scrollbar
|
||
}
|
||
_completeDiv.style.left = newLeft + "px";
|
||
_completeDiv.style.top = newTop + "px";
|
||
|
||
_completeDiv.style.width = newdivWidth + "px";
|
||
}
|
||
}
|
||
|
||
function doRequest(keyword, bAll) {
|
||
if (typeof params.prerequisite == "function" && !params.prerequisite())
|
||
return;
|
||
var pos = $(params.queryField).next().offset();
|
||
$suggestbusy.css("top", pos.top + 2);
|
||
$suggestbusy.css("left", pos.left);
|
||
window.suggesttimer = setTimeout(function() { $suggestbusy.show(); }, 500);
|
||
|
||
sendQuery(keyword, bAll);
|
||
latestServerQuery = keyword;
|
||
}
|
||
|
||
var ESCAPE = 27;
|
||
var KEYUP = 38;
|
||
var KEYDOWN = 40;
|
||
var KEYENTER = 13;
|
||
var KEYTAB = 9;
|
||
var KEYPGUP = 33;
|
||
var KEYPGDOWN = 34;
|
||
// Deze functie is via een timer gescheduled
|
||
function requestLoop(toetskey) { // Toetskey
|
||
// -1: Geen toets, focus op veld
|
||
// 0: Initialisatie
|
||
// >0: Toets aangeklikt
|
||
|
||
if (!doAction) { // komt uit $klikker.on(click), dan hoeft de focus(); niet te worden uitgevoerd
|
||
doAction = true;
|
||
return;
|
||
}
|
||
|
||
// Als de suggest readonly is hoef ik niet verder te kijken.
|
||
if (isReadOnly()) return;
|
||
setClass("suggest");
|
||
|
||
timerID = null;
|
||
|
||
if (params.queryField.value == "" && params.queryField.getAttribute("sgKey") != emptyKey)
|
||
setValue(emptyKey, emptyText, true, false, emptyText);
|
||
|
||
// Bepaal wat de gebruiker heeft ingetikt exclusief het deel wat gehighlight is
|
||
var keyword = query().toLowerCase();
|
||
|
||
// Is het een te snelle tab zonder popup selectie. Dan is er geen waarde gezet. Focus terug.
|
||
var isToFastTab = (toetskey == KEYTAB && (params.queryField.value != params.queryField.getAttribute("sgCurrentValue")))
|
||
if (isToFastTab)
|
||
params.queryField.select();
|
||
|
||
var isUpDownKey = (toetskey == KEYUP || toetskey == KEYDOWN || toetskey == KEYPGUP || toetskey == KEYPGDOWN);
|
||
var isNoSpecialKey = (toetskey > 0 && !isUpDownKey && toetskey != KEYENTER && toetskey != KEYTAB);
|
||
// Bij toestsaanslag altijd popup scherm. Ook bij default waarde. Omschrijving tekst kan vaker voorkomen.
|
||
if (toetskey != 0 &&
|
||
(keyword != latestServerQuery) &&
|
||
(keyword != '') &&
|
||
((params.queryField.value != params.queryField.defaultValue) || (toetskey > 0 && !isUpDownKey)) &&
|
||
(params.queryField.value != params.queryField.getAttribute("sgCurrentValue") || isNoSpecialKey)) {
|
||
doRequest(query().toLowerCase(), false);
|
||
}
|
||
|
||
if (params.queryField.value == '' || params.queryField.value == params.queryField.defaultValue) {
|
||
hideAutocompleteDiv();
|
||
suggestionValues = [];
|
||
latestServerQuery = null;
|
||
selected = 0;
|
||
if (params.queryField.value == params.queryField.defaultValue && toetskey == 0)
|
||
setValue(params.initKey, null, false, false, params.initExtraParam)
|
||
else if (params.queryField.value == "" && params.queryField.getAttribute("sgKey") != emptyKey)
|
||
setValue(emptyKey, emptyText, true, false, emptyText);
|
||
if (keyword == "" && toetskey > 0) { // Eventuele sgCascade uitvoeren als suggest veld wordt leeg gemaakt.
|
||
eval(params.queryField.getAttribute("sgCascade"));
|
||
}
|
||
}
|
||
}
|
||
|
||
// Bepaal wat de gebruiker heeft ingetikt exclusief het deel wat gehighlight is
|
||
function query() {
|
||
var textbox = params.queryField;
|
||
var N;
|
||
if (textbox.createTextRange) // IE
|
||
{ // IE6/7 soms bij het opstarten: htmlfile: unspecified error. Daarom de catch
|
||
try {
|
||
var fa = document.selection.createRange().duplicate();
|
||
N = fa.text.length;
|
||
} catch (e) {
|
||
N = 0;
|
||
}
|
||
} else
|
||
if (textbox.setSelectionRange) // Mozilla
|
||
{
|
||
try {
|
||
N = textbox.selectionEnd - textbox.selectionStart;
|
||
} catch (e) // Firefox-->Error
|
||
{
|
||
N = 0;
|
||
}
|
||
}
|
||
return textbox.value.substring(0, textbox.value.length - N);
|
||
}
|
||
|
||
function sendQuery(txt, bAll, checkExist) {
|
||
var url = params.queryUrl + _urlAddParams(params.urlAdd) + "&k=" + myEncode(txt);
|
||
if (bAll) url += "&SuggestAll=1";
|
||
if (checkExist) url += "&checkExist=1";
|
||
|
||
jQuery.ajax({
|
||
type: "GET",
|
||
url: url,
|
||
dataType: params.JSONP ? "jsonp" : "json",
|
||
success: process
|
||
});
|
||
}
|
||
|
||
// Callback functie van HTTP Request
|
||
function process(data, textStatus) {
|
||
clearTimeout(window.suggesttimer);
|
||
$suggestbusy.hide();
|
||
|
||
var checkExist = params.queryField.hasAttribute("checkExist");
|
||
var doonChange = params.queryField.getAttribute("doonChange");
|
||
|
||
// Afhankelijk van het readonly zijn de suggest class zetten zodat de suggestBusy wordt vervangen.
|
||
// De suggest class toont het vergrootglas in beeld.
|
||
if (!isReadOnly())
|
||
setClass("suggest");
|
||
|
||
showAutocompleteDiv();
|
||
resultsObj = data;
|
||
if (params.addfixedoption)
|
||
resultsObj.result.unshift(params.addfixedoption);
|
||
|
||
selected = resultsObj.isAll ? Math.min(resultsObj.result.length - 1, 10 - 1) : 0;
|
||
|
||
// voorheen htmlFormat(checkExist, doonChange), nu ingeplakt
|
||
|
||
lastHighlight = null;
|
||
while (_completeDiv.childNodes.length > 0) {
|
||
_completeDiv.removeChild(_completeDiv.childNodes[0]);
|
||
}
|
||
|
||
if (!resultsObj.result.length) // Hmm, geen resultaten gevonden
|
||
{
|
||
if (params.queryField.value.length > 0 && params.queryField.value != "*") {
|
||
// Als de nieuwe waarde niet voorkomt in de query en niet kan worden gezet
|
||
// dan wordt geprobeerd om de huidige waarde weer opnieuw te zetten (currentKey > 0).
|
||
// Indien ook de huidige waarde niet meer aanwezig is in de query,
|
||
// dan wordt de suggestbox leeg gemaakt.
|
||
if (checkExist && currentKey > 0) {
|
||
var pcurrentKey = currentKey;
|
||
var pcurrentText = currentText;
|
||
var pcurrentExtraParam = currentExtraParam;
|
||
currentKey = emptyKey;
|
||
currentText = "";
|
||
currentExtraParam = null;
|
||
setValue(pcurrentKey, pcurrentText, doonChange, true, pcurrentExtraParam, true);
|
||
} else {
|
||
setValue(emptyKey, (checkExist ? "" : null), true, false, (checkExist ? "" : null));
|
||
}
|
||
if (!checkExist) {
|
||
setClass("suggestBad");
|
||
}
|
||
} else { // Geen resultaten gevonden en params.queryField was leeg.
|
||
// Zet nu opnieuw de lege waarde.
|
||
setValue(emptyKey, "", true, false, null, true);
|
||
}
|
||
hideAutocompleteDiv();
|
||
return;
|
||
}
|
||
|
||
// Maak suggestbox leeg indien checkExist is true en gevonden key en ingevoerde key komen niet overeen:
|
||
if (checkExist && resultsObj.result.length == 1 && resultsObj.result[0].key != params.queryField.getAttribute("sgKey")) { // Maak suggestbox leeg
|
||
if (params.queryField.value.length > 0) {
|
||
setValue(emptyKey, "", true, false, "");
|
||
setClass("suggestBad");
|
||
}
|
||
hideAutocompleteDiv();
|
||
return;
|
||
}
|
||
// Indien checkExist is true en er zijn meerdere waarden gevonden (Begin gedeelte van de omschrijving komt overeen) dan:
|
||
// 1) Komt maar van 1 van deze de gevonden key en ingevoerde key overeen, dan deze selecteren
|
||
// 2) Anders selectbox leeg maken.
|
||
else if (checkExist && resultsObj.result.length > 1) {
|
||
var nr_of_hits = 0;
|
||
for (var i = 0; i < resultsObj.result.length; i++) {
|
||
if (resultsObj.result[i].key == params.queryField.getAttribute("sgKey")) {
|
||
nr_of_hits++;
|
||
var hit_i = i;
|
||
}
|
||
}
|
||
if (nr_of_hits == 1) { // Geselecteerde text selecteren (enige overeenkomende resultaat van de meerdere gevonden waarden)
|
||
selected = hit_i; // Kies wel de juiste overeenkomende resultaat met de juiste key
|
||
setValues(doonChange);
|
||
if (!checkExist) selectRange(0, 0);
|
||
hideAutocompleteDiv();
|
||
return;
|
||
} else { // Gevonden key en ingevoerde key komen vaker overeen. Maak suggestbox leeg
|
||
if (params.queryField.value.length > 0) {
|
||
setValue(emptyKey, "", true, false, "");
|
||
setClass("suggestBad");
|
||
}
|
||
hideAutocompleteDiv();
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (checkExist && resultsObj.result.length == 1 && resultsObj.result[0].key == params.queryField.getAttribute("sgKey")) {
|
||
// geselecteerde text selecteren (enige resultaat)
|
||
setValues(doonChange);
|
||
if (!checkExist) selectRange(0, 0);
|
||
hideAutocompleteDiv();
|
||
return;
|
||
}
|
||
|
||
|
||
suggestionValues = [];
|
||
if (params.queryField.getAttribute("sgCurrentValue") && params.queryField.getAttribute("sgKey") > 0) {
|
||
var extra = params.queryField.getAttribute("sgExtraParam");
|
||
// Plak de current er voor als eerste keuze
|
||
resultsObj.result = [{
|
||
txt: params.queryField.getAttribute("sgCurrentValue"),
|
||
key: params.queryField.getAttribute("sgKey"),
|
||
extra: extra ? extra : "",
|
||
desc: L("lcl_shared_suggest_huidig")
|
||
}].concat(resultsObj.result);
|
||
}
|
||
|
||
if (resultsObj.similar)
|
||
$(_completeDiv).addClass("suggestsimilar");
|
||
else
|
||
$(_completeDiv).removeClass("suggestsimilar");
|
||
|
||
for (var i = 0; i < resultsObj.result.length; i++) {
|
||
if (resultsObj.result[i].txt) {
|
||
suggestionValues.push(resultsObj.result[i].txt);
|
||
|
||
var xDiv = thisdoc.createElement("div");
|
||
xDiv.sgIndex = i;
|
||
if (i == selected) {
|
||
xDiv.className = "suggestsrs";
|
||
lastHighlight = xDiv;
|
||
} else {
|
||
xDiv.className = "suggestsr";
|
||
}
|
||
|
||
xDiv.onmouseover = function() { highlight(this.sgIndex, this); return false; };
|
||
xDiv.onmousedown = function() {
|
||
setValues(true);
|
||
hideAutocompleteDiv();
|
||
return true;
|
||
};
|
||
if ("title" in resultsObj.result[i])
|
||
xDiv.title = resultsObj.result[i].title;
|
||
if (resultsObj.anyfoto) {
|
||
var fotourl = resultsObj.result[i].foto;
|
||
if (fotourl && fotourl.match(/\.(png|jpg|jpeg)$/i)) // het is een image
|
||
{
|
||
var xFoto = thisdoc.createElement("img");
|
||
xFoto.setAttribute("src", fotourl);
|
||
xFoto.setAttribute("height", "40");
|
||
xFoto.className = "suggestfoto";
|
||
xDiv.appendChild(xFoto);
|
||
} else {
|
||
var xFoto = thisdoc.createElement("div");
|
||
xFoto.innerHTML = " ";
|
||
xFoto.className = "suggestfoto";
|
||
xDiv.appendChild(xFoto);
|
||
}
|
||
}
|
||
var xSpan = thisdoc.createElement("span");
|
||
xSpan.className = "suggestsrt";
|
||
if (i == 0 &&
|
||
params.queryField.getAttribute("sgCurrentValue") &&
|
||
params.queryField.getAttribute("sgKey") > 0) // eerste krijgt aparte opmaak
|
||
{
|
||
xSpan.style.borderBottom = "1px solid black"; // TODO: Stijl voor verzinnen
|
||
xSpan.style.paddingBottom = "10px";
|
||
}
|
||
|
||
var ll = 0;
|
||
// first matching part bold
|
||
var lsq = latestServerQuery;
|
||
if (lsq && lsq.charAt(0) == "*") lsq = lsq.substring(1);
|
||
ll = resultsObj.result[i].txt.toLowerCase().indexOf(lsq);
|
||
if (resultsObj.result[i].isHTML)
|
||
xSpan.innerHTML = resultsObj.result[i].txt;
|
||
else if (ll >= 0 && lsq.length) {
|
||
if (ll > 0)
|
||
xSpan.appendChild(thisdoc.createTextNode(resultsObj.result[i].txt.substring(0, ll)));
|
||
var xb = thisdoc.createElement("b");
|
||
xb.appendChild(thisdoc.createTextNode(resultsObj.result[i].txt.substring(ll, ll + lsq.length)));
|
||
xSpan.appendChild(xb);
|
||
xSpan.appendChild(thisdoc.createTextNode(resultsObj.result[i].txt.substring(ll + lsq.length)));
|
||
} else
|
||
xSpan.appendChild(thisdoc.createTextNode(resultsObj.result[i].txt));
|
||
|
||
xDiv.appendChild(xSpan);
|
||
if ("txtextra" in resultsObj.result[i]) {
|
||
var $Text = $("<span>").text(resultsObj.result[i].txtextra)
|
||
.addClass("suggestextratext");
|
||
$(xDiv).append("<br>");
|
||
$(xDiv).append($Text);
|
||
}
|
||
|
||
if ("desc" in resultsObj.result[i]) // Extra description present
|
||
{
|
||
var x3 = thisdoc.createElement("span");
|
||
x3.className = "suggestsrc";
|
||
var desc = resultsObj.result[i].desc || "";
|
||
ll = desc && desc.toLowerCase().indexOf(lsq);
|
||
if (params.highlightDescript && ll >= 0) {
|
||
x3.appendChild(thisdoc.createTextNode(desc.substring(0, ll)));
|
||
var xb = thisdoc.createElement("b");
|
||
xb.appendChild(thisdoc.createTextNode(desc.substring(ll, ll + lsq.length)));
|
||
x3.appendChild(xb);
|
||
x3.appendChild(thisdoc.createTextNode(desc.substring(ll + lsq.length)));
|
||
} else
|
||
x3.appendChild(thisdoc.createTextNode(desc));
|
||
xDiv.appendChild(x3);
|
||
}
|
||
|
||
_completeDiv.appendChild(xDiv);
|
||
}
|
||
}
|
||
|
||
// xDiv is op dit moment de laatste
|
||
if (!xDiv || (xDiv.offsetTop + xDiv.clientHeight < 300))
|
||
_completeDiv.style.height = ""; // Auto
|
||
else { //_completeDiv.style.overflow = "hidden";
|
||
_completeDiv.style.height = "300px";
|
||
if (/MSIE 7.0/.test(navigator.userAgent))
|
||
_completeDiv.style.paddingRight = "16px"; // Anders valt bij IE7 een deel achter de scrollbar
|
||
_completeDiv.style.overflowY = "auto";
|
||
_completeDiv.style.overflowX = "hidden";
|
||
|
||
}
|
||
if (resultsObj.hasMore) // Is gezet als er 10 of meer records zijn
|
||
{
|
||
var xDiv = thisdoc.createElement("div");
|
||
|
||
xDiv.className = "suggestsr";
|
||
var xSpan = thisdoc.createElement("span");
|
||
xSpan.className = "suggestMore";
|
||
if (resultsObj.isAll)
|
||
xSpan.appendChild(thisdoc.createTextNode(resultsObj.hasMoreMsg)); // Maximum bereikt
|
||
else {
|
||
$(xDiv).mousedown(function(evt) {
|
||
doRequest(latestServerQuery, true);
|
||
evt.preventDefault(); // Voorkom blur
|
||
});
|
||
xSpan.appendChild(thisdoc.createTextNode(resultsObj.hasMoreMsg)); // Er is meer
|
||
}
|
||
xDiv.appendChild(xSpan);
|
||
_completeDiv.appendChild(xDiv);
|
||
}
|
||
//requestSuggestions();
|
||
}
|
||
|
||
function keyupHandler(evt) {
|
||
// make sure we have a valid event variable
|
||
if (!evt && window.event) {
|
||
evt = window.event;
|
||
}
|
||
var key = evt.keyCode;
|
||
|
||
if (key < 32 || (key >= 33 && key <= 46) || (key >= 112 && key <= 123)) {
|
||
//ignore
|
||
} else {
|
||
//request suggestions from the suggestion provider
|
||
// Backspace key(8), Delete key (48)
|
||
if (key != 8 && key != 48) {
|
||
requestSuggestions();
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function keypressHandler(evt) {
|
||
params.queryField.removeAttribute("checkExist");
|
||
params.queryField.setAttribute("doonChange", true);
|
||
|
||
// make sure we have a valid event variable
|
||
if (!evt && window.event) {
|
||
evt = window.event;
|
||
}
|
||
var key = evt.keyCode;
|
||
|
||
// if this key isn't one of the ones we care about, just return
|
||
|
||
if (timerID) // reset oude. Is goed voor de performance/response
|
||
clearTimeout(timerID);
|
||
timerID = setTimeout(params.objectName + ".requestLoop(" + key + ");", THROTTLE_PERIOD);
|
||
|
||
// don't do anything if the div is hidden
|
||
if (!isAutocompleteDivVisible()) {
|
||
if (key == KEYDOWN || key == KEYPGDOWN)
|
||
autoOpen();
|
||
return;
|
||
}
|
||
|
||
if (key == KEYPGDOWN) {
|
||
if (resultsObj.hasMore && !resultsObj.isAll) {
|
||
doRequest(latestServerQuery, true);
|
||
} else if (isAutocompleteDivVisible) {
|
||
_completeDiv.scrollTop += _completeDiv.clientHeight;
|
||
//selected += 20;
|
||
//highlight(selected);
|
||
}
|
||
return false;
|
||
}
|
||
if (key == KEYPGUP) {
|
||
if (isAutocompleteDivVisible) {
|
||
_completeDiv.scrollTop -= _completeDiv.clientHeight;
|
||
//selected -= 20;
|
||
//highlight(selected);
|
||
}
|
||
return false;
|
||
}
|
||
if (key == KEYUP) {
|
||
if ((selected - 1) >= 0)
|
||
selected = selected - 1;
|
||
else if (!resultsObj.hasMore)
|
||
selected = resultsObj.result.length - 1;
|
||
highlight(selected);
|
||
return false;
|
||
}
|
||
|
||
if (key == KEYDOWN) {
|
||
if ((selected + 1) < resultsObj.result.length)
|
||
selected = selected + 1;
|
||
else if (resultsObj.hasMore && !resultsObj.isAll)
|
||
doRequest(latestServerQuery, true);
|
||
else
|
||
selected = 0;
|
||
highlight(selected);
|
||
return false;
|
||
}
|
||
|
||
if (key == ESCAPE) {
|
||
params.queryField.onblur();
|
||
}
|
||
if (key == KEYENTER) {
|
||
setValues(true);
|
||
selectRange(0, 0);
|
||
hideAutocompleteDiv();
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// De gewone scrollIntoView() heeft wel eens de neiging de complete pagina ook te scrollen
|
||
function myScrollIntoView(theDiv, toView) {
|
||
if (theDiv.scrollTop + theDiv.clientHeight < toView.offsetTop + toView.clientHeight)
|
||
theDiv.scrollTop = toView.offsetTop + toView.clientHeight - theDiv.clientHeight;
|
||
if (theDiv.scrollTop > toView.offsetTop)
|
||
theDiv.scrollTop = toView.offsetTop;
|
||
}
|
||
|
||
function highlight(number) {
|
||
selected = number;
|
||
// Herstel vorige highlight
|
||
if (lastHighlight && lastHighlight.className)
|
||
lastHighlight.className = "suggestsr";
|
||
// Zet nieuwe highlight
|
||
var ieDIVs = $(_completeDiv).find('div').not(".suggestfoto");
|
||
lastHighlight = ieDIVs[selected];
|
||
if (lastHighlight && lastHighlight.className)
|
||
lastHighlight.className = "suggestsrs";
|
||
myScrollIntoView(_completeDiv, lastHighlight);
|
||
}
|
||
|
||
function setValues(doonChange) {
|
||
if (resultsObj) {
|
||
var result = resultsObj.result[selected][resultsObj.storeDesc ? "desc" : "txt"];
|
||
setValue(resultsObj.result[selected].key, result, doonChange, false, resultsObj.result[selected].extra) // doonChange
|
||
}
|
||
}
|
||
|
||
function autoOpen() {
|
||
params.queryField.value = latestServerQuery || "*"; //"*";
|
||
doRequest(params.queryField.value, false);
|
||
if (params.queryField.createTextRange) {
|
||
// Alleen IE komt hier, FF niet!
|
||
// alert(JSON.stringify(params));
|
||
// var el = document.getElementById("sgRoom");
|
||
// var range = el.createTextRange();
|
||
// range.move("character", 1);
|
||
// range.select();
|
||
var oRange = params.queryField.createTextRange();
|
||
// alert(JSON.stringify(params.queryField)); // = {"jQuery{blablabla": 103}
|
||
// alert(JSON.stringify(oRange)); // oRange = {}
|
||
// oRange.collapse(true);
|
||
// oRange.moveEnd('character', 1);
|
||
// oRange.moveStart('character', 1);
|
||
oRange.move("character", 1);
|
||
oRange.select();
|
||
// oRange.setSelectionRange(1,1);
|
||
}
|
||
// TODO: else wat voor FireFox?
|
||
//set focus back to the textbox (when field is not disabled)
|
||
//if (!textbox.disabled) textbox.focus();
|
||
|
||
//params.queryField.focus();
|
||
//selectRange(0,1);
|
||
}
|
||
|
||
function showAutocompleteDiv() {
|
||
$(window).on("resize", setCompleteDivSize) // Also runs after "orientationchange"(tilting) for Mobile
|
||
.on("scroll", setCompleteDivSize);
|
||
setCompleteDivSize(); // voor de zekerheid
|
||
_completeDiv.style.display = "block";
|
||
}
|
||
|
||
function hideAutocompleteDiv() {
|
||
$(window).off("resize", setCompleteDivSize)
|
||
.off("scroll", setCompleteDivSize);
|
||
_completeDiv.style.display = "none";
|
||
}
|
||
|
||
function isAutocompleteDivVisible() {
|
||
return (_completeDiv.style.display == "block");
|
||
}
|
||
|
||
function requestSuggestions() {
|
||
var sTextboxValue = query().toLowerCase();
|
||
var aSuggestions = [];
|
||
|
||
if (suggestionValues.length > 0) { //search for matching states
|
||
for (var i = 0; i < suggestionValues.length; i++) {
|
||
if (suggestionValues[i].toLowerCase().indexOf(sTextboxValue) == 0)
|
||
aSuggestions.push(suggestionValues[i]);
|
||
}
|
||
autosuggest(aSuggestions);
|
||
}
|
||
};
|
||
|
||
function autosuggest(aSuggestions) { //make sure there's at least one suggestion
|
||
if (aSuggestions.length == 1)
|
||
typeAhead(aSuggestions[0]);
|
||
}
|
||
|
||
function typeAhead(sSuggestion) {
|
||
var textbox = params.queryField;
|
||
//check for support of typeahead functionality
|
||
if (textbox.createTextRange || textbox.setSelectionRange) {
|
||
var iLen = query().length;
|
||
textbox.value = sSuggestion;
|
||
selectRange(iLen, sSuggestion.length);
|
||
}
|
||
};
|
||
|
||
function selectRange(iStart, iLength) {
|
||
var textbox = params.queryField;
|
||
//use text ranges for Internet Explorer
|
||
if (textbox.createTextRange) {
|
||
var oRange = textbox.createTextRange();
|
||
oRange.moveStart("character", iStart);
|
||
oRange.moveEnd("character", iLength - textbox.value.length);
|
||
oRange.select();
|
||
//use setSelectionRange() for Mozilla
|
||
} else if (textbox.setSelectionRange) {
|
||
textbox.setSelectionRange(iStart, iLength);
|
||
}
|
||
|
||
//set focus back to the textbox (when field is not disabled)
|
||
if (!textbox.disabled) textbox.focus();
|
||
};
|
||
} |