From a1e3142d84032596f189cdb23d3fdeaec36de83b Mon Sep 17 00:00:00 2001 From: mishogv Date: Mon, 4 Sep 2023 17:03:02 +0300 Subject: [PATCH 1/3] Implement support for injecting scirpts with action attribute. --- .../Attributes/InjectScriptsAttribute.cs | 52 +++++++++++++++++++ .../Views/AutoCrudAdmin/EntityForm.cshtml | 7 ++- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs diff --git a/src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs b/src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs new file mode 100644 index 0000000..5627fa3 --- /dev/null +++ b/src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs @@ -0,0 +1,52 @@ +namespace AutoCrudAdmin.Attributes +{ + using System; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Filters; + + /// + /// An attribute that injects a script into the EntityForm view. + /// The script is loaded as a module. + /// The script path starts from the currently running application static files folder location. + /// Correct value: "/js/entities/manualJobs/create.js". + /// Wrong value: "wwwroot/js/entities/manualJobs/create.js". + /// + public class InjectScriptsAttribute : Attribute, IActionFilter + { + private readonly string scriptPath; + + /// + /// Initializes a new instance of the class. + /// + /// The path to the script to inject. + public InjectScriptsAttribute(string scriptPath) + { + this.scriptPath = scriptPath; + } + + /// + public void OnActionExecuting(ActionExecutingContext context) + { + this.AddScriptToViewData(context); + } + + /// + public void OnActionExecuted(ActionExecutedContext context) + { + } + + /// + /// Adds the script path to the view data. And the view will load the script as module. + /// + /// The action executing context. + private void AddScriptToViewData(ActionExecutingContext context) + { + var controller = context.Controller as Controller; + + if (controller?.ViewData != null) + { + controller.ViewData["AdditionalScriptPath"] = this.scriptPath; + } + } + } +} \ No newline at end of file diff --git a/src/AutoCrudAdmin/Views/AutoCrudAdmin/EntityForm.cshtml b/src/AutoCrudAdmin/Views/AutoCrudAdmin/EntityForm.cshtml index 12b3cf8..7e8e1ae 100644 --- a/src/AutoCrudAdmin/Views/AutoCrudAdmin/EntityForm.cshtml +++ b/src/AutoCrudAdmin/Views/AutoCrudAdmin/EntityForm.cshtml @@ -3,6 +3,7 @@ @{ Layout = ViewBag.LayoutName; var aspAction = Model.CustomActionName ?? $"Post{ViewContext.RouteData.Values["action"]}"; + var additionalScriptPath = this.ViewData["AdditionalScriptPath"] as string; }
@@ -23,4 +24,8 @@ : $(`#${expandElementId}`).addClass('d-none'); }); }); - \ No newline at end of file + + +@Html.Raw(additionalScriptPath != null + ? $"" + : null) \ No newline at end of file From aa672d499b6487ff1f1e5426aca7f3ef6c68a5d0 Mon Sep 17 00:00:00 2001 From: mishogv Date: Mon, 4 Sep 2023 17:23:33 +0300 Subject: [PATCH 2/3] Rename attribute name in singular form --- .../{InjectScriptsAttribute.cs => InjectScriptAttribute.cs} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/AutoCrudAdmin/Attributes/{InjectScriptsAttribute.cs => InjectScriptAttribute.cs} (91%) diff --git a/src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs b/src/AutoCrudAdmin/Attributes/InjectScriptAttribute.cs similarity index 91% rename from src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs rename to src/AutoCrudAdmin/Attributes/InjectScriptAttribute.cs index 5627fa3..95d5a6c 100644 --- a/src/AutoCrudAdmin/Attributes/InjectScriptsAttribute.cs +++ b/src/AutoCrudAdmin/Attributes/InjectScriptAttribute.cs @@ -11,15 +11,15 @@ namespace AutoCrudAdmin.Attributes /// Correct value: "/js/entities/manualJobs/create.js". /// Wrong value: "wwwroot/js/entities/manualJobs/create.js". /// - public class InjectScriptsAttribute : Attribute, IActionFilter + public class InjectScriptAttribute : Attribute, IActionFilter { private readonly string scriptPath; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The path to the script to inject. - public InjectScriptsAttribute(string scriptPath) + public InjectScriptAttribute(string scriptPath) { this.scriptPath = scriptPath; } From 283ddab88be3436483411eea78a9cc7b457be752 Mon Sep 17 00:00:00 2001 From: mishogv Date: Wed, 13 Sep 2023 19:10:49 +0300 Subject: [PATCH 3/3] Add docs and implement injecting in index view --- .../Controllers/TasksController.cs | 8 +++ .../wwwroot/js/tasks.js | 4 ++ docs/README.md | 15 ++++ docs/inject-script-attribute.md | 71 +++++++++++++++++++ .../Views/AutoCrudAdmin/Index.cshtml | 5 ++ 5 files changed, 103 insertions(+) create mode 100644 demo/AutoCrudAdmin.Demo.SqlServer/wwwroot/js/tasks.js create mode 100644 docs/inject-script-attribute.md diff --git a/demo/AutoCrudAdmin.Demo.SqlServer/Controllers/TasksController.cs b/demo/AutoCrudAdmin.Demo.SqlServer/Controllers/TasksController.cs index b4bde86..8847c28 100644 --- a/demo/AutoCrudAdmin.Demo.SqlServer/Controllers/TasksController.cs +++ b/demo/AutoCrudAdmin.Demo.SqlServer/Controllers/TasksController.cs @@ -5,7 +5,9 @@ namespace AutoCrudAdmin.Demo.SqlServer.Controllers; using System.Linq; using AutoCrudAdmin.Controllers; using AutoCrudAdmin.Demo.Models.Models; +using AutoCrudAdmin.Attributes; using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Mvc; public class TasksController : AutoCrudAdminController @@ -37,6 +39,12 @@ protected override IEnumerable DateTimeFormats "MM/dd/yyyy hh:mm:ss tt", }; + [InjectScript("/js/tasks.js")] + public override IActionResult Index() + { + return base.Index(); + } + protected override IQueryable ApplyIncludes(IQueryable set) => set.Include(x => x.Project); } \ No newline at end of file diff --git a/demo/AutoCrudAdmin.Demo.SqlServer/wwwroot/js/tasks.js b/demo/AutoCrudAdmin.Demo.SqlServer/wwwroot/js/tasks.js new file mode 100644 index 0000000..9738c56 --- /dev/null +++ b/demo/AutoCrudAdmin.Demo.SqlServer/wwwroot/js/tasks.js @@ -0,0 +1,4 @@ +(function(){ + [...document.getElementsByTagName("td")] + .forEach((td,index)=> td.style.color = index % 2 === 0 ? "red" : "green") +})() \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index ab7fd44..5c2381e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -205,6 +205,21 @@ protected override IEnumerable HiddenFormControlNames {..} See [API Reference](https://github.com/minkov/autocrudadmin/blob/master/src/AutoCrudAdmin/Controllers/AutoCrudAdminController.cs) for full customization options. +### Inject Scripts in endpoints + +The InjectScript attribute allows modular JavaScript injection into views by specifying the script path in the controller action. + +Usage example: +```csharp +[InjectScript("/js/tasks.js")] +public override IActionResult Index() +{ + return base.Index(); +} +``` + +See [Injecting Scripts](inject-script-attribute.md) for more details and options. + ## Troubleshooting Some common issues: diff --git a/docs/inject-script-attribute.md b/docs/inject-script-attribute.md new file mode 100644 index 0000000..146020f --- /dev/null +++ b/docs/inject-script-attribute.md @@ -0,0 +1,71 @@ +# The InjectScript attribute + +The InjectScript attribute is an integral part of the AutoCrudAdmin framework, designed to enhance the EntityForm view by injecting custom JavaScript modules. This attribute allows developers to add client-side logic to the form without modifying the core files. It leverages the power of ASP.NET Core's MVC filters to inject the script automatically. + +# Problem Statement + +Customizing the behavior of an entity form usually requires modifications to the base HTML or JavaScript files, making it hard to manage and update. This traditional method is cumbersome, prone to errors, and not modular. + +# Traditional Methods and Drawbacks + +- Inline Scripting: Embedding JavaScript directly into the HTML. This is not modular and makes the HTML file bulky. + +- Global Script Files: Adding custom logic in a global JavaScript file, making it hard to manage and leading to potential conflicts. + +- Manual Injection: Manually adding ` + +@Html.Raw(additionalScriptPath != null + ? $"" + : null) \ No newline at end of file