DEV Community

Cover image for Web forms with Bootstrap for DotVVM from ASP.NET Core
Daniel Gomez for DotVVM

Posted on

Web forms with Bootstrap for DotVVM from ASP.NET Core

Bootstrap, is a framework originally created by Twitter, that allows you to create web interfaces with CSS and JavaScript, whose particularity is to adapt the website interface to the size of the device on which it is displayed. That is, the website automatically adapts to the size of a PC, Tablet or other device. This design and development technique is known as "responsive design" or adaptive design.

Bootstrap has several resources to configure the styles of page elements in a simple and efficient way, as well as facilitating the construction of pages that, at the same time, are adapted for the web and for mobile devices. Within the framework of ASP.NET Core, specifically DotVVM for web page design, there is a set of tools called Bootstrap for DotVVM, which allows us to work with ASP.NET Core and Bootstrap at the same time.

Model, View, ViewModel Pattern

DotVVM is based on the Design Pattern Model, View, ViewModel over .NET for communication between HTML (web pages) and C# (source code). The purpose of these parts are as follows:

  • The model. — is responsible for all application data and related business logic.

  • The view. — Representations for the end-user of the application model. The view is responsible for displaying the data to the user and allowing manipulation of the application data.

  • Model-View or View-Model. — one or more per view; the model-view is responsible for implementing view behavior to respond to user actions and for easily exposing model data.

Acquire Bootstrap for DotVVM

Bootstrap for DotVVM is nothing more than a private NuGet for Visual Studio, in which, we can make use of the competent ones already established for the construction of web applications in the business field.

To install the Bootstrap for DotVVM version, in addition to obtaining the corresponding license (a trial version is available), it is necessary to configure a few minutes to be able to use these functionalities. The steps to add the private NuGet can be found on the following page: Installing Bootstrap for DotVVM.

Create a Bootstrap for DotVVM project in Visual Studio 2019

To create a project with the Bootstrap option in DotVVM from Visual Studio 2019, we'll start by creating the project for this DotVVM Web Application (.NET Core):

By specifying the name and continuing, the project initialization wizard will give us a number of options to add certain functionality to the project. In this case, the functionality we are interested in is Bootstrap for DotVVM located in the DotVVM Commercial Extensions section:

Web form with Bootstrap for DotVVM

To exemplify the use of certain Bootstrap components with DotVVVM we have a small web application like this:

Considering that this website in DotVVM consists of a view and its corresponding model view, let's look at the most important parts as a whole of these elements.

View

<dot:Content ContentPlaceHolderID="MainContent">

    <bs:PageHeader>
        <div align="center"><h3 align="center"><b>{{value: Title}}</b></h3></div>
    </bs:PageHeader>

    <div align="center">
        <bs:Form>
            <br />
            <bs:Panel Type="Primary" style="width:70%;">
                <HeaderTemplate>
                    <div>
                        <br />
                        <bs:Image ImageUrl="UserIcon.png" AlternateText="Persons" width="35%" height="35%" />
                    </div>
                </HeaderTemplate>
                <ContentTemplate>

                    <bs:FormGroup>
                        <div Validator.Value="{value: Person.Username}"
                             Validator.InvalidCssClass="has-error"
                             Validator.SetToolTipText="true"
                             class="page-input-box">

                            <bs:TextBoxGroup LabelText="Username"
                                             Text="{value: Person.Username}"
                                             Type="Normal" />
                        </div>
                    </bs:FormGroup>

                    <bs:FormGroup>
                        <div Validator.Value="{value: Person.EnrollmentDate}"
                             Validator.InvalidCssClass="has-error"
                             Validator.SetToolTipText="true"
                             class="page-input-box">
                            <bs:DateTimePickerGroup SelectedDate="{value: Person.EnrollmentDate}" LabelText="EnrollmentDate" Mode="Date" />
                        </div>
                    </bs:FormGroup>

                    <bs:FormGroup LabelText="Gender">
                        <div Validator.Value="{value: Person.Gender}"
                             Validator.InvalidCssClass="has-error"
                             Validator.SetToolTipText="true"
                             class="page-input-box">

                            <bs:RadioButton Text="Male"
                                            GroupName="RadioButtonsGenders"
                                            CheckedValue="Male"
                                            CheckedItem="{value: Person.Gender}"
                                            Inline="true" />
                            <bs:RadioButton Text="Female"
                                            GroupName="RadioButtonsGenders"
                                            CheckedValue="Female"
                                            CheckedItem="{value: Person.Gender}"
                                            Inline="true" />
                            <bs:RadioButton Text="Other"
                                            GroupName="RadioButtonsGenders"
                                            CheckedValue="Other"
                                            CheckedItem="{value: Person.Gender}" 
                                            Inline="true" />

                        </div>
                    </bs:FormGroup>

                    <bs:FormGroup>
                        <div Validator.Value="{value: Person.About}"
                             Validator.InvalidCssClass="has-error"
                             Validator.SetToolTipText="true"
                             class="page-input-box">
                            <bs:TextBoxGroup LabelText="About"
                                             Text="{value: Person.About}"
                                             Type="MultiLine" />
                        </div>
                    </bs:FormGroup>

                </ContentTemplate>
                <FooterTemplate>
                    <b>Bootstrap for DotVVM with ASP.NET Core demo</b>
                </FooterTemplate>
            </bs:Panel>
        </bs:Form>
    </div>

</dot:Content>
Enter fullscreen mode Exit fullscreen mode

Viewmodel

public class DefaultViewModel : MasterPageViewModel
{
    public string Title { get; set; }
    public PersonModel Person { get; set; } = new PersonModel { EnrollmentDate = DateTime.UtcNow.Date };

    public DefaultViewModel()
    {
        Title = "Person Form";
    }
}
Enter fullscreen mode Exit fullscreen mode

Model

The model for a person's data is defined as follows:

public class PersonModel
{
    [Required]
    public string Username { get; set; }
    public DateTime EnrollmentDate { get; set; }
    public string Gender { get; set; }
    public string About { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

The first Bootstrap element within the application is the PageHeader component, which represents the header of this web page.

<bs:PageHeader>
    <div align="center"><h3 align="center"><b>{{value: Title}}</b></h3></div>
</bs:PageHeader>
Enter fullscreen mode Exit fullscreen mode

For the base format of the web form, the Form component is used. As the name implies, this element represents a Bootstrap form. For corresponding elements such as text boxes, RadioButton, LabelText, and so on the FormGroup control is used to indicate that these elements are part of this form. For example, for a form with a TextBox, the source code would look something like this:

<bs:Form>
    <bs:FormGroup LabelText="TextBox">
        <dot:TextBox Text="{value: Text}" />
    </bs:FormGroup>
</bs:Form>
Enter fullscreen mode Exit fullscreen mode

To display a visually friendly interface and to exemplify Bootstrap controls, the form is organized through the Panel component, which allows you to set a header, body, and footer.

In the header for example we can find in this case an image that has been created through the component Image:

<HeaderTemplate>
    <div>
        <br />
        <bs:Image ImageUrl="UserIcon.png" AlternateText="Persons" width="35%" height="35%" />
    </div>
</HeaderTemplate>
Enter fullscreen mode Exit fullscreen mode

Within the contents of the panel are the form's own elements, each with a component of the base controls called Validator, which, as the name implies, allows validations on a form. For example, for a Person's Username attribute, validation is performed according to the annotations set in the Model of the Person class, [Required] for this particular attribute.

[Required]
public string Username { get; set; }
Enter fullscreen mode Exit fullscreen mode

In the case of the Username attribute for a person, the TextBoxGroup component is used to visually represent it on the form. One of the attributes of this control is the LabelText, which allows you to set a label for this text box.


<bs:FormGroup>
    <div Validator.Value="{value: Person.Username}"
            Validator.InvalidCssClass="has-error"
            Validator.SetToolTipText="true"
            class="page-input-box">

        <bs:TextBoxGroup LabelText="Username"
                            Text="{value: Person.Username}"
                            Type="Normal" />
    </div>
</bs:FormGroup>
Enter fullscreen mode Exit fullscreen mode

Following this sequence, the DateTimePickerGroup control is used for the EnrollmentDate field. Something interesting about this component is that it allows us to work with a different date, time, or combination formats. In the following image we can see an example of this:

In the case of the person's gender, the RadioButton component is used, which extends the default RadioButton control with additional Bootstrap features. In this case, the IsInline attribute is used, as it allows you to set whether there will be more radio buttons on the same line.


<bs:RadioButton Text="Male"
                GroupName="RadioButtonsGenders"
                CheckedValue="Male"
                CheckedItem="{value: Person.Gender}"
                Inline="true" />
<bs:RadioButton Text="Female"
                GroupName="RadioButtonsGenders"
                CheckedValue="Female"
                CheckedItem="{value: Person.Gender}"
                Inline="true" />
<bs:RadioButton Text="Other"
                GroupName="RadioButtonsGenders"
                CheckedValue="Other"
                CheckedItem="{value: Person.Gender}" 
                Inline="true" />

Enter fullscreen mode Exit fullscreen mode

Finally, for the person's About field is also used with the component of type TextBoxGroup as in the field of Username, the difference, in this case, is in the attribute Type, this time being of type MultiLine.

<bs:TextBoxGroup LabelText="About"
                    Text="{value: Person.About}"
                    Type="MultiLine" />
Enter fullscreen mode Exit fullscreen mode

What's next?

With this article, we learned certain features of Bootstrap custom components for DotVVM. We've also seen how to create dynamic forms through the implementation of views and models with DotVVM-defined controls over ASP.NET Core from Visual Studio 2019 to work with web pages.

The source code for this implementation is available in this repository: Bootstrap for DotVVM.

Additional Resources

Want to continue to acquire new knowledge about ASP.NET Core and DotVVM? these resources may be of interest to you:

Thank you:

If you have any concerns or need help in something particular, it will be a pleasure to be able to help.

See you at Twitter!! :)

Top comments (0)