Demos/Grid/DinnersGridCrudController.cs
using AwesomeWebFormsDemo.Data;
using AwesomeWebFormsDemo.Models;
using AwesomeWebFormsDemo.Utils.Awesome;
using AwesomeWebFormsDemo.ViewModels.Input;
using System.Web.Mvc;
using Omu.AwesomeWebForms;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace AwesomeWebFormsDemo.Controllers.Demos.Grid
{
/// <summary>
/// Note: If your Key Property is not "Id" (but "MyId"), you need to change the GridModelBuilder.Key = "MyId" in GridGetItems and in the view
/// change the Bind = "MyId" (if you have an Id column),
/// and for the action columns (edit, delete btns) you can either specify the MyId property (e.g. GridUtils.EditFormatForGrid("DinnersGrid", "MyId"));
/// or in MapToGridModel additionally to o.MyId add another property Id = o.MyId
/// parameters for Edit, Delete controller Actions need to remain called "id", that's how they are set in GridUtils.cs ( "params:{{ id:" );
/// Edit and Delete post actions must return an object with property "Id" - in aweUtils.js itemEdited and itemDeleted functions expect it this way;
/// </summary>
public class DinnersGridCrudController : Controller
{
private readonly MyContext mcx = new MyContext();// mock EF Db context
public DinnersGridCrudController()
{
}
private static object MapToGridModel(Dinner o)
{
return
new
{
o.Id,
o.Name,
Date = o.Date.ToShortDateString(),
ChefName = o.Chef.FullName,
Meals = string.Join(", ", o.Meals.Select(m => m.Name)),
BonusMeal = o.BonusMeal.Name
};
}
public async Task<ActionResult> GridGetItems(GridParams g, string search = "")
{
var query = mcx.Dinners
.Include(o => o.Chef)
.Include(o => o.Meals)
.Include(o => o.Country)
.Include(o => o.BonusMeal)
.Where(o => o.Name.Contains(search)).AsQueryable();
var model = new GridModelBuilder<Dinner>(query, g)
{
KeyProp = o => o.Id, // needed for api select, update, tree, nesting, EF
Map = MapToGridModel,
};
return Json(await model.EFBuildAsync());
}
public ActionResult Create()
{
// make sure to use "return PartialView" for PopupForm/Popup views
// this will ignore _viewstart.cshtml so that you don't use the _Layout.cshtml and reload all the scripts
return PartialView();
}
[HttpPost]
public async Task<ActionResult> Create(DinnerInput input)
{
return await save(input);
}
public async Task<ActionResult> Edit(int id)
{
var dinner = await mcx.Dinners
.Include(o => o.Chef)
.Include(o => o.Meals)
.Include(o => o.BonusMeal)
.SingleAsync(o => o.Id == id);
var input = new DinnerInput
{
Id = dinner.Id,
Name = dinner.Name,
ChefId = dinner.Chef.Id,
Date = dinner.Date,
MealsIds = dinner.Meals.Select(o => o.Id),
BonusMealId = dinner.BonusMeal.Id
};
return PartialView("Create", input);
}
[HttpPost]
public async Task<ActionResult> Edit(DinnerInput input)
{
return await save(input);
}
private async Task<ActionResult> save(DinnerInput input)
{
if (!ModelState.IsValid) return PartialView("Create", input);
var isCreate = !input.Id.HasValue;
var ent = isCreate ? new Dinner() :
await mcx.Dinners
.Include(o => o.Meals)
.FirstAsync(o => o.Id == input.Id);
ent.Name = input.Name;
ent.Date = input.Date.Value;
ent.Chef = await mcx.FindAsync<Chef>(input.ChefId);
// ToList req for EF
ent.Meals = await mcx.Meals
.Where(o => input.MealsIds.Contains(o.Id)).ToListAsync();
ent.BonusMeal = await mcx.FindAsync<Meal>(input.BonusMealId);
ent.Organic = input.Organic ?? false;
if (isCreate)
{
mcx.Add(ent);
}
await mcx.SaveChangesAsync();
if (isCreate)
{
// the create PopupForm's success function aweUtils.itemCreated expects the grid row model obj, to render and append the new row
return Json(MapToGridModel(ent));
}
// the edit PopupForm's success function aweUtils.itemEdited expects an obj with "Id" property
return Json(new { Id = ent.Id });
}
public async Task<ActionResult> Delete(int id)
{
var dinner = await mcx.FindAsync<Dinner>(id);
return PartialView(new DeleteConfirmInput
{
Id = id,
Type = "dinner",
Name = dinner.Name
});
}
[HttpPost]
public async Task<ActionResult> Delete(DeleteConfirmInput input)
{
await mcx.DeleteAsync<Dinner>(input.Id);
// the delete PopupForm's success function aweUtils.itemDeleted expects an obj with "Id" property
return Json(new { Id = input.Id });
}
}
}