P11Table Component
P11Table component is a versatile data display element that renders tabular data using native HTML <table> elements. It integrates seamlessly with Bootstrap's table styling utilities and is designed with accessibility in mind, ensuring proper structure for screen readers.Caption parameter is important for accessibility, providing a summary for screen readers. You can either pass a collection of Items and use child components like P11TableHeader, P11TableRow, etc., or define the table structure entirely within ChildContent.P11Table Component Examples
These examples demonstrate various configurations and functionalities of the P11Table component, showcasing its flexibility for different data display scenarios.
1. Standard Usage with Bootstrap Styling and Improved Accessibility
A fully featured table with striped rows, hover effect, borders, responsive behavior, and a descriptive caption for screen readers.
| No Columns Defined |
|---|
Implementation
<h4 class="mb-3">1. Standard Usage with Bootstrap Styling and Improved Accessibility</h4>
<p>A fully featured table with striped rows, hover effect, borders, responsive behavior, and a descriptive caption for screen readers.</p>
<div class="mb-5">
<P11Table TItem="Person2"
Items="people3"
IsStriped="true"
IsHoverable="true"
IsBordered="true"
IsResponsive="true"
CssClass="my-custom-table-style"
Caption="Overview of persons in our database">
<P11Column TItem="Person2" Header="ID">
<CellContent Context="person">
@person.Id
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="Name">
<CellContent Context="person">
<strong>@person.FirstName @person.LastName</strong>
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="Age">
<CellContent Context="person">
@person.Age
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="City">
<CellContent Context="person">
@person.City
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="Status">
<CellContent Context="person">
@if (person.IsActive)
{
<span class="badge bg-success">Active</span>
}
else
{
<span class="badge bg-secondary">Inactive</span>
}
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="Actions">
<CellContent Context="person">
<button class="btn btn-sm btn-info"
@onclick="() => EditPerson(person)"
aria-label="Edit person @person.FirstName @person.LastName">
Edit
</button>
</CellContent>
</P11Column>
</P11Table>
@if (selectedPersonForEdit != null)
{
<div class="mt-3 p-3 border rounded bg-light">
<h5>Editing Person: @selectedPersonForEdit.FirstName @selectedPersonForEdit.LastName</h5>
<p>This is a placeholder for an editing form (variant B of the DataGrid).</p>
<button class="btn btn-primary" @onclick="() => SavePerson(selectedPersonForEdit)">Save</button>
<button class="btn btn-secondary" @onclick="() => CancelEdit()">Cancel</button>
<button class="btn btn-danger" @onclick="() => DeletePerson(selectedPersonForEdit)">Delete</button>
</div>
}
</div>@* You may need the using *@
@* @using System.Globalization *@
@code {
// --- Datenmodelle ---
public class Person2
{
public int Id { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public int Age { get; set; }
public string City { get; set; } = string.Empty;
public bool IsActive { get; set; }
}
// --- Beispieldaten ---
private List<Person2> people3 = new()
{
new Person2 { Id = 1, FirstName = "Alice", LastName = "Smith", Age = 30, City = "New York", IsActive = true },
new Person2 { Id = 2, FirstName = "Bob", LastName = "Johnson", Age = 24, City = "London", IsActive = false },
new Person2 { Id = 3, FirstName = "Charlie", LastName = "Brown", Age = 45, City = "Paris", IsActive = true },
new Person2 { Id = 4, FirstName = "Diana", LastName = "Miller", Age = 38, City = "Berlin", IsActive = true }
};
// --- Logik für Aktionen (Beispiel Master-Detail-Ansatz) ---
private Person2? selectedPersonForEdit;
private void EditPerson(Person2 person)
{
selectedPersonForEdit = person;
Console.WriteLine($"Bearbeiten von: {person.FirstName} {person.LastName}");
}
private void SavePerson(Person2 person)
{
Console.WriteLine($"Person '{person.FirstName}' gespeichert.");
selectedPersonForEdit = null;
}
private void DeletePerson(Person2 person)
{
people3.Remove(person);
selectedPersonForEdit = null;
Console.WriteLine($"Person '{person.FirstName}' gelöscht.");
// Forciert das Rendern der UI nach dem Löschen
StateHasChanged();
}
private void CancelEdit()
{
selectedPersonForEdit = null;
Console.WriteLine("Bearbeitung abgebrochen.");
}
}2. Compact, Dark Table without Hover Effect (with Caption)
Demonstrates IsSmall and IsDark.
| No Columns Defined |
|---|
Implementation
<h4 class="mb-3">2. Compact, Dark Table without Hover Effect (with Caption)</h4>
<p>Demonstrates <code>IsSmall</code> and <code>IsDark</code>.</p>
<div class="mb-5">
<P11Table TItem="Person2"
Items="people3"
IsSmall="true"
IsDark="true"
IsStriped="true"
IsResponsive="true"
Caption="Compact view of the person list">
<P11Column TItem="Person2" Header="Name">
<CellContent Context="person">
@person.FirstName
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="City">
<CellContent Context="person">
@person.City
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="Active">
<CellContent Context="person">
<input type="checkbox" checked="@person.IsActive" disabled="true" />
</CellContent>
</P11Column>
</P11Table>
</div>@* You may need the using *@
@* @using System.Globalization *@
@code {
// --- Datenmodelle ---
public class Person2
{
public int Id { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public int Age { get; set; }
public string City { get; set; } = string.Empty;
public bool IsActive { get; set; }
}
// --- Beispieldaten ---
private List<Person2> people3 = new()
{
new Person2 { Id = 1, FirstName = "Alice", LastName = "Smith", Age = 30, City = "New York", IsActive = true },
new Person2 { Id = 2, FirstName = "Bob", LastName = "Johnson", Age = 24, City = "London", IsActive = false },
new Person2 { Id = 3, FirstName = "Charlie", LastName = "Brown", Age = 45, City = "Paris", IsActive = true },
new Person2 { Id = 4, FirstName = "Diana", LastName = "Miller", Age = 38, City = "Berlin", IsActive = true }
};
}3. Table with No Data (with Default Styling and Caption)
Demonstrates the display when the data list is empty.
| No Columns Defined |
|---|
| No data available. |
Implementation
<h4 class="mb-3">3. Table with No Data (with Default Styling and Caption)</h4>
<p>Demonstrates the display when the data list is empty.</p>
<div class="mb-5">
<P11Table TItem="Person2" Items="new List<Person2>()"
IsBordered="true"
Caption="Table with optional data">
<P11Column TItem="Person2" Header="Name">
<CellContent Context="person">
@person.FirstName
</CellContent>
</P11Column>
<P11Column TItem="Person2" Header="Profession">
<CellContent Context="person">
@person.City
</CellContent>
</P11Column>
</P11Table>
</div>@* You may need the using *@
@* @using System.Globalization *@
@code {
// --- Datenmodelle ---
public class Person2
{
public int Id { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public int Age { get; set; }
public string City { get; set; } = string.Empty;
public bool IsActive { get; set; }
}
// --- Beispieldaten ---
private List<Person2> people3 = new()
{
new Person2 { Id = 1, FirstName = "Alice", LastName = "Smith", Age = 30, City = "New York", IsActive = true },
new Person2 { Id = 2, FirstName = "Bob", LastName = "Johnson", Age = 24, City = "London", IsActive = false },
new Person2 { Id = 3, FirstName = "Charlie", LastName = "Brown", Age = 45, City = "Paris", IsActive = true },
new Person2 { Id = 4, FirstName = "Diana", LastName = "Miller", Age = 38, City = "Berlin", IsActive = true }
};
}4. Table for Products with Minimal Styling (with Caption)
Displaying product information without borders and stripes, but with hover effect.
| No Columns Defined |
|---|
AOT warning: This table uses TItem="object". As `object` is a very general type,
the AOT linker cannot guarantee that all properties accessed via reflection
(like item?.ToString() or item?.GetHashCode() in the columns)
will be preserved. This will cause an AOT/Trimming warning to be displayed.
| No Columns Defined |
|---|
Implementation
<h4 class="mb-3">4. Table for Products with Minimal Styling (with Caption)</h4>
<p>Displaying product information without borders and stripes, but with hover effect.</p>
<div class="mb-5">
<P11Table TItem="Product" Items="products"
IsHoverable="true"
IsResponsive="true"
Caption="Inventory list of products">
<P11Column TItem="Product" Header="Product Name">
<CellContent Context="product">
@product.Name
</CellContent>
</P11Column>
<P11Column TItem="Product" Header="Price">
<CellContent Context="product">
@product.Price.ToString("C2", CultureInfo.CurrentCulture)
</CellContent>
</P11Column>
<P11Column TItem="Product" Header="Available">
<CellContent Context="product">
<input type="checkbox" checked="@product.InStock" disabled="true" />
</CellContent>
</P11Column>
</P11Table>
</div>
<br />
<br />
<p>
AOT warning: This table uses <code>TItem="object"</code>. As `object` is a very general type,
the AOT linker cannot guarantee that all properties accessed via reflection
(like <code>item?.ToString()</code> or <code>item?.GetHashCode()</code> in the columns)
will be preserved. This will cause an AOT/Trimming warning to be displayed.
</p>
<P11Table TItem="object"
Items="objectItems"
Caption="Example Table with Object Type"
ShowDevelopmentErrors=false>
<P11Column TItem="object" Header="Value (ToString)">
<CellContent Context="item">
@item?.ToString()
</CellContent>
</P11Column>
<P11Column TItem="object" Header="Hash Code">
<CellContent Context="item">
@item?.GetHashCode()
</CellContent>
</P11Column>
<P11Column TItem="object" Header="Type Name">
<CellContent Context="item">
@item?.GetType().Name
</CellContent>
</P11Column>
</P11Table>@* You may need the using *@
@* @using System.Globalization *@
@code {
public class Person2
{
public int Id { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public int Age { get; set; }
public string City { get; set; } = string.Empty;
public bool IsActive { get; set; }
}
public class Product
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public bool InStock { get; set; }
}
private List<Product> products = new()
{
new Product { Name = "Laptop X", Price = 1200.50m, InStock = true },
new Product { Name = "Mouse Y", Price = 25.00m, InStock = true },
new Product { Name = "Keyboard Z", Price = 80.75m, InStock = false }
};
// AOT-Warning (TItem="object")
private List<object> objectItems = new()
{
"Simple String",
12345,
DateTime.Now,
new { Name = "Anonymous Object", Value = 99.9m, IsValid = true }, // Anonymes Objekt
new Person2 { Id = 5, FirstName = "Eve", LastName = "White", Age = 28, City = "Rome", IsActive = false } // Eine Instanz von Person2 als object
};
}Component API
| Parameter | Type | Default | Description |
|---|---|---|---|
Items |
IEnumerable<TItem> |
- | Gets or sets the collection of items to display in the table. |
ChildContent |
RenderFragment |
- | Gets or sets the content to render inside the table, typically used for custom table elements like <P11TableHeader>, <P11TableRow>, etc. |
Caption |
string |
null |
A brief description or title for the table, displayed for screen readers and optionally visible. |
CssClass |
string |
null |
Gets or sets additional CSS classes to apply to the table. |
IsStriped |
bool |
false |
Gets or sets a value indicating whether the table should have striped rows. |
IsHoverable |
bool |
false |
Gets or sets a value indicating whether the table rows should highlight on hover. |
IsBordered |
bool |
false |
Gets or sets a value indicating whether the table should have borders. |
IsSmall |
bool |
false |
Gets or sets a value indicating whether the table should be small in size. |
IsResponsive |
bool |
true |
Gets or sets a value indicating whether the table should be responsive (horizontally scrollable on small screens). |
IsDark |
bool |
false |
Gets or sets a value indicating whether the table should use dark styling. |