Tree grid inline editing


TreeGrid with inline editing, it also has lazy loading for nodes of level 2.
TreeGridInlineEditing/Index.cshtml
@{
var gridId = "inlineTreeGrid";
}
@Html.InitDeletePopupForGrid(gridId)
<div class="bar">
<button type="button" onclick="$('#@gridId').data('api')?.inlineCreate?.()" class="awe-btn">Create</button>
</div>
<script>
function addChild(model) {
return model.Id ? '<button class="awe-btn addChild" type="button">add child</button>' : '';
}

$(function() {
$('#@gridId').on('click', '.addChild', function() {
var row = $(this).closest('.awe-row');
$('#@gridId').data('api')?.inlineCreate?.({ parentId: row.data('k') }, { parent: row });
});
});
</script>
@(Html.Awex().Grid<TreeNode>(gridId)
.Url(Url.Action("CrudTree"))
.InlEdit(new InlEditOpt { SaveUrl = Url.Action("Save") })
.Columns(b =>{
b.Add(o => o.Name)
.InlString();

b.Add(o => o.Id, new Column { Width = 100 })
.Mod(o => o.InlineId().InlineHidden("parentId"));

b.Add(new Column { ClientFormatFunc = "addChild", Width = 120 });

b.Add(Html.InlEditDelColumn(gridId));
})
.Resizable()
.PageSize(3)
.Height(400))
Demos/Grid/TreeGridInlineEditingController.cs
public IActionResult Save(TreeNodeInput input)
{
if (!ModelState.IsValid) return Json(ModelState.GetErrorsInline()); ;

var edit = input.Id.HasValue;
var ent = edit ? Db.Find<TreeNode>(input.Id) : new TreeNode();

ent.Name = input.Name;

if (!edit)
{
if (input.ParentId.HasValue)
{
ent.Parent = Db.Find<TreeNode>(input.ParentId);
}

Db.Add(ent);
}

return Json(new { });
}

public IActionResult Delete(int id)
{
var node = Db.Find<TreeNode>(id);

return PartialView(new DeleteConfirmInput
{
Id = id,
Type = "node",
Name = node.Name
});
}

[HttpPost]
public IActionResult Delete(DeleteConfirmInput input)
{
var node = Db.Find<TreeNode>(input.Id);
DeleteNode(node);

return Json(new { node.Id });
}

public IActionResult CrudTree(GridParams g)
{
var rootsQuery = Db.TreeNodes.Where(o => o.Parent == null);

var gmb = new GridModelBuilder<TreeNode>(rootsQuery.AsQueryable(), g)
{
KeyProp = o => o.Id,
Map = MapNode
};

gmb.GetChildren = (node, nodeLevel) =>
{
// non lazy version
//var children = result.Where(o => o.Parent == node).ToArray();
//return children.AsQueryable();

var children = Db.TreeNodes.Where(o => o.Parent == node).AsQueryable();

children = gmb.OrderBy(children);

var count = children.Count();

// set this node as lazy when it's above level 1 (relative), it has children, and this is not a lazy request already
if (nodeLevel > 1 && count > 0 && g.Key == null) return Awe.LazyNode;

return children.ToArray();
};

gmb.GetItem = () =>
{
var id = Convert.ToInt32(g.Key);
var node = Db.TreeNodes.First(o => o.Id == id);
return node;
};

return this.AweJson(gmb.Build());
}

private object MapNode(TreeNode node)
{
return new { node.Name, node.Id };
}

private void DeleteNode(TreeNode node)
{
var children = Db.TreeNodes.Where(o => o.Parent == node).ToList();

foreach (var child in children)
{
DeleteNode(child);
}

Db.Remove(node);
}



Comments