Dynamic Forms

Warning: Before getting into this document, be sure that you have clearly understood abp form elements document.

Introduction

abp-dynamic-form creates a bootstrap form for a given c# model.

Basic usage:

<abp-dynamic-form abp-model="@Model.MyDetailedModel"/>

Model:

public class DynamicFormsModel : PageModel
    {
        [BindProperty]
        public DetailedModel MyDetailedModel { get; set; }

        public List<SelectListItem> CountryList { get; set; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "CA", Text = "Canada"},
            new SelectListItem { Value = "US", Text = "USA"},
            new SelectListItem { Value = "UK", Text = "United Kingdom"},
            new SelectListItem { Value = "RU", Text = "Russia"}
        };

        public void OnGet()
        {
                MyDetailedModel = new DetailedModel
                {
                    Name = "",
                    Description = "Lorem ipsum dolor sit amet.",
                    IsActive = true,
                    Age = 65,
                    Day = DateTime.Now,
                    MyCarType = CarType.Coupe,
                    YourCarType = CarType.Sedan,
                    Country = "RU",
                    NeighborCountries = new List<string>() { "UK", "CA" }
                };
        }

        public class DetailedModel
        {
            [Required]
            [Placeholder("Enter your name...")]
            [Display(Name = "Name")]
            public string Name { get; set; }
            
            [TextArea(Rows = 4)]
            [Display(Name = "Description")]
            [InputInfoText("Describe Yourself")]
            public string Description { get; set; }

            [Required]
            [DataType(DataType.Password)]
            [Display(Name = "Password")]
            public string Password { get; set; }

            [Display(Name = "Is Active")]
            public bool IsActive { get; set; }

            [Required]
            [Display(Name = "Age")]
            public int Age { get; set; }

            [Required]
            [Display(Name = "My Car Type")]
            public CarType MyCarType { get; set; }

            [Required]
            [AbpRadioButton(Inline = true)]
            [Display(Name = "Your Car Type")]
            public CarType YourCarType { get; set; }

            [DataType(DataType.Date)]
            [Display(Name = "Day")]
            public DateTime Day { get; set; }
            
            [SelectItems(nameof(CountryList))]
            [Display(Name = "Country")]
            public string Country { get; set; }
            
            [SelectItems(nameof(CountryList))]
            [Display(Name = "Neighbor Countries")]
            public List<string> NeighborCountries { get; set; }
        }

        public enum CarType
        {
            Sedan,
            Hatchback,
            StationWagon,
            Coupe
        }
    }

Demo

See the dynamic forms demo page to see it in action.

Attributes

abp-model

Sets the c# model for dynamic form. Properties of this modal are turned into inputs in the form.

submit-button

Can be True or False.

If True, a submit button will be generated at the bottom of the form.

Default value is False.

required-symbols

Can be True or False.

If True, required inputs will have a symbol (*) that indicates they are required.

Default value is True.

Form Content Placement

By default, abp-dynamicform clears the inner html and places the inputs into itself. If you want to add additional content to dynamic form or place the inputs to some specific area, you can use <abp-form-content /> tag. This tag will be replaced by form content and rest of the inner html of abp-dynamic-form tag will be unchanged.

Usage:

<abp-dynamic-form abp-model="@Model.MyExampleModel">
    <div>
        Some content....
    </div>
    <div class="input-area">
        <abp-form-content />
    </div>
    <div>
        Some more content....
    </div>
</abp-dynamic-form>

Input Order

abp-dynamic-form orders the properties by their DisplayOrder attribute and then their property order in model class.

Default DisplayOrder attribute number is 10000 for every property.

See example below:

        public class OrderExampleModel
        {
            [DisplayOrder(10004)]
            public string Name{ get; set; }
            
            [DisplayOrder(10005)]
            public string Surname{ get; set; }

            //Default 10000
            public string EmailAddress { get; set; }

            [DisplayOrder(10003)]
            public string PhoneNumber { get; set; }

            [DisplayOrder(9999)]
            public string City { get; set; }
        }

In this example, input fields will be displayed with this order: City > EmailAddress > PhoneNumber > Name > Surname.

Ignoring a property

By default, abp-dynamic-form generates input for every property in model class. If you want to ignore a property, use DynamicFormIgnore attribute.

See example below:

        public class MyModel
        {
            public string Name { get; set; }

            [DynamicFormIgnore]
            public string Surname { get; set; }
        }

In this example, no input will be generated for Surname property.

Indicating Text box, Radio Group and Combobox

If you have read the Form elements document, you noticed that abp-radio and abp-select tags are very similar on c# model. So we have to use [AbpRadioButton()] attribute to tell abp-dynamic-form which of your properties will be radio group and which will be combobox. See example below:

<abp-dynamic-form abp-model="@Model.MyDetailedModel"/>

Model:

public class DynamicFormsModel : PageModel
    {
        [BindProperty]
        public DetailedModel MyDetailedModel { get; set; }

        public List<SelectListItem> CountryList { get; set; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "CA", Text = "Canada"},
            new SelectListItem { Value = "US", Text = "USA"},
            new SelectListItem { Value = "UK", Text = "United Kingdom"},
            new SelectListItem { Value = "RU", Text = "Russia"}
        };

        public void OnGet()
        {
                MyDetailedModel = new DetailedModel
                {
                    ComboCarType = CarType.Coupe,
                    RadioCarType = CarType.Sedan,
                    ComboCountry = "RU",
                    RadioCountry = "UK"
                };
        }

        public class DetailedModel
        {
            public CarType ComboCarType { get; set; }

            [AbpRadioButton(Inline = true)]
            public CarType RadioCarType { get; set; }
            
            [SelectItems(nameof(CountryList))]
            public string ComboCountry { get; set; }
            
            [AbpRadioButton()]
            [SelectItems(nameof(CountryList))]
            public string RadioCountry { get; set; }
        }

        public enum CarType
        {
            Sedan,
            Hatchback,
            StationWagon,
            Coupe
        }
    }

As you see in example above:

  • If [AbpRadioButton()] are used on a Enum property, it will be a radio group. Otherwise, combobox.
  • If [SelectItems()] and [AbpRadioButton()] are used on a property, it will be a radio group.
  • If just [SelectItems()] is used on a property, it will be a combobox.
  • If none of these attributes are used on a property, it will be a text box.

Localization

abp-dynamic-form handles localization as well.

By default, it will try to find "DisplayName:{PropertyName}" or "{PropertyName}" localization keys and set the localization value as input label.

You can set it yourself by using [Display()] attribute of Asp.Net Core. You can use a localization key in this attribute. See example below:

            [Display(Name = "Name")]
            public string Name { get; set; }
In this document