Grid CRUD using Popup Demo
Built using the Grid and PopupForm helpers, initialized via `InitCrudPopupsForGrid`.
Each PopupForm has an assigned Success JavaScript function, located in `aweUtils.js`.
Post actions return a JSON object indicating success. This JSON includes an id property, used to flash the row upon success.
The Delete PopupForm uses an `OnLoad` JavaScript function to animate the row before deletion.
For PopupForm/Popup views use return PartialView to bypass _viewstart.cshtml, preventing _Layout.cshtml from being applied.
Each PopupForm has an assigned Success JavaScript function, located in `aweUtils.js`.
Post actions return a JSON object indicating success. This JSON includes an id property, used to flash the row upon success.
The Delete PopupForm uses an `OnLoad` JavaScript function to animate the row before deletion.
For PopupForm/Popup views use return PartialView to bypass _viewstart.cshtml, preventing _Layout.cshtml from being applied.
Shared/Demos/GridCrud.cshtml
@{
var gridId = "DinnersGrid";
}
@Html.InitCrudPopupsForGrid(gridId, "DinnersGridCrud")
<div class="bar">
<button type="button" class="awe-btn o-btnf" onclick="awe.open({id: 'create@(gridId)' })">
@MyAweIcons.PlusIco()
Create
</button>
<button type="button" class="awe-btn o-btnf"
onclick="awe.open({id: 'create@(gridId)', popupType: 'drawer', from: 'left', width: 0 })">
@MyAweIcons.PanelLeftIco()
Create drawer
</button>
<div style="margin-left: auto;">
@Html.Awe().TextBox("txtSearch").Placeholder("search...").CssClass("searchtxt")
</div>
</div>
@(Html.Awex().Grid<Dinner>(gridId)
.Main()
.Url(Url.Action("GridGetItems", "DinnersGridCrud"))
.Parent("txtSearch", "search")
.Attr("data-syncg", "dinner")
.Height(350)
.Columns(b =>
{
b.Add(o => o.Id).Width(75);
b.Add(o => o.Name);
b.Add(o => o.Date);
b.Add(o => new {o.Chef.FirstName, o.Chef.LastName});
b.Add(o => o.Meals.Select(m => m.Name)).Grow(2).MinWidth(200);
b.Add(o => o.BonusMeal.Name).Header("Bonus Meal");
b.Add(Html.EditDelColumn(gridId));
})
)
Demos/Grid/DinnersGridCrudController.cs
/// </summary>
/// parameters for Edit, Delete controller Actions need to remain called "id", that's how they are set in GridUtils.cs ( "params:{{ id:" );
/// <summary>
public class DinnersGridCrudController : Controller
{
public IActionResult GridGetItems(GridParams g, string search)
{
var gmb = new GridModelBuilder<Dinner>(Db.Dinners.AsQueryable(), g)
{
KeyProp = o => o.Id, // needed for api select, update, tree, nesting, EF
};
gmb.FilterContainsStr(o => o.Name, search);
return this.AweJson(gmb.Build());
}
public IActionResult 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 IActionResult Create(DinnerInput input)
{
return Save(input);
}
public IActionResult Edit(int id)
{
var dinner = Db.Dinners
.Single(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 IActionResult Edit(DinnerInput input)
{
return Save(input);
}
private IActionResult Save(DinnerInput input)
{
if (!ModelState.IsValid) return PartialView("Create", input);
var isCreate = !input.Id.HasValue;
var ent = isCreate ? new Dinner() :
Db.Dinners
.First(o => o.Id == input.Id);
ent.Name = input.Name;
ent.Date = input.Date.Value;
ent.Chef = Db.Find<Chef>(input.ChefId);
// ToList req when using EF
ent.Meals = Db.Meals
.Where(o => input.MealsIds.Contains(o.Id)).ToList();
ent.BonusMeal = Db.Find<Meal>(input.BonusMealId);
ent.Organic = input.Organic ?? false;
if (isCreate)
{
Db.Add(ent);
}
// json obj = success for the popupform, id is used to flash the row
return this.AweJson(new { Id = ent.Id });
}
public IActionResult Delete(int id)
{
var dinner = Db.Find<Dinner>(id);
return PartialView(new DeleteConfirmInput
{
Id = id,
Type = nameof(Dinner).ToLower(),
Name = dinner.Name
});
}
[HttpPost]
public IActionResult Delete(DeleteConfirmInput input)
{
Db.Delete<Dinner>(input.Id);
// delete PopupForm's success function will use the Id to animate the row
return this.AweJson(new { Id = input.Id });
}
}
DinnersGridCrud/Create.cshtml
@model AweCoreDemo.ViewModels.Input.DinnerInput
@using (Html.BeginForm())
{
using (Html.Awe().BeginContext())
{
<div class="eform">
<div class="earea">
@Html.EditorFor(o => o.Name)
@Html.EditorFor(o => o.Date)
@Html.EditorFor(o => o.ChefId)
</div>
<div class="earea">
@Html.EditorFor(o => o.BonusMealId)
@Html.EditorFor(o => o.MealsIds)
</div>
</div>
}
}
Grid Crud Inline Popup
Crud popups are open inline, using the inline popup, it will be open inside a div identified by html id.
GridCrudDemo/Index.cshtml
@{
var gridId = "GridInline1";
}
@Html.InitCrudPopupsForGrid(gridId, "DinnersGridCrud", inlineContId: "inlCont1")
<div class="bar">
@(Html.Awe().Button()
.Text("Create")
.OnClick(Html.Awe().OpenPopup("create" + gridId)))
<div style="margin-left: auto;">
@Html.Awe().TextBox("txtSearch1").Placeholder("search...").CssClass("searchtxt")
</div>
</div>
@(Html.Awex().Grid<Dinner>(gridId)
.Main()
.Url(Url.Action("GridGetItems", "DinnersGridCrud"))
.Parent("txtSearch1", "search")
.Attr("data-syncg", "dinner")
.Height(350)
.Columns(b =>
{
b.Add(o => o.Id, new Column { Width = 75 });
b.Add(o => o.Name);
b.Add(o => o.Date);
b.Add(o => new {o.Chef.FirstName, o.Chef.LastName});
b.Add(o => o.Meals.Select(m => m.Name)).Grow(2).MinWidth(200);
b.Add(o => o.BonusMeal.Name).Header("Bonus Meal");
b.Add(Html.EditDelColumn(gridId));
})
)
<script>
$(function () {
var inlc = $('#inlCont1');
inlc.on('aweopen', function () {
awe.flash(inlc);
});
});
</script>
<div id="inlCont1"></div>
Comments