18

Blazor EditForms, an essential tool or too much magic?

 4 years ago
source link: https://jonhilton.net/why-use-blazor-edit-forms/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Blazor EditForms, an essential tool or too much magic?

July 23, 2020 · 6 minute read · Tags: blazor

Blazor ships with something called an EditForm.

But what is it, do you have to use it, and what if you don’t fancy relying on magic to make your application work?

What is it?

Here’s a Blazor EditForm in action.

<EditForm Model="Command" OnValidSubmit="HandleValidSubmit">
    <label for="title">Title</label>
    <InputText id="title" @bind-Value="Command.Title" class="form-control"/>
    <label for="slug">Slug</label>
    <InputText id="slug" @bind-Value="Command.Slug" class="form-control"/>
    <InputTextArea @bind-Value="Command.Body" class="form-control" rows="20"/>
    <button type="submit" class="btn btn-primary">Publish</button>
</EditForm>

We have the EditForm component itself, which we’ve pointed at an instance of a C# class (Command in this case) via the Model property.

We’ve assigned a method to the OnValidSubmit attribute, so when the form is submitted (and if it’s valid, more on that in a moment), HandleValidSubmit will be invoked.

This simple example also utilises InputText and InputTextArea components to render each field in the form.

Run this in the browser and you’ll get a pretty standard looking form…

<form>
    <label for="title">Title</label>
    <input id="title" class="valid">
    <label for="slug">Slug</label>
    <input id="slug" class="valid">
    <textarea rows="20" class="valid"></textarea>
    <button type="submit">Publish</button>
</form>

So far so good, EditForm hasn’t required us to jump through too many hoops; the resulting form is un-opinionated and largely the same as the one you might have hand-crafted yourself.

Considering Blazor for your next project?

Learn my simple, repeatable process for transforming ideas into features using Blazor's component model.

4 days, 4 emails; enter your email in the box below and I'll send you Lesson #1.

Email address

The only ‘extra’ thing ‘EditForm’ has done for us, is to mark up each input with a valid CSS class.

Oh, and of course it will keep the values in our Command model in sync with the values entered by the user, which is handy!

But if that’s all the EditForm did you might be left wondering why bother? The answer, it turns out, is EditForm's true superpower…

Validation - a necessary evil?

Let’s be honest, wiring up validation in your forms is really important, but pretty boring!

You probably don’t fall asleep every night dreaming of all the different types of validation you can implement in your application.

So the big question, can EditForms make validation so simple you don’t need to worry about it (and can focus on more interesting things!)

Here’s the simplest way to add validation to our EditForm.

<EditForm Model="Command" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <label for="title">Title</label>
    <InputText id="title" @bind-Value="Command.Title" class="form-control"/>
    <label for="slug">Slug</label>
    <InputText id="slug" @bind-Value="Command.Slug" class="form-control"/>
    <InputTextArea @bind-Value="Command.Body" class="form-control" rows="20"/>
    <button type="submit" class="btn btn-primary">Publish</button>
</EditForm>

Simply by adding the <DataAnnotationsValidator /> component we’ve enabled validation for the entire form.

This will make sure our EditForm considers any validation rules on our Command model, if they’re marked up using DataAnnotations.

public class Command {

    [Required]
    public string Title { get;set; }

    public string Slug { get; set; }

    public string Body { get;set; }
}

With this [Required] attribute we’ve indicated that the user must enter a Title.

By adding the <DataAnnotationsValidator /> component to our form, any attempt to submit said form will result in errors if this field is left blank.

Now when you run this in the browser, if you leave Title blank but enter values for the other fields and hit the submit button you’ll end up with this rendered HTML…

<form>   
   <label for="title">Title</label>
   <input id="title" class="invalid">
   <label for="slug">Slug</label>
   <input id="slug" class="modified valid">
   <textarea rows="20" class="modified valid"></textarea>
   <button type="submit">Publish</button>
</form>

This behaves largely as you’d expect.

  • If you attempt to submit the form without entering anything into any of the inputs the title input will get a class of invalid
  • Any input you type something into will be decorated with a modified CSS class
  • If you type something into the title input but then delete it again it will be decorated with both modified and invalid classes

Now you just have to implement a little bit of CSS to highlight any fields with valid or invalid css classes (or use Bootstrap which has these covered).

If you want to show a summary of all the validation errors you can simply render an instance of the <ValidationSummary /> component in your EditForm.

Bring your own validator?

What if you don’t want to use DataAnnotations?

One nice aspect of how EditForms have been designed is that you can easily implement any form of validation you like.

For example, check out this post to see FluentValidation used as an alternative.

What else can you do?

So now you have an EditForm what else can you do with it?

Style it up

You can easily style your forms as normal.

Any classes you assign to any of your inputs will be respected. Here’s our same form dressed up with a few more Bootstrap CSS classes.

<EditForm Model="Command" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <div class="form-group">
        <label for="title">Title</label>
        <InputText id="title" @bind-Value="Command.Title" class="form-control"/>
    </div>
    <div class="form-group">
        <label for="slug">Slug</label>
        <InputText id="slug" @bind-Value="Command.Slug" class="form-control"/>
    </div>
    <div class="form-group">
        <InputTextArea @bind-Value="Command.Body" class="form-control" rows="20"/>
    </div>
    <div class="text-right">
        <button type="submit" class="btn btn-primary">Publish</button>
    </div>
    <ValidationSummary />
</EditForm>

Handle invalid submissions

We’ve seen how our simple EditForm handled valid submissions. It’s no surprise you can also handle the form being submitted whilst invalid…

<EditForm Model="Command" OnValidSubmit="HandleValidSubmit" OnInvalidSubmit="HandleInvalidSubmit">
</EditForm>

Take more direct control

Under the hood EditForm keeps track of the current state of the form (which fields have been modified) and any validation errors which have been triggered.

It stores this in something called an EditContext.

If you wish, you can access that EditContext.

<EditForm OnSubmit="HandleSubmit" EditContext="MyEditContext">
</EditForm>

Note we’ve dropped the Model attribute assignment and swapped it for an EditContext instead. You can specify either a Model or EditContext but not both.

We’ve also replaced OnValidSubmit with OnSubmit which will be invoked on submit whether the form is valid or invalid.

When you assign a model using the Model attribute your EditForm will create and manage its own EditContext. Conversely, when you assign your own EditContext you need to create it yourself.

Here’s how we can create our own EditContext to make this work.

@code {
    protected Add.Command Command { get; set; } = new Add.Command();

    protected EditContext MyEditContext { get; set; }

    protected override void OnInitialized()
    {
        MyEditContext = new EditContext(Command);
    }
}

Note how we point our new EditContext to an instance of our model (Command) when we instantiate it.

Now you can access MyEditContext to trigger validation, check if anything has been modified etc.

CustomEditContext.png

Whether you need direct access to EditContext will vary depending on your requirements.

Oftentimes using Model will suffice, but it’s good to know you can dig a little deeper when needed.

Just enough magic?

So that’s how the EditForm works in Blazor, but do you have to use it?

Technically there’s nothing stopping you creating your own forms, writing logic to perform validation etc. and using binding to update the UI accordingly.

But, as framework magic goes EditForm is pretty unassuming.

It doesn’t really stop you from doing anything, and massively reduces the amount of boilerplate you’d otherwise have to write to make something like validation work so smoothly.

So overall, I put it in the ‘useful abstraction’ rather than the ‘so magic I have no idea what it’s doing’ camp!

Considering Blazor for your next project?

Learn my simple, repeatable process for transforming ideas into features using Blazor's component model.

4 days, 4 emails; enter your email in the box below and I'll send you Lesson #1.

Email address

Next up

Dark mode for your web applications (using Blazor and Tailwind CSS)
Eyestrain is a real problem; help your users by adapting your site to their dark mode preferences
Is it possible to render components “dynamically” using Blazor?
Because life’s not complicated enough already!
Render Blazor WASM components in your existing MVC/Razor Pages applications
You can render individual Blazor WASM components in your existing Razor Pages (or MVC) Core app.

Recommend

  • 40
    • www.tuicool.com 6 years ago
    • Cache

    Too Much Accessibility

    I like to blog little veins of thought as I see them. We recentlylinked to an article by Facundo Corradini calling out a tweet of ours where we used an...

  • 35
    • Imgur imgur.com 5 years ago
    • Cache

    Too much rare! - Imgur

    Too much rare! Add to FavoritesShareToo much rare!

  • 16

    Pimp up your Blazor EditForms with Tailwind CSS!July 28, 2020 · 7 minute read · Tags: blazorBlazor’s EditFo...

  • 15
    • rachelbythebay.com 4 years ago
    • Cache

    Taking too much slack out of the rubber band

    Taking too much slack out of the rubber band Of late, I keep hearing more and more about elastic this and elastic that. People use it in order to "right-size" their services, and only run the number of instances, pods, or whateve...

  • 16
    • www.mikechambers.com 4 years ago
    • Cache

    Too much interference? Get in the car

    Too much interference? Get in the car Friday, January 12, 2007 Well, I have been pretty frustrated for the past week or so, as I have realized that there is just too much RF and electrical interference in my house. It is mak...

  • 8

    The Pmarca Guide to StartupsThe Pmarca Guide to Startups Part 6: How much funding is too little? Too much? Jul 3, 2007 In this post, I answer these questions: How much fun...

  • 7
    • softwareengineering.stackexchange.com 4 years ago
    • Cache

    How much is too much Dependency Injection?

    As always, It Depends™. The answer depends on the problem one is trying to solve. In this answer, I'll try to address some common motivating forces: Favour smaller code bases If you have 4,000 lines of Spring configuration c...

  • 13

    When REACT is too much, what do you go with? Apr 17 ・1 min read ...

  • 7

    South Australia Vs. Too Much Home Solar Once upon a time, the consensus was that renewable energy was too expensive and in too sparse supply to be a viable power source to run ou...

  • 10

    CultureAmerica Has a Drinking ProblemA little alcohol can boost creativity and strengthen social ties. But there’s nothing moderate, or convivial, about the way...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK