var $ArrSearch = new Array(); function $Search(resultFunction,productListURL) { var referer = this; this.caller = null; this.header = null; this.placeholderHeight = 0; this.searchString = ""; this.results = new Array(); this.resultBox = document.createElement("div"); this.resultBox.style.display = "none"; this.resultBox.className = "resultBox"; this.resultBox.oncontextmenu = function() { return false; }; this.resultBox. = function() { referer.mouseOver(); }; this.resultBox. = function() { referer.mouseOut(); }; this.selectedIndex = null; this.over = false; this.data = new Array(); this.ajaxStatus = 0; if (resultFunction) { this.throwResult = resultFunction; } else { this.throwResult = function(product) { } } if (productListURL) { this.ajaxUrl = productListURL; } else { this.ajaxUrl = "/includes/ajax/productsearch.asp"; } $ArrSearch.push(this); document.onmousedown = $Search_hideAll; } $Search.prototype.showResults = function(caller) { if (this.caller == caller) { if (this.results.length > 0) { var callerPos = getAbsolutePosition(this.caller, true); this.resultBox.style.left = (callerPos[0] + 0) + "px"; this.resultBox.style.top = (callerPos[1] + this.caller.offsetHeight + 0) + "px"; this.resultBox.style.minWidth = (this.caller.offsetWidth - 2) + "px"; this.resultBox.style.display = "block"; } } else { this.search(caller, true); } } function getHttpObject() { var xmlHttp = null; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } $Search.prototype.search = function(caller, forced) { var referer = this; this.caller = caller; if (this.data.length == 0 && this.ajaxStatus == 0) { var tmpAjaxUrl = this.ajaxUrl + "?nocache=" + Math.random(); var http = getHttpObject(); if (http != null) { http.onreadystatechange = function() { if (this.readyState == 4) { referer.ajaxStatus = 2; referer.parseXML(this.responseXML, caller); } } http.open("GET", tmpAjaxUrl, true); http.send(null); this.ajaxStatus = 1; this.resultBox.innerHTML = ""; var loadingDiv = document.createElement("div"); var loadingImg = document.createElement("img"); loadingImg.src = "images/miscellaneous/loading.gif"; loadingDiv.style.textAlign = "center"; loadingDiv.style.padding = "5px"; loadingDiv.appendChild(loadingImg); this.resultBox.appendChild(loadingDiv); document.body.appendChild(this.resultBox); var callerPos = getAbsolutePosition(this.caller, true); this.resultBox.style.left = (callerPos[0] + 0) + "px"; this.resultBox.style.top = (callerPos[1] + this.caller.offsetHeight + 0) + "px"; this.resultBox.style.minWidth = (this.caller.offsetWidth - 2) + "px"; this.resultBox.style.display = "block"; } else { this.ajaxStatus = 2; } } if ((caller.value != this.searchString || forced) && this.ajaxStatus == 2) { this.searchString = caller.value; this.results = new Array(); this.resultBox.innerHTML = ""; this.selectedIndex = null; if (this.header != null) { var div = document.createElement("div"); div.className = "rowHeader"; div.appendChild(document.createTextNode(this.header + " «")); div. = function() { this.className = "rowHeader over"; }; div. = function() { this.className = "rowHeader"; }; div.onclick = function() { referer.removeHeader(); }; this.resultBox.appendChild(div); } var j = -1; for (var i = 0; i < this.data.length && j < 9; i++) { if (this.data[i].name.toLowerCase().indexOf(this.searchString.toLowerCase(), 0) >= 0) { j++; this.results.push(new $Result(this.data[i], this, j)); } } //FIXME: Hvis der er flere end 10 resultater kan resultboxen udvides til at indeholde dem alle if (j >= 0) { document.body.appendChild(this.resultBox); var callerPos = getAbsolutePosition(this.caller, true); this.resultBox.style.left = (callerPos[0] + 0) + "px"; this.resultBox.style.top = (callerPos[1] + this.caller.offsetHeight + 0) + "px"; this.resultBox.style.minWidth = (this.caller.offsetWidth - 2) + "px"; this.resultBox.style.display = "block"; if (this.resultBox.offsetHeight > this.placeholderHeight) { this.placeholderHeight = this.resultBox.offsetHeight; if (document.getElementById("searchPlaceholder")) { document.getElementById("searchPlaceholder").style.height = (this.placeholderHeight + 5) + "px"; } } } else { this.hideResults(); } } } $Search.prototype.parseXML = function(xmlDoc, caller) { if (xmlDoc != null && xmlDoc.childNodes.length > 0) { var xml = xmlDoc.getElementsByTagName("productsearch")[0]; var productPages = xml.getElementsByTagName("productPages")[0].getElementsByTagName("page"); var products = xml.getElementsByTagName("products")[0].getElementsByTagName("product"); var siteProducts = xml.getElementsByTagName("siteProducts")[0].getElementsByTagName("product"); var page; var product; var siteProduct; var tmpName; var tmpImage; var tmpClass; var tmpInfo; var arrProductPagesId = new Array(); var arrProductsId = new Array(); for (var i = 0; i < productPages.length; i++) { page = productPages[i]; if (page.childNodes[0]) { tmpName = page.childNodes[0].data; } else { tmpName = ""; } arrProductPagesId[parseInt(page.getAttribute("id"))] = new $ProductPage(page.getAttribute("id"), tmpName); this.push(arrProductPagesId[parseInt(page.getAttribute("id"))], false); } for (var i = 0; i < products.length; i++) { product = products[i]; if (product.getElementsByTagName("name")[0].childNodes[0]) { tmpName = product.getElementsByTagName("name")[0].childNodes[0].data; } else { tmpName = ""; } if (product.getElementsByTagName("image")[0].childNodes[0]) { tmpImage = product.getElementsByTagName("image")[0].childNodes[0].data; } else { tmpImage = ""; } arrProductsId[parseInt(product.getAttribute("id"))] = new $Product(product.getAttribute("id"), tmpName, tmpImage); this.push(arrProductsId[parseInt(product.getAttribute("id"))], false); for (var j = 0; j < product.getElementsByTagName("pageRelation").length; j++) { arrProductPagesId[parseInt(product.getElementsByTagName("pageRelation")[j].childNodes[0].data)].push(arrProductsId[parseInt(product.getAttribute("id"))]); } } for (var i = 0; i < siteProducts.length; i++) { siteProduct = siteProducts[i]; if (siteProduct.getElementsByTagName("className")[0].childNodes[0]) { tmpClass = siteProduct.getElementsByTagName("className")[0].childNodes[0].data; } else { tmpClass = ""; } if (siteProduct.getElementsByTagName("infoText")[0].childNodes[0]) { tmpInfo = siteProduct.getElementsByTagName("infoText")[0].childNodes[0].data; } else { tmpInfo = ""; } arrProductsId[parseInt(siteProduct.getAttribute("id"))].info.push({ text: tmpInfo, className: tmpClass }); } this.search(caller, true); } else { this.ajaxStatus = 3; } } $Search.prototype.keyDown = function(caller,key) { var returnVar = true; switch(key) { case 8: //backspace if (this.caller == caller && this.caller.value.length == 0) { this.removeHeader(); } break; case 40: //down if (this.caller == caller) { this.moveDown(); } break; case 38: //up if (this.caller == caller) { this.moveUp(); } break; case 13: //enter if (this.caller == caller) { returnVar = this.select(); } break; } return returnVar; } $Search.prototype.moveDown = function() { if (this.results.length > 0) { if (this.selectedIndex == null) { this.selectedIndex = 0; } else { this.results[this.selectedIndex].highlight(false); this.selectedIndex++; } if (this.selectedIndex >= this.results.length) { this.selectedIndex = this.selectedIndex - this.results.length; } this.results[this.selectedIndex].highlight(true); } } $Search.prototype.moveUp = function() { if (this.results.length > 0) { if (this.selectedIndex == null) { this.selectedIndex = -1; } else { this.results[this.selectedIndex].highlight(false); this.selectedIndex--; } if (this.selectedIndex < 0) { this.selectedIndex = this.results.length + this.selectedIndex; } this.results[this.selectedIndex].highlight(true); } } $Search.prototype.select = function() { if (this.selectedIndex != null) { this.results[this.selectedIndex].click(); return false; } else { return true; } } $Search.prototype.mouseOver = function() { this.over = true; } $Search.prototype.mouseOut = function() { this.over = false; } $Search.prototype.hideResults = function() { this.resultBox.style.display = "none"; } $Search.prototype.removeHeader = function(noFocus) { if (this.header != null) { this.header = null; this.data = this.oldData; if (noFocus != true) { this.caller.focus(); } this.search(this.caller, true); } } function $Result(dataObject,owner,index) { this.index = index; this.owner = owner; this.data = dataObject; this.className = "resultRow"; if (this.owner.header != null) { this.className = this.className + " sub1"; } if (index == 0) { this.className = this.className+" firstRow"; } var referer = this; this.highlighted = false; this.row = document.createElement("div"); this.row.className = this.className; this.name = dataObject.name; var i = 0; var p = 0; var l = this.owner.searchString.length; var txtN; var spanN; var n = document.createElement("span"); while (p >= 0) { p = this.name.toLowerCase().indexOf(this.owner.searchString.toLowerCase(), i); if (this.owner.searchString.length == 0) { p = -1; } if (p == -1) { txtN = document.createTextNode(this.name.substr(i)); n.appendChild(txtN); } else { txtN = document.createTextNode(this.name.substr(i,p-i)); n.appendChild(txtN); spanN = document.createElement("span"); txtN = document.createTextNode(this.name.substr(p,l)); spanN.appendChild(txtN); spanN.className = "highlight"; n.appendChild(spanN); i = p + l; } } this.row.appendChild(dataObject.render(n)); this.row. = function() { referer.over(); }; this.row. = function() { referer.out(); }; this.row.onclick = function() { referer.click(); }; this.owner.resultBox.appendChild(this.row); } function $result_highlight(highlighted) { this.highlighted = highlighted; if (this.highlighted) { this.row.className = this.className+" over"; } else { this.row.className = this.className; } } function $result_over() { if (!this.highlighted) { this.row.className = this.className+" over"; } } function $result_out() { if (!this.highlighted) { this.row.className = this.className; } } function $result_click() { this.data.throwResult(this.owner); } $Result.prototype.highlight = $result_highlight; $Result.prototype.over = $result_over; $Result.prototype.out = $result_out; $Result.prototype.click = $result_click; function $Product(id, name, image) { this.id = id; this.name = name; if (image) { this.image = "/files/products/" + id + "/mini/" + image; } this.info = new Array(); } $Product.prototype.render = function(n) { var div = document.createElement("div"); var imgDiv = document.createElement("div"); var textDiv = document.createElement("div"); var breakDiv = document.createElement("div"); var titleDiv = document.createElement("div"); titleDiv.style.fontWeight = "bold"; breakDiv.style.clear = "both"; imgDiv.className = "resultImgDiv"; textDiv.className = "resultTextDiv"; if (this.image) { var img = document.createElement("img"); img.src = this.image; imgDiv.appendChild(img); } titleDiv.appendChild(n); textDiv.appendChild(titleDiv); var infoDiv; if (this.info.length > 0) { for (var i = 0; i < this.info.length; i++) { infoDiv = document.createElement("div"); infoDiv.className = "infoLine" if (this.info[i].className) { infoDiv.className = infoDiv.className + " " + this.info[i].className; } infoDiv.appendChild(document.createTextNode(this.info[i].text)); textDiv.appendChild(infoDiv); } } div.appendChild(imgDiv); div.appendChild(textDiv); div.appendChild(breakDiv); return div; } $Product.prototype.throwResult = function(search) { search.throwResult(this); } function $ProductPage(id, name) { this.id = id; this.name = name; this.products = new Array(); } $ProductPage.prototype.render = function(n) { var div = document.createElement("div"); var div1 = document.createElement("div"); var div2 = document.createElement("div"); div1.style.fontWeight = "bold"; div1.appendChild(n); div1.appendChild(document.createTextNode(" »")); div2.style.color = "#999999"; div2.appendChild(document.createTextNode(" (" + this.products.length + " produkter)")); div.appendChild(div1); div.appendChild(div2); return div; } $ProductPage.prototype.throwResult = function(search) { search.header = this.name; search.oldData = search.data; search.data = this.products; search.caller.value = ""; search.caller.focus(); search.search(search.caller, true); } $ProductPage.prototype.push = function(dataObject) { this.products.push(dataObject); } $Search.prototype.push = function(dataObject,toSort) { if (toSort) { //FIXME: Lav en sorteringsalgoritme her this.data.push(dataObject); } else { this.data.push(dataObject); } //Når data indsættes manuelt, skal der ikke længere hentes ny data ind via AJAX this.ajaxStatus = 2; } function $Search_hideAll(e) { for (var i = 0; i < $ArrSearch.length; i++) { if (!$ArrSearch[i].over) { $ArrSearch[i].hideResults(); } } } //if (!document.addEventListener && document.attachEvent) { document.attachEvent("onmousedown", $Search_hideAll); } //else if (document.addEventListener) { document.addEventListener("mousedown", $Search_hideAll, false); } document.onmousedown = $Search_hideAll;