diff --git a/config/alfresco/messages/office-addin.properties b/config/alfresco/messages/office-addin.properties index 9c662a6ba4..07ef67110b 100644 --- a/config/alfresco/messages/office-addin.properties +++ b/config/alfresco/messages/office-addin.properties @@ -135,6 +135,7 @@ office.result.exception=Action failed due to exception office.result.create_space.failed=Could not create space office.result.create_space.missing_name=Space must have a Name office.result.space_created=New space created +office.result.user_not_found=Username could not be found # Miscellaneous office.unit.kb=KB diff --git a/source/web/css/office.css b/source/web/css/office.css index 68c20e9022..ef6342c6fc 100644 --- a/source/web/css/office.css +++ b/source/web/css/office.css @@ -120,9 +120,9 @@ input.button { } .tabBar .help { - left: 20px; - position: relative; - top: 4px; + left: 270px; + position: absolute; + top: 8px; } .tabBarInline { @@ -246,7 +246,6 @@ input.button { float: left; width: 282px; height: 373px; - overflow: auto; border: 1px solid #cccccc; margin: 0px 4px 0px 4px; background: #fff; @@ -374,7 +373,9 @@ input.button { padding: 2px 0px 0px 0px; width: 180px; } -.spaceValue select, .spaceValue input, .spaceValue textarea { +.spaceValue select, +.spaceValue input, +.spaceValue textarea { font-family: tahoma, sans-serif; font-size: 8pt; margin: 0px 1px 1px 1px; @@ -394,6 +395,12 @@ input.button { padding: 4px; filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#ffffff', EndColorStr='#cce6ff'); } +.spaceAction.disabled { + background-color: #fff; + border-color: #c0c0c0; + color: #c0c0c0; + cursor: default; +} .spaceItem { border-bottom: 1px solid #eee; @@ -479,6 +486,8 @@ input.button { #nonStatusText { height: 100%; min-height: 100%; + overflow-x: hidden; + overflow-y: auto; position: relative; } @@ -528,6 +537,18 @@ input.button { overflow: hidden; } +.tool-tip { + background-color: #ffffe1; + border: 1px solid black; + padding: 2px; +} +.tool-tip .tool-title { + display: none; +} +.tool-tip .tool-text { + color: #000; +} + .checkedoutItem { border-bottom: 1px solid #eee; } @@ -571,7 +592,8 @@ input.button { .taskActionContainer { float: left; - width: 272px; + padding-bottom: 0.2em; + width: 260px; } .taskActions { diff --git a/source/web/css/office_ie6.css b/source/web/css/office_ie6.css index 6436dbf05d..5fe6b0e7e8 100644 --- a/source/web/css/office_ie6.css +++ b/source/web/css/office_ie6.css @@ -5,7 +5,7 @@ } .tabBar .help { - left: 14px; + left: 268px; } .toggle { diff --git a/source/web/scripts/office/doc_details.js b/source/web/scripts/office/doc_details.js index 615e68f50f..6e0901dd25 100644 --- a/source/web/scripts/office/doc_details.js +++ b/source/web/scripts/office/doc_details.js @@ -7,7 +7,6 @@ var OfficeDocDetails = init: function() { OfficeDocDetails.setupTabs(); - OfficeDocDetails.setupTags(); }, setupTabs: function() @@ -41,11 +40,6 @@ var OfficeDocDetails = }); }, - setupTags: function() - { - // Placeholder - }, - showAddTagForm: function() { $("addTagLinkContainer").setStyle("display", "none"); @@ -62,13 +56,13 @@ var OfficeDocDetails = addTag: function(nodeId, tagName) { - OfficeAddin.postAction(window.serviceContextPath + "/collaboration/tagActions", "add", nodeId, null, "t=" + encodeURI(tagName)); + OfficeAddin.postAction(window.serviceContextPath + "/collaboration/tagActions", "add", nodeId, null, "t=" + encodeURIComponent(tagName)); return false; }, removeTag: function(nodeId, tagName) { - OfficeAddin.postAction(window.serviceContextPath + "/collaboration/tagActions", "remove", nodeId , null, "t=" + encodeURI(tagName)); + OfficeAddin.postAction(window.serviceContextPath + "/collaboration/tagActions", "remove", nodeId , null, "t=" + encodeURIComponent(tagName)); return false; } }; diff --git a/source/web/scripts/office/my_alfresco.js b/source/web/scripts/office/my_alfresco.js index 99ba81ef33..d7cb367817 100644 --- a/source/web/scripts/office/my_alfresco.js +++ b/source/web/scripts/office/my_alfresco.js @@ -68,8 +68,9 @@ var OfficeMyAlfresco = setupToggles: function() { // Elements of interest - var panels = $$('.togglePanel'); - var toggles = $$('.toggle'); + var panels = $$('.togglePanel'), + toggles = $$('.toggle'), + toggle; // Animation var fxPanel = new Fx.Elements(panels, {wait: false, duration: OfficeMyAlfresco.ANIM_LENGTH, transition: Fx.Transitions.Back.easeInOut}); diff --git a/source/web/scripts/office/my_tasks.js b/source/web/scripts/office/my_tasks.js index 609e1d8d2d..1f5b841a0d 100644 --- a/source/web/scripts/office/my_tasks.js +++ b/source/web/scripts/office/my_tasks.js @@ -60,8 +60,7 @@ var OfficeMyTasks = { this.setProperty('value', this.getProperty('value').substr(0, OfficeMyTasks.MAX_DESCRIPTION)); } - } - + }; } }, @@ -77,7 +76,9 @@ var OfficeMyTasks = task.addEvent('mouseenter', function(e) { if (task.isOpen) + { return; + } // highlight the item title task.addClass('taskItemSelected'); @@ -97,7 +98,9 @@ var OfficeMyTasks = task.addEvent('mouseleave', function(e) { if (task.isOpen) + { return; + } // unhighlight the item title task.removeClass('taskItemSelected'); @@ -119,7 +122,8 @@ var OfficeMyTasks = // ajax call to load task details var actionURL = window.serviceContextPath + "/office/myTasksDetail" + OfficeAddin.defaultQuery + "&t=" + task.id.replace(/\./, "$"); - var myAjax = new Ajax(actionURL, { + var myAjax = new Ajax(actionURL, + { method: 'get', headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, onComplete: function(textResponse, xmlResponse) @@ -171,21 +175,22 @@ var OfficeMyTasks = OfficeAddin.showStatusText("Running workflow...", "ajax_anim.gif", false); // ajax call to run workflow - var myAjax = new Ajax(commandURL, { + var myAjax = new Ajax(commandURL, + { method: 'get', headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, onComplete: function(textResponse, xmlResponse) { // Remove any trailing hash - var href = window.location.href.replace("#", "") + var href = window.location.href.replace("#", ""); // Remove any "st" and "w" parameters href = OfficeAddin.removeParameters(href, "st|w"); // Optionally add a status string - if (successMessage != "") + if (successMessage !== "") { var json = "{\"statusString\":\"" + successMessage + "\",\"statusCode\":true}"; href += (href.indexOf("?") == -1) ? "?" : "&"; - href += "st=" + encodeURI(json); + href += "st=" + encodeURIComponent(json); } window.location.href = href; }, @@ -198,41 +203,48 @@ var OfficeMyTasks = startWorkflow: function(commandURL, Doc) { - var wrkType=$('wrkType').value; - // wrkAssignTo should be "First Last (Username)" - var wrkAssignTo=$('wrkAssignTo').value; + var wrkType = $('wrkType').value, + wrkAssignTo = $('wrkAssignTo').value, + wrkDueDate = $('wrkDueDate').value, + wrkDescription=$('wrkDescription').value; + if (wrkAssignTo.test(/(?:\(([^\)]+)\))/)) { - // Extract the Username - wrkAssignTo=wrkAssignTo.match(/(?:\(([^\)]+)\))/)[1]; + // Extract the Username - should be "First Last (Username)" + wrkAssignTo = wrkAssignTo.match(/(?:\(([^\)]+)\))/)[1]; + } + + if (wrkAssignTo === "") + { + OfficeAddin.showStatusText("Assign to cannot be empty", "info.gif", true); + return; } - var wrkDueDate = $('wrkDueDate').value;; - var wrkDescription=$('wrkDescription').value; OfficeAddin.showStatusText("Starting workflow...", "ajax_anim.gif", false); var actionURL = commandURL + "?a=workflow&n=" + Doc; actionURL += "&wt=" + wrkType; actionURL += "&at=" + wrkAssignTo; // Date supplied? - if (wrkDueDate != "") + if (wrkDueDate !== "") { actionURL += "&dd=" + wrkDueDate; } actionURL += "&desc=" + wrkDescription; - var myAjax = new Ajax(actionURL, { + var myAjax = new Ajax(actionURL, + { method: 'get', headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, onComplete: function(textResponse, xmlResponse) { // Remove any trailing hash - var href = window.location.href.replace("#", "") + var href = window.location.href.replace("#", ""); // Remove any previous "st", "w" or "wd" parameters href = OfficeAddin.removeParameters(href, "st|w|wd"); // Optionally add a status string - if (textResponse != "") + if (textResponse !== "") { href += (href.indexOf("?") == -1) ? "?" : "&"; - href += "st=" + encodeURI(textResponse); + href += "st=" + encodeURIComponent(textResponse); } window.location.href = href; } @@ -244,12 +256,12 @@ var OfficeMyTasks = runAction: function(useTemplate, action, nodeId, confirmMsg) { // Re-select a selected task after reload - var taskSel = $E('#taskList .taskItemSelected'); - var outParams = null; - if (taskSel != null) + var taskSel = $E('#taskList .taskItemSelected'), + outParams = null; + if (taskSel !== null) { var taskId = taskSel.id; - outParams = "t=" + encodeURI(taskId); + outParams = "t=" + encodeURIComponent(taskId); } return OfficeAddin.getAction(useTemplate, action, nodeId, confirmMsg, null, outParams); @@ -258,16 +270,16 @@ var OfficeMyTasks = refreshPage: function() { // Remove any trailing hash - var href = window.location.href.replace("#", "") + var href = window.location.href.replace("#", ""); // Remove any previous "st", "w", "wd" or "t" parameters href = OfficeAddin.removeParameters(href, "st|w|wd|t"); // Re-select a selected task after reload var taskSel = $E('#taskList .taskItemSelected'); - if (taskSel != null) + if (taskSel !== null) { var taskId = taskSel.id; href += (href.indexOf("?") == -1) ? "?" : "&"; - href += "t=" + encodeURI(taskId); + href += "t=" + encodeURIComponent(taskId); } window.location.href = href; } diff --git a/source/web/scripts/office/navigation.js b/source/web/scripts/office/navigation.js index cdfd2e49d4..f393350f11 100644 --- a/source/web/scripts/office/navigation.js +++ b/source/web/scripts/office/navigation.js @@ -30,8 +30,9 @@ var OfficeNavigation = setupToggles: function() { // Elements of interest - var panels = $$('.togglePanel'); - var toggles = $$('.toggle'); + var panels = $$('.togglePanel'), + toggles = $$('.toggle'), + toggle; // Animation var fxPanel = new Fx.Elements(panels, @@ -198,11 +199,11 @@ var OfficeNavigation = onComplete: function(textResponse, xmlResponse) { // Remove any trailing hash - var href = window.location.href.replace("#", "") + var href = window.location.href.replace("#", ""); // Remove any "st" and "cc" parameters href = OfficeAddin.removeParameters(href, "st|cc"); // Optionally add a status string - if (textResponse != "") + if (textResponse !== "") { href += (href.indexOf("?") == -1) ? "?" : "&"; href += "st=" + encodeURIComponent(textResponse); @@ -218,10 +219,10 @@ var OfficeNavigation = // Does the current doc have an extension? - async request ExternalComponent.docHasExtension(function() { - ExternalComponent.saveToAlfresco(currentPath) + ExternalComponent.saveToAlfresco(currentPath); }, function() { - OfficeNavigation.showSaveFilenamePanel(currentPath) + OfficeNavigation.showSaveFilenamePanel(currentPath); }); }, @@ -235,6 +236,22 @@ var OfficeNavigation = var panel = $("saveDetailsPanel"); panel.setStyle("opacity", 0); panel.setStyle("display", "inline"); + + var fnToggleOK = function() + { + var pattern = new RegExp(/([\"\*\\\><\?\/\:\|]+)|([\.]?[\.]+$)/), + filename = $('saveFilename').value; + if (filename.trim() === "" || pattern.test(filename)) + { + $('saveFilenameOK').addClass('disabled'); + } + else + { + $('saveFilenameOK').removeClass('disabled'); + } + }; + + fnToggleOK(); var anim = new Fx.Styles(panel, { @@ -249,21 +266,27 @@ var OfficeNavigation = { OfficeNavigation.saveOK(); event.stop(); - $('saveFilename').removeEvent('keypress'); + this.removeEvent('keypress'); + this.removeEvent('keyup'); } else if (event.key == 'esc') { OfficeNavigation.saveCancel(); event.stop(); - $('saveFilename').removeEvent('keypress'); + this.removeEvent('keypress'); + this.removeEvent('keyup'); } }); + $('saveFilename').addEvent('keyup', function(event) + { + fnToggleOK(); + }); $('saveFilename').focus(); } }).start({'opacity': 1}); this.fxOverlay.start(OfficeNavigation.OVERLAY_OPACITY); - if (panel != null) + if (panel !== null) { this.popupPanel = panel; this.popupPanel.currentPath = currentPath; @@ -273,14 +296,14 @@ var OfficeNavigation = saveOK: function() { // Shortcut for double-event firing issue - if (this.popupPanel == null) + if (this.popupPanel === null) { return; } - var filename = $('saveFilename').value; - var currentPath = this.popupPanel.currentPath; - var cancelSave = false; + var filename = $('saveFilename').value.trim(), + currentPath = this.popupPanel.currentPath, + cancelSave = false; if (filename.length > 0) { @@ -289,7 +312,7 @@ var OfficeNavigation = { if ((doc == filename) || (doc == filename + ".doc")) { - if (!confirm("The document exists and is not versionable. Overwrite this file?")) + if (!window.confirm("The document exists and is not versionable. Overwrite this file?")) { cancelSave = true; } @@ -306,7 +329,7 @@ var OfficeNavigation = saveCancel: function() { - if (this.popupPanel != null) + if (this.popupPanel !== null) { this.popupPanel.setStyle("display", "none"); this.popupPanel = null; diff --git a/source/web/scripts/office/office_addin.js b/source/web/scripts/office/office_addin.js index 991d7a1520..82c14e4a1e 100644 --- a/source/web/scripts/office/office_addin.js +++ b/source/web/scripts/office/office_addin.js @@ -13,14 +13,14 @@ var OfficeAddin = { window.queryObject = OfficeAddin.toQueryObject(document.location.search); window.contextPath = OfficeAddin.getContextPath(); - window.serviceContextPath = OfficeAddin.getServiceContextPath();; + window.serviceContextPath = OfficeAddin.getServiceContextPath(); /* Update needed after page load? */ if(this.queryObject.st) { - var objResponse = Json.evaluate(this.queryObject.st); - var imgSuccess = (objResponse.statusCode ? "action_successful.gif" : "action_failed.gif"); - var colBackground = (objResponse.statusCode ? "#50ff50" : "#ff5050"); + var objResponse = Json.evaluate(this.queryObject.st), + imgSuccess = (objResponse.statusCode ? "action_successful.gif" : "action_failed.gif"), + colBackground = (objResponse.statusCode ? "#50ff50" : "#ff5050"); OfficeAddin.showStatusText(objResponse.statusString, imgSuccess, true, colBackground); } @@ -58,7 +58,7 @@ var OfficeAddin = } e.innerHTML = statusText; e.setStyle("opacity", "1"); - if (statusText == "") + if (statusText === "") { e.setStyle("border-top", ""); } @@ -72,13 +72,13 @@ var OfficeAddin = }); if (fadeOut) { - fx.onComplete = new function() + fx.onComplete = function() { OfficeAddin.hideStatusText.delay(OfficeAddin.STATUS_FADE); - } + }; } - var colBackground = (colBackground == null) ? "#ffffcc" : colBackground; - fx.start(colBackground, "#ffffff"); + var fxBackground = (typeof colBackground == "undefined") ? "#ffffcc" : colBackground; + fx.start(fxBackground, "#ffffff"); } }, @@ -95,17 +95,17 @@ var OfficeAddin = /* AJAX call to perform server-side actions */ getAction: function(useTemplate, action, nodeId, confirmMsg, inParams, outParams) { - return OfficeAddin.runAction("get", useTemplate, action, nodeId, confirmMsg, inParams, outParams) + return OfficeAddin.runAction("get", useTemplate, action, nodeId, confirmMsg, inParams, outParams); }, postAction: function(useTemplate, action, nodeId, confirmMsg, inParams, outParams) { - return OfficeAddin.runAction("post", useTemplate, action, nodeId, confirmMsg, inParams, outParams) + return OfficeAddin.runAction("post", useTemplate, action, nodeId, confirmMsg, inParams, outParams); }, runAction: function(httpMethod, useTemplate, action, nodeId, confirmMsg, inParams, outParams) { - if ((confirmMsg != null) && (confirmMsg != "")) + if ((confirmMsg !== null) && (confirmMsg !== "")) { - if (!confirm(confirmMsg)) + if (!window.confirm(confirmMsg)) { return; } @@ -113,25 +113,26 @@ var OfficeAddin = OfficeAddin.showStatusText("Running action...", "ajax_anim.gif", false); var actionURL = useTemplate + "?a=" + action + "&n=" + nodeId; - if ((inParams != null) && (inParams != "")) + if ((inParams !== null) && (inParams !== "")) { actionURL += "&" + inParams; } - var myAjax = new Ajax(actionURL, { + var myAjax = new Ajax(actionURL, + { method: httpMethod, headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, onComplete: function(textResponse, xmlResponse) { // Remove any trailing hash - var href = window.location.href.replace("#", "") + var href = window.location.href.replace("#", ""); // Remove any previous "st" parameters href = OfficeAddin.removeParameters(href, "st|version"); // Optionally add a status string - if (textResponse != "") + if (textResponse !== "") { href += (href.indexOf("?") == -1) ? "?" : "&"; - href += "st=" + encodeURI(textResponse); - if ((outParams != null) && (outParams != "")) + href += "st=" + encodeURIComponent(textResponse); + if ((outParams !== null) && (outParams !== "")) { href += "&" + outParams; } @@ -144,9 +145,9 @@ var OfficeAddin = /* Calculates and returns the context path for the current page */ getContextPath: function() { - var path = window.location.pathname; - var idx = path.indexOf("/", 1); - var contextPath = ""; + var path = window.location.pathname, + idx = path.indexOf("/", 1), + contextPath = ""; if (idx != -1) { contextPath = path.substring(0, idx); @@ -162,9 +163,9 @@ var OfficeAddin = /* Calculates and returns the service context path for the current page */ getServiceContextPath: function() { - var path = window.location.pathname; - var idx = path.indexOf("/", 1); - var serviceContextPath = ""; + var path = window.location.pathname, + idx = path.indexOf("/", 1), + serviceContextPath = ""; if (idx != -1) { serviceContextPath = path.substring(0, idx); @@ -183,8 +184,8 @@ var OfficeAddin = /* Removes params "param1|param2...|paramN" from a URL */ removeParameters: function(theUrl, theParams) { - var regexp = new RegExp("[?&](" + theParams + ")=([^&$]+)", "g"); - var url = theUrl.replace(regexp, ""); + var regexp = new RegExp("[?&](" + theParams + ")=([^&$]+)", "g"), + url = theUrl.replace(regexp, ""); // Check that an href still contains a "?" after removing parameters var pos = url.indexOf("?"); @@ -203,7 +204,7 @@ var OfficeAddin = sortTasks: function(taskContainer) { - var taskArray = new Array(); + var taskArray = []; taskContainer.getElementsBySelector('.taskItem').each(function(task, i) { taskArray[i] = {dueDate: task.getProperty('rel'), theTask: task.clone()}; @@ -214,15 +215,15 @@ var OfficeAddin = for(var i = 0; i < taskArray.length; i++) { - taskArray[i].theTask.addClass((i % 2 == 0) ? "odd" : "even"); + taskArray[i].theTask.addClass((i % 2 === 0) ? "odd" : "even"); taskArray[i].theTask.injectInside(taskContainer); } }, sortByDueDate: function(a, b) { - var x = a.dueDate; - var y = b.dueDate; + var x = a.dueDate, + y = b.dueDate; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }, diff --git a/source/web/scripts/office/search.js b/source/web/scripts/office/search.js index efc13b3d68..e4ceda7953 100644 --- a/source/web/scripts/office/search.js +++ b/source/web/scripts/office/search.js @@ -25,7 +25,7 @@ var OfficeSearch = itemsFound: function(shownResults, totalResults) { var strFound; - if (totalResults == 0) + if (totalResults === 0) { strFound = "No items found"; } @@ -54,7 +54,8 @@ var OfficeSearch = OfficeAddin.showStatusText("Searching...", "ajax_anim.gif", false); var actionURL = useTemplate + argPath + "&search=" + encodeURIComponent(searchString) + "&maxresults=" + maxResults; - var myAjax = new Ajax(actionURL, { + var myAjax = new Ajax(actionURL, + { method: 'get', headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, evalScripts: true, @@ -62,6 +63,13 @@ var OfficeSearch = { OfficeAddin.hideStatusText(); $('searchResultsList').innerHTML = textResponse; + /* Custom tooltips + var myTips = new Tips($$(".toolTip"), + { + fixed: true, + maxTitleChars: 50 + }); + */ } }); myAjax.request(); diff --git a/source/web/scripts/office/tags.js b/source/web/scripts/office/tags.js index 2eae3c155b..2322ec9000 100644 --- a/source/web/scripts/office/tags.js +++ b/source/web/scripts/office/tags.js @@ -21,7 +21,8 @@ var OfficeTags = // ajax call to get repository tag data var actionURL = window.serviceContextPath + "/collaboration/tagQuery"; - var myJsonRequest = new Json.Remote(actionURL, { + var myJsonRequest = new Json.Remote(actionURL, + { method: 'get', headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, onComplete: function(tagQuery) @@ -34,9 +35,9 @@ var OfficeTags = populateTagCloud: function(tagQuery) { - var tagCloud = $("tagCloud"); - var range = tagQuery.countMax - tagQuery.countMin; - var scale = (range / OfficeTags.SCALE_FACTOR); + var tagCloud = $("tagCloud"), + range = tagQuery.countMax - tagQuery.countMin, + scale = (range / OfficeTags.SCALE_FACTOR); var tagContainer, tagName, tagNameClass, tagCount; @@ -61,6 +62,10 @@ var OfficeTags = tagCount.appendText("(" + tag.count + ")"); tagCount.injectInside(tagName); }); + if (OfficeTags.preselectedTag !== "") + { + OfficeTags.selectTag(OfficeTags.preselectedTag); + } }, /* AJAX call to perform server-side tag search */ @@ -68,12 +73,11 @@ var OfficeTags = { OfficeAddin.showStatusText("Searching tags...", "ajax_anim.gif", false); - // var maxResults = $('maxResults').value; - var maxResults = 100; - - var args = OfficeAddin.defaultQuery + "&type=tag"; - var actionURL = window.serviceContextPath + "/office/searchResults" + args + "&search=" + encodeURI(tagName.replace(" ", "_x0020_")) + "&maxresults=" + maxResults; - var myAjax = new Ajax(actionURL, { + var maxResults = 100, + args = OfficeAddin.defaultQuery + "&type=tag", + actionURL = window.serviceContextPath + "/office/searchResults" + args + "&search=" + encodeURIComponent(tagName) + "&maxresults=" + maxResults; + var myAjax = new Ajax(actionURL, + { method: 'get', headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'}, evalScripts: true, @@ -102,7 +106,6 @@ var OfficeTags = preselectTag: function(tagName) { OfficeTags.preselectedTag = tagName; - OfficeTags.selectTag(tagName); } }; @@ -112,7 +115,7 @@ var OfficeSearch = itemsFound: function(shownResults, totalResults) { var strFound; - if (totalResults == 0) + if (totalResults === 0) { strFound = "No items found"; }