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.Awe().Grid(gridId)
.Mod(o => o.Main())
.Url(Url.Action("GridGetItems", "DinnersGridCrud"))
.Parent("txtSearch", "search")
.Attr("data-syncg", "dinner")
.Height(350)
.Columns(
new Column { Bind = "Id", Width = 75 },
new Column { Bind = "Name" }.Mod(o => o.Nohide()),
new Column { Bind = "Date" },
new Column { Bind = "Chef.FirstName,Chef.LastName", Prop = "ChefName", Header = "Chef" },
new Column { Prop = "Meals", Header = "Meals", Grow = 2, MinWidth = 200 },
new Column { Bind = "BonusMeal.Name", Prop = "BonusMeal", Header = "Bonus Meal"},
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:" );
/// or in MapToGridModel additionally to o.MyId add another property Id = o.MyId
/// and for the action columns (edit, delete btns) you can either specify the MyId property (e.g. GridUtils.EditFormatForGrid("DinnersGrid", "MyId"));
/// change the Bind = "MyId" (if you have an Id column),
/// Note: If your Key Property is not "Id" (but "MyId"), you need to change the GridModelBuilder.Key = "MyId" in GridGetItems and in the view
/// <summary>
public class DinnersGridCrudController : Controller
{
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 IActionResult GridGetItems(GridParams g, string search = "")
{
var query = Db.Dinners
.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,
GetItem = () => Db.Get<Dinner>(Convert.ToInt32(g.Key)), // used when calling api.update (signalrSync.js)
};
return Json(model.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 for 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 Json(new { Id = ent.Id });
}
public IActionResult Delete(int id)
{
var dinner = Db.Find<Dinner>(id);
return PartialView(new DeleteConfirmInput
{
Id = id,
Type = "dinner",
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 Json(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.Awe().Grid(gridId)
.Mod(o => o.Main())
.Url(Url.Action("GridGetItems", "DinnersGridCrud"))
.Parent("txtSearch1", "search")
.Attr("data-syncg", "dinner")
.Height(350)
.Columns(
new Column { Bind = "Id", Width = 75 },
new Column { Bind = "Name" }.Mod(o => o.Nohide()),
new Column { Bind = "Date" },
new Column { Bind = "Chef.FirstName,Chef.LastName", Prop = "ChefName", Header = "Chef" },
new Column { Prop = "Meals", Header = "Meals", Grow = 2, MinWidth = 200 },
new Column { Bind = "BonusMeal.Name", Prop = "BonusMeal", Header = "Bonus Meal"},
Html.EditDelColumn(gridId)
))
<script>
$(function () {
var inlc = $('#inlCont1');
inlc.on('aweopen', function () {
awe.flash(inlc);
});
});
</script>
<div id="inlCont1"></div>
Comments