From 4e5b909329a50dbb9d941fc23875b876c08c09c4 Mon Sep 17 00:00:00 2001 From: akdalin Date: Wed, 5 Mar 2025 16:10:12 +0000 Subject: [PATCH 1/4] Create Button View, ViewComponent and Model --- .../ViewComponents/ButtonViewComponent.cs | 18 +++++++++++ .../ViewModels/ButtonViewModel.cs | 30 +++++++++++++++++++ .../Shared/Components/Button/Default.cshtml | 6 ++++ 3 files changed, 54 insertions(+) create mode 100644 DotnetViewComponents/ViewComponents/ButtonViewComponent.cs create mode 100644 DotnetViewComponents/ViewModels/ButtonViewModel.cs create mode 100644 DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml diff --git a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs new file mode 100644 index 0000000000..d6092ba0e2 --- /dev/null +++ b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs @@ -0,0 +1,18 @@ +namespace DotnetViewComponents.ViewComponents +{ + using Microsoft.AspNetCore.Mvc; + using DotnetViewComponents.ViewModels; + + public class ButtonViewComponent : ViewComponent + { + public IViewComponentResult Invoke( + string text, + string styling = ButtonStyle.PRIMARY, + bool preventDoubleClick = false) + { + var model = new ButtonViewModel(text, styling, preventDoubleClick); + + return View(model); + } + } +} diff --git a/DotnetViewComponents/ViewModels/ButtonViewModel.cs b/DotnetViewComponents/ViewModels/ButtonViewModel.cs new file mode 100644 index 0000000000..b87734bc66 --- /dev/null +++ b/DotnetViewComponents/ViewModels/ButtonViewModel.cs @@ -0,0 +1,30 @@ +namespace DotnetViewComponents.ViewModels +{ + public class ButtonViewModel + { + public ButtonViewModel( + string text, + string styling = ButtonStyle.PRIMARY, + bool preventDoubleClick = false) + { + Text = text; + Styling = styling; + PreventDoubleClick = preventDoubleClick; + } + + public string Text { get; set; } + + public string Styling { get; set; } + + public bool PreventDoubleClick { get; set; } + + } + + public static class ButtonStyle + { + public const string PRIMARY = "nhsuk-button"; + public const string SECONDARY = "nhsuk-button nhsuk-button--secondary"; + public const string REVERSE = "nhsuk-button nhsuk-button--reverse"; + public const string WARNING = "nhsuk-button nhsuk-button--warning"; + } +} diff --git a/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml b/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml new file mode 100644 index 0000000000..7b7e193dff --- /dev/null +++ b/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml @@ -0,0 +1,6 @@ +@using DotnetViewComponents.ViewModels +@model ButtonViewModel + + From 911621e08695a92367c834cb6d315ebc5e450d3a Mon Sep 17 00:00:00 2001 From: akdalin Date: Wed, 12 Mar 2025 16:04:30 +0000 Subject: [PATCH 2/4] Document code --- .../ViewComponents/ButtonViewComponent.cs | 10 ++++++++++ .../ViewModels/ButtonViewModel.cs | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs index d6092ba0e2..645e00584d 100644 --- a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs +++ b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs @@ -3,8 +3,18 @@ namespace DotnetViewComponents.ViewComponents using Microsoft.AspNetCore.Mvc; using DotnetViewComponents.ViewModels; + /// + /// Represents a view component for rendering a button. + /// public class ButtonViewComponent : ViewComponent { + /// + /// Invokes the button view component with the specified parameters. + /// + /// The text to be displayed on the button. + /// The styling class for the button. Receives predefined styles from . Defaults to if no input is passed to it. + /// Indicates whether to prevent double-clicking the button. Defaults to false. + /// An that renders the button view. public IViewComponentResult Invoke( string text, string styling = ButtonStyle.PRIMARY, diff --git a/DotnetViewComponents/ViewModels/ButtonViewModel.cs b/DotnetViewComponents/ViewModels/ButtonViewModel.cs index b87734bc66..74dcfc612f 100644 --- a/DotnetViewComponents/ViewModels/ButtonViewModel.cs +++ b/DotnetViewComponents/ViewModels/ButtonViewModel.cs @@ -2,6 +2,12 @@ namespace DotnetViewComponents.ViewModels { public class ButtonViewModel { + /// + /// Initializes a new instance of the class. + /// + /// The text to be displayed on the button. + /// The styling class for the button. Defaults to . + /// Indicates whether to prevent double-clicking the button. Defaults to false. public ButtonViewModel( string text, string styling = ButtonStyle.PRIMARY, @@ -12,10 +18,19 @@ public ButtonViewModel( PreventDoubleClick = preventDoubleClick; } + /// + /// Gets or sets the text displayed on the button. + /// public string Text { get; set; } + /// + /// Gets or sets the styling for the button. + /// public string Styling { get; set; } + /// + /// Gets or sets a value indicating whether to prevent double-clicking the button. + /// public bool PreventDoubleClick { get; set; } } From 504e6954f41adbb743daf745a324f2653f361aa2 Mon Sep 17 00:00:00 2001 From: akdalin Date: Fri, 25 Apr 2025 18:03:39 +0100 Subject: [PATCH 3/4] Add ability to have a traditional button or a link styled as a button. Add ability to add custom inline css attributes --- .../ViewComponents/ButtonViewComponent.cs | 6 +++++- .../ViewModels/ButtonViewModel.cs | 20 +++++++++++++++++-- .../Shared/Components/Button/Default.cshtml | 18 ++++++++++++++--- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs index 645e00584d..fa6d3919f7 100644 --- a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs +++ b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs @@ -12,15 +12,19 @@ public class ButtonViewComponent : ViewComponent /// Invokes the button view component with the specified parameters. /// /// The text to be displayed on the button. + /// The url for the link. + /// The style attributes for the button.The style attributes for the button. /// The styling class for the button. Receives predefined styles from . Defaults to if no input is passed to it. /// Indicates whether to prevent double-clicking the button. Defaults to false. /// An that renders the button view. public IViewComponentResult Invoke( string text, + string style, string styling = ButtonStyle.PRIMARY, + string? url = null, bool preventDoubleClick = false) { - var model = new ButtonViewModel(text, styling, preventDoubleClick); + var model = new ButtonViewModel(text, url, styling, style, preventDoubleClick); return View(model); } diff --git a/DotnetViewComponents/ViewModels/ButtonViewModel.cs b/DotnetViewComponents/ViewModels/ButtonViewModel.cs index 74dcfc612f..cf87827676 100644 --- a/DotnetViewComponents/ViewModels/ButtonViewModel.cs +++ b/DotnetViewComponents/ViewModels/ButtonViewModel.cs @@ -6,15 +6,21 @@ public class ButtonViewModel /// Initializes a new instance of the class. /// /// The text to be displayed on the button. + /// The url for the link. + /// The style attributes for the button. /// The styling class for the button. Defaults to . /// Indicates whether to prevent double-clicking the button. Defaults to false. public ButtonViewModel( string text, - string styling = ButtonStyle.PRIMARY, - bool preventDoubleClick = false) + string url, + string styling, + string style, + bool preventDoubleClick) { Text = text; + Url = url; Styling = styling; + Style = style; PreventDoubleClick = preventDoubleClick; } @@ -23,11 +29,21 @@ public ButtonViewModel( /// public string Text { get; set; } + /// + /// Gets or sets the url of the link. + /// + public string Url { get; set; } + /// /// Gets or sets the styling for the button. /// public string Styling { get; set; } + /// + /// Gets or sets the style attributes on the button. + /// + public string Style { get; set; } + /// /// Gets or sets a value indicating whether to prevent double-clicking the button. /// diff --git a/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml b/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml index 7b7e193dff..2b42815829 100644 --- a/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml +++ b/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml @@ -1,6 +1,18 @@ @using DotnetViewComponents.ViewModels @model ButtonViewModel - +@{ + var isLink = !String.IsNullOrWhiteSpace(Model.Url); + var tagType = isLink ? "a" : "button"; + var canSubmit = isLink ? "role=\"button\"" : "type =\"submit\""; + var undecorate = isLink ? "text-decoration: none;" : ""; + var url = isLink ? $"href=\"{Model.Url}\"" : ""; + var preventDoubleClick = @Model.PreventDoubleClick ? "data-prevent-double-click=true" : ""; + + var buttonOpening = $"<{tagType} class=\"{Model.Styling}\" data-module=\"nhsuk-button\" {url} {preventDoubleClick} {canSubmit} style=\"{undecorate}{Model.Style}\">"; + var buttonClosing = $""; +} + +@Html.Raw(buttonOpening) + @Model.Text +@Html.Raw(buttonClosing) From 7846e7b0691b5503d311d9f44a82a6ad7d76839f Mon Sep 17 00:00:00 2001 From: akdalin Date: Thu, 1 May 2025 09:30:13 +0100 Subject: [PATCH 4/4] Replace URL with dynamic asp parameters --- .../ViewComponents/ButtonViewComponent.cs | 9 +++++-- .../ViewModels/ButtonViewModel.cs | 25 ++++++++++++++++--- .../Shared/Components/Button/Default.cshtml | 7 +++--- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs index fa6d3919f7..d03162ec02 100644 --- a/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs +++ b/DotnetViewComponents/ViewComponents/ButtonViewComponent.cs @@ -12,6 +12,9 @@ public class ButtonViewComponent : ViewComponent /// Invokes the button view component with the specified parameters. /// /// The text to be displayed on the button. + /// The asp-controller to dynamically set the controller path of the link. + /// The asp-action to dynamically set the action path of the link.. + /// The asp-all-route-data to dynamically set the extra parameters to the path of the link. /// The url for the link. /// The style attributes for the button.The style attributes for the button. /// The styling class for the button. Receives predefined styles from . Defaults to if no input is passed to it. @@ -21,10 +24,12 @@ public IViewComponentResult Invoke( string text, string style, string styling = ButtonStyle.PRIMARY, - string? url = null, + string aspController = null, + string aspAction = null, + Dictionary aspRouteData = null, bool preventDoubleClick = false) { - var model = new ButtonViewModel(text, url, styling, style, preventDoubleClick); + var model = new ButtonViewModel(text, aspController, aspAction, aspRouteData, styling, style, preventDoubleClick); return View(model); } diff --git a/DotnetViewComponents/ViewModels/ButtonViewModel.cs b/DotnetViewComponents/ViewModels/ButtonViewModel.cs index cf87827676..583bc333c9 100644 --- a/DotnetViewComponents/ViewModels/ButtonViewModel.cs +++ b/DotnetViewComponents/ViewModels/ButtonViewModel.cs @@ -6,19 +6,26 @@ public class ButtonViewModel /// Initializes a new instance of the class. /// /// The text to be displayed on the button. + /// The asp-controller to dynamically set the controller path of the link. + /// The asp-action to dynamically set the action path of the link.. + /// The asp-all-route-data to dynamically set the extra parameters to the path of the link. /// The url for the link. /// The style attributes for the button. /// The styling class for the button. Defaults to . /// Indicates whether to prevent double-clicking the button. Defaults to false. public ButtonViewModel( string text, - string url, + string aspController, + string aspAction, + Dictionary aspRouteData, string styling, string style, bool preventDoubleClick) { Text = text; - Url = url; + AspController = aspController; + AspAction = aspAction; + AspRouteData = aspRouteData; Styling = styling; Style = style; PreventDoubleClick = preventDoubleClick; @@ -30,9 +37,19 @@ public ButtonViewModel( public string Text { get; set; } /// - /// Gets or sets the url of the link. + /// Gets or sets the asp-controller of the link. /// - public string Url { get; set; } + public string AspController { get; set; } + + /// + /// Gets or sets the as-action of the link. + /// + public string AspAction { get; set; } + + /// + /// Gets or sets the asp-all-route-data of the link. + /// + public Dictionary AspRouteData { get; set; } /// /// Gets or sets the styling for the button. diff --git a/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml b/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml index 2b42815829..6562500906 100644 --- a/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml +++ b/DotnetViewComponents/Views/Shared/Components/Button/Default.cshtml @@ -2,14 +2,15 @@ @model ButtonViewModel @{ - var isLink = !String.IsNullOrWhiteSpace(Model.Url); + var isLink = !String.IsNullOrWhiteSpace(Model.AspController); var tagType = isLink ? "a" : "button"; var canSubmit = isLink ? "role=\"button\"" : "type =\"submit\""; var undecorate = isLink ? "text-decoration: none;" : ""; - var url = isLink ? $"href=\"{Model.Url}\"" : ""; + var url = Url.Action(Model.AspAction, Model.AspController, Model.AspRouteData); + var href = isLink ? $"href=\"{url}\"" : ""; var preventDoubleClick = @Model.PreventDoubleClick ? "data-prevent-double-click=true" : ""; - var buttonOpening = $"<{tagType} class=\"{Model.Styling}\" data-module=\"nhsuk-button\" {url} {preventDoubleClick} {canSubmit} style=\"{undecorate}{Model.Style}\">"; + var buttonOpening = $"<{tagType} class=\"{Model.Styling}\" data-module=\"nhsuk-button\" {href} {preventDoubleClick} {canSubmit} style=\"{undecorate}{Model.Style}\">"; var buttonClosing = $""; }