Default Form Layout

The Form Layout control simplifies the manner in which you create edit forms. It allows you to quickly create form layouts of any complexity by combining the order and hierarchy of the control's layout elements.

The Form Layout control renders its contents using the Bootstrap grid system markup. In compliance with the grid system functionality, each item within a Form Layout occupies between 1 and 12 virtual columns. The number of virtual columns an item occupies determines how it is sized relative to other items in the current row. This value can be defined separately for four different screen resolution groups - large, medium, small, and extra small. The following Layout Item properties allow you to define how many virtual columns an item occupies in different resolutions:

  • ColSpanXl - Extra large screens (1200px or wider).
  • ColSpanLg - Large screens (992px or wider).
  • ColSpanMd - Medium screens (768px or wider).
  • ColSpanSm - Small screens (576px or wider).
  • ColSpanXs - Extra small screens (less than 576px).

Note that all layout items are rendered as .col elements within a single .row container by default. A browser moves an item to the next row if there are not enough virtual columns (with the current screen resolution) within the current virtual row to fit the item. Set the item's BeginRow property to true to specify if an item should be rendered within a new row.

Refer to the Bootstrap documentation for more information on the Bootstrap Grid system, and the Form Layout Rendering documentation topic to learn about the Form Layout rendering specifics and how to apply these specifics to construct efficient adaptive layouts.

<dx:BootstrapFormLayout runat="server">
    <Items>
        <dx:BootstrapLayoutItem Caption="Contact Name" ColSpanMd="6">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="Thomas Hardy" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Company Name" ColSpanMd="6">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="Around the Horn" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Title" ColSpanMd="6">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="Sales Representative" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Phone Number" ColSpanMd="6">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox Text="1715557788" runat="server">
                        <MaskSettings Mask="(000) 000-0000" IncludeLiterals="None" />
                    </dx:BootstrapTextBox>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
    </Items>
</dx:BootstrapFormLayout>

Vertical Layout

The LayoutType property defines how layout item caption and layout item contents are stacked. In this demo, the LayoutType property is set to Vertical.

<dx:BootstrapFormLayout runat="server" LayoutType="Vertical">
    <Items>
        <dx:BootstrapLayoutItem Caption="Location" ColSpanLg="4" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" NullText="e.g. city, country or specific hotel" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Check in" ColSpanLg="4" ColSpanMd="6">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapDateEdit runat="server" ID="CheckInDateEdit">
                        <CssClasses IconDropDownButton="fa fa-calendar" />
                    </dx:BootstrapDateEdit>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Check out" ColSpanLg="4" ColSpanMd="6">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapDateEdit runat="server" ID="CheckOutDateEdit">
                        <CssClasses IconDropDownButton="fa fa-calendar" />
                        <DateRangeSettings StartDateEditID="CheckInDateEdit" MinDayCount="1" CalendarColumnCount="1" />
                    </dx:BootstrapDateEdit>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem ShowCaption="False">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapButton Text="Submit" AutoPostBack="true" CausesValidation="false" runat="server">
                        <SettingsBootstrap RenderOption="Primary" />
                    </dx:BootstrapButton>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
    </Items>
</dx:BootstrapFormLayout>
protected void Page_Init(object sender, EventArgs e) {
    DateTime minCheckInDate = DateTime.Now + TimeSpan.FromDays(1);
    CheckInDateEdit.MinDate = minCheckInDate;
    CheckInDateEdit.Date = minCheckInDate;
    CheckOutDateEdit.Date = minCheckInDate + TimeSpan.FromDays(2);
}

Item Wrapping

The Form Layout control uses Bootstrap - Grid System classes to render layout items. By default, all items are created as .col elements within a single .row container. A browser automatically moves an item to the next row if there are not enough virtual columns in a row to fit the item in the current screen resolution. This behavior is known as column wrapping in Bootstrap. If you wish to force an item to be displayed on a new row, set the item's BeginRow property to true.

<dx:BootstrapFormLayout runat="server">
    <Items>
        <dx:BootstrapLayoutItem Caption="Address" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="120 Hanover Sq." />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="City">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="London" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Postal/ZIP Code">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="WA1 1DP" MaxLength="10" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Country">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" Text="UK" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Address Type" BeginRow="true">
            <ContentCollection>
                <dx:ContentControl>
                    <div class="form-control-plaintext">
                        <dx:BootstrapRadioButton runat="server" Text="Home" GroupName="AddressTypeGroup">
                            <SettingsBootstrap InlineMode="true" />
                        </dx:BootstrapRadioButton>
                        <dx:BootstrapRadioButton runat="server" Text="Work" GroupName="AddressTypeGroup" Checked="true">
                            <SettingsBootstrap InlineMode="true" />
                        </dx:BootstrapRadioButton>
                    </div>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
    </Items>
</dx:BootstrapFormLayout>

Caption and HelpText

The Form Layout control allows you to supply each layout item with a caption and help text providing supplementary information about the displayed editor's purpose.

A caption can be provided with an additional optional or required mark that indicates whether the field is treated as optional or required when validating the form data.

Enter your first name
Enter your middle name or initial
Enter your last name
<dx:BootstrapFormLayout runat="server" RequiredMarkDisplayMode="All" RequiredMark="*required" LayoutType="Vertical">
    <SettingsItemCaptions HorizontalAlign="Left" />
    <SettingsItemHelpTexts HorizontalAlign="Left" />
    <Items>
        <dx:BootstrapLayoutItem Caption="First Name" HelpText="Enter your first name" ColSpanLg="4" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server">
                        <ValidationSettings>
                            <RequiredField IsRequired="true" ErrorText="First Name is required" />
                        </ValidationSettings>
                    </dx:BootstrapTextBox>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Middle Name" HelpText="Enter your middle name or initial" ColSpanLg="4" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server" />
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
        <dx:BootstrapLayoutItem Caption="Last Name" HelpText="Enter your last name" ColSpanLg="4" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapTextBox runat="server">
                        <ValidationSettings>
                            <RequiredField IsRequired="true" ErrorText="Last Name is required" />
                        </ValidationSettings>
                    </dx:BootstrapTextBox>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
    </Items>
</dx:BootstrapFormLayout>

Groups

A layout group (BootstrapLayoutGroup) is a container for layout items and other layout groups. A group stores its child items in the Items collection.

A layout group exposes ColSpanXX properties, which allow you to align layout groups based on the display resolution in the same way, in which you align layout items (see the Default FormLayout demo). Note that a layout group cannot be placed in one Bootstrap grid row with a layout item. If there are an item and a group in one layout item collection, the group is placed on a new row as if it had the BeginRow property set to true.

A layout group exposes the GroupDecoration property which can be set to either Card or None. If this property is set to Card, the group has a border and can display caption provided that the ShowCaption property is set to true.

Personal Information
Work Information
<dx:BootstrapFormLayout runat="server">
    <Items>
        <dx:BootstrapLayoutGroup Caption="Personal Information">
            <Items>
                <dx:BootstrapLayoutItem Caption="First Name" ColSpanMd="4">
                    <ContentCollection>
                        <dx:ContentControl>
                            <dx:BootstrapTextBox runat="server" Text="Nancy" />
                        </dx:ContentControl>
                    </ContentCollection>
                </dx:BootstrapLayoutItem>
                <dx:BootstrapLayoutItem Caption="Last Name" ColSpanMd="4">
                    <ContentCollection>
                        <dx:ContentControl>
                            <dx:BootstrapTextBox runat="server" Text="Davolio" />
                        </dx:ContentControl>
                    </ContentCollection>
                </dx:BootstrapLayoutItem>
                <dx:BootstrapLayoutItem Caption="Birth Date" ColSpanMd="4">
                    <ContentCollection>
                        <dx:ContentControl>
                            <dx:BootstrapDateEdit runat="server" Date="12/8/1948" />
                        </dx:ContentControl>
                    </ContentCollection>
                </dx:BootstrapLayoutItem>
            </Items>
        </dx:BootstrapLayoutGroup>
        <dx:BootstrapLayoutGroup Caption="Work Information">
            <Items>
                <dx:BootstrapLayoutItem Caption="Position" ColSpanMd="6">
                    <ContentCollection>
                        <dx:ContentControl>
                            <dx:BootstrapTextBox runat="server" Text="Sales Representative" />
                        </dx:ContentControl>
                    </ContentCollection>
                </dx:BootstrapLayoutItem>
                <dx:BootstrapLayoutItem Caption="Hire Date" ColSpanMd="6">
                    <ContentCollection>
                        <dx:ContentControl>
                            <dx:BootstrapDateEdit runat="server" Date="5/1/1992" />
                        </dx:ContentControl>
                    </ContentCollection>
                </dx:BootstrapLayoutItem>
                <dx:BootstrapLayoutItem Caption="Notes" ColSpanMd="12">
                    <ContentCollection>
                        <dx:ContentControl>
                            <dx:BootstrapMemo runat="server" Rows="4"
                                Text="Education includes a BA in psychology from Colorado State University in 1970.  She also completed 'The Art of the Cold Call.'  Nancy is a member of Toastmasters International." />
                        </dx:ContentControl>
                    </ContentCollection>
                </dx:BootstrapLayoutItem>
            </Items>
        </dx:BootstrapLayoutGroup>
        <dx:BootstrapLayoutItem HorizontalAlign="Right" ShowCaption="False" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapButton runat="server" Text="Submit" SettingsBootstrap-RenderOption="Primary" AutoPostBack="true" />
                    <dx:BootstrapButton runat="server" Text="Cancel" SettingsBootstrap-RenderOption="Link" AutoPostBack="false">
                        <ClientSideEvents Click="function(s, e) { document.location.reload(); }" />
                    </dx:BootstrapButton>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
    </Items>
</dx:BootstrapFormLayout>

Tabbed Groups

A tabbed layout group (BootstrapTabbedLayoutGroup) is a tabbed container for layout items and other layout groups. A group stores its child items in the Items collection. A tabbed group displays its child elements on a tab page with a caption. Note that child layout items are displayed on a tab page without a caption and child layout groups have no decoration.

A layout group exposes ColSpanXX properties, which allow you to align layout groups based on the display resolution in the same way, in which you align layout items (see the Default FormLayout demo). Note that a layout group cannot be placed in one Bootstrap grid row with a layout item. If there are an item and a group in one layout item collection, the group is placed on a new row as if it had the BeginRow property set to true.

The tabbed layout group exposes the following properties specific to tabbed UI:

<dx:BootstrapFormLayout runat="server">
    <Items>
        <dx:BootstrapTabbedLayoutGroup>
            <Items>
                <dx:BootstrapLayoutGroup Caption="Info">
                    <Items>
                        <dx:BootstrapLayoutItem Caption="First Name" ColSpanMd="6">
                            <ContentCollection>
                                <dx:ContentControl>
                                    <dx:BootstrapTextBox runat="server" Text="Nancy" />
                                </dx:ContentControl>
                            </ContentCollection>
                        </dx:BootstrapLayoutItem>
                        <dx:BootstrapLayoutItem Caption="Last Name" ColSpanMd="6">
                            <ContentCollection>
                                <dx:ContentControl>
                                    <dx:BootstrapTextBox runat="server" Text="Davolio" />
                                </dx:ContentControl>
                            </ContentCollection>
                        </dx:BootstrapLayoutItem>
                        <dx:BootstrapLayoutItem Caption="Position" ColSpanMd="12">
                            <ContentCollection>
                                <dx:ContentControl>
                                    <dx:BootstrapTextBox runat="server" Text="Sales Representative" />
                                </dx:ContentControl>
                            </ContentCollection>
                        </dx:BootstrapLayoutItem>
                        <dx:BootstrapLayoutItem Caption="Birth Date" ColSpanMd="6">
                            <ContentCollection>
                                <dx:ContentControl>
                                    <dx:BootstrapDateEdit runat="server" Date="12/8/1948" />
                                </dx:ContentControl>
                            </ContentCollection>
                        </dx:BootstrapLayoutItem>
                        <dx:BootstrapLayoutItem Caption="Hire Date" ColSpanMd="6">
                            <ContentCollection>
                                <dx:ContentControl>
                                    <dx:BootstrapDateEdit runat="server" Date="5/1/1992" />
                                </dx:ContentControl>
                            </ContentCollection>
                        </dx:BootstrapLayoutItem>
                    </Items>
                </dx:BootstrapLayoutGroup>
                <dx:BootstrapLayoutGroup Caption="Notes">
                    <Items>
                        <dx:BootstrapLayoutItem ShowCaption="false" ColSpanMd="12">
                            <ContentCollection>
                                <dx:ContentControl>
                                    <dx:BootstrapMemo runat="server" Rows="5"
                                        Text="Education includes a BA in psychology from Colorado State University in 1970.  She also completed 'The Art of the Cold Call.'  Nancy is a member of Toastmasters International." />
                                </dx:ContentControl>
                            </ContentCollection>
                        </dx:BootstrapLayoutItem>
                    </Items>
                </dx:BootstrapLayoutGroup>
            </Items>
        </dx:BootstrapTabbedLayoutGroup>
        <dx:BootstrapLayoutItem HorizontalAlign="Right" ShowCaption="False" ColSpanMd="12">
            <ContentCollection>
                <dx:ContentControl>
                    <dx:BootstrapButton runat="server" Text="Submit" SettingsBootstrap-RenderOption="Primary" AutoPostBack="true" />
                    <dx:BootstrapButton runat="server" Text="Cancel" SettingsBootstrap-RenderOption="Link" AutoPostBack="false">
                        <ClientSideEvents Click="function(s, e) { document.location.reload(); }" />
                    </dx:BootstrapButton>
                </dx:ContentControl>
            </ContentCollection>
        </dx:BootstrapLayoutItem>
    </Items>
</dx:BootstrapFormLayout>

Data Binding

You can use the Form Layout control to display and edit items from any data source. In this demo, an object containing edited data is assigned to the DataSource property in the code-behind. Form Layout items are contained in the Items collection and are bound to data source fields using the LayoutItem.FieldName property. Each layout item contains a DevExpress data editor that allows editing values of the corresponding field type. If no items are specified explicitly, the Form Layout control automatically generates layout items with suitable editors for each data field.

When the edit form is submitted to the server, new field values are obtained via the GetNestedControlValueByFieldName method in the code-behind.

To place a custom control in a layout item, handle the BootstrapFormLayout.LayoutItemDataBinding event.

<dx:BootstrapFormLayout runat="server" ID="FormLayoutDataBinding" ClientInstanceName="FormLayoutDataBinding" OnLayoutItemDataBinding="FormLayoutDataBinding_LayoutItemDataBinding">
</dx:BootstrapFormLayout>
<div class="text-right">
    <dx:BootstrapButton runat="server" Text="Submit" SettingsBootstrap-RenderOption="Primary" ValidationGroup="DataBinding" OnClick="UpdateButton_Click" >
        <ClientSideEvents Click="function(s, e) { e.processOnServer = ASPxClientEdit.AreEditorsValid(FormLayoutDataBinding.GetMainElement()); }" />
    </dx:BootstrapButton>
    <dx:BootstrapButton runat="server" Text="Cancel" SettingsBootstrap-RenderOption="Link" AutoPostBack="false">
        <ClientSideEvents Click="function(s, e) { document.location.reload(); }" />
    </dx:BootstrapButton>
</div>
protected void Page_Load(object sender, EventArgs e) {
    FormLayoutDataBinding.DataSource = PersonProvider.GetData();
    FormLayoutDataBinding.DataBind();
}
protected void FormLayoutDataBinding_LayoutItemDataBinding(object sender, DevExpress.Web.Bootstrap.BootstrapLayoutItemDataBindingEventArgs e) {
    if(e.LayoutItem.FieldName == "Notes") {
        e.LayoutItem.ColSpanMd = 12;
    }
    if(e.LayoutItem.FieldName == "CountryID") {
        e.LayoutItem.Controls.Clear();
        BootstrapComboBox comboBox = new BootstrapComboBox();
        comboBox.DataSource = new DevExpress.Web.Demos.WorldCitiesContextSL().Countries.ToArray();
        comboBox.ValueField = "CountryId";
        comboBox.TextField = "CountryName";
        e.LayoutItem.Controls.Add(comboBox);
    }
}
protected void UpdateButton_Click(object sender, EventArgs e) {
    PersonProvider.UpdateData(
        (string)FormLayoutDataBinding.GetNestedControlValueByFieldName("FirstName"),
        (string)FormLayoutDataBinding.GetNestedControlValueByFieldName("LastName"),
        (DateTime)FormLayoutDataBinding.GetNestedControlValueByFieldName("Birthday"),
        (string)FormLayoutDataBinding.GetNestedControlValueByFieldName("Email"),
        (string)FormLayoutDataBinding.GetNestedControlValueByFieldName("Notes"),
        (int?)FormLayoutDataBinding.GetNestedControlValueByFieldName("CountryID"),
        (string)FormLayoutDataBinding.GetNestedControlValueByFieldName("Password")
    );
}
public class Person {
    [Browsable(false)]
    public int ID { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [DataType(DataType.Password)]
    public string Password { get; set; }
    [Required]
    [RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]
    public string Email { get; set; }
    [Range(typeof(DateTime), "01/01/1945", "01/01/2000")]
    [DisplayFormat(DataFormatString = "dd MMMM yyyy")]
    public DateTime? Birthday { get; set; }
    [Display(Name = "Country of residence")]
    public int? CountryID { get; set; }
    [DataType(DataType.MultilineText)]
    [DisplayFormat(NullDisplayText = "N/A")]
    [System.ComponentModel.DataAnnotations.MaxLength(200, ErrorMessage = "Text is too long")]
    public string Notes { get; set; }
}
public class PersonProvider {
    static string DataObjectName = "DXPerson";
    public static Person GetData() {
        var session = System.Web.HttpContext.Current.Session;
        if((session[DataObjectName] as Person) == null)
            session[DataObjectName] = new Person { FirstName = "Andrew", LastName = "Fuller", Birthday = new DateTime(1974, 8, 3), Email = "andrew.fuller@devexpress.com", CountryID = 216};
        return (Person)session[DataObjectName];
    }
    public static void UpdateData(string firstName, string lastName, DateTime birthday, string email, string notes, int? countryID, string password) {
        Person person = GetData();
        person.FirstName = firstName;
        person.LastName= lastName;
        person.Birthday = birthday;
        person.Email = email;
        person.Notes = notes;
        person.CountryID = countryID;
        person.Password = password;
    }
}
Screen Size
Color Themes
Demo QR Code