Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Future Investments - Form validation helper improvements #4819

Closed
DamianEdwards opened this issue Jun 20, 2016 · 8 comments
Closed

Future Investments - Form validation helper improvements #4819

DamianEdwards opened this issue Jun 20, 2016 · 8 comments
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one Needs: Design This issue requires design work before implementating.
Milestone

Comments

@DamianEdwards
Copy link
Member

DamianEdwards commented Jun 20, 2016

Overview

The validation helpers in MVC are due for some usability and capability improvements. We added Tag Helper-based validation helpers in the last release but they didn't really expand on the feature-set of the helpers themselves. Specifically, we're talking about the HTML Helpers and Tag Helpers that are used to enforce and show form validation on pages, including server-side and client-side validation.

Ideas

  • Address DateTime validation aspnet/Mvc#575 Improvements to DateTime validation
  • Address Allow hiding ValidationSummary content when there are no errors aspnet/Mvc#2372
  • Address ValidationSummary could provide some way to jump to the field that is wrong aspnet/Mvc#1469
  • Address Different markup state for empty/no errors validation summary between server and client implementations aspnet/Mvc#3377
  • Validation summary helpers should work better with client-side validation
    • Hide validation errors once they've been fixed on the form
    • Show new validation errors when form fields are modified
  • Support applying relevant validation CSS class names via server-side & client-side validation to elements associated with a form field, along with the form field input and label elements themselves:
    • Containing elements like <div> or <li>, e.g. <div class="form-group field-validation-error">.... This makes it much simpler to style entire form fields based on their current validation state.
    • The <form> element itself, e.g. <form class="form-horizontal form-validation-error" ...>. This makes it possible to style forms based on the validation state of the fields they contain.
    • This will make it possible to easily apply Bootstrap's Form Validation states styles to elements associated with a form field
  • Support consistent tri-state CSS class names for validation states or all elements related to a form field. Currently, different class names are used to represent the three possible states of elements associated with a form field, e.g. "valid" for the <input /> and "field-validation-valid" for the <span>. Also, the <span> is never represented with the initial state (untouched by user) but rather always starts as valid. This can make it difficult to achieve certain form field styles.
  • Make it easier to style and/or render markup for form fields that are required that is separate to the required validation message itself, e.g. showing a "required" glyph next to form label or form input element:
    • Support adding a CSS class on elements associated with required fields, e.g. <label for="FirstName" class="control-label form-field-required">First name:</label>
  • Support easily adding custom markup associated with the validation state of form fields to allow for more interactive/informative field validation states, e.g. see the "With option icons" section of Bootstrap's form validation states documentation
  • Support alternate form submission behaviors when form is invalid using client-side validation:
    • Suppress submit until form is valid (the only mode available today)
    • Disable submit button until form is valid
  • Support initial focus:
    • to first form field on page after document load
    • to first invalid form field on page after document load (server-side validation)
    • to first invalid form field on form submit (client-side validation) (this one already works I think)
  • Support adding attributes and/or CSS class for form fields marked as read-only in model metadata (see Bootstrap support)
@Muchiachio
Copy link
Contributor

Very nice list, moving forward. I did implement most of these in my previous MVC5 projects, so I will share some of my thoughts. Hope it helps in some way or another

Hide validation errors once they've been fixed on the form
Show new validation errors when form fields are modified

Didn't this work automatically from jQuery validation or jQuery unobtrusive validation scripts?
Unless we are talking about summary errors, which would be nice to have, but it's hard to get them to reappear after they have been hidden/removed.

Support applying relevant validation CSS class names via server-side & client-side validation

This one could be be achieved after hierarchical tag helpers are implemented, because it's very problematic to make it work with independent html helpers. I was wondering if MVC still tries to keep tag helper and html helper functionality the same. Because html helper's are very problematic here.

Support easily adding custom markup associated with the validation state of form fields

Again, would be easy with tag helper, but hard with html helpers, especially then something needs to go in between an input and it's validation span, which can't be easily expressed in html helper.

Make it easier to style and/or render markup for form fields that are required

This will need a parameter of some sort, to disable/enable required glyph on specific fields or their groups. Because some of the dynamic model's don't really know if they will be required or not, until they are rendered. Or users just don't want to see required glyphs on checkboxes, even though they are "required" value type booleans on server side.

Support initial focus to first form field on page after document load

I wouldn't recommend implementing this, because it has a lot of exceptions and edge cases. It starts with "lets focus first input tag". Oh, we have very similar input tags called text areas, lets include those too. But wait, we don't really need to focus check boxes, because most of the users click them with mouse anyway. And lastly date pickers and other custom input, which get's opened/validated/loaded and whatnot by focus event, which we don't want, but can't easily exclude them too. (And I don't even want to start talking about having more than one form on the page... 😄)

Support initial focus to first invalid form field on form submit (client-side validation) (this one already works I think)

Yes it does work now.

Support adding attributes and/or CSS class for form fields marked as read-only

I would be great if already existing data annotation attributes would be used to indicate read only, like Editable(false).

@ctolkien
Copy link
Contributor

I'd also like the flag the Foundation form validation helpers:

http://foundation.zurb.com/sites/docs/abide.html

Ideally any solution that is devised, there shouldn't be any blockers from implementing a Bootstrap specific version, a Foundation version and a "YourFavouriteFramework" here.

@rynowak rynowak changed the title [WIP] Form validation helper improvements Future Investments - Form validation helper improvements Jul 18, 2017
@DamianEdwards
Copy link
Member Author

New Bootstrap v4 example for forms is another reference we should consider when we look at addressing the stuff outlined above: https://getbootstrap.com/docs/4.0/examples/checkout/

@MikeBairdRocks
Copy link

MikeBairdRocks commented Jun 6, 2018

I was looking for a solution for this today for bs4. I'll create custom css to support the field validation for now but maybe expose the HtmlHelper.cs readonly static fields and put them in HtmlHelperOptions.cs with the default values?

@MikeBairdRocks
Copy link

Here's what I'm proposing for a temporary solution: aspnet/Mvc@dev...michaeljbaird:exposevalidationcss

@aspnet-hello aspnet-hello transferred this issue from aspnet/Mvc Dec 13, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 13, 2018
@aspnet-hello aspnet-hello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one Future Investments Needs: Design This issue requires design work before implementating. labels Dec 13, 2018
@pranavkm pranavkm added the c label Aug 22, 2019
@alexandrejobin
Copy link

With Core 2.2, I was able to override the default styling of the error messages by doing this in the Startup.cs file. I don't remember where I took this sample code but it worked flawlessly until I upgrade my project to Core 3.0 where I get the error message:

System.FieldAccessException: 'Cannot set initonly static field 'ValidationInputValidCssClassName' after type 'Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper' is initialized.'

Any idea how I can workaround this or is there any news on how to properly override the default styling of the error message to support Bootstrap validation styles (or others)?

public class Startup
{
    private readonly IConfiguration configuration;
    private readonly IHostingEnvironment hostingEnvironment;

    public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
    {
        //logger.LogInformation("Application starting.");

        this.configuration = configuration;
        this.hostingEnvironment = hostingEnvironment;

        ChangeDefaultValidationClassesForBootstrap4ValidationClasses();
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services
            .AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
        if (hostingEnvironment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseStaticFiles();
        app.UseCookiePolicy();
        app.UseMvc();
    }

    /// <summary>
    /// Change from default validation CSS classes to 'Bootstrap 4' validation classes.
    /// In particular it changes values of a bunch of static readonly variables in HtmlHelper class.
    /// </summary>
    private void ChangeDefaultValidationClassesForBootstrap4ValidationClasses()
    {
        SetPublicFieldValue<HtmlHelper>(nameof(HtmlHelper.ValidationInputCssClassName), "is-invalid");
        SetPublicFieldValue<HtmlHelper>(nameof(HtmlHelper.ValidationInputValidCssClassName), "is-valid");
        SetPublicFieldValue<HtmlHelper>(nameof(HtmlHelper.ValidationMessageCssClassName), "invalid-feedback");
        SetPublicFieldValue<HtmlHelper>(nameof(HtmlHelper.ValidationMessageValidCssClassName), "valid-feedback");
        SetPublicFieldValue<HtmlHelper>(nameof(HtmlHelper.ValidationSummaryCssClassName), "validation-summary-errors alert alert-danger");
        SetPublicFieldValue<HtmlHelper>(nameof(HtmlHelper.ValidationSummaryValidCssClassName), "validation-summary-valid alert alert-success");
    }

    private static void SetPublicFieldValue<T>(string fieldName, object fieldValue)
    {
        FieldInfo fieldInfo = typeof(T).GetField(fieldName, BindingFlags.Public | BindingFlags.Static);

        if (fieldInfo == null)
        {
            throw new NullReferenceException(string.Format("Static field '{0}' not found in '{1}' class", fieldName, nameof(T)));
        }

        fieldInfo.SetValue(null, fieldValue);
    }
}

@mkArtakMSFT
Copy link
Member

@alexandrejobin can you please file a separate issue please. We're closing this one as there has been no much community involvement here.

@bigcitydev
Copy link

We have 2020 and hardcoded css class ! WOW

@ghost ghost locked as resolved and limited conversation to collaborators Dec 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one Needs: Design This issue requires design work before implementating.
Projects
None yet
Development

No branches or pull requests

9 participants