dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.36k stars 9.99k forks source link

Blazor Form CSS: "valid" CSS should only be applied when the field has actually been validated. #18884

Open ryanelian opened 4 years ago

ryanelian commented 4 years ago

Describe the bug

Directly quoting from Bootstrap 4 Form Validation guidelines: https://getbootstrap.com/docs/4.4/components/forms/#validation

Bootstrap scopes the :invalid and :valid styles to parent .was-validated class, usually applied to the form. Otherwise, any required field without a value shows up as invalid on page load. This way, you may choose when to activate them (typically after form submission is attempted).

Contrary to that pattern / advice, Blazor sets valid CSS to all form fields BEFORE they are validated in the first place!

Unfortunately the modified CSS is also not helpful because it is not applied when the entire form is validated through submission / submit button. (We can't do .modified.valid CSS styling or something like that)

Related code: https://github.com/dotnet/aspnetcore/blob/8d46b3a64ea784c95dddeb9d421c7cda6de993a2/src/Components/Web/src/Forms/EditContextFieldClassExtensions.cs#L26-L43

Technically speaking, the form is in the state of "not valid" / "not validated" / "not known to be validated" until it is validated, so Blazor applying valid CSS to the field should be counted as bug...

If fixing this bug is not going to happen, maybe add this method to EditContext so I can roll my own field CSS method?

bool IsValidated(in FieldIdentifier)

To Reproduce

<EditForm Model="MyForm">
<InputText @bind-Value="MyForm.MyField"></InputText>
</EditForm>

Then witness in the inspect element browser window that image valid CSS is applied before the form is even touched.

Further technical details

.NET Core SDK (reflecting any global.json):
 Version:   3.1.101
 Commit:    b377529961

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.101\

Host (useful for support):
  Version: 3.1.1
  Commit:  a1388f194c

.NET Core SDKs installed:
  2.1.801 [C:\Program Files\dotnet\sdk]
  2.2.401 [C:\Program Files\dotnet\sdk]
  3.0.100 [C:\Program Files\dotnet\sdk]
  3.1.101 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
Microsoft Visual Studio Enterprise 2019
Version 16.4.4
VisualStudio.16.Release/16.4.4+29728.190
Microsoft .NET Framework
Version 4.8.03752

Installed Version: Enterprise

ASP.NET and Web Tools 2019   16.4.460.23317
ASP.NET and Web Tools 2019

ASP.NET Web Frameworks and Tools 2019   16.4.460.23317
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0   16.4.460.23317
Azure App Service Tools v3.0.0

C# Tools   3.4.1-beta4-19614-01+165046097562cfe65b09c2e9a9d8f7cd88526f2c
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Extensibility Message Bus   1.2.0 (d16-2@8b56e20)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

IntelliCode Extension   1.0
IntelliCode Visual Studio Extension Detailed Info

Microsoft Continuous Delivery Tools for Visual Studio   0.4
Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft Library Manager   2.0.87+gbb515bf382
Install client-side libraries easily to any web project

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual Studio Tools for Containers   1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

Mono Debugging for Visual Studio   16.5.24 (1fafd7e)
Support for debugging Mono processes with Visual Studio.

Node.js Tools   1.5.11023.1 Commit Hash:579896f0984848d17d080c8a1c3ddff98d5ba96f
Adds support for developing and debugging Node.js apps in Visual Studio

NuGet Package Manager   5.4.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

Open Command Line   2.4.226
2.4.226

ProjectServicesPackage Extension   1.0
ProjectServicesPackage Visual Studio Extension Detailed Info

SQL Server Data Tools   16.0.61912.09160
Microsoft SQL Server Data Tools

TypeScript Tools   16.0.11031.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   3.4.1-beta4-19614-01+165046097562cfe65b09c2e9a9d8f7cd88526f2c
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools 10.4 for F# 4.6   16.4.0-beta.19556.5+e7597deb7042710a7142bdccabd6f92b0840d354
Microsoft Visual F# Tools 10.4 for F# 4.6

Visual Studio Code Debug Adapter Host Package   1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Container Tools Extensions (Preview)   1.0
View, manage, and diagnose containers within Visual Studio.

Visual Studio Tools for Containers   1.0
Visual Studio Tools for Containers

VisualStudio.DeviceLog   1.0
Information about my package

VisualStudio.Foo   1.0
Information about my package

VisualStudio.Mac   1.0
Mac Extension for Visual Studio

Xamarin   16.4.000.309 (d16-4@1d551f9)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer   16.4.0.475 (remotes/origin/d16-4@ac250f5aa)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin Templates   16.4.25 (579ee62)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

Xamarin.Android SDK   10.1.3.7 (d16-4/d66aed0)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: fd9f379
    Java.Interop: xamarin/java.interop/d16-4@c4e569f
    ProGuard: xamarin/proguard/master@905836d
    SQLite: xamarin/sqlite/3.28.0@46204c4
    Xamarin.Android Tools: xamarin/xamarin-android-tools/master@9f4ed4b

Xamarin.iOS and Xamarin.Mac SDK   13.10.0.17 (5f802ef)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
javiercn commented 4 years ago

@ryanelian thanks for contacting us.

@SteveSandersonMS do you have any thoughts on this? Is there a way to achieve this with the current model?

ryanelian commented 4 years ago

And oh, can we change the "valid" and "invalid" field input CSS class to use Bootstrap's "is-valid" and "is-invalid" classes?

That way we can have some pretty slick form styling with the default shipped Bootstrap CSS:

image

boukenka commented 4 years ago

I hope @SteveSandersonMS will have an opportunity to have a look at it. 😄 It's part for me of 'Create a great UX with Blazor' from the .NET Conference : Focus on Blazor.

aarondcoleman commented 4 years ago

want to echo @ryanelian on the is-invalid / is-valid for css. Just traced this down why my bootstrap theme doesn't work with blazor and ugh, it's just a missing is-* 😫

DjeeBay commented 4 years ago

Since .valid / .invalid is hard coded in Microsoft.AspNetCore.Components.Forms.EditContextFieldClassExtensions one could just edit the app.css to apply the Bootstrap styles :

.valid.modified:not([type=checkbox]) {
    /*outline: 1px solid #26b050;*/
    border-color: #28a745;
    padding-right: calc(1.5em + .75rem);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: center right calc(.375em + .1875rem);
    background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}

.invalid {
    /*outline: 1px solid red;*/
    border-color: #dc3545;
    padding-right: calc(1.5em + .75rem);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");
    background-repeat: no-repeat;
    background-position: center right calc(.375em + .1875rem);
    background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}
ghost commented 4 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

TanvirArjel commented 3 years ago

I have tested that the following would fix the issue:

 public static string FieldCssClass(this EditContext editContext, in FieldIdentifier fieldIdentifier) 
 { 
      if (editContext == null)
      {
          throw new ArgumentNullException(nameof(editContext));
      }

      var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any(); 

     if (editContext.IsModified(fieldIdentifier)) 
     { 
         return isValid ? "modified valid" : "modified invalid"; 
     } 

     return isValid ? string.Empty  : "invalid"; 
 }

@mkArtakMSFT @javiercn Can I make a pull request, please?

daver77 commented 2 years ago

I still see this issue in .NET 6.0, is there a work-around?

mkArtakMSFT commented 2 years ago

It looks like there have been some improvements in this area done already. Specifically, we now have the FieldCssClassProvider API (documented here, which allows detailed customization. Would you mind sharing your thoughts regarding whether this API covering your scenarios or not?

Baklap4 commented 1 year ago

It looks like there have been some improvements in this area done already. Specifically, we now have the FieldCssClassProvider API (documented here, which allows detailed customization. Would you mind sharing your thoughts regarding whether this API covering your scenarios or not?

This fixes one of the mentioned problems: using another css class name for the different states (valid/invalid)

The OP asked to not have either valid or invalid css class if the form hasn't been touched. So no this does not cover the initial bug report. It is still the case in latest blazor.

Original statement was:

Blazor sets valid CSS to all form fields BEFORE they are validated in the first place!

To Reproduce

<EditForm Model="MyForm">
<InputText @bind-Value="MyForm.MyField"></InputText>
</EditForm>

Then witness in the inspect element browser window that image valid CSS is applied before the form is even touched. image

Without touching the form there shouldn't be a valid class on the fields.

ghost commented 10 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost commented 9 months ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.