From 3898caa12c7530b597922e4a4b517a28af70f239 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sat, 18 May 2019 17:57:42 +0200 Subject: [PATCH] Add instant results on search form of side bar --- assets/css/components/sidebar.css | 40 +++++ assets/js/components/sidebar/main.js | 223 +++++++++++++++++++++++---- 2 files changed, 232 insertions(+), 31 deletions(-) diff --git a/assets/css/components/sidebar.css b/assets/css/components/sidebar.css index f4ebf1ac..6be3dbbf 100644 --- a/assets/css/components/sidebar.css +++ b/assets/css/components/sidebar.css @@ -26,6 +26,42 @@ body.sidebar-collapse .main-sidebar > .sidebar .hide-on-collapse { font-size: 12px; } + +/** + * Search form + */ +.sidebar-search-results { + display: flex; + height: 200px; + background-color: white; + position: absolute; + z-index: 2; + width: 90%; + margin-top: -2px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + +.sidebar-search-results .results-container { + flex: 1; +} + +.sidebar-search-results .results-container > div { + padding: 10px; + cursor: pointer; +} + +.sidebar-search-results .results-container > div:hover { + background-color: #0003; +} + +.sidebar-search-results .results-container > div img { + height: 30px; +} + +/** + * Memberships + */ .main-sidebar .memberships-list { flex: 2; overflow: hidden; @@ -65,6 +101,10 @@ body.sidebar-collapse .main-sidebar .memberships-list li:hover .subinfo { padding-left: 20px; } + +/** + * Conversations + */ .main-sidebar .recents-conversations-list { flex: 1; } \ No newline at end of file diff --git a/assets/js/components/sidebar/main.js b/assets/js/components/sidebar/main.js index 9ed87c66..6ef28706 100644 --- a/assets/js/components/sidebar/main.js +++ b/assets/js/components/sidebar/main.js @@ -72,37 +72,7 @@ ComunicWeb.components.sideBar.main = { // Search form - var searchForm = createElem2({ - appendTo: section, - type: "form", - class: "sidebar-form", - children: [ - createElem2({ - type: "div", - class: "input-group", - children: [ - createElem2({ - type: "input", - class: "form-control", - elemType: "text", - placeholder: "Search...", - }), - - createElem2({ - type: "span", - class: "input-group-btn", - innerHTML: '', - }), - ] - }) - ] - }); - - searchForm.addEventListener("submit", function(e){ - e.preventDefault(); - - openPage("search?q=" + searchForm.getElementsByTagName("input")[0].value); - }); + this.addSearchForm(section); // User memberships createElem2({ @@ -142,6 +112,197 @@ ComunicWeb.components.sideBar.main = { }, + + + // ************************************** + // Search + // ************************************** + + + /** + * Add search form to sidebar + * + * @param {HTMLElement} target The target for the search form + */ + addSearchForm: function(target) { + + + // Search input + + /** + * @type {HTMLInputElement} + */ + let searchInput = createElem2({ + type: "input", + class: "form-control", + elemType: "text", + id: "sidebarSearchInput", + placeholder: "Search...", + }); + + let searchForm = createElem2({ + appendTo: target, + type: "form", + class: "sidebar-form", + children: [ + createElem2({ + type: "div", + class: "input-group", + children: [ + searchInput, + + createElem2({ + type: "span", + class: "input-group-btn", + innerHTML: '', + }), + ] + }) + ] + }); + + // Search results target + let searchResults = createElem2({ + appendTo: searchForm, + type: "div", + class: "sidebar-search-results" + }); + searchResults.style.display = "none"; + + + searchInput.addEventListener("keyup", e => { + + //Update UI + searchResults.style.display + = searchInput.value.length < 3 ? "none" : "unset"; + + if(searchInput.value.length < 3) + return; + + // Perform the search on the server + ComunicWeb.components.search.interface.global(searchInput.value, results => { + if(results.error) return; + + //Get information about related groups and users + getMultipleUsersInfo(ComunicWeb.components.search.utils.getUsersId(results), usersInfo => { + if(usersInfo.error) return; + + getInfoMultipleGroups(ComunicWeb.components.search.utils.getGroupsId(results), groupsInfo => { + if(groupsInfo.error) return; + + this.applySearchResults(searchResults, results, usersInfo, groupsInfo); + }); + }); + }); + + }) + + searchForm.addEventListener("submit", e => { + e.preventDefault(); + + openPage("search?q=" + searchForm.getElementsByTagName("input")[0].value); + }); + }, + + + /** + * Put search form back to its initial state + */ + resetSearchFrom: function(){ + byId("sidebarSearchInput").value = ""; + document.querySelector(".sidebar-search-results").style.display = "none"; + }, + + /** + * Apply search results + * + * @param {HTMLElement} target + * @param {Array} results + * @param {*} users + * @param {*} groups + */ + applySearchResults: function(target, results, users, groups) { + emptyElem(target); + + let resultsTarget = createElem2({ + appendTo: target, + type: "div", + class: "results-container" + }); + + results.forEach(el => { + + if(el.kind == "user") + this.applyUserResult(resultsTarget, users["user-" + el.id]); + + else + this.applyGroupResult(resultsTarget, groups[el.id]); + + }); + + $(resultsTarget).slimScroll({ + height: '100%' + }); + }, + + + applyUserResult: function(target, user) { + + createElem2({ + appendTo: target, + type: "div", + children: [ + createElem2({ + type: "img", + class: "img-circle", + src: user.accountImage + }), + + createElem2({ + type: "span", + innerHTML: userFullName(user) + }), + ], + onclick: () => { + openUserPage(user); + this.resetSearchFrom(); + } + }); + + }, + + + applyGroupResult: function(target, group) { + createElem2({ + appendTo: target, + type: "div", + children: [ + createElem2({ + type: "img", + src: group.icon_url + }), + + createElem2({ + type: "span", + innerHTML: group.name + }), + ], + onclick: () => { + openGroupPage(group); + this.resetSearchFrom(); + } + }); + }, + + + + + + + // ************************************** + // Memberships + // ************************************** + /** * Refresh user memberships *