// global constants var minSearchLength=2, // min. number of characters to activate preview maxSearchCacheEntries=20; // number of cache entries // global vars var searchPreviewTimeout, searchCache, $searchForm, $liefInput, $searchInput; // clears the timer var clearTimer = function() { window.clearTimeout(searchPreviewTimeout); return true; }; // returns a list element with events, cloning via $.clone(true) did not work var getResultNode = function(str) { return $('
  • ' + str + '
  • ').bind('click.search', function(){ // unbind click handler var $this = $(this).siblings().andSelf().unbind('click.search').end().end(); // fill search field/submit form var idPrefix = $this.parent().attr('id').replace(/-result-list/,''), $input = $searchForm.find('#input-' + idPrefix), isLief = (idPrefix == 'lief'); if (isLief) { // Lieferanten $input.val($this.html()).next('div.search-preview-container').hide(); $searchInput.focus().select(); } else { // Artikel/Katalog $input.val($this.data('qResult')); $searchForm.submit(); } return false; }).hover( function(){ $(this).addClass('over'); }, function(){ $(this).removeClass('over'); } ); }; // input field event handler var addInputEventHandler = function($input, backendUrl, isLief, isKatalog) { var $preview = $input.siblings('div.search-preview-container'), $wait = $preview.find('div.wait-container'), $noResult = $preview.find('div.noresult'), $result = $noResult.next('div'), $resultList = $preview.find('ul.search-result-list'), $resultBtns = isLief ? null : $result.find('a[id^=btn-search-result-]').bind('click.search',function() { // button up/down clicked? var args = $input.data('backendArgs'); getPreviewList($input, backendUrl, isLief, isKatalog, args.value, $(this).data('limit'), args.Aufruf_art, args.SucheUeber); }); //console.log('addInputEventHandler() isLief:', isLief, ', isKatalog:', isKatalog, ', input[name]=' + $input.attr('name')); // store data/jQuery elements, add event handler $input.data('$el', {'input':$input, 'preview':$preview, 'wait':$wait, 'noResult':$noResult, 'result':$result, 'btns':$resultBtns, 'resultList':$resultList}) .focus(function() { // hide other preview containers $searchForm.find('div.search-preview-container:visible').not($preview).hide(); }).keyup(function(e){ var key = TCode(e), value = $.trim($(this).val()), lastQuery = $input.data('lastquery') || ''; children = null; // hide container $preview.children().andSelf().hide(); if (lastQuery == value // backspace=8, tab=9, delete=46 || isLief && (value=='' || key==8 || key==9 || key==46) || !isLief && value.length < minSearchLength){ $preview.hide(); return false; } if (!isLief && key== 13) { // submit form $searchForm.submit(); return false; } $input.data('lastquery', value); // store last query // Lieferanten if (isLief) { $wait.show(); getPreviewList($input, backendUrl, isLief, isKatalog, value); return false; } // Artikel, Katalog var $withPreview = $searchForm.find('input[name=ShowVorschau]'); if ($withPreview.length == 1 && $withPreview.val() == "1") { clearTimer(); searchPreviewTimeout = window.setTimeout(function(){ getPreviewList($input, backendUrl, isLief, isKatalog, value, isKatalog ? 0 : 1, $searchForm.find('input[name=art]').val().toUpperCase(), $searchForm.find('input[name=SucheUeber]').val()); }, 500); } return false; }); }; // initializes jquery vars var initSearch = function() { // Erweiterte Suche $('#ErwSucheToggle').click(function(){ $(this).children('span').toggle(); // toggle +/- $('#ErwSuche').toggle(); }); $searchForm=$('#search-form'); // Lieferanten $liefInput = $searchForm.find('input#input-lief'); if ($liefInput.length == 1) { addInputEventHandler($liefInput, 'backend/LiefRequest.php', true, false); } // Artikelsuche/Katalogsuche $searchInput = $searchForm.find('#input-search'); var isKatalog = ($searchInput.attr('name').search('Kat') == 0); addInputEventHandler($searchInput, 'backend/Vorschau' + (isKatalog ? 'K' : '') + 'Request.php', false, isKatalog); // global search cache searchCache = function() { var _keys = [], _values = [], // two arrays used as hashmap-like lookup table _getKey = function(data) { // returns a key for given parameters var s = ''; if (typeof data == 'object') { for (i in data) { s += data[i] + ','; } } else { // string s = data; } //console.log('searchCache._getKey() key=' + s); return s; }, _find = function(data) { var key = _getKey(data); for (var i=0; i<_keys.length; i++) { if (_keys[i] === key) { // cache hit //console.log('searchCache._find() key=' + key + ', value=', _values[i]); return _values[i]; } } return null; }; return { // add data and result to "cache" add: function(data, result) { if (_keys.length == maxSearchCacheEntries) { // cache is full, remove first element _keys.pop(); _values.pop(); } _keys.push(_getKey(data)); _values.push(result); }, // get cached result or null for given data get: function(data) { if (!data) return null; return _find(data); } }; }(); }; /* ### Lieferanten-/Artikel-/Katalogvorschau ###################################### */ var getPreviewList = function($input, backendUrl, isLief, isKatalog, value, slimit, art, type) { // inner callback for (cached) json var _previewListCallback = function(json) { $el.wait.hide(); if(!json || json.nohits){ // no result... $el.noResult.show(); if (isLief) $el.input.focus().select(); return; } // show result... $el.result.show(); if (json.hits) { $el.result.children('div.search-result-hits').empty() .append('[' + json.hits + '] Treffer').show(); } if (json.up !=null || json.down != null) { if (json.up != null) { $el.btns.eq(0).data('limit',json.up).css('display','block'); } else { $el.btns.eq(0).hide(); } if (json.down != null) { $el.btns.eq(1).data('limit',json.down).css('display','block'); } else { $el.btns.eq(1).hide(); } } if (json.data) { // fill result list if (isLief) { // Lieferanten if (json.data.length == 1) { // one result // fill input field and select search field $el.input.val(json.data); $searchInput.focus().select(); return; } else { // result list var $s = $('
    '); $.each(json.data,function(){ $s.append(getResultNode('' + this)); }); $el.resultList.empty().append($s.children()).show(); } } else { // Katalog/Artikel var $s = $('
    '); // dummy container $.each(json.data,function(){ var str = isKatalog ? (this[0] + ' [' + this[1] + '] Treffer') : this[1]; $s.append( getResultNode(str).data('qResult', this[0]) ); }); $el.resultList.empty().append($s.children()).show(); } } }; var $el = $input.data('$el'), backendArgs = isLief ? {value : value} // Lieferanten : (isKatalog ? {value : value, // Katalog SLimit : slimit} : {value : value, // Artikel SLimit : slimit, Aufruf_art : art, SucheUeber : type, LiefName : (type == 4) ? $liefInput.val() : ''}); // save args for search cache and up-/down-buttons $el.input.data('backendArgs', backendArgs); $el.noResult.hide(); $el.result.children().andSelf().hide(); // hide: hits, up, down, result-list $el.wait.show(); $el.preview.show(); var cached = searchCache.get(backendArgs); if (cached) { // return cached data return _previewListCallback(cached); } // return data from backend URL $.getJSON(backendUrl, backendArgs, function(json){ searchCache.add(backendArgs, json); _previewListCallback(json); } ); };