I am facing a problem in kendo treeview. I have a tree with 'folders'. I enabled the drag and drop functionality but whenever i drop a folder into another folder, it is positioned as the last item of that folder where it was dropped.
My datasource is of type kendo.data.HierarchicalDataSource and the incoming data is sorted by the 'caption'/text alphabetically. I want the dropped node to be sorted alfabetically as well, so in some way i want to trigger a resort call to the node where the other node was dropped.
How would i achieve this?
I already tried defining the sort parameter in the kendo.data.HierarchicalDataSource object but this doesn't change much.
Under the hood, a HierarchicalDataSource is a DataSource that has an array of children (items) that are also DataSources. Often, the items are just treated like a normal field, and operations on the main DataSource are not done recursively on the children.
Sorting is an example of this. As you see on https://docs.telerik.com/kendo-ui/controls/navigation/treeview/how-to/binding/sort-child-nodes, you need to sort the children recursively yourself:
function setSort(items){
for(var i=0; i < items.length; i++){
if(items[i].hasChildren){
items[i].children.sort({field: "FullName", dir: "desc"});
setSort(items[i].children.view());
}
}
}
Related
I'm using RadListView and intercepting onItemLoading event.
Within that event, can I reference individual view elements inside the itemTemplate.
I see args.view._subViews - but I was wondering whether i could find element by name or something else. I assume id would not work because each item would have the same id.
You are correct getting by Id would only return the first one. However, if you have the reference to the ListView child group; using id will work to get the element out of a group.
Now if you use my NativeScript-Dom plugin then it is very simple; you can do:
var elements = RadListView.getElementsByClassName('someClass'); or RadListView.getElementsByTagName('Label'); or the newer functionality `
RadListView.runAgainstTagNames('Label', function(element) {
/* do something with this element */
});
And work with an array of elements that match your criteria.
Please also note that in a ListView that not all elements are preset; ListViews only have as many elements are needed to fill the ListView + 1 typically; so even if you have 2,000 items in the list view; you might only have 10 actual child ListView groups of elements. So when you did a GetElementsByTagNames('Label') you would only get 10 of them...
I have two NSTableViews both bound to their own NSArrayControllers and the user can drag & drop items from table A to table B. Now I want the dropped items in table B to be selected after insertion (so that the table can scroll to them). But it's not working.
The table view selection indexes are bound to the array controller indexes in IB.
Select Inserted Objects is checked on the array controllers in IB.
If I check arrayControllerB.selectedObjects it lists only the first inserted object, even if more were inserted.
Selection is never reflected in the associated table view.
Now, I could try to temporarily store the newly inserted objects in an array and then select them in the arrayControllerB via setSelectedObjects(), like this ...
func insertIndicesToTargetAC(indexSet:NSIndexSet)
{
let a = indexSet.toArray();
var tmpObjects = [AnyObject]();
for i in a
{
let sourceItem = sourceAC.arrangedObjects.objectAtIndex(i);
let obj:NSManagedObject = createNewFromSourceItem(sourceItem);
targetAC.addObject(obj);
tmpObjects.append(obj);
}
sourceAC.removeObjectsAtArrangedObjectIndexes(indexSet);
targetAC.setSelectedObjects(tmpObjects);
println("\(targetAC.selectedObjects)");
}
}
Here, setSelectedObjects() does show me the correct amount of newly inserted objects in the target AC but it still doesn't reflect the selection in the associated table view. Can somebody inaugurate me into the holy sanctuary of trivial Cocoa operations that persistently refuse to work?
I figured it out. I shall not attempt to tableView.reloadData() after the insertion. That will erase the selection.
I need the ability to add a random amount of subgrids to a jqgrid. Basically the subgrid is idential to the parent jqgrid apart from having their column headings hidden. Is there a way where I can define the grid once in say a js file method and have the grid id and data url passed in as a parameter and then append different versions of itself into its subGridRowExpand after its defined. It just seems very laborious to have to define multiple versions of the same jqgrid one inside the other.
Could I do something like
var i = 0;
var maxsubgrids = 5;
function CreateGrid(gridId, dataUrl) {
$(gridId).grid(
...... Grid definition
subGridRowExpand: function(subgrid_id, row_id) {
if (subgridcount < maxsubgrids){
CreateGrid('#subgridId' + i++, subgridDataURL);
}
}
......... continue with grid definition
}
I know the above isn't correct but just an idea, but I think it would be better if the grid could be just created once in a method and then find a way to insert the subGridRowExpand section afterwards. Is this even possible?
You should consider to use TreeGrid instead of Subgrids. It's important to understand that subitems of TreeGrid have always the same number of columns like it's parent elements. So I suppose it corresponds to requirements which you have. Of extending of tree node nodeid, parentid and n_level will be automatically added to the list of parameters of the URL (see the documentation).
I have the following code:
var cnt = 0;
$(document).ready(function () {
var data = [
{
"id": cnt++,
"text":"node_" + cnt
}
];
var tree = $("#treeview").kendoTreeView({
dataSource:kendo.observableHierarchy(data)
}).data("kendoTreeView");
$("#push").click(function () {
var pos = tree.dataItem(tree.select());
pos.items.push({id:cnt++, text:"node_" + cnt});
});
$("#append").click(function () {
var pos = tree.select();
tree.append({id:cnt++, text:"node_" + cnt}, pos);
});
$("#show").click(function () {
var data = tree.dataItem(".k-item:first");
$("#content").html(JSON.stringify(data, null, 2));
});
});
And there are two functions:
1. push: once selected a node in the tree, it uses dataItem to get current data item and pushes one additional node into it (child node). This should be valid since dataSource is an ObservableHierarchy object.
2. append: once selected a node in the tree, it uses append to introduce one additional node into it (child node). This was valid on previous release of KendoUI and modify the tree but should not reflect changes in the DataSource.
The question / problem is:
1. If I use append the tree is update (visually) but the dataItem is not updated.
2. If I use push then dataItem is update but not the tree.
3. If I select a node, use append and then push, the tree is visually updated and the model too.
It seems that the first time that I introduce a child append updates some internal structure and from there the tree 'observes' the observable hierarchy put if I directly push it then the tree does not observe the observable hierarchy.
How should I insert nodes dynamically being able to check the DataSource and get the current state of the tree?
NOTE This is with the latest version of KendoUI Q2.1024.
Ok so,I just got an answer on a ticket about this matter after 2 days.
It is indeed a BUG which is already fixed in the latest builds,but the builds are only available for customers with an active subscription...
It will be available for the rest of the community in the next official release (around March 2013).So currently the only solution is to purchase a commercial subscription and you will get immediate access to the new builds...
Kinda disappointed with all this commercial stuff since it is a bug..But anyway,nothing we can do about it..
At least we know we are not crazy,and in a few months we can replace our code with the fixed build. :P
Kinda my problem too at the moment since append doesn't update the dataSource at all and while push updates the dataSource,it does so only the first time I add a node,I can't even select that node afterwards until I save the dataSource and refresh the page.(or I get an pos.items is undifined error)
What I've though so far is that maybe we can use the push method that adds the child-node to the dataSource and try to force load the selected node's children in the dataSource everytime through treeview.dataSource.get(treeview.select()).load()
According to documentation here http://docs.kendoui.com/documentation/api/framework/node
If we can get the selected Node we can load it's children forcibly.But I haven't been able to have datasource.get() or dataSource.view()[] read the selected node so far..
PS I know this is not a complete answer but maybe it helps..
Ok, let me explain my scenario more clearly:
When a cell is edited, it becomes 'dirty' and I style it a certain way by adding a CSS class to the cell via javascript.
Then, if the user Sorts the grid, the styling is lost (I believe because all the rows are recreated) and I need a way to restore the styling to the appropriate cell/row after a Sort.
What I attempted to do is add an entry into data[] called 'status' and onCellChange I loop through data[] and match the args.item.Id to appropriate entry in data[].
grid.onCellChange.subscribe(function (e, args) {
var done = false;
for (var i = 0; i < data.length && !done; i++) {
if (data[i].id == args.item.id) {
data[i].status = "dirty";
done = true;
}
}
}
However, onSort I'm not sure how to match the sorted rows to the data array. (Since I have no args.item) I've attempted to do selector statements:
$(".slick-row")
to restyle the correct cells, but I have no way to associate the rows with their entry in data[].
1) There is no need to search for the item in your onCellChange handler - it is available at "args.item".
2) Sorting the "data" array will not wipe out your change to the item in #1.
3) You mention dynamically styling cells. I see no code for that. If your custom formatter is the piece of code that looks at "item.status" and renders it differently if it is dirty, then you don't have to do anything extra. Sorting the data and telling the grid to re-render will preserve the "dirty" cell styles.