I need to create a folder structure in FTP similar to that of the tree structure on my view. I want to allow the user to edit the tree structure before creating folders.
I have a TreeView with server binding:
@model IEnumerable<TreeViewItemModel>
@(Html.Kendo().TreeView()
.Name("PipelineStructureMajor")
.BindTo(Model)
.ExpandAll(true)
.DragAndDrop(true)
)
The binding is fine. With some client-side restructuring (appending/dragging/removing some nodes), I want to post the treeview (root node with all its children recursively) to my action.
public ActionResult _CreateFtp(TreeViewItemModel root)
{
//FTPClient in action : Parsing whole tree and converting into the folder structure
return PartialView("_TreeMajor", <refreshed model>);
}
On the Client side, I tried to alert treeview data, it shows the root node text with its Items empty.
$('#createFtpConfirmed').click(function () {
//TreeView data
var treeData = $("#PipelineStructureMajor").data("kendoTreeView").dataSource.data();
alert(JSON.stringify(treeData));
$.ajax({
url:'@Url.Action("_CreateFtp", "Structure")',
data: {root: treeData},
type:"POST",
success: function (result, status, xhr) {
//Doing something useful
}
});
});
Is there a way to accomplish this?
As my question explains, I have 3 steps:
- Server-bind the default tree
- Edit nodes (delete, add, rename nodes)
- Fetch back all treeview data (including added ones)
After going through the kendo docs and this demo, I got the point. I have to make my tree datasource observable so as to reflect the node-changes. For this I had to use kendo-web-scripts (instead of server wrappers). So I changed my step 1 to:
- Remote bind the default tree (To make my dataSource observable)
I want my tree view fully loaded at once remotely and seeing this demo, I figured out that treeview only allows one level to be loaded at a time. (UserVoice already queued but Kendo team still ignoring it). So I use a hacky way:
<div id="PipelineStructureMajor"></div>
<button id="createandorinsert" class="k-button hugebtn">Send</button>
<script>
$.get("../Structure/LoadTreeData", function (data) {
var sat = new kendo.data.HierarchicalDataSource({
data: data
});
var pipelinetree = $("#PipelineStructureMajor").kendoTreeView({
dataSource: kendo.observableHierarchy(sat),
dragDrop: true,
select: onNodeSelect
}).data("kendoTreeView");
});
</script>
And I sent my data to the controller action like:
$('#createandorinsert').click(function (e) {
//TreeView's current datasource
var tree = $("#PipelineStructureMajor").data("kendoTreeView").dataSource.data();
$.ajax({
url: '../Structure/FtpCreateAndOrSync',
type: 'POST',
data: {
xmlNodes: JSON.stringify(tree)
},
beforeSend: function (xhr) {
alertSpan.removeClass().addClass("loading");
},
success: function (result, status, xhr) {
alertSpan.removeClass().addClass("success");
},
error: function (jqXhr, textStatus, errorThrown) {
alertSpan.removeClass().addClass("error");
}
});
});
And on the controller side, I Deserialized string json as: Just showing partial code
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FtpCreateAndOrSync(string xmlNodes)
{
//Deserializing nodes
var xmlNodesModels = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<IEnumerable<XmlNode>>(
xmlNodes).ToArray();
////Alternative
//var data = JsonConvert.DeserializeObject<IEnumerable<XmlNode>>(xmlNodes);
return Json(new { cr = createResult, dr = dbResult });
}
Hope this helps someone.