Grid inline editing conditional
rows with 1 meal are not editable
dates with year less than 2015 are readonly
Organic is editable only if isAdmin set to true (set to false in code)
dates with year less than 2015 are readonly
Organic is editable only if isAdmin set to true (set to false in code)
GridInlineEditDemo/ConditionalDemo.cshtml
@{ var grid = "DinnersGrid2"; }
@Html.InitDeletePopupForGrid(grid, "GridInlineEditDemo")
<div class="bar">
@Html.InlineCreateButtonForGrid(grid, new { DispOrganic = "" })
</div>
@{
var isAdmin = false;
}
@(Html.Awe().Grid(grid)
.Mod(o => o.PageInfo())
.Url(Url.Action("GridGetItems"))
.InlEdit(new InlEditOpt { SaveUrl = Url.Action("Save") })
.Height(350)
.Resizable()
.Columns(
new Column { Bind = "Id", Width = 75 }
.InlId(),
new Column { Bind = "Name" }
.InlString(),
new Column { Bind = "Date", Width = 170 }
.Mod(o => o.InlineFunc("dateCond")
.Inline("<input type='hidden' name='Date' value='#Value'/>#Value")
.Inline(Html.Awe().DatePicker("Date"))),
new Column { Bind = "Chef.FirstName,Chef.LastName", Prop = "ChefName", Header = "Chef", MinWidth = 200 }
.Inl(Html.Awe().Lookup("ChefId").Controller("ChefLookup"), "ChefId"),
new Column { Prop = "Meals", Header = "Meals", MinWidth = 200, Grow = 2}
.InlMultiselect(new MultiselectOpt { Name = "MealsIds", Url = Url.Action("GetMealsImg", "Data") }.ImgItem()),
new Column { Bind = "BonusMeal.Name", Prop = "BonusMeal", Header = "Bonus Meal" }
.InlDropdownList(new DropdownListOpt {
Name = "BonusMealId",
Url = Url.Action("GetMealsImg", "Data")
}
.ImgItem()),
new Column { Bind = "Organic", Width = 100, Prop = "DispOrganic" }
.Mod(o =>
{
if (isAdmin)
o.Inline(Html.Awe().Toggle(new ToggleOpt { Name = "Organic" }));
else
o.InlineReadonly(); // readonly, used if you set isAdmin = false
}),
new Column { ClientFormatFunc = "editff", Width = GridUtils.EditBtnWidth },
new Column { ClientFormatFunc = "delff", Width = GridUtils.DeleteBtnWidth }))
<script>
function dateCond(o, params) {
if (o.DateReadOnly) return params[0];
return params[1];
}
function editff(o) {
return o.Editable === false ? '': '@Html.Raw(GridUtils.InlineEditFormat())';
}
function delff(o) {
var format = @Html.Raw(DemoUtils.Encode(Html.InlineDeleteFormatForGrid(grid)));
format = format.split(".(Id)").join(o.Id);
return o.Editable === false ? '': format;
}
</script>
Demos/Grid/GridInlineEditDemoController.cs
using AweCoreDemo.Data;
using AweCoreDemo.Models;
using AweCoreDemo.Utils.Awesome;
using AweCoreDemo.ViewModels.Input;
using Microsoft.AspNetCore.Mvc;
using Omu.Awem.Utils;
using Omu.AwesomeMvc;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace AweCoreDemo.Controllers.Demos.Grid
{
public class GridInlineEditDemoController : Controller
{
private readonly MyContext mcx = new MyContext();// mock EF Db context
public GridInlineEditDemoController()
{
}
private 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,
o.Organic,
DispOrganic = o.Organic ? "Yes" : "No",
// below properties used for inline editing only
MealsIds = o.Meals.Select(m => m.Id).ToArray(),
ChefId = o.Chef.Id,
BonusMealId = o.BonusMeal.Id,
// for conditional demo
Editable = o.Meals.Count() > 1,
DateReadOnly = o.Date.Year < 2015
};
}
public async Task<IActionResult> 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());
// you can use .Build() for non EF datasource (like a List<Dinner> query)
// EFBuildAsync - custom extension for EF, you can copy it from demo source code
}
[HttpPost]
public async Task<IActionResult> Save(DinnerInput input)
{
// custom validation example
if (ModelState.IsValid && input.Name.Contains("asdf"))
{
ModelState.AddModelError("Name", "Name can't contain asdf");
}
if (ModelState.IsValid)
{
var isCreate = !input.Id.HasValue;
var ent = isCreate ? new Dinner() :
await mcx.Dinners
.Include(o => o.Meals)
.FirstOrDefaultAsync(o => o.Id == input.Id);
if (ent == null)
{
throw new Exception("Item doesn't exist anymore, 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();
return Json(new { Item = MapToGridModel(ent) });
}
return Json(ModelState.GetErrorsInline());
}
public async Task<IActionResult> 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<IActionResult> Delete(DeleteConfirmInput input)
{
mcx.Remove(await mcx.FindAsync<Dinner>(input.Id));
await mcx.SaveChangesAsync();
// the PopupForm's success function aweUtils.itemDeleted expects an obj with "Id" property
return Json(new { input.Id });
}
public IActionResult Index()
{
return View();
}
public IActionResult ConditionalDemo()
{
return View();
}
public IActionResult MultiEditorsDemo()
{
return View();
}
public IActionResult ClientSave()
{
return View();
}
public IActionResult AlwaysEdit()
{
return View();
}
}
}
Comments