384 lines
15 KiB
Plaintext
Raw Normal View History

2025-01-24 19:17:26 -03:00
@if( Data is not null && Data.Any())
{
<div class="container">
<div class="row">
<!-- TITULO TABLA-->
<div class="col-md-10">
@if (ShowQuickSearch)
{
<div class="row mb-3">
<div class="col-md-6">
<InputText type="text" class="form-control" placeholder="Búsqueda rápida..." @bind-Value="SearchTerm"/>
</div>
</div>
}
</div>
<!-- CONTROLES DE PAGINACION-->
2025-04-06 19:22:37 -03:00
2025-01-24 19:17:26 -03:00
<div class="col-md-2">
2025-04-06 19:22:37 -03:00
@if (ShowPageButtons)
{
<nav aria-label="Page Navigation">
<ul class="pagination justify-content-end">
<li class="page-item @(CurrentPage == 1 ? "disabled" : "")">
<a class="page-link" href="#" tabindex="-1" @onclick:preventDefault @onclick="GoToPreviousPage">Anterior</a>
</li>
@if(TotalPages<=10)
2025-01-24 19:17:26 -03:00
{
2025-04-06 19:22:37 -03:00
@for (int i = 1; i <=TotalPages; i++ )
{
int pageNumber = i;
<li class="page-item @(i==CurrentPage ? "active" : "")">
<a class="page-link" href="#" @onclick:preventDefault @onclick="(()=>ChangePage(pageNumber))">@i</a>
</li>
}
2025-01-24 19:17:26 -03:00
}
2025-04-06 19:22:37 -03:00
else
2025-01-24 19:17:26 -03:00
{
2025-04-06 19:22:37 -03:00
int maxVIsiblePages = 4;
int startPage = Math.Max(1, CurrentPage - maxVIsiblePages / 2);
int endPage = Math.Min(TotalPages, startPage + maxVIsiblePages - 1);
if (CurrentPage > maxVIsiblePages / 2)
{
<li class="page-item">
<a class="page-link" href="#" @onclick:preventDefault @onclick="(()=>ChangePage(1))">1</a>
</li>
<li class="page-item disabled">
<span class="page-link">...</span>
</li>
}
@for (int i = startPage; i<=endPage; i++)
{
int pageNumber = i;
<li class="page-item @(i==CurrentPage ? "active" : "")">
<a class="page-link" href="#" @onclick:preventDefault @onclick="(()=>ChangePage(pageNumber))">@i</a>
</li>
}
if (endPage<TotalPages)
{
<li class="page-item disabled">
<span class="page-link">...</span>
</li>
<li class="page-item">
<a class="page-link" href="#" @onclick:preventDefault @onclick="(()=>ChangePage(TotalPages))">@TotalPages</a>
</li>
}
2025-01-24 19:17:26 -03:00
}
2025-04-06 19:22:37 -03:00
<li class="page-item @(CurrentPage == TotalPages ? "disabled" : "")">
<a class="page-link" href="#" @onclick:preventDefault @onclick="GoToNextPage">Siguiente</a>
</li>
</ul>
</nav>
}
2025-01-24 19:17:26 -03:00
</div>
</div>
</div>
<!-- RENDERIZACION DE TABLA-->
2025-05-23 23:31:10 -03:00
<table class="table table-sm table-hover">
2025-01-24 19:17:26 -03:00
<!-- RENDERIZAR ENCABEZADOS-->
<thead>
<tr>
<!-- RENDERIZAR ENCABEZADO DE COLUMNA TIPO SELECT-->
@if (RenderSelect)
{
<th class="ph-header">
<input type="checkbox" @bind="SelectAll" @onclick="ToggleSelectAll" />
</th>
}
<!-- RENDERIZAR ENCABEZADOS DE COLUMNA TIPO DATOS-->
@foreach (var column in Columns)
{
if (!column.Contains("Hide:"))
{
<th @onclick="()=>SortbyColumn(column)" style="cursor:pointer;user-select:none;" class="ph-header">
@column
@if (column==SortedColumn)
{
<span>@(new MarkupString(GetSortIcon(column)))</span>
}
</th>
}
}
<!-- RENDERIZAR ENCABEZADO DE COLUMNA TIPO BUTTON-->
@if (RenderButtons)
{
<th style="cursor:default; user-select:none;" class="ph-header">Acciones</th>
}
</tr>
</thead>
<!-- RENDERIZACION DE DATOS-->
<tbody>
<!-- RENDERIZAR DATOS POR PAGINA-->
@foreach (var item in PaginatedData.Where(row => string.IsNullOrWhiteSpace(SearchTerm) || Columns.Any(col => row[col]?.ToString()?.IndexOf(SearchTerm, StringComparison.OrdinalIgnoreCase) >= 0)))
{
int index = PaginatedData.IndexOf(item);
<tr>
<!-- RENDERIZAR COLUMNA DE SELECCION-->
@if (RenderSelect)
{
<td>
<input type="checkbox" checked="@SelectedRowIndexes.Contains(item[SelectionField].ToString()??string.Empty)" @onclick="() => ToggleRowSelection(item[SelectionField].ToString()??string.Empty)" />
</td>
}
<!-- RENDERIZAR COLUMNAS DE DATOS-->
@foreach (var column in Columns)
{
<!-- RENDERIZAR COLUMNA DE DESCARGA-->
if(column.Contains("Descarga:"))
{
@* <td>
@if (!string.IsNullOrEmpty(item[column]?.ToString()))
{
@foreach (var link in item[column].ToString().Split('|'))
{
<a href="@link" download><span class="oi oi-file largertext" aria-hidden="true"></span></a>
}
}
else
{
<span class="oi oi-file glowinfo" aria-hidden="true">&nbsp;Sin Archivos</span>
}
</td>
*@
}
<!-- NO RENDERIZAR COLUMNA OCULTA-->
else if (column.Contains("Hide:"))
{
}
<!-- RENDERIZAR COLUMNA DE DATOS ESTANDAR-->
else
{
<td>@item[column]</td>
}
}
<!-- RENDERIZAR COLUMNA DE BOTONES-->
@if (RenderButtons)
{
<td>
@foreach (var button in Buttons)
{
<!-- RENDERIZAR BOTON TIPO HREF-->
string cUrlAction = string.Empty;
@if (!string.IsNullOrEmpty(button.UrlAction))
{
cUrlAction = button.UrlAction;
@if (!string.IsNullOrEmpty(SelectionField))
{
cUrlAction = @button.UrlAction + item[SelectionField].ToString();
}
}
<!-- RENDERIZAR BOTON TIPO ONCLICK-->
@if (button.OnClickAction is not null)
{
@* <a class="@button.ElementClass" @onclick="async () => button?.OnClickAction(item[SelectionField].ToString())" style="zoom:@button.ElementZoom">@button.Caption</a>
*@
@if (item[SelectionField] != null)
{
<a class="@button.ElementClass"
@onclick='async () => button?.OnClickAction(item[SelectionField]?.ToString() ?? "")'
style="zoom:@button.ElementZoom">
2025-07-15 12:42:30 -03:00
@((MarkupString)button.Caption)
2025-01-24 19:17:26 -03:00
</a>
}
}
else
{
<a class="@button.ElementClass" href="@cUrlAction" style="zoom:@button.ElementZoom">@button.Caption</a>
}
}
</td>
}
</tr>
}
</tbody>
</table>
}
@code {
#region Parameters
[Parameter]
public List<string> Columns { get; set; } = new List<string>();
[Parameter]
public List<Dictionary<string, object>> Data { get; set; } = new List<Dictionary<string, object>>();
[Parameter]
public bool ShowQuickSearch { get; set; } = true;
[Parameter]
public bool RenderButtons { get; set; } = false;
[Parameter]
public List<ButtonOptions> Buttons { get; set; } = new List<ButtonOptions>();
[Parameter]
public bool RenderSelect {get;set;} =false;
[Parameter]
public List<string> SorteableCols { get; set; } = new List<string>();
[Parameter]
public int RowsPerPage { get; set; } = 10;
[Parameter]
2025-04-06 19:22:37 -03:00
public bool ShowPageButtons { get; set; } = true;
[Parameter]
2025-01-24 19:17:26 -03:00
public string SelectionField { get; set; } = string.Empty;
[Parameter]
public string TableTitle { get; set; } = string.Empty;
// [Parameter]
// public string HeaderColorScheme { get; set; } = "#f7f7f7";
#endregion
#region Declarations
private string SearchTerm { get; set; } = string.Empty;
private int CurrentPage { get; set; } = 1;
private int TotalPages => (int)Math.Ceiling((double)Data.Count/RowsPerPage);
public string SortedColumn { get; set; } = null!;
public bool SortDirection { get; set; }
public bool SelectAll { get; set; } = false;
public Dictionary<string, bool> SortDirections { get; set; } = new Dictionary<string, bool>();
private List<Dictionary<string, object>> PaginatedData { get; set; } = new List<Dictionary<string, object>>();
private List<string> SelectedRowIndexes = new List<string>();
private List<Dictionary<string, object>> SelectRows => GetSelectedRows();
public event Action<List<Dictionary<string, object>>>? OnGetSelectedRows;
#endregion
#region Sort Procedures
private void SortbyColumn(string column)
{
if (SorteableCols.Contains(column))
{
if (SortedColumn == column)
{
SortDirection = !SortDirection;
}
else
{
SortedColumn = column;
SortDirection = true;
}
if (SortDirections.ContainsKey(column))
{
SortDirections[column] = !SortDirections[column];
}
else
{
SortDirections[column] = true;
}
if (SortDirections[column])
{
PaginatedData = PaginatedData.OrderBy(_ => _[column]).ToList();
}
else
{
PaginatedData = PaginatedData.OrderByDescending(_ => _[column]).ToList();
}
}
}
private string GetSortIcon(string column)
{
if (SortDirections.ContainsKey(column) && column == SortedColumn)
{
if (SortDirection)
{
return "&#8593";
}
else
{
return "&#8595";
}
}
return string.Empty;
}
#endregion
#region Selection Procedures
private void ToggleSelectAll()
{
SelectAll = !SelectAll;
if (SelectAll)
{
foreach (var item in Data)
{
string? rowId = item[SelectionField]?.ToString();
if (rowId != null && !SelectedRowIndexes.Contains(rowId))
{
SelectedRowIndexes.Add(rowId);
}
}
}
else
{
SelectedRowIndexes.Clear();
}
OnGetSelectedRows?.Invoke(GetSelectedRows());
}
private List<Dictionary<string, object>> GetSelectedRows()
{
List<Dictionary<string, object>> selectedRows = new List<Dictionary<string, object>>();
foreach (var item in Data)
{
string? rowId = item[SelectionField]?.ToString(); // Usa el operador null-conditional
if (rowId != null && SelectedRowIndexes.Contains(rowId))
{
selectedRows.Add(item);
}
}
return selectedRows;
}
private void ToggleRowSelection (string rowIndex)
{
if (SelectedRowIndexes.Contains(rowIndex))
{
SelectedRowIndexes.Remove(rowIndex);
}
else
{
SelectedRowIndexes.Add(rowIndex);
}
OnGetSelectedRows?.Invoke(GetSelectedRows());
}
#endregion
#region Pagination Procedures
protected override void OnParametersSet()
{
PaginateData();
}
private void PaginateData()
{
int startIndex = (CurrentPage - 1) * RowsPerPage;
PaginatedData = Data.Skip(startIndex).Take(RowsPerPage).ToList();
}
private void ChangePage(int pageNumber)
{
CurrentPage = pageNumber;
PaginateData();
}
private void GoToNextPage()
{
if (CurrentPage < TotalPages)
{
CurrentPage++;
PaginateData();
}
}
private void GoToPreviousPage()
{
if (CurrentPage > 1)
{
CurrentPage--;
PaginateData();
}
}
#endregion
#region Elements Configuration
public class ButtonOptions
{
public string Caption { get; set; } = string.Empty;
public string UrlAction { get; set; } = string.Empty;
public string ElementClass { get; set; } = string.Empty;
public string ElementZoom { get; set; } = "100%";
public Func<string, Task> OnClickAction { get; set; } = _ => Task.CompletedTask;
}
#endregion
public void UpdateSearchTerm()
{
CurrentPage = 1; // Resetear la página a 1 al cambiar el término de búsqueda
PaginateData(); // Volver a paginar los datos con el nuevo término de búsqueda
StateHasChanged(); // Forzar la actualización de la interfaz de usuario
}
}