Grid Filtering Misc
Grid outside filter row and custom render
Grid auto filters placed outside the grid.
Using theAutoFilter() extension method on the controls, so that their names and values are automatically added to the grid filter model,
and handled automatically in the GridModelBuilder, no custom filtering logic required.
The
OutsideFilter("#outfrow") method is used to specify the container of the filters.
We can also get data from the Grid Model, as we do as an example in the
Date filter where we get the years from the grid model.
Additionally there is filter persistence, so after page refresh the grid will have the same filters applied.
And there's a custom item render mod applied so you can switch between cards view and rows.
Shared/Demos/GridFilterOutside.cshtml
@{
var pref = "frowOut";
var gridId = "GridFrowOut";
}
<div id="outfrow" class="o-flex o-flex-wrap o-gap-2 o-pb-2 o-items-end">
@*context will add a prefix to all awesome editors html ids*@
@using (Html.Awe().BeginContext(pref))
{
@*html input name matches filter rule name*@
<label class="o-flex o-flex-col">
Name<br />
@Html.Awe().TextBox(new TextBoxOpt {
Name = nameof(Dinner.Name),
ClearBtn = true,
Placeholder = "name"
}
.AutoFilter())
</label>
<label class="o-flex o-flex-col">
Chef<br />
@Html.Awe().DropdownList(new DropdownListOpt {
Name = "Chef.Id",
ClearBtn = true,
Url = Url.Action("GetChefs","Data")
}
.AutoFilter())
</label>
<label class="o-flex o-flex-col">
Year<br />
@Html.Awe().DropdownList(new DropdownListOpt {
Name = "Date.Year",
ClearBtn = true,
DataFunc = $"awe.filterData('Date', '#{gridId}')"
}.AutoFilter())
</label>
<label class="o-flex o-flex-col">
Meals<br />
@(Html.Awe().Multicheck(new MulticheckOpt
{
Name = nameof(Dinner.Meals),
ClearBtn = true,
Url = Url.Action("GetAllMeals", "Data")
}
.AutoFilter()))
</label>
<label class="o-flex o-flex-col">
Organic<br />
@Html.Awe().DropdownList(new DropdownListOpt {
Name = nameof(Dinner.Organic),
ClearBtn = true,
DataFunc = "awe.boolValData"
}.AutoFilter())
</label>
<label class="o-flex o-flex-col">
<button type="button" id="btnClearFilter" class="awe-btn">Clear filters
@MyAweIcons.ReloadIco()
</button>
</label>
}
<label class="o-nonflt o-flex o-flex-col">
Show items as:
@Html.Awe().Toggle(new ToggleOpt{ Name = "itemsType", No = "Rows", Yes = "Cards", Width = "7em" })
</label>
</div>
@(Html.Awex().Grid<Dinner>(gridId)
.Main()
.Url(Url.Action("DinnersFilterGrid", "GridFilterRowServerSideData"))
.Persistence(Persistence.Session)
.Height(350)
.OutsideFilter("#outfrow")
.Columns(b =>
{
b.Add(o => o.Id, new Column { Width = 75 });
b.Add(o => o.Name);
b.Add(o => new { o.Chef.FirstName, o.Chef.LastName }, new Column { Header = "Chef" });
b.Add(o => o.Date);
b.Add(o => o.Meals.Select(m => m.Name), new Column { MinWidth = 200, Grow = 2 });
b.Add(o => o.Organic);
}))
<script>
$(function () {
let grid = $('#@gridId');
$('#btnClearFilter').on('click', () => grid.data('api').outsideFilterClear());
// rows/cards render switch
$('#itemsType').on('change', function () {
awe.use({
useType: 'gridSwitchView',
o: grid.data('o'),
cards: $(this).val() === 'true'
});
});
});
</script>
Demos/Grid/GridFilterRowServerSideDataController.cs
public IActionResult DinnersFilterGrid(GridParams g)
{
var query = Db.Dinners.AsQueryable();
var yearsList = new List<KeyContent>
{
new KeyContent("", "all years")
};
var years = query.Select(o => o.Date.Year).Distinct().ToArray().OrderBy(o => o);
yearsList.AddRange(AweUtil.ToKeyContent(years));
var gmb = new GridModelBuilder<Dinner>(query, g)
{
KeyProp = o => o.Id
};
gmb.Tag = new
{
frow = new
{
Date = yearsList.ToArray()
}
};
gmb.Prop(o => o.Organic, render: o => o ? "Yes" : "No");
gmb.FilterCfgForCollection(o => o.Meals, nameof(Meal.Id));
return this.AweJson(gmb.Build());
}
Filter by all columns, client data
Filtering by multiple columns at once from one textbox, you can type multiple keywords separated by space and the grid will get filtered.
The grid data is loaded once from the server after it is stored in the 'lunches' variable. The function defined in
The grid data is loaded once from the server after it is stored in the 'lunches' variable. The function defined in
DataFunc can either return the grid model or a promise which will return the grid model later,
and in this case on the first load we return a promise ($.get).
GridDemo/Filtering.cshtml
<div class="bar">
@Html.Awe().TextBox("txtsearch").Placeholder("search ...").CssClass("searchtxt")
<span class="hint"> you can search multiple columns at the same time (try 'pizza tavern')</span>
</div>
@(Html.Awe().Grid("GridClientData")
.DataFunc("loadGridClientData")
.Height(350)
.Main()
.Resizable()
.Reorderable()
.Parent("txtsearch", "search", false)
.Columns(
new Column { Bind = "Id", Width = 75, Groupable = false, Resizable = false },
new Column { Bind = "Person" },
new Column { Bind = "DishName", Header = "Dish" },
new Column { Bind = "Location" },
new Column { Bind = "Date", Width = 120 },
new Column { Bind = "CountryName", Header = "Country" },
new Column { Bind = "ChefName", Header = "Chef" }))
<script>
function loadGridClientData(sgp) {
// cache storage used by this demo (cstorg.js), it will load data on first call
return $.when(cstorg.get('@Url.Action("GetLunches", "Data")')).then(function(lunches) {
return getGridClientData(sgp, lunches);
});
}
function getGridClientData(sgp, lunches) {
var where = awef.where, contains = awef.scont, loop = awef.loop;
var gp = aweUtils.getGridParams(sgp);
var list = lunches;
if (gp.search) {
var words = gp.search.toLowerCase().split(" ");
list = where(lunches, function (o) {
var matches = 0;
loop(words, function (w) {
if (contains(o.DishName, w) || contains(o.Person, w) || contains(o.Location, w) || contains(o.CountryName, w)
|| contains(o.DateStr, w)
|| contains(o.ChefName, w)) matches++;
});
return matches === words.length;
});
}
function map(o) { return { Id: o.Id, Person: o.Person, DishName: o.DishName, Location: o.Location,
Date: o.DateStr, CountryName: o.CountryName, ChefName: o.ChefName }; };
return aweUtils.gridModelBuilder(
{
key:"Id",
gp: gp,
items: list,
map:map,
// replace default group header value for Date column
getHeaderVal:{ Date: function(o){ return o.DateStr; } }
});
}
$(function() {
$('#txtsearch').keyup(function() {
$('#GridClientData').data('api').load();
});
});
</script>
Comments