Diseño de formularios web con Bootstrap para DotVVM desde ASP.NET Core
Published: 2020-07-20 12:44:28

Bootstrap, es un framework originalmente creado por Twitter, que permite crear interfaces web con CSS y JavaScript, cuya particularidad es la de adaptar la interfaz del sitio web al tamaño del dispositivo en que se visualice. Es decir, el sitio web se adapta automáticamente al tamaño de una PC, una Tablet u otro dispositivo. Esta técnica de diseño y desarrollo se conoce como “responsive design” o diseño adaptativo.

Bootstrap tiene varios recursos para configurar los estilos de los elementos de la página de una manera simple y eficiente, además de facilitar la construcción de páginas que, al mismo tiempo, están adaptadas para la web y para dispositivos móviles. Dentro del marco de trabajo de ASP.NET Core, específicamente DotVVM para el diseño de páginas web, existe un conjunto de herramientas denominadas como Bootstrap for DotVVM, la cual nos permite trabajar con ASP.NET Core y Bootstrap a la vez. 

####El patrón de diseño Modelo, Vista, Vistamodelo - MVVM

DotVVM se fundamenta en el patrón de diseño Modelo, Vista, Vistamodelo sobre .NET para la comunicación entre HTML (páginas web) y C# (código fuente). La finalidad de estas partes son las siguientes: 

+ **El modelo**. — es responsable de todos los datos de la aplicación y de la lógica de negocios relacionada.

+ **La vista**. — Representaciones para el usuario final del modelo de la aplicación. La vista es responsable de mostrar los datos al usuario y de permitir la manipulación de los datos de la aplicación.

+ **El Modelo-Vista o Vista-Modelo**. — uno o más por vista; el modelo-vista es responsable de implementar el comportamiento de la vista para responder a las acciones del usuario y de exponer los datos del modelo fácilmente.

####Adquirir Bootstrap for DotVVM 

Bootstrap for DotVVM no es más que un NuGet privado para Visual Studio, en el cual, podemos hacer uso de los competentes ya establecidos para la construcción de aplicaciones web en el ámbito empresarial. 

Para la instalación de la versión del Bootstrap for DotVVM, además de obtener la licencia correspondiente (existe una versión de prueba), es necesario realizar una configuración de unos pocos minutos para poder emplear estas funcionalidades. Los pasos para agregar el NuGet privado se pueden consultar en la siguiente dirección: [Installing Bootstrap for DotVVM](https://www.dotvvm.com/docs/tutorials/commercial-bootstrap-for-dotvvm/2.0).

####Crear un proyecto Bootstrap for DotVVM en Visual Studio 2019

Para crear un proyecto con la opción de Bootstrap en DotVVM desde Visual Studio 2019, empezaremos creando el proyecto para este caso de tipo *DotVVM Web Application (.NET Core)*: 

![](https://dev-to-uploads.s3.amazonaws.com/i/cx6h29oyq7t16ifhfi07.png)

Al especificar el nombre y continuar, el asistente de inicialización del proyecto nos brindará una serie de opciones para agregar ciertas funcionalidades al proyecto. En este caso la funcionalidad que nos interesa es la de *Bootstrap for DotVVM* ubicada en la sección *DotVVM Commercial Extensions*: 

![](https://dev-to-uploads.s3.amazonaws.com/i/ojhn920bey9mso9jrc5n.png)

####Formulario web con Bootstrap for DotVVM 

Para ejemplificar la utilización de ciertos componentes de Bootstrap con DotVVVM tendemos una pequeña aplicación web como esta: 

![](https://dev-to-uploads.s3.amazonaws.com/i/kqllnqsx3s4c2dbcon8x.png)

Teniendo en cuenta que esta página web en DotVVM está conformada por una vista y por su correspondiente vistamodelo, analicemos las partes más importantes en conjunto de estos elementos.

***Vista***

```html
<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>
```

***Vistamodelo**

```csharp
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";
	}
}
```

***Modelo***

El modelo para los datos de una persona se encuentra definida de la siguiente manera: 

```csharp
public class PersonModel
{
    [Required]
    public string Username { get; set; }
    public DateTime EnrollmentDate { get; set; }
    public string Gender { get; set; }
    public string About { get; set; }
}
```

El primer elemento Bootstrap dentro de la aplicación es el componente `PageHeader`, el cua, representa el encabezado de esta página web.  

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

Para el formato base del formulario web, se hace uso del componente `Form`. Como su nombre lo indica, este elemento representa a un formulario Bootstrap. Para los elementos correspondientes como las cajas de texto, los RadioButton, LabelText, etc. se utiliza el control FormGroup para indicar que estos elementos son parte de este formulario. Por ejemplo, para un formulario con un `TextBox`, el código fuente se vería algo como esto: 

```html
<bs:Form>
	<bs:FormGroup LabelText="TextBox">
		<dot:TextBox Text="{value: Text}" />
	</bs:FormGroup>
</bs:Form>
```

Para mostrar una interfaz visualmente amigable para el usuario y para ejemplificar los controles de Bootstrap, el formulario está organizado a través del componente `Panel`, el cual permite establecer un encabezado, un cuerpo y un pie de página.

En el encabezado por ejemplo podemos encontrarnos en este caso con una imagen que ha sido creada a través del componente `Image`:

![](https://dev-to-uploads.s3.amazonaws.com/i/a3b42wp0gowwtbmfr7tn.png)

```html
<HeaderTemplate>
	<div>
		<br />
		<bs:Image ImageUrl="UserIcon.png" AlternateText="Persons" width="35%" height="35%" />
	</div>
</HeaderTemplate>
```

Dentro del contenido del panel se encuentran los elementos propios del formulario, cada uno con un componente de los controles base llamado `Validator`, el cual, como su nombre lo indica, permite realizar validaciones en un formulario. Por el ejemplo, para el atributo `Username` de una Persona, la validación se realiza de acuerdo con las anotaciones establecidas en el modelo de la clase Persona, `[Required]` para este atributo en particular. 

```csharp
[Required]
public string Username { get; set; }
```
En el caso del atributo `Username` para una persona, el componente `TextBoxGroup` es utilizado para representarlo visualmente en el formulario. Uno de los atributos de este control es el `LabelText`, el cual permite establecer una etiqueta para esta caja de texto. 

![](https://dev-to-uploads.s3.amazonaws.com/i/krnttmowyj8ssv7uofds.png)

```html
<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>
```

Siguiendo esta secuencia, para el campo `EnrollmentDate` se utiliza el control `DateTimePickerGroup`. Algo interesante de este componente es que nos permite trabajar con distintos formatos de fecha, hora o la combinación de ambos. En la siguiente imagen podemos ver un ejemplo de esto:

![](https://dev-to-uploads.s3.amazonaws.com/i/kmpqw3vex5l74v39t4dr.png)

En el caso del genero de la persona, se utiliza el componente `RadioButton`, el cual extiende el control `RadioButton` predeterminado con características de Bootstrap adicionales. Para este caso se hace uso del atributo `IsInline`, ya que permite establecer si habrá más botones de opción en la misma línea. 

![](https://dev-to-uploads.s3.amazonaws.com/i/pmwfkk3axgv9er61x4aa.png)

```html
<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" />

```

Finalmente, para el campo `About` de la persona también se utiliza con componente de tipo `TextBoxGroup` como en el campo de `Username`, la diferencia en este caso es en el atributo `Type`, siendo en esta ocasión de tipo `MultiLine`.

```html
<bs:TextBoxGroup LabelText="About"
					Text="{value: Person.About}"
					Type="MultiLine" />
```

####¿Qué sigue?

Con este artículo, hemos aprendido ciertas características de los componentes personalizados de Bootstrap para DotVVM. Asimismo, hemos visto como crear formularios dinámicos a través de la implementación de vistas y modelos de las vistas con los controles predefinidos por DotVVM sobre ASP.NET Core desde Visual Studio 2019 para trabajar con páginas web. 

El código fuente de esta implementación está disponible en este repositorio: [Bootstrap for ASP.NET Core with DotVVM](https://github.com/esdanielgomez/BootstrapForDotVVM).  

**Recursos adicionales**

Deseas seguir adquiriendo nuevos conocimientos sobre ASP.NET Core y DotVVM, estos recursos podrían ser de tu interés:

+ Curso gratuito y abierto en YouTube: [Fundamentos de ASP.NET Core y DotVVM](http://bit.ly/cursoaspnetdotvvm). 

+ [DotVVM y ASP.NET Core: Implementación de operaciones CRUD](https://dev.to/dotvvm/dotvvm-y-asp-net-core-implementacion-de-operaciones-crud-43oe).

**Gracias:**

Si tienes alguna inquietud o necesitas ayuda en algo particular, será un gusto poder ayudar. 

Nos vemos en [Twitter](https://twitter.com/esDanielGomez)!! :)

¡Hasta pronto!