Grid Demo

Quick overview of the awesome grid.

- set to 0 for autosize
- load grid when parent (e.g. Person textbox) triggers change, live search is used when using client data

  • Column.Bind - binds column to the DataSource Model, it can be bound to one or more properties, including subproperties in the model, examples: "FirstName", "FirstName,LastName", "Country.Name", "Chef.FirstName, Chef.LastName"
  • Persistence - makes the grid save its state ( collapsed groups, current page), it can be None - no persistence, View - view context (will loose state on page refresh); Session - using HTML sessionStorage (will loose state on closing browser); Local - using HTML localStorage ( state will be persisted even after the browser is closed)
  • ColumnsPersistence - save columns state
  • GridModelBuilder<Model> - builds the model of the grid by sorting, paging and grouping the items.
  • GridModelBuilder<Model>.Map - defines a function that maps the Model to a Dto, this way Column.Name will still be bound the the DataSource Model properties, but for cell values the values from the Dto will be used
  • GridModelBuilder<Model>.Key - defines a property on which the data will be sorted when there's no sorting, this is needed when using Entity Framework because it does not allow paging if the data is not ordered at least by one column; it's also used for nesting, tree, api
GridDemo/IndexContent.cshtml
@model AwesomeMvcDemo.ViewModels.Input.GridDemoCfgInput
@(Html.Awe().Grid("Grid")
.Mod(o => o.ColumnsSelector().PageSize().PageInfo().Loading().AutoMiniPager())
.Columns(
new Column { Bind = "Id", Width = 75, Groupable = false, Resizable = false },
new Column { Bind = "Person" },
new Column { Bind = "Food" },
new Column { Bind = "Country.Name", ClientFormat = ".CountryName", Header = "Country" },
new Column { Bind = "Date", Width = 120 },
new Column { Bind = "Location" },
new Column { Bind = "Chef.FirstName,Chef.LastName", ClientFormat = ".ChefName", Header = "Chef" }
)
.Url(Url.Action("GetItems", "LunchGrid")) // used for remote data
.DataFunc(Model.DataFunc) // used for client side data
.Persistence(Persistence.Session)
.ColumnsPersistence(Persistence.Session)
.LoadOnParentChange(Model.LoadOnParentChange)
.Resizable(Model.Resizable)
.Reorderable(Model.Reorderable)
.Groupable(Model.Groupable)
.Sortable(Model.Sortable)
.SingleColumnSort(Model.SingleColumnSorting)
.ShowGroupedColumn(Model.ShowGroupedColumn)
.Page1OnSort(Model.Page1OnSort)
.Height(Model.Height)
.Parent("txtperson", "person") /* binds to person parameter */
.Parent("txtfood", "food")
.Parent("oCountry", "country"))
Awesome/Grid/LunchGridController.cs
public class LunchGridController : Controller
{
public ActionResult GetItems(GridParams g, string person, string food, int? country)
{
food = (food ?? "").ToLower();
person = (person ?? "").ToLower();

var list = Db.Lunches
.Where(o => o.Food.ToLower().Contains(food) && o.Person.ToLower().Contains(person))
.AsQueryable();

if (country.HasValue) list = list.Where(o => o.Country.Id == country);

return Json(new GridModelBuilder<Lunch>(list, g)
{
KeyProp = o => o.Id,// needed for Entity Framework | nesting | tree | api
Map = o => new
{
o.Id,
o.Person,
o.Food,
o.Location,
o.Price,
Date = o.Date.ToShortDateString(),
CountryName = o.Country.Name,
ChefName = o.Chef.FirstName + " " + o.Chef.LastName
}
}.Build());
}
}
GridDemo/Index.cshtml
<div class="bar">
@Html.Awe().TextBox("txtperson").Placeholder("search for person ...").CssClass("searchtxt")
@Html.Awe().TextBox("txtfood").Placeholder("search for food ...").CssClass("searchtxt")
@Html.Awe().AjaxRadioList("oCountry").Url(Url.Action("GetCountries", "Data")).Odropdown().HtmlAttributes(new { style = "min-width:15em;"})
<button type="button" class="awe-btn mbtn" id="btnSearch" style="display: none;">search</button>
</div>

<div id="demoContent">
@Html.Partial("IndexContent")
</div>
<script>
var litems;
if (sessionStorage.getItem("lunches")) {
litems = JSON.parse(sessionStorage.getItem("lunches"));
};

function getGridData(gp) {
var g = utils.getGridParams(gp);
function maph(o) {
return {
Id: o.Id, Person: o.Person, Food: o.Food, Location: o.Location,
Date: o.DateStr, CountryName: o.Country.Name, ChefName: o.Chef.FirstName + ' ' + o.Chef.LastName
};
}

function filter(list) {
var foodr = new RegExp(g.food, "i");
var personr = new RegExp(g.person, "i");
var res = $.grep(list, function (o) {
return foodr.test(o.Food) && personr.test(o.Person) && (!g.country || g.country == o.Country.Id);
});

return res;
}

var opt = { key: "Id", map: maph, ghval: { Date: "DateStr" }, filter: filter };

if (litems) {
return utils.gridModelBuilder(this, g, litems, opt);
}

return $.post('@Url.Action("GetLunches", "GridClientDataDemo")').then(function (items) {
litems = items;
sessionStorage.setItem('lunches', JSON.stringify(items));
return utils.gridModelBuilder(this, g, items, opt);
});
}
</script>

@*code for changing grid settings*@
@Html.Awe().Form().FormClass("ConfigForm").Success("setContent")

<script type="text/javascript">

var liveSearch = true;

function setContent(o) {
// use live search only when not using remote data and LoadOnParentChange is true
liveSearch = !o.Cfg.UseRemoteData && o.Cfg.LoadOnParentChange;

$('#Grid').data('api').clearpersist();

// when grid is initialized it binds to parents' change event (awepch for awe controls)
$('#txtperson, #txtfood').off('change');
$('#oCountry').off('awepch');

// set content (grid reinit)
$('#demoContent').html(o.Content);

if (!o.Cfg.LoadOnParentChange) {
$('#btnSearch').show();
} else {
$('#btnSearch').hide();
}
}

$(function() {
$('#txtperson, #txtfood').keyup(function () {
if (liveSearch)
$('#Grid').data('api').load();
});

$('#btnSearch').click(function() {
$('#Grid').data('api').load();
});
});
</script>

See also:

Grid Client Data Demo
Grid Crud Demo (Popup editing), using PopupForm
Grid In Nest Editing Demo
Grid Inline editing demo
Master Detail Crud Demo