From a1d749423e8be3e5fd2ec0f09594ae3ca455c8eb Mon Sep 17 00:00:00 2001 From: piedone Date: Wed, 2 Nov 2011 15:15:29 -0700 Subject: [PATCH] #18182: Implementing Autocompleted on Tags Work Item: 18182 --HG-- branch : 1.x --- .../Controllers/HomeController.cs | 7 +++ .../Modules/Orchard.Tags/Module.txt | 2 +- .../Modules/Orchard.Tags/Orchard.Tags.csproj | 4 ++ .../Modules/Orchard.Tags/ResourceManifest.cs | 6 +- .../Modules/Orchard.Tags/Scripts/Web.config | 21 +++++++ .../Scripts/orchard-tags-autocomplete.js | 57 +++++++++++++++++++ .../Orchard.Tags/Services/ITagService.cs | 8 +++ .../Orchard.Tags/Services/TagService.cs | 5 ++ .../Styles/orchard-tags-admin.css | 2 +- .../Views/EditorTemplates/Parts/Tags.cshtml | 19 ++++++- 10 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.Tags/Scripts/Web.config create mode 100644 src/Orchard.Web/Modules/Orchard.Tags/Scripts/orchard-tags-autocomplete.js diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs b/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs index 4e120966e..a40c7b3b3 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Controllers/HomeController.cs @@ -63,5 +63,12 @@ namespace Orchard.Tags.Controllers { return View(viewModel); } + + public JsonResult FetchSimilarTags(string snippet) { + return Json( + _tagService.GetTagsByNameSnippet(snippet).Select(tag => tag.TagName).ToList(), + JsonRequestBehavior.AllowGet + ); + } } } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Module.txt b/src/Orchard.Web/Modules/Orchard.Tags/Module.txt index 0cfc09978..9f1ed7939 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Module.txt +++ b/src/Orchard.Web/Modules/Orchard.Tags/Module.txt @@ -8,7 +8,7 @@ Features: Orchard.Tags: Name: Tags Description: The tags module is providing basic tagging for arbitrary content types. - Dependencies: Settings + Dependencies: Settings, Orchard.jQuery Category: Navigation Orchard.Tags.Projections: Name: Tags Projections diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj index ddf5077d2..2cb550db0 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj +++ b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj @@ -82,6 +82,7 @@ + @@ -117,6 +118,9 @@ + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Scripts/orchard-tags-autocomplete.js b/src/Orchard.Web/Modules/Orchard.Tags/Scripts/orchard-tags-autocomplete.js new file mode 100644 index 000000000..0c3ad75e5 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Tags/Scripts/orchard-tags-autocomplete.js @@ -0,0 +1,57 @@ +(function ($) { + $.extend({ + tagsAutocomplete: { + minSnippetLength: 3, + + autocomplete: function (textboxId, fetchUrl, minSnippetLength) { + if (minSnippetLength != null) this.minSnippetLength = minSnippetLength; + + function split(val) { + return val.split(/,\s*/); + } + function extractLast(snippet) { + return split(snippet).pop(); + } + + var that = this; + var textBox = $('#' + textboxId); + + textBox.bind('keydown', function (event) { + // don't navigate away from the field on tab when selecting an item + if (event.keyCode === $.ui.keyCode.TAB && $(this).data('autocomplete').menu.active) { + event.preventDefault(); + } + }).autocomplete({ + source: function (request, response) { + $.getJSON(fetchUrl, { + snippet: extractLast(request.term) + }, response); + }, + appendTo: textBox.parent(), + search: function () { + // custom minLength + var snippet = extractLast(this.value); + if (snippet.length < that.minSnippetLength) { + return false; + } + }, + focus: function () { + // prevent value inserted on focus + return false; + }, + select: function (event, ui) { + var snippets = split(this.value); + // remove the current input + snippets.pop(); + // add the selected item + snippets.push(ui.item.value); + // add placeholder to get the comma-and-space at the end + snippets.push(''); + this.value = snippets.join(', '); + return false; + } + }); + } + } + }); +})(jQuery); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs index 10208db39..890678fb9 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/ITagService.cs @@ -5,6 +5,14 @@ using Orchard.Tags.Models; namespace Orchard.Tags.Services { public interface ITagService : IDependency { IEnumerable GetTags(); + + /// + /// Returns tags whose name start with snippet + /// + /// The starting snippet + /// Maximum number of tags returned + /// Tags found + IEnumerable GetTagsByNameSnippet(string snippet, int maxCount = 10); TagRecord GetTag(int tagId); TagRecord GetTagByName(string tagName); IEnumerable GetTaggedContentItems(int tagId); diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs index 31ad4b681..fdac31923 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/TagService.cs @@ -41,6 +41,11 @@ namespace Orchard.Tags.Services { return _tagRepository.Table.ToList(); } + public IEnumerable GetTagsByNameSnippet(string snippet, int maxCount = 10) { + if (String.IsNullOrEmpty(snippet)) return null; // Otherwise would return the whole dataset + return _tagRepository.Fetch(tag => tag.TagName.StartsWith(snippet)).Take(maxCount); + } + public TagRecord GetTag(int tagId) { return _tagRepository.Get(x => x.Id == tagId); } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Styles/orchard-tags-admin.css b/src/Orchard.Web/Modules/Orchard.Tags/Styles/orchard-tags-admin.css index edf2945a1..3efcbfd0c 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Styles/orchard-tags-admin.css +++ b/src/Orchard.Web/Modules/Orchard.Tags/Styles/orchard-tags-admin.css @@ -8,4 +8,4 @@ } .orchard-tags .manage label[for=TagName] { display:none; -} \ No newline at end of file +} diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/Tags.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/Tags.cshtml index a768df01d..33456be14 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/Tags.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/Tags.cshtml @@ -1,6 +1,23 @@ @model Orchard.Tags.ViewModels.EditTagsViewModel +@{ + Style.Require("jQueryUI_Orchard"); + Script.Require("TagsAutocomplete"); +} +
@Html.LabelFor(m => m.Tags, T("Tags")) @Html.TextBoxFor(m => m.Tags, new { @class = "large text" }) -
\ No newline at end of file + + +@using (Script.Foot()) { + +} \ No newline at end of file