| | 1 | | @inherits TELComponentBase |
| | 2 | | @implements IAccessibleComponent |
| | 3 | | @inject ILogger<TELButton> Logger |
| | 4 | |
|
| 18 | 5 | | @if (IsSubmitButtonForEditForm) |
| 0 | 6 | | { |
| | 7 | | <TELButtonSubComponent |
| | 8 | | ButtonStyle="@ButtonStyle" |
| | 9 | | ButtonText="@ButtonText" |
| | 10 | | AriaLabel="@AriaLabel" |
| | 11 | | AssistiveText="@AssistiveText" |
| | 12 | | TabIndex="@TabIndex" |
| | 13 | | ToolTipTitle="@ToolTipTitle" |
| | 14 | | AdditionalCssClasses="@AdditionalCssClasses" |
| | 15 | | PreventDoubleClick="@PreventDoubleClick" |
| | 16 | | /> |
| 0 | 17 | | } |
| | 18 | | else |
| 18 | 19 | | { |
| | 20 | | @*FormData as the model doesnt really mean anything were not using it if its blazor*@ |
| | 21 | | <EditForm |
| | 22 | | Model="FormData" |
| | 23 | | OnSubmit="HandleClick" |
| | 24 | | action="@NoJSActionUrl" |
| | 25 | | role="form" |
| | 26 | | tabindex="-1" |
| | 27 | | method="post"> |
| 90 | 28 | | @foreach (var keyValuePair in FormData) |
| 18 | 29 | | { |
| | 30 | | <input tabindex="-1" type="hidden" name="@keyValuePair.Key" value="@keyValuePair.Value" /> |
| 18 | 31 | | } |
| | 32 | | <TELButtonSubComponent |
| | 33 | | ButtonStyle="@ButtonStyle" |
| | 34 | | ButtonText="@ButtonText" |
| | 35 | | AriaLabel="@AriaLabel" |
| | 36 | | AssistiveText="@AssistiveText" |
| | 37 | | TabIndex="@TabIndex" |
| | 38 | | ToolTipTitle="@ToolTipTitle" |
| | 39 | | AdditionalCssClasses="@AdditionalCssClasses" |
| | 40 | | PreventDoubleClick="@PreventDoubleClick" |
| | 41 | | /> |
| | 42 | | </EditForm> |
| 18 | 43 | | } |
| | 44 | |
|
| | 45 | | @code { |
| | 46 | |
|
| | 47 | |
|
| | 48 | | // ----------------------------- |
| | 49 | | // Parameters: Behavior & State |
| | 50 | | // ----------------------------- |
| | 51 | |
|
| | 52 | | ///<summary> |
| | 53 | | /// All buttons will be submit. But if this is a submit for a form then true. |
| | 54 | | /// They all will actually be submit because for NoJS we have to put then in editform |
| | 55 | | ///</summary> |
| 54 | 56 | | [Parameter] public bool IsSubmitButtonForEditForm { get; set; } = false; |
| 72 | 57 | | [Parameter] public Dictionary<string, string> FormData { get; set; } = new(); |
| 54 | 58 | | [Parameter] public string NoJSActionUrl { get; set; } = null; // URL for the form submission (not required because t |
| 18 | 59 | | [Parameter] public EventCallback OnClick { get; set; } // Not required because the submit wont use it, when its plac |
| 54 | 60 | | [Parameter] public bool PreventDoubleClick { get; set; } = false; // View Component equivalent behaviour |
| | 61 | |
|
| | 62 | | // ----------------------------- |
| | 63 | | // Parameters: Button Display |
| | 64 | | // ----------------------------- |
| 36 | 65 | | [EditorRequired, Parameter] public required string ButtonText { get; set; } |
| 54 | 66 | | [Parameter] public TELButtonStyle ButtonStyle { get; set; } = TELButtonStyle.Primary; |
| 54 | 67 | | [Parameter] public string AdditionalCssClasses { get; set; } = ""; |
| 36 | 68 | | [EditorRequired, Parameter] public required string ToolTipTitle { get; set; } |
| | 69 | |
|
| | 70 | | // ----------------------------- |
| | 71 | | // Parameters: Accessibility |
| | 72 | | // ----------------------------- |
| | 73 | |
|
| 36 | 74 | | [EditorRequired, Parameter] public required string AriaLabel { get; set; } |
| 36 | 75 | | [EditorRequired, Parameter] public required string AssistiveText { get; set; } |
| 54 | 76 | | [EditorRequired, Parameter] public required int TabIndex { get; set; } = 0; |
| | 77 | | // These properties are public, satisfying the interface, but not a Parameter because I wanted to force it to be use |
| 18 | 78 | | public string AriaRole { get; set; } = "Button"; |
| 18 | 79 | | public string AriaDescribedBy { get; set; } = $"assistive-text-{Guid.NewGuid()}"; |
| | 80 | |
|
| | 81 | |
|
| | 82 | |
|
| | 83 | | // ----------------------------- |
| | 84 | | // Internal State |
| | 85 | | // ----------------------------- |
| 18 | 86 | | private bool isButtonDisabled = false; |
| 18 | 87 | | private bool isClickedRecently = false; |
| | 88 | |
|
| | 89 | | // ----------------------------- |
| | 90 | | // Handlers |
| | 91 | | // ----------------------------- |
| | 92 | | /// <summary> |
| | 93 | | /// The wrapped click handler that manages the prevention of double-clicking |
| | 94 | | /// Because this method is triggered by the form submit code coverage does not detect its covered |
| | 95 | | /// </summary> |
| | 96 | | [ExcludeFromCodeCoverage] |
| | 97 | | private async Task HandleClick() |
| | 98 | | { |
| | 99 | | Logger.LogInformation($"Button clicked: {ButtonText}"); |
| | 100 | |
|
| | 101 | | if (PreventDoubleClick && !isClickedRecently) |
| | 102 | | { |
| | 103 | | isClickedRecently = true; |
| | 104 | | isButtonDisabled = true; |
| | 105 | |
|
| | 106 | | if (OnClick.HasDelegate) |
| | 107 | | { |
| | 108 | | await OnClick.InvokeAsync(null); |
| | 109 | | } |
| | 110 | |
|
| | 111 | | await Task.Delay(1000); // Re-enable after 1 sec |
| | 112 | | isClickedRecently = false; |
| | 113 | | isButtonDisabled = false; |
| | 114 | | } |
| | 115 | | else if (!PreventDoubleClick && OnClick.HasDelegate) // Just call the OnClick handler if double-click prevention |
| | 116 | | { |
| | 117 | | await OnClick.InvokeAsync(null); |
| | 118 | | } |
| | 119 | | } |
| | 120 | |
|
| | 121 | | } |
| | 122 | |
|