Grid Inline Editing Cascade using Parent and ActivePanel


Binding inline awesome controls using ParentInline extension to get a cascade effect.
This way when we select some categories in the in one column, only those corresponding meals will be available for selection in the bound columns.
Using an active panel to display additional info regarding the selected categories.
Shared/Demos/GridInlineEditParent.cshtml
@{
var gridId = "gridInlPar";
}

<div class="bar">
<button type="button" onclick="$('#@gridId').data('api').inlineCreate()" class="awe-btn mbtn">Create</button>
</div>

@Html.InitDeletePopupForGrid(gridId, "GridInlineEditParent")


@(Html.Awe().Grid(gridId)
.Mod(o => o.PageInfo())
.InlEdit(new InlEditOpt { SaveUrl = Url.Action("Save", "GridInlineEditParent") })
.Url(Url.Action("GridGetItems", "GridInlineEditParent"))
.Groupable(false)
.Height(350)
.Columns(
new Column { Bind = "Id", Width = 100 }
.InlId(),

new Column { Header = "Categories", Prop = "CategoriesDisplay" }
.Inl(Html.Awe().CheckBoxList(new CheckBoxListOpt()
{
Name = "Categories",
Url = Url.Action("GetCategories", "Data"),
SelectAll = true
})),

new Column { Bind = "Meal.Name", Header = "Meal", Grow = 1.5 }
.InlDropdownList(
new DropdownListOpt
{
Name = "MealId",
Url = Url.Action("GetMeals", "Data"),
}
.ParentInl("Categories", "categories"))
.Inl(Html.Awe().ActivePanel(new ActivePanelOpt
{
Name = "panel1",
Url = Url.Action("CategoryContent", "GridInlineEditParent")
}
.Parameter("rowKey", ".(Id)")
.ParentInl("Categories", "category"))),

new Column { Prop = "Meals1Names", Header = "Meals1", Grow = 1.5 }
.InlMultiselect(
new MultiselectOpt
{
Name = "Meals1Ids",
Url = Url.Action("GetMeals", "Data"),
}
.ParentInl("Categories", "categories")),

Html.InlEditColumn(),
Html.InlDeleteColumn(gridId)))
Demos/Grid/GridInlineEditParentController.cs
public class GridInlineEditParentController : Controller
{
public IActionResult Index()
{
return View();
}

private object MapToGridModel(ParentMeal o)
{
return new
{
o.Id,

// for display
CategoriesDisplay = string.Join(", ", o.Categories.Select(c => c.Name)),
MealName = o.Meal.Name,
Meals1Names = string.Join(", ", o.Meals1.Select(m => m.Name)),

// for inline editing helpers to get value
Categories = o.Categories.Select(c => c.Id),
MealId = o.Meal.Id,
Meals1Ids = o.Meals1.Select(m => m.Id).ToArray()
};
}

public IActionResult CategoryContent(int[] category, string rowKey)
{
category = category ?? new int[] { };
var meals = Db.Meals.Where(o => category.Contains(o.Category.Id)).ToList();

ViewData["rowKey"] = rowKey;

return PartialView(meals);
}

public IActionResult GridGetItems(GridParams g)
{
var query = Db.ParentMeals.AsQueryable();

var gmb = new GridModelBuilder<ParentMeal>(query, g)
{
KeyProp = o => o.Id,
Map = MapToGridModel,
};

return Json(gmb.Build());
}

[HttpPost]
public IActionResult Save(ParentMealInput input)
{
if (ModelState.IsValid)
{
var isCreate = !input.Id.HasValue;

var ent = isCreate ? new ParentMeal() :
Db.ParentMeals.First(o => o.Id == input.Id);

ent.Categories = Db.Categories
.Where(o => input.Categories.Contains(o.Id)).ToList();

ent.Meal = Db.Find<Meal>(input.MealId);

// ToList req for EF
ent.Meals1 = Db.Meals
.Where(o => input.Meals1Ids.Contains(o.Id)).ToList();

if (isCreate)
{
Db.Add(ent);
}

return Json(new { });
}

return Json(ModelState.GetErrorsInline());
}

public IActionResult Delete(int id)
{
// check for presence
Db.Find<ParentMeal>(id);

return PartialView(new DeleteConfirmInput
{
Id = id
});
}

[HttpPost]
public IActionResult Delete(DeleteConfirmInput input)
{
Db.Remove(Db.Find<ParentMeal>(input.Id));

return Json(new { input.Id });
}
}
GridInlineEditParent/CategoryContent.cshtml
@using AweCoreDemo.Models
@model IEnumerable<Meal>

@if (!Model.Any())
{
<div>Please select a category</div>
}
else
{
<div>
Meals in the selected category: @string.Join(", ", Model.Select(o => o.Name))
</div>
}
<div>

@if (ViewData["rowKey"] != null)
{
<text>row key: @ViewData["rowKey"]</text>
}
| custom editor in activePanel:
@* context will give the checkbox an unique id, prefixed with the activepanel id *@
@using (Html.Awe().BeginContext())
{
@Html.Awe().CheckBox(new CheckBoxOpt { Name = "forDemoChk", Value = true, Enabled = false })
}
</div>



Comments