From 46e7c6f495d5b928886738e42ce1dc434ac408ff Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 14 May 2011 00:49:57 -0700 Subject: [PATCH] Added auto completion on General Settings for RootDir settings using jQuery UI. --- NzbDrone.Web/Content/jquery-ui.custom.css | 36 +++++++++++++ .../Controllers/SettingsController.cs | 52 ++++++++++++++++++- NzbDrone.Web/NzbDrone.Web.csproj | 3 ++ NzbDrone.Web/Views/Settings/General.cshtml | 7 +++ NzbDrone.Web/Views/Settings/RootDir.cshtml | 2 +- 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Web/Content/jquery-ui.custom.css b/NzbDrone.Web/Content/jquery-ui.custom.css index ab1742531..6201a1cdd 100644 --- a/NzbDrone.Web/Content/jquery-ui.custom.css +++ b/NzbDrone.Web/Content/jquery-ui.custom.css @@ -15,3 +15,39 @@ { margin-top: 2px; } + +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/SettingsController.cs b/NzbDrone.Web/Controllers/SettingsController.cs index ba082c650..6b517627d 100644 --- a/NzbDrone.Web/Controllers/SettingsController.cs +++ b/NzbDrone.Web/Controllers/SettingsController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Web.Mvc; using NLog; @@ -27,10 +28,12 @@ namespace NzbDrone.Web.Controllers private readonly RootDirProvider _rootDirProvider; private readonly AutoConfigureProvider _autoConfigureProvider; private readonly NotificationProvider _notificationProvider; + private readonly DiskProvider _diskProvider; public SettingsController(ConfigProvider configProvider, IndexerProvider indexerProvider, QualityProvider qualityProvider, RootDirProvider rootDirProvider, - AutoConfigureProvider autoConfigureProvider, NotificationProvider notificationProvider) + AutoConfigureProvider autoConfigureProvider, NotificationProvider notificationProvider, + DiskProvider diskProvider) { _configProvider = configProvider; _indexerProvider = indexerProvider; @@ -38,6 +41,7 @@ namespace NzbDrone.Web.Controllers _rootDirProvider = rootDirProvider; _autoConfigureProvider = autoConfigureProvider; _notificationProvider = notificationProvider; + _diskProvider = diskProvider; } public ActionResult Index(string viewName) @@ -313,6 +317,52 @@ namespace NzbDrone.Web.Controllers } } + public ActionResult AutoCompletePath(string path) + { + var windowsSep = path.LastIndexOf('\\'); + + if (windowsSep > -1) + { + var start = path.Substring(windowsSep + 1); + var dirs = _diskProvider.GetDirectories(path.Substring(0, windowsSep + 1)).Where(d => new DirectoryInfo(d).Name.ToLower().StartsWith(start.ToLower())); + return Content(String.Join("\n", dirs)); + } + + var index = path.LastIndexOf('/'); + + if (index > -1) + { + var start = path.Substring(index + 1); + var dirs = _diskProvider.GetDirectories(path.Substring(0, index + 1)).Where(d => new DirectoryInfo(d).Name.ToLower().StartsWith(start.ToLower())); + return Content(String.Join("\n", dirs)); + } + + return Content(""); + } + + public JsonResult JsonAutoCompletePath(string term) + { + var windowsSep = term.LastIndexOf('\\'); + + if (windowsSep > -1) + { + var start = term.Substring(windowsSep + 1); + var dirs = _diskProvider.GetDirectories(term.Substring(0, windowsSep + 1)).Where(d => new DirectoryInfo(d).Name.ToLower().StartsWith(start.ToLower())).Take(10); + return Json(dirs.ToArray(), JsonRequestBehavior.AllowGet); + } + + var index = term.LastIndexOf('/'); + + if (index > -1) + { + var start = term.Substring(index + 1); + var dirs = _diskProvider.GetDirectories(term.Substring(0, index + 1)).Where(d => new DirectoryInfo(d).Name.ToLower().StartsWith(start.ToLower())).Take(10); + return Json(dirs.ToArray(), JsonRequestBehavior.AllowGet); + } + + return Json(new JsonResult(), JsonRequestBehavior.AllowGet); + } + [HttpPost] public ActionResult SaveGeneral(SettingsModel data) { diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 9a8ec4cc3..4a3bea3bf 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -573,6 +573,7 @@ + @@ -596,6 +597,7 @@ + @@ -637,6 +639,7 @@ + diff --git a/NzbDrone.Web/Views/Settings/General.cshtml b/NzbDrone.Web/Views/Settings/General.cshtml index 226c60317..e24e8b1d9 100644 --- a/NzbDrone.Web/Views/Settings/General.cshtml +++ b/NzbDrone.Web/Views/Settings/General.cshtml @@ -11,6 +11,13 @@ }; $('#form').ajaxForm(options); $('#save_button').attr('disabled', ''); + + $(".root_dir_text").autocomplete({ url: '@Url.Action("AutoCompletePath", "Settings")', paramName: 'path', minChars: 3, delay: 300, maxCacheLength: 1 }); + + $(".root_dir_text").autocomplete({ + source: '@Url.Action("JsonAutoCompletePath", "Settings")', + minLength: 3 + }); }); function showRequest(formData, jqForm, options) { diff --git a/NzbDrone.Web/Views/Settings/RootDir.cshtml b/NzbDrone.Web/Views/Settings/RootDir.cshtml index cd5ccee22..65df3ab13 100644 --- a/NzbDrone.Web/Views/Settings/RootDir.cshtml +++ b/NzbDrone.Web/Views/Settings/RootDir.cshtml @@ -19,7 +19,7 @@
-
+
@Html.TextBoxFor(m => m.Path, new { @class = "root_dir_text" }) Delete