The library contains a component, that nests itself into the Blazor EditForm instead of a wrapper around the EditForm. The component is able to generate a form based on a POCO or a ExpandoObject. Because of this architecture the library provides the developer flexibility and direct usage of the EditForm.
Turns an annotated object....
publicclassFeedingSession{[Display(Name="Kind of food")]publicFoodKindKindOfFood{get;set;}[Display(Name="Note")][MinLength(5)]publicstringNote{get;set;}[Display(Name="Amount")]publicdecimalAmount{get;set;}[Display(Name="Start")]publicDateTimeStart{get;set;}[Display(Name="End")]publicDateTimeEnd{get;set;}[Display(Name="Throwing up")]publicboolThrowingUp{get;set;}[Display(Name="Throwing up dict")]publicValueReferences<FoodKind>ThrowingUpDict{get;set;}=newValueReferences<FoodKind>();[Display(Name="Color")]publicVxColorColor{get;set;}}
... into a nice Blazor form:

Add the NuGet package.
Open a terminal in the project folder where you want to add theVxFormGenerator. Pick one of the options below:
The unstyled version of the input components for theVxFormGenerator
dotnet add package VxFormGenerator.Components.Plain
The assumption made by the library is that you already added Bootstrap (4.5.0 and up) setup in your Blazor app
The Bootstrap styled form components for theVxFormGenerator
dotnet add package VxFormGenerator.Components.Bootstrap
Open theStartup.cs
and add one of the following usage statements:
using VxFormGenerator.Settings.Plain;
using VxFormGenerator.Settings.Bootstrap;
After adding one of the usage statements add the lineservices.AddVxFormGenerator();
like shown here below.
publicIConfigurationConfiguration{get;}// This method gets called by the runtime.// Use this method to add services to the container.// For more information on how to configure your application,// visit https://go.microsoft.com/fwlink/?LinkID=398940publicvoidConfigureServices(IServiceCollectionservices){services.AddRazorPages();services.AddServerSideBlazor();services.AddVxFormGenerator();}
You can have a model that renders inputs for the properties. All that's required is adding aRenderFormElements
component to theEditForm
. The inputs can be validated by the attached Data Annotations on the property. Just add the built-inDataAnnotationsValidator
component.
@page "/"@using VxFormGenerator.Core@using FormGeneratorDemo.Data@using System.Dynamic<EditFormModel="Model"OnValidSubmit="HandleValidSubmit"OnInvalidSubmit="HandleInValidSubmit"><DataAnnotationsValidator></DataAnnotationsValidator><RenderFormElements></RenderFormElements><buttonclass="btn btn-primary"type="submit">Submit</button></EditForm>@code{ ///<summary> /// Model that is used for the form ///</summary> private FeedingSession Model = new FeedingSession(); ///<summary> /// Will handle the submit action of the form ///</summary> ///<paramname="context">The model with values as entered in the form</param> private void HandleValidSubmit(EditContext context) { // save your changes } private void HandleInValidSubmit(VEditContext context) { // Do something }}
You can render a form that is based on a dynamicExpandoObject
. The developer is that able to create a model based at runtime. All that's required is adding aRenderFormElements
component to theEditForm
. The inputs canNOTYET be validated by Data Annotations. This is a feature yet to be completed.
@page "/"@using VxFormGenerator.Core@using FormGeneratorDemo.Data@using System.Dynamic<EditFormModel="Model"OnValidSubmit="HandleValidSubmit"OnInvalidSubmit="HandleInValidSubmit"><DataAnnotationsValidator></DataAnnotationsValidator><RenderFormElements></RenderFormElements><buttonclass="btn btn-primary"type="submit">Submit</button></EditForm>@code{ ///<summary> /// Model that is used for the form ///</summary> private dynamic Model = new ExpandoObject();///<summary>/// Create a dynamic object ///</summary> protected override void OnInitialized() { var dict = (IDictionary<String,Object>) Model; dict.Add("Name", "add"); dict.Add("Note", "This is a note"); dict.Add("Date", DateTime.Now); dict.Add("Amount", 1); } ///<summary> /// Will handle the submit action of the form ///</summary> ///<paramname="context">The model with values as entered in the form</param> private void HandleValidSubmit(EditContext context) { // save your changes } private void HandleInValidSubmit(VEditContext context) { // Do something }}
The form generator supports layout structuring based on meta-data defined at model level.
// Add label to row 2[VxFormRowLayout(Id=2,Label="Adress")]publicclassAddressViewModel{[Display(Name="Firstname")]// Add element to row 1 with automatic width based on number of items in a row[VxFormElementLayout(RowId=1)]publicstringSurName{get;set;}// Add element to row 1 with automatic width based on number of items in a row and define a placeholder[VxFormElementLayout(RowId=1,Placeholder="Your Lastname")][Display(Name="Lastname")]publicstringLastName{get;set;}[Display(Name="Street")]// Add element to row 2 and set the width to 9 of 12 columns[VxFormElementLayout(RowId=2,ColSpan=9)][MinLength(5)]publicstringStreet{get;set;}[Display(Name="Number")]// Add element to row 2 and set the width to 3 of 12 columns[VxFormElementLayout(RowId=2,ColSpan=3)]publicstringNumber{get;set;}[Display(Name="Country"),// Show PlaceholderVxFormElementLayout(Placeholder="The country you live")]publicstringCountry{get;set;}[Display(Name="State")][MinLength(5)]publicstringState{get;set;}}

There is also support for nested models.
publicclassOrderViewModel{// Indicate that this property type should be rendered as a separate elements in the form and give it a label[VxFormGroup(Label="Delivery")]// Use this to valdidate a complex object[ValidateComplexType]publicAddressViewModelAddress{get;set;}=newAddressViewModel();// Indicate that this property type should be rendered as a separate elements in the form and give it a label[VxFormGroup(Label="Invoice")]// Use this to valdidate a complex object[ValidateComplexType]publicAddressViewModelBillingAddress{get;set;}=newAddressViewModel();[Display(Name="Send insured")]publicboolValid{get;set;}=true;[Display(Name="What color box")]publicVxColorColor{get;set;}}}

The form support multiple rendering options:
Set optionsGlobal
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddServerSideBlazor(); services.AddVxFormGenerator(new VxFormLayoutOptions() { LabelOrientation = LabelOrientation.TOP }); }
Set options atComponent level, these options override the global one.
<RenderFormElementsFormLayoutOptions="@OptionsForForm"></RenderFormElements>@code{ private VxFormLayoutOptions OptionsForForm = new VxFormLayoutOptions();}
Set the label position for the form
Label position: Top | Left | None
Set the placeholder policy for the form
Placeholder Policy: Explicit | Implicit | None | ExplicitFallbackToLabels | ImplicitFallbackToLabels
Set the trigger for showing validation state
Validation Policy: OnlyValid | OnlyInvalid | BothValidAndInvalid
Run the demo so you can see the options and effects interactively:
git clone https://github.com/Aaltuj/VxFormGenerator.git
cd VxFormGenerator
run.cmd
on Windows orbash run.sh
on Linux/Mac- navigate to
http://localhost:5000/definition-form
This is a work in progress
Server