Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions LearningHub.Nhs.WebUI/Controllers/SearchController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,5 +296,17 @@ public async Task<IActionResult> Image(string name)
return this.Ok(this.Content("No file found"));
}
}

/// <summary>
/// GetAutoSuggestion returns the auto suggestion options.
/// </summary>
/// <param name="term">search term.</param>
/// <returns>ActionResult.</returns>
[HttpGet("GetAutoSuggestion")]
public async Task<IActionResult> GetAutoSuggestion(string term)
{
var autoSuggestions = await this.searchService.GetAutoSuggestionList(term);
return this.PartialView("_AutoComplete", autoSuggestions);
}
}
}
7 changes: 7 additions & 0 deletions LearningHub.Nhs.WebUI/Interfaces/ISearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,12 @@
/// <param name="catalogueSearchRequestModel">The catalogue Search Request Model.</param>
/// <returns>The <see cref="Task{SearchAllCatalogueViewModel}"/>.</returns>
Task<SearchAllCatalogueViewModel> GetAllCatalogueSearchResultAsync(AllCatalogueSearchRequestModel catalogueSearchRequestModel);

/// <summary>
/// The Get AutoSuggestion List.
/// </summary>
/// <param name="term">The term.</param>
/// <returns>The <see cref="Task"/>.</returns>
Task<AutoSuggestionModel> GetAutoSuggestionList(string term);

Check failure on line 93 in LearningHub.Nhs.WebUI/Interfaces/ISearchService.cs

View workflow job for this annotation

GitHub Actions / Build and test

The type or namespace name 'AutoSuggestionModel' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 93 in LearningHub.Nhs.WebUI/Interfaces/ISearchService.cs

View workflow job for this annotation

GitHub Actions / Build and test

The type or namespace name 'AutoSuggestionModel' could not be found (are you missing a using directive or an assembly reference?)
}
}
25 changes: 25 additions & 0 deletions LearningHub.Nhs.WebUI/Services/SearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,31 @@
}
}

/// <summary>
/// The GetAutoSuggestionList.
/// </summary>
/// <param name="term">The term.</param>
/// <returns>The auto suggestion list.</returns>
public async Task<AutoSuggestionModel> GetAutoSuggestionList(string term)

Check failure on line 642 in LearningHub.Nhs.WebUI/Services/SearchService.cs

View workflow job for this annotation

GitHub Actions / Build and test

The type or namespace name 'AutoSuggestionModel' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 642 in LearningHub.Nhs.WebUI/Services/SearchService.cs

View workflow job for this annotation

GitHub Actions / Build and test

The type or namespace name 'AutoSuggestionModel' could not be found (are you missing a using directive or an assembly reference?)
{
var client = await this.LearningHubHttpClient.GetClientAsync();
var request = $"Search/GetAutoSuggestionResult/{term}";
var response = await client.GetAsync(request).ConfigureAwait(false);

var viewModel = new AutoSuggestionModel();
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
viewModel = JsonConvert.DeserializeObject<AutoSuggestionModel>(result);
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || response.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
throw new Exception("AccessDenied");
}

return viewModel;
}

/// <summary>
/// The RemoveHtmlTags.
/// </summary>
Expand Down
63 changes: 63 additions & 0 deletions LearningHub.Nhs.WebUI/Styles/nhsuk/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,57 @@
}
}

.autosuggestion-menu {
padding: 16px 16px 0px 16px;
background-color: $color_nhsuk-white;
border-bottom: 1px solid $color_nhsuk-grey-4;
border-radius: 0px 0px 4px 4px;
border-left: 1px solid $color_nhsuk-grey-4;
border-right: 1px solid $color_nhsuk-grey-4;
box-shadow: 0px 2px 3px 0px $color_nhsuk-grey-4;
list-style: none;
overflow-x: hidden;
overflow-y: auto;
position: absolute;
width: 100%;
z-index: 1;
margin-bottom: 0;
}

.autosuggestion-option {
margin-bottom: 0;
border-bottom: 1px solid $color_nhsuk-grey-4;
color: $color_nhsuk-blue;
cursor: pointer;
font-size: 16px;
padding-bottom: 12px;
text-align: left;
text-decoration: none;
}

.autosuggestion-option .autosuggestion-icon {
fill: $color_nhsuk-grey-3 !important;
float: left;
height: 20px;
margin: 2px 8px 0 0;
width: 16px;
}

.autosuggestion-option .autosuggestion-subtext {
color: $color_nhsuk-grey-2 !important;
padding-left: 24px;
margin: 0px;
}

.autosuggestion-option .autosuggestion-link {
display: flex;
margin-bottom: 0px;
text-decoration: underline;
}

li.autosuggestion-option:last-of-type {
border-bottom: none !important;
}
/* large desktop */
@media (min-width: px2rem(990)) {

Expand Down Expand Up @@ -314,6 +365,10 @@
box-shadow: 0 0 0 2px white;
z-index: 10;
}

.autosuggestion-menu {
top: 100%;
}
}

/* tablet */
Expand All @@ -332,6 +387,10 @@
.nhsuk-header__menu .nhsuk-header__not-mobile {
display: none;
}

.autosuggestion-menu {
top: 100%;
}
}

/* mobile */
Expand Down Expand Up @@ -430,4 +489,8 @@
.nhsuk-width-container.nhsuk-header__container.app-width-container {
padding-bottom: 0;
}

.autosuggestion-menu {
top: 100%;
}
}
45 changes: 45 additions & 0 deletions LearningHub.Nhs.WebUI/Views/Search/_AutoComplete.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@model LearningHub.Nhs.Models.Search.AutoSuggestionModel;
@{
var counter = 0;
var counter_res = 0;
}
@if (Model != null)
{
@foreach (var item in Model.ConceptDocument.ConceptDocumentList)
{
counter++;
<li class="autosuggestion-option autosugg-concepts" style="@((Model.ConceptDocument.ConceptDocumentList.Count == counter)? "border-bottom: 3px solid #d8dde0;": "" )">
<a tabindex="0" style="text-decoration:none !important" asp-controller="Search" asp-action="results" asp-route-term="@item.Concept">
<svg class="nhsuk-icon autosuggestion-icon" width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M11.8558 10.5296L15.7218 14.3861C15.8998 14.5627 16 14.8031 16 15.0539C16 15.3047 15.8998 15.5451 15.7218 15.7218C15.5451 15.8998 15.3047 16 15.0539 16C14.8031 16 14.5627 15.8998 14.3861 15.7218L10.5296 11.8558C7.76424 13.9254 3.86973 13.5064 1.60799 10.8959C-0.653748 8.28537 -0.513826 4.37088 1.92852 1.92852C4.37088 -0.513826 8.28537 -0.653748 10.8959 1.60799C13.5064 3.86973 13.9254 7.76424 11.8558 10.5296ZM6.58846 1.88528C3.99101 1.88528 1.88537 3.99093 1.88537 6.58837C1.88537 9.18581 3.99101 11.2915 6.58846 11.2915C9.1859 11.2915 11.2915 9.18581 11.2915 6.58837C11.2915 3.99093 9.1859 1.88528 6.58846 1.88528Z" />
</svg>
<p class="nhsuk-u-font-size-16 autosuggestion-link">@item.Concept</p>
</a>
</li>
}
@foreach (var item in Model.ResourceDocument.ResourceDocumentList)
{
counter_res++;
<li class="autosuggestion-option autosugg-resource" style="@((Model.ResourceDocument.ResourceDocumentList.Count == counter_res)? "border-bottom: 3px solid #d8dde0;": "" )">
<a tabindex="0" style="text-decoration:none !important" asp-controller="Search" asp-action="results" asp-route-term="@item.Title">
<svg class="nhsuk-icon autosuggestion-icon" width="16" height="12" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg">
<path d="M7.89365 11.4887C7.90726 11.4837 7.92086 11.4787 7.93508 11.4738C7.93508 11.4239 7.93508 11.3735 7.93508 11.3236C7.93508 8.61493 7.93199 5.90624 7.94003 3.19754C7.94064 2.90288 7.87263 2.64621 7.71621 2.40574C7.64263 2.29299 7.57091 2.17836 7.48744 2.0737C6.01592 0.238416 3.7023 -0.378952 1.5148 0.23094C1.47028 0.2434 1.41958 0.322518 1.41526 0.374225C1.40165 0.533706 1.40907 0.695679 1.40907 0.856407C1.4066 2.50044 1.40536 4.14447 1.40042 5.78787C1.39671 6.93975 1.38743 8.09163 1.37878 9.24351C1.37816 9.35814 1.38125 9.43103 1.53706 9.39676C2.4076 9.20613 3.28186 9.18433 4.15983 9.34942C5.54973 9.61107 6.73561 10.249 7.70631 11.2869C7.76876 11.3535 7.83121 11.4208 7.89365 11.4881V11.4887ZM8.06863 11.475C8.08718 11.4862 8.10573 11.4974 8.12427 11.5093C8.14159 11.4769 8.1521 11.4389 8.17621 11.4127C9.89195 9.56061 11.9978 8.93327 14.4462 9.39365C14.5823 9.41919 14.6157 9.39116 14.6144 9.25473C14.6064 8.38381 14.6045 7.51351 14.6014 6.64259C14.5996 6.11493 14.5983 5.58728 14.5971 5.05899C14.5946 4.19742 14.5915 3.33585 14.5891 2.47427C14.5872 1.789 14.5829 1.10435 14.5866 0.419079C14.5872 0.291369 14.5495 0.23094 14.4209 0.209759C14.223 0.177988 14.0289 0.123166 13.8311 0.0895252C12.5048 -0.135992 11.2454 0.0596224 10.0725 0.732435C9.29964 1.17537 8.64673 1.751 8.20094 2.54031C8.10511 2.70976 8.0575 2.88793 8.0575 3.0879C8.06121 5.83896 8.05997 8.58939 8.06059 11.3404C8.06059 11.3853 8.06554 11.4295 8.06801 11.4744L8.06863 11.475ZM0.012984 10.9673C2.58011 10.6072 5.08849 10.819 7.55669 11.5535C5.62084 9.96865 3.44076 9.39926 0.981219 9.97239C0.976273 9.90262 0.970709 9.85714 0.970709 9.81166C0.973182 8.20377 0.975037 6.59587 0.978746 4.98797C0.981219 3.65979 0.983074 2.33099 0.99173 1.00281C0.992349 0.857653 0.932375 0.797224 0.80439 0.800962C0.610248 0.806569 0.416106 0.824635 0.221965 0.839587C0.0513177 0.852669 0 0.940508 0 1.11619C0.00680114 3.0717 0.00494629 5.02722 0.00494629 6.98336C0.00494629 8.23928 0.00370971 9.49519 0.004328 10.7511C0.004328 10.8171 0.00989257 10.8826 0.0136023 10.9673H0.012984ZM15.9771 10.966C15.9815 10.8938 15.9876 10.8383 15.9883 10.7835C15.9932 9.39303 15.9994 8.00317 16 6.61269C16 5.82961 15.9901 5.04653 15.9889 4.26345C15.987 3.19443 15.9864 2.12541 15.9913 1.05638C15.9913 0.93241 15.9456 0.868243 15.8318 0.855161C15.6235 0.832111 15.4139 0.81093 15.2049 0.800339C15.0602 0.792863 15.0033 0.86762 15.0039 1.02212C15.0083 2.48549 15.0033 3.94823 15.0046 5.4116C15.0052 6.01214 15.0182 6.61331 15.0206 7.21386C15.0243 8.06983 15.0243 8.92642 15.025 9.78238C15.025 9.83783 15.0182 9.89328 15.0132 9.97488C13.8416 9.69953 12.6829 9.66838 11.5267 9.9537C10.3699 10.239 9.34601 10.7879 8.43713 11.5572C10.9047 10.8196 13.4112 10.6091 15.9771 10.9667V10.966Z" />
</svg>
<p class="nhsuk-u-font-size-16 autosuggestion-link">@item.Title</p>
<p class="nhsuk-u-font-size-14 autosuggestion-subtext">Resource</p>
</a>
</li>
}
@foreach (var item in Model.CatalogueDocument.CatalogueDocumentList)
{
<li class="autosuggestion-option autosugg-catalogue">
<a tabindex="0" style="text-decoration:none !important" asp-controller="Search" asp-action="results" asp-route-term="@item.Name">
<svg class="nhsuk-icon autosuggestion-icon" width="14" height="16" viewBox="0 0 14 16" xmlns="http://www.w3.org/2000/svg">
<path d="M13.4986 1.62391C13.498 1.35936 13.4452 1.06975 13.3272 0.835751C13.0286 0.243103 12.5027 0.0164303 11.8428 0.0182632C8.84631 0.0255949 5.84982 0.0219291 2.85272 0.0213181C2.75073 0.0213181 2.64873 0.023151 2.54735 0.0127644C1.80514 -0.0623858 1.18766 0.19728 0.673397 0.712944C0.171423 1.217 -0.000612773 1.84325 1.639e-06 2.53977C0.00491694 6.56672 0.00184488 10.5937 0.00245929 14.62C0.00245929 14.7208 0.00368811 14.8229 0.0116755 14.9231C0.0645149 15.5566 0.516722 15.9941 1.15571 15.9953C4.34574 16.0008 7.53638 16.002 10.7264 15.9959C11.433 15.9947 11.9012 15.5322 11.9018 14.8332C11.9073 11.1099 11.9104 7.38665 11.8901 3.66335C11.8889 3.40796 11.7377 3.12081 11.5774 2.90635C11.3464 2.59659 10.9808 2.51899 10.5937 2.5196C7.8823 2.52449 5.17151 2.52083 2.46011 2.52388C2.10252 2.52388 1.77197 2.46156 1.49425 2.22084C1.11209 1.88908 1.11762 1.35691 1.509 1.03249C1.79654 0.794204 2.1357 0.709278 2.50312 0.709278C3.85851 0.709278 5.21452 0.709278 6.56991 0.709278C8.11946 0.709278 9.66839 0.705002 11.2179 0.711111C12.1445 0.714777 12.8345 1.30315 12.8357 2.09559C12.84 5.84576 12.8375 9.59655 12.8375 13.3376C13.2854 13.1604 13.5048 12.8133 13.5054 12.1853C13.5072 8.6642 13.5097 5.14314 13.4993 1.62269L13.4986 1.62391ZM4.60133 5.26595C4.60809 4.92013 4.766 4.7625 5.10945 4.76189C6.48328 4.75822 7.8571 4.75822 9.23032 4.76189C9.60326 4.76311 9.76854 4.93235 9.771 5.29955C9.77468 5.77428 9.77653 6.24901 9.77038 6.72374C9.76547 7.08727 9.59221 7.2614 9.22479 7.26506C8.5434 7.27117 7.8614 7.2669 7.17941 7.2669C6.50785 7.2669 5.8363 7.26873 5.16475 7.26567C4.76538 7.26384 4.60625 7.11415 4.59949 6.72068C4.5915 6.23618 4.59212 5.75106 4.60072 5.26656L4.60133 5.26595Z" />
</svg>
<p class="nhsuk-u-font-size-16 autosuggestion-link">@item.Name</p>
<p class="nhsuk-u-font-size-14 autosuggestion-subtext">Catalogue</p>
</a>
</li>
}
}
66 changes: 64 additions & 2 deletions LearningHub.Nhs.WebUI/Views/Search/_SearchBar.cshtml
Original file line number Diff line number Diff line change
@@ -1,14 +1,76 @@
@model string

<form id="search" asp-controller="search" asp-action="results" method="get" role="search">
<div class="nhsuk-u-margin-bottom-5 nhsuk-header__search-form--search-results">
<div class="nhsuk-u-margin-bottom-5 nhsuk-header__search-form--search-results" style="position:relative !important">
<label class="nhsuk-label nhsuk-u-visually-hidden" for="sub-search-field">Search the learning hub</label>
<input class="nhsuk-input nhsuk-search__input" type="search" name="term" autocomplete="off" id="sub-search-field" placeholder="Search the learning hub" value="@Model">
<ul id="sub-search-field_listbox" class="nhsuk-list autosuggestion-menu" style="display:none;top: 100%;"></ul>
<button class="nhsuk-search__submit" type="submit">
<span class="nhsuk-u-visually-hidden">Search</span>
<svg class="nhsuk-icon nhsuk-icon__search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M19.71 18.29l-4.11-4.1a7 7 0 1 0-1.41 1.41l4.1 4.11a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.42zM5 10a5 5 0 1 1 5 5 5 5 0 0 1-5-5z"></path>
</svg>
</button>
</div>
</form>
</form>

<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var searchInput = document.getElementById("sub-search-field");
var suggestionsList = document.getElementById("sub-search-field_listbox");
var minLengthAutoComplete = 3;

function fetchSuggestions(term) {
var xhr = new XMLHttpRequest();
xhr.open("GET", '@Url.Action("GetAutoSuggestion", "Search")' + '?term=' + encodeURIComponent(term), true);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) {
if (xhr.responseText.trim().length > 5) {
suggestionsList.style.display = "block";
suggestionsList.innerHTML = xhr.responseText;
}
else {
closeAllLists();
}
} else {
closeAllLists();
}
};
xhr.onerror = function () {
closeAllLists();
};
xhr.send();
}

function autocomplete(input, minLength) {
if (input != null) {
input.addEventListener("input", function () {
var val = this.value;
if (val.length < minLength) {
closeAllLists();
return false;
}
fetchSuggestions(val);
});

document.addEventListener("click", function (e) {
if (!searchInput.contains(e.target)) {
suggestionsList.style.display = "none";
} else {
var val = searchInput.value;
if (val.length >= minLengthAutoComplete) {
if (suggestionsList.children.length > 0) { suggestionsList.style.display = "block"; }
}
}
});
}
}

function closeAllLists() {
suggestionsList.innerHTML = '';
suggestionsList.style.display = "none";
}

autocomplete(searchInput, minLengthAutoComplete);
});
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<form class="nhsuk-header__search-form" id="search" asp-controller="search" asp-action="results" method="get" role="search">
<label class="nhsuk-u-visually-hidden" for="search-field">Search the learning hub</label>
<input class="nhsuk-search__input" id="search-field" name="term" type="search" placeholder="Search the learning hub" autocomplete="off">
<ul id="search-field_listbox" class="nhsuk-list autosuggestion-menu" style="display:none"></ul>
<button class="nhsuk-search__submit" type="submit">
<svg class="nhsuk-icon nhsuk-icon__search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false" width="27" height="27">
<path d="M19.71 18.29l-4.11-4.1a7 7 0 1 0-1.41 1.41l4.1 4.11a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.42zM5 10a5 5 0 1 1 5 5 5 5 0 0 1-5-5z"></path>
Expand All @@ -37,3 +38,63 @@
</div>

<!-- end Searchbar -->
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var searchInput = document.getElementById("search-field");
var suggestionsList = document.getElementById("search-field_listbox");
var minLengthAutoComplete = 3;

function fetchSuggestions(term) {
var xhr = new XMLHttpRequest();
xhr.open("GET", '@Url.Action("GetAutoSuggestion", "Search")' + '?term=' + encodeURIComponent(term), true);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) {
if (xhr.responseText.trim().length > 5) {
suggestionsList.style.display = "block";
suggestionsList.innerHTML = xhr.responseText;
}
else {
closeAllLists();
}
} else {
closeAllLists();
}
};
xhr.onerror = function () {
closeAllLists();
};
xhr.send();
}

function autocomplete(input, minLength) {
if (input != null) {
input.addEventListener("input", function () {
var val = this.value;
if (val.length < minLength) {
closeAllLists();
return false;
}
fetchSuggestions(val);
});

document.addEventListener("click", function (e) {
if (!searchInput.contains(e.target)) {
suggestionsList.style.display = "none";
} else {
var val = searchInput.value;
if (val.length >= minLengthAutoComplete) {
if (suggestionsList.children.length > 0) { suggestionsList.style.display = "block"; }
}
}
});
}
}

function closeAllLists() {
suggestionsList.innerHTML = '';
suggestionsList.style.display = "none";
}

autocomplete(searchInput, minLengthAutoComplete);
});
</script>
14 changes: 14 additions & 0 deletions WebAPI/LearningHub.Nhs.API/Controllers/SearchController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,20 @@ public async Task<IActionResult> GetAllCatalogueSearchResult(AllCatalogueSearchR
return this.Ok(vm);
}

/// <summary>
/// Get AutoSuggestionResults.
/// </summary>
/// <param name="term">The term.</param>
/// <returns>The <see cref="Task"/>.</returns>
[HttpGet]
[Route("GetAutoSuggestionResult/{term}")]
public async Task<IActionResult> GetAutoSuggestionResults(string term)
{
var autosuggestionViewModel = new AutoSuggestionModel();
autosuggestionViewModel = await this.searchService.GetAutoSuggestionResultsAsync(term);
return this.Ok(autosuggestionViewModel);
}

/// <summary>
/// Get search result.
/// </summary>
Expand Down
9 changes: 5 additions & 4 deletions WebAPI/LearningHub.Nhs.API/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@
"FindWise": {
"IndexUrl": "",
"SearchUrl": "",
"CollectionIds": {
"Resource": "",
"Catalogue": ""
},
"CollectionIds": {
"Resource": "",
"Catalogue": "",
"AutoSuggestion": ""
},
"UrlSearchComponent": "rest/apps/HEE/searchers/{0}",
"UrlClickComponent": "rest/apps/HEE/searchers/hee/signals/hee/signal/click",
"Token": "",
Expand Down
Loading
Loading