Skip to content

Commit c0e3747

Browse files
authored
[release/8.0] Fix "Blazor enhanced form handling doesn't honor button formaction attribute" (#52220)
# [release 8.0] Fix "Blazor enhanced form handling doesn't honor button formaction attribute" Manual backport of #51895 ## Description This PR fixes Blazor enhanced form honoring submit button's `formaction` attribute ```html <form data-enhance action="test-action"> <button type="submit" formaction="test-formaction">Submit to formaction url</button> </form> ``` Workaround is to remove `data-enhance` attribute. Fixes #51734 ## Customer Impact Without this change customers will have bad experience using enhanced form that has a button with `formaction` attribute. The attribute will not be honored. ## Regression? - [ ] Yes - [x] No [If yes, specify the version the behavior has regressed from] ## Risk - [ ] High - [ ] Medium - [x] Low This is a minor change. There are unit and e2e tests for this change. ## Verification - [x] Manual (required) - [x] Automated ## Packaging changes reviewed? - [ ] Yes - [ ] No - [x] N/A ---- ## When servicing release/2.1 - [ ] Make necessary changes in eng/PatchConfig.props
1 parent d8acc61 commit c0e3747

File tree

5 files changed

+31
-6
lines changed

5 files changed

+31
-6
lines changed

src/Components/Web.JS/dist/Release/blazor.web.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Services/NavigationEnhancement.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,20 @@ function onDocumentSubmit(event: SubmitEvent) {
118118

119119
event.preventDefault();
120120

121-
const url = new URL(formElem.action);
121+
let url = new URL(formElem.action);
122122
const fetchOptions: RequestInit = { method: formElem.method };
123123
const formData = new FormData(formElem);
124-
125-
// Replicate the normal behavior of appending the submitter name/value to the form data
124+
126125
const submitter = event.submitter as HTMLButtonElement;
127-
if (submitter && submitter.name) {
128-
formData.append(submitter.name, submitter.value);
126+
if (submitter) {
127+
if (submitter.name) {
128+
// Replicate the normal behavior of appending the submitter name/value to the form data
129+
formData.append(submitter.name, submitter.value);
130+
}
131+
if (submitter.getAttribute("formaction") !== null) {
132+
// Replicate the normal behavior of overriding action attribute of form element
133+
url = new URL(submitter.formAction);
134+
}
129135
}
130136

131137
if (fetchOptions.method === 'get') { // method is always returned as lowercase

src/Components/test/E2ETest/ServerRenderingTests/FormHandlingTests/FormWithParentBindingContextTest.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,17 @@ void AssertUiState(string expectedStringValue, bool expectedBoolValue)
13371337
}
13381338
}
13391339

1340+
[Fact]
1341+
public void SubmitButtonFormactionAttributeOverridesEnhancedFormAction()
1342+
{
1343+
GoTo("forms/form-submit-button-with-formaction");
1344+
1345+
Browser.Exists(By.Id("submit-button")).Click();
1346+
1347+
Assert.EndsWith("/test-formaction", Browser.Url);
1348+
Browser.Equal("Formaction url", () => Browser.Exists(By.TagName("html")).Text);
1349+
}
1350+
13401351
// Can't just use GetAttribute or GetDomAttribute because they both auto-resolve it
13411352
// to an absolute URL. We want to be able to assert about the attribute's literal value.
13421353
private string ReadFormActionAttribute(IWebElement form)

src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ private static void MapEnhancedNavigationEndpoints(IEndpointRouteBuilder endpoin
173173
return Task.Delay(Timeout.Infinite, token);
174174
});
175175

176+
endpoints.Map("/test-formaction", () => "Formaction url");
177+
176178
static Task PerformRedirection(HttpRequest request, HttpResponse response)
177179
{
178180
response.Redirect(request.Query["external"] == "true"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@page "/forms/form-submit-button-with-formaction"
2+
<h1>Form Submit Button with formaction</h1>
3+
4+
<form data-enhance action="test-action">
5+
<button type="submit" formaction="test-formaction" id="submit-button">Submit to formaction url</button>
6+
</form>

0 commit comments

Comments
 (0)