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.Awe().Grid(gridId)
.Url(Url.Action("CrudTree"))
.InlEdit(new InlEditOpt { SaveUrl = Url.Action("Save") })
.Columns(
new Column { Bind = "Name" }
.InlString(),

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

new Column { ClientFormatFunc = "addChild", Width = 120},
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 Json(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