Kendo TreeView: Can you edit a single dataitem without full tree update? - javascript

I'm currently running with kendo v2012.3.1315 and I am trying to edit a specific node in a tree view without a full tree view update.
I would like to be able to edit the name and have it reflect on the tree and any access to dataitem. Right now, I have been able to just overwrite the html but a) this could change due to template changes and b) when i access the dataitem later, it still has the old text.
The reasoning for this desired functionality is two fold: performance and consistent user interface.
Does anyone know if this is possible?
Thanks.

Find the element in the tree and update its .html() to the same value it would have if you would redraw the tree.

Related

Algorithm to update only the changed innerHTML of the document

I have 2 JS variables. before and after. They contains the SAME html document, but have some modification. About 1%-10% change between them. I want to update the body from before to after. The variablesbefore and after are raw string.
I can do something like that:
document.documentElement.innerHTML=after
The problem is that if I render this way it not look good. The render takes time, and there is a white screen between the renders. I want to show the user 10 modification in a second (video of modifications)
So what I want to do. I want to search and find only the elements that changed only by analyze the HTML text of before and after.
My way of solution:
I can find the changes and the position in the text using Javascript Library for diff & match & patch.
The question is:
After I find the text changes. How to find only the elements who changed. I update only those elements.
I thought, maybe to create a range, that contains every change, and update the range, but how exactly to do that?
If anything unclear, please comment, I will explain better.
I found a very good library for it: https://github.com/patrick-steele-idem/morphdom
Lightweight module for morphing an existing DOM node tree to match a
target DOM node tree. It's fast and works with the real DOM—no virtual
DOM here!
Very easy to use, and doing exactly what I need
If I have understood your question correctly, then what I would have done is,
1) Make a new object (view Object) which will control the rendering of DOM elements. (Similar to MVC)
2) In this object, I would have created 3 functions.
a) init function (contains the event-handlers)
b) render1 function (which will contain elements in before element)
c) render2 function (which will contain elements in after element)
Whenever there is an event where I need to change the HTML of a class/id/body/document, I will change that in init function and call render2 function which contains the after element.
This should not give any error, however the browser has to work to render all the page, but rendering can be divided over multiple elements of document. So, whenever you need to render a part of document, make separate render functions.
p.s. there can be different approaches.
You must implement the LCS(Longest Common Subsequence). To understand better of this algorithm you can watch this youtube video. Also It's easier to first study Longest Common Substring.
I think I have a solution. virtual-dom can do the work for me. I can create two VTree, make a diff, and apply a patch.
From the documentation of virtual-dom:
virtual-dom is what I need.
Manual DOM manipulation is messy and keeping track of the previous DOM
state is hard. A solution to this problem is to write your code as if
you were recreating the entire DOM whenever state changes. Of course,
if you actually recreated the entire DOM every time your application
state changed, your app would be very slow and your input fields would
lose focus.
virtual-dom is a collection of modules designed to provide a
declarative way of representing the DOM for your app. So instead of
updating the DOM when your application state changes, you simply
create a virtual tree or VTree, which looks like the DOM state that
you want. virtual-dom will then figure out how to make the DOM look
like this efficiently without recreating all of the DOM nodes.
virtual-dom allows you to update a view whenever state changes by
creating a full VTree of the view and then patching the DOM
efficiently to look exactly as you described it. This results in
keeping manual DOM manipulation and previous state tracking out of
your application code, promoting clean and maintainable rendering
logic for web applications.
https://github.com/Matt-Esch/virtual-dom

What's a good approach to creating a table in angular JS that highlights cells when they change?

I want to create an example of a table with dynamic data that also indicates when a table value has changed.
So imagine a table of data. One cell on one row changes it's value and it turns green to show that it has changed.
I'm new to Angular. I've been through the tutorial but I'm struggling to figure out the right kind of approach to this. I'm not asking for a step by step tutorial, but if an Angular veteran could give me a broad-strokes approach as to which parts of Angular I need to be focusing on, and a few tips on how best to structure the app, it would be a big help.
Right now I have an array of JSON objects attached to $scope.rows and a table with the rows created using ng-repeat. There's a button that changes some values in the rows data at random. That seems to be doing the trick of updating the rows as I expected, but I haven't figured out how to bridge that gap between data-binding and dom manipulation. And it's possible that my approach is all wrong.
You need to detect when your rows object changes and which element changed. I have done something similar by first creating a copy of your rows object then putting a watch on scope.rows (make sure you include the object equality flag). When the watch fires, loop through the scope.rows object and when you find the element that is different, put some boolean property on it and set it to true.
In your row DOM tag, use:
ng-class="{highlightRowCSSClass:row.boolProp, normalRowCSSClass:!row.boolProp }"
and set the highlightRowCSSClass to be whatever you want to indicate a changed element.
After you set the prop on the object, set the copy of the rows to what it currently is and wait for the watch to fire again. You will need to clear the old value off each element when you loop through it again so you don't have two elements that are "on".

AngularJS: Connecting data to model in a directive

My intent is to have some data displayed on a page and have any changes to it reflected in the model. However, the data needs to have specific manipulations applied before display, and remain connected to the model.
For example, if the data is an html fragment, I'd be wrapping it in a DIV with attribute contentEditable. However if it's a set of options, I'll be wrapping it in a UL and LIs, each of which containing a SPAN with attribute contentEditable.
In each case, the contentEditable part should remain connected to the model.
I'm working on a JSFiddle to try to make some inroads (starting with the case where the item is an html fragment) and have labelled points (2) and (3) where I'm currently stuck. Trying to:
a) Get the watch function to notice a change to the content
b) Maintain the two way binding between the displayed editable content and the model
My fiddle is here: http://jsfiddle.net/rAXmV/
Any suggestions for how I could approach this would be much appreciated.
Edit
I've been looking into using $compile to generate the output structure and it does look like it is getting the relevant data passed in. However it's still disconnected from the model:
http://jsfiddle.net/xRQ7M/
Edit 2
After some more hacking I have a working implementation for the contenteditable areas within the supplied HTML. It picks up the changes on focusout, which is the only way I could find that bubbled up from contenteditable areas within the processed html.
A more permanent JSFiddle is here: http://jsfiddle.net/donovanh/q6auY/
You can use the ngModelController directive to modify the data in a model and keep the data binding of the model.

jstree contextmenu with a foreign node

Currently I'm trying to figure out if it's possible to attach the default contextmenu jstree uses, to a foreign node ?
To explain my scenario please go to this link and go to the bottom of the page. In the first demo you can drag'n'drop a foreign node (being "I have the jstree-draggable class") to the folders in jstree.
I'm trying to understand if it's possible to attach the jstree contextmenu plugin to that foreign node?
Yeah it's possible to attach contextmenu to foreign nodes in jstree.
You should keep in mind, though, you'll need to rewrite a lot of code if you're using different html from what you have in the tree.
In my case this was not acceptable because I had to rewrite more than half of the library so I could get it to work with my html structure.
Creating a separate context menu (as #Jed suggested) is also an option - if you have the time to deal with all the problems that will come. :)

How to trigger rendering of JQuery treeview

I use jquery tree plugin to render hierarchical data.
I have coded additional functions which would allow user to interact with this data (like adding/deleting nodes, swapping nodes, etc...)
Currently this plugin supports that whenever you want to add any node, you can call following method,
$("#browser").treeview({
add: branches
});
here branches is jQuery object created with the HTML block, which would represent a particular node.
However, for delete and swapping of nodes, I use common JQuery functions like,
for delete,
$("#topnd2").remove();
for swapping,
var next = $("#topnd2").next();
$("#topnd2").insertAfter(next);
topnd2 is an id of any particular tree node.
The nodes get deleted / swapped properly but the problem is the tree does not get rendered and therefore the tree images (mainly vertical lines denoting branches) are not set properly.
For example, if I delete the last node then that node will be removed from rendered treeview but the remaining sibling node should get L as branch line image but not | .
I tried calling
$("#browser").treeview();
Please let me know your ideas.
Thanks,
Jatan
I found some workaround as given below,
Once the node is swapped up, virtually add its previous node to its child,
$("#browser").treeview({add:$("#topnd2").insertBefore(previous).next()});
If node is swapped down, virtuall add the current node to its next node.
$("#browser").treeview({add:$("#topnd2").insertAfter(next)});
currently it's working fine, will update this post, if I find any problems in this approach. Also please validate this approach if you know.
Regards,
Jatan
If you try to refresh the treeview again after node removal, the link will work but not the [+] or [-] icon. Tried this on several browsers..

Categories