@namespace Oqtane.Modules.Controls @inherits ModuleControlBase @inject IStringLocalizerFactory LocalizerFactory @inject IStringLocalizer SharedLocalizer @typeparam TableItem @if (ItemList != null) { @if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Interactive) { @if (!string.IsNullOrEmpty(SearchProperties)) {
} @if ((Toolbar == "Top" || Toolbar == "Both") && _pages > 0 && Items.Count() > _maxItems) { } } else { @if (!string.IsNullOrEmpty(SearchProperties)) {
@SharedLocalizer["Reset"]
} @if ((Toolbar == "Top" || Toolbar == "Both") && _pages > 0 && Items.Count() > _maxItems) { } } @if (Format == "Table" && Row != null) {
@Header @foreach (var item in ItemList) { @Row(item) @if (Detail != null) { @Detail(item) } } @Footer
} @if (Format == "Grid" && Row != null) { int count = 0; int rows = 0; int cols = 0; if (ItemList != null) { if (_columns == 0) { count = ItemList.Count(); rows = 1; cols = count; } else { count = (int)Math.Ceiling(ItemList.Count() / (decimal)_columns) * _columns; rows = count / _columns; cols = _columns; } }
@for (int row = 0; row < rows; row++) {
@for (int col = 0; col < cols; col++) { int index = (row * _columns) + col; if (index < ItemList.Count()) {
@Row(ItemList.ElementAt(index))
} else {
 
} }
}
} @if ((Toolbar == "Bottom" || Toolbar == "Both") && _pages > 0 && Items.Count() > _maxItems) { @if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Interactive) { } else { } } } @code { private IStringLocalizer Localizer; private int _pages = 0; private int _page = 1; private int _maxItems = 10; private int _displayPages = 5; private int _startPage = 0; private int _endPage = 0; private int _columns = 0; private string _search = ""; private IEnumerable AllItems; [Parameter] public string Format { get; set; } // Table or Grid [Parameter] public string Toolbar { get; set; } // Top, Bottom or Both [Parameter] public RenderFragment Header { get; set; } = null; // only applicable to Table layouts [Parameter] public RenderFragment Row { get; set; } = null; // required [Parameter] public RenderFragment Footer { get; set; } = null; // only applicable to Table layouts [Parameter] public RenderFragment Detail { get; set; } = null; // only applicable to Table layouts [Parameter] public IEnumerable Items { get; set; } // the IEnumerable data source [Parameter] public string PageSize { get; set; } // number of items to display on a page [Parameter] public string Columns { get; set; } // only applicable to Grid layouts - default is zero indicating use responsive behavior [Parameter] public string CurrentPage { get; set; } // sets the initial page to display [Parameter] public string DisplayPages { get; set; } // maximum number of page numbers to display for user selection [Parameter] public string Class { get; set; } // class for the containing element - ie. for Table or
for Grid [Parameter] public string RowClass { get; set; } // class for row element - ie.
for Table or
for Grid [Parameter] public string ColumnClass { get; set; } // class for column element - only applicable to Grid format [Parameter] public Action OnPageChange { get; set; } // a method to be executed in the calling component when the page changes [Parameter] public string SearchProperties { get; set; } // comma delimited list of property names to include in search [Parameter] public string SearchBoxClass { get; set; } // class for Search box [Parameter] public string Parameters { get; set; } // optional - querystring parameters in the form of "id=x&name=y" used in static render mode [SupplyParameterFromForm(FormName = "PagerForm")] public string _Search { get => ""; set => _search = value; } private IEnumerable ItemList { get; set; } protected override void OnInitialized() { Localizer = LocalizerFactory.Create(GetType().FullName); } protected override void OnParametersSet() { if (string.IsNullOrEmpty(Format)) { Format = "Table"; } if (string.IsNullOrEmpty(Toolbar)) { Toolbar = "Top"; } if (string.IsNullOrEmpty(Class)) { if (Format == "Table") { Class = "table table-borderless"; } else { Class = "container-fluid"; } } if (string.IsNullOrEmpty(RowClass)) { if (Format == "Table") { RowClass = ""; } else { RowClass = "row"; } } if (string.IsNullOrEmpty(ColumnClass)) { if (Format == "Table") { ColumnClass = ""; } else { ColumnClass = "col"; } } if (PageState.QueryString.ContainsKey("search")) { _search = PageState.QueryString["search"]; } if (!string.IsNullOrEmpty(SearchProperties)) { AllItems = Items; // only used in search if (!string.IsNullOrEmpty(_search)) { Search(); } } if (!string.IsNullOrEmpty(PageSize)) { _maxItems = int.Parse(PageSize); } if (!string.IsNullOrEmpty(Columns)) { _columns = int.Parse(Columns); } if (!string.IsNullOrEmpty(DisplayPages)) { _displayPages = int.Parse(DisplayPages); } if (PageState.QueryString.ContainsKey("page") && int.TryParse(PageState.QueryString["page"], out int page)) { _page = page; } else { if (!string.IsNullOrEmpty(CurrentPage)) { _page = int.Parse(CurrentPage); } else { _page = 1; } } if (_page < 1) _page = 1; _startPage = 0; _endPage = 0; if (Items != null) { _pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems); if (_page > _pages) { _page = _pages; } SetPagerSize(); } } public void SetPagerSize() { _startPage = ((_page - 1) / _displayPages) * _displayPages + 1; _endPage = _startPage + _displayPages - 1; if (_endPage > _pages) { _endPage = _pages; } ItemList = Items.Skip((_page - 1) * _maxItems).Take(_maxItems); StateHasChanged(); OnPageChange?.Invoke(_page); } public void UpdateList(int page) { _page = page; SetPagerSize(); } public void SkipPages(string direction) { switch (direction) { case "forward": _page = _endPage + 1; break; case "back": _page = _startPage - 1; break; } SetPagerSize(); } public void NavigateToPage(string direction) { switch (direction) { case "next": if (_page < _pages) { _page += 1; } break; case "previous": if (_page > 1) { _page -= 1; } break; } UpdateList(_page); } public void Search() { if (!string.IsNullOrEmpty(_search)) { Items = AllItems.Where(item => { var values = SearchProperties.Split(',') .Select(itemType => GetPropertyValue(item, itemType)) .Where(value => value != null) .Select(value => value.ToString().ToLower()); return values.Any(value => value.Contains(_search.ToLower())); }).ToList(); } else { Items = AllItems; } _pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems); UpdateList(1); } private object GetPropertyValue(object obj, string propertyName) { var index = propertyName.IndexOf("."); if (index != -1) { var propertyInfo = obj.GetType().GetProperty(propertyName.Substring(0, index)); if (propertyInfo != null) { return GetPropertyValue(propertyInfo.GetValue(obj), propertyName.Substring(index + 1)); } return null; } else { var propertyInfo = obj.GetType().GetProperty(propertyName); if (propertyInfo != null) { return propertyInfo.GetValue(obj); } return null; } } public void Reset() { _search = ""; Items = AllItems; _pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems); UpdateList(1); } private string FormatSearchProperties() { var properties = new List(); foreach (var property in SearchProperties.Split(',', StringSplitOptions.RemoveEmptyEntries)) { var index = property.LastIndexOf("."); if (index != -1) { properties.Add(property.Substring(index + 1)); } else { properties.Add(property); } } return string.Join(",", properties); } private string PageUrl(int page, string search) { var parameters = new Dictionary(PageState.QueryString); if (parameters.ContainsKey("page")) parameters.Remove("page"); parameters.Add("page", page.ToString()); if (parameters.ContainsKey("search")) parameters.Remove("search"); if (!string.IsNullOrEmpty(search)) { parameters.Add("search", search); } if (!string.IsNullOrEmpty(Parameters)) { foreach (var parameter in Utilities.ParseQueryString(Parameters)) { if (parameters.ContainsKey(parameter.Key)) parameters.Remove(parameter.Key); parameters.Add(parameter.Key, parameter.Value); } } return PageState.Route.AbsolutePath + Utilities.CreateQueryString(parameters); } }