dojo.tree has no node persistence - javascript

In my ASP.NET project I tried to use some dojo UI elements. My first attempt was a tree like it is shown in the dojo documentation. But the tree refuses to hold the state of the expanded nodes after refreshing the browser page.
require([
"dojo/ready", "dojo/_base/window", "dojo/store/Memory",
"dijit/tree/ObjectStoreModel", "dijit/Tree"
], function (ready, win, Memory, ObjectStoreModel, Tree) {
// Create test store, adding the getChildren() method required by ObjectStoreModel
var myStore = new Memory({
data: [
{ id: 'world', name: 'The earth', type: 'planet', population: '6 billion' },
{ id: 'AF', name: 'Africa', type: 'continent', parent: 'world'
},
{ id: 'EG', name: 'Egypt', type: 'country', parent: 'AF' },
{ id: 'KE', name: 'Kenya', type: 'country', parent: 'AF' },
{ id: 'Nairobi', name: 'Nairobi', type: 'city', parent: 'KE' },
{ id: 'Mombasa', name: 'Mombasa', type: 'city', parent: 'KE' },
{ id: 'SD', name: 'Sudan', type: 'country', parent: 'AF' },
{ id: 'Khartoum', name: 'Khartoum', type: 'city', parent: 'SD' },
{ id: 'AS', name: 'Asia', type: 'continent', parent: 'world' },
{ id: 'CN', name: 'China', type: 'country', parent: 'AS' },
{ id: 'IN', name: 'India', type: 'country', parent: 'AS' },
{ id: 'RU', name: 'Russia', type: 'country', parent: 'AS' },
{ id: 'MN', name: 'Mongolia', type: 'country', parent: 'AS' },
{ id: 'OC', name: 'Oceania', type: 'continent', population: '21 million', parent: 'world' },
{ id: 'EU', name: 'Europe', type: 'continent', parent: 'world' },
{ id: 'DE', name: 'Germany', type: 'country', parent: 'EU' },
{ id: 'FR', name: 'France', type: 'country', parent: 'EU' },
{ id: 'ES', name: 'Spain', type: 'country', parent: 'EU' },
{ id: 'IT', name: 'Italy', type: 'country', parent: 'EU' },
{ id: 'NA', name: 'North America', type: 'continent', parent: 'world' },
{ id: 'SA', name: 'South America', type: 'continent', parent: 'world' }
],
getChildren: function (object) {
return this.query({ parent: object.id });
}
});
// Create the model
var myModel = new ObjectStoreModel({
store: myStore,
query: { id: 'world' }
});
// Create the Tree. Note that all widget creation should be inside a dojo.ready().
ready(function () {
var tree = new Tree({
model: myModel,
persist: true
});
tree.placeAt("tree2");
tree.startup();
});
});
</script>
<div id="tree2"></div>
Cookies are activated. I want this to happen just on client side. Tried it with chrome, firefox and IE.

The id for the tree was missing. With id it works:
var tree = new Tree({
id: "yourtree",
model: myModel,
....

Related

React.Js. Mapping in nested array to update state

In React.js I have array of object:
arr = [
{
type: 'folder',
name: 'src',
id: '1',
files: [
{
type: 'folder',
name: 'name 1',
id: '2',
files: [
{ type: 'file', name: 'JSFile.js', id: '3' },
],
},
{
type: 'folder',
name: 'name 2 ',
id: '6',
files: [
{ type: 'file', name: 'File.js', id: '7' },
{ type: 'file', name: 'JSXfile.jsx', id: '14' },
type: 'folder',
name: 'name 1',
id: '6',
files: [
{ type: 'file', name: 'HTMLfile.html', id: '5' },
],
},
],
},
],
},
]
I have an array of objects, and I want to update this array with some object, for example something like this:
const onAddFile = () => {
const newFile = {
type: 'file',
name: 'SXfile',
id: "100,
}
const folderToPush = files: (1) [{…}],
id: "6",
name: "name 1 ",
type: "folder" <---this is folder which I have selected via click, which I have id of folder and array of files that I have push newFile. and update state instantly.
folderToPush.files.push(newFile)
}
expected output is something like this:
arr = [
{
type: 'folder',
name: 'src',
id: '1',
files: [
{
type: 'folder',
name: 'name 1',
id: '2',
files: [
{ type: 'file', name: 'JSFile.js', id: '3' },
],
},
{
type: 'folder',
name: 'name 2 ',
id: '6',
files: [
{ type: 'file', name: 'File.js', id: '7' },
{ type: 'file', name: 'JSXfile.jsx', id: '14' },
type: 'folder',
name: 'name 1',
id: '6',
files: [
{ type: 'file', name: 'HTMLfile.html', id: '5' },
{ type: 'file', name: 'SXfile.jsx', id: '100' }, <--- here is pushed object
],
},
],
},
],
},
]
I know it have to be some recursive function to map through whole array, but I have no idea how to implement this. Is there a way to make it, with useState only to see changes instantly?

How to split array of objects into arrays of objects connected with the same value for some property?

So I have this array of objects:
var users =
[
{ action: 'search', time: 1487098109, name: 'Charlie' },
{ action: 'search', time: 1487184715, name: 'Charlie' },
{ action: 'search', time: 1487184755, name: 'John' },
{ action: 'search', time: 1487271527, name: 'John' },
{ action: 'search', time: 1487271527, name: 'Mark' },
{ action: 'search', time: 1487271537, name: 'Mark' },
{ action: 'c', time: 1487098139, name: 'Mike' },
{ action: 'b', time: 1487098169, name: 'Mike' },
{ action: 'a', time: 1487098199, name: 'Mike' },
{ action: 'login', time: 1487098300, name: 'Mike' },
{ action: 'search', time: 1, name: 'Robert' },
{ action: 'search', time: 2, name: 'Robert' },
{ action: 'search', time: 1487098169, name: 'Woody' },
{ action: 'search', time: 1487271467, name: 'Woody' }
]
And I want to convert it into this structure which is an array of arrays of objects connects by the same name property:
[
[
{ action: 'search', time: 1487098109, name: 'Charlie' },
{ action: 'search', time: 1487184715, name: 'Charlie' }
],
[
{ action: 'search', time: 1487184755, name: 'John' },
{ action: 'search', time: 1487271527, name: 'John' }
],
[
{ action: 'search', time: 1487271527, name: 'Mark' },
{ action: 'search', time: 1487271537, name: 'Mark' }
],
[
{ action: 'c', time: 1487098139, name: 'Mike' },
{ action: 'b', time: 1487098169, name: 'Mike' },
{ action: 'a', time: 1487098199, name: 'Mike' },
{ action: 'login', time: 1487098300, name: 'Mike' }
],
[
{ action: 'search', time: 1, name: 'Robert' },
{ action: 'search', time: 2, name: 'Robert' }
],
[
{ action: 'search', time: 1487098169, name: 'Woody' },
{ action: 'search', time: 1487271467, name: 'Woody' }
]
]
So how can I accomplish this? Thank you in advance!
You can sort and then execute the function reduce to group the objects by name.
var users = [ { action: 'search', time: 1487098109, name: 'Charlie' }, { action: 'search', time: 1487184715, name: 'Charlie' }, { action: 'search', time: 1487184755, name: 'John' }, { action: 'search', time: 1487271527, name: 'John' }, { action: 'search', time: 1487271527, name: 'Mark' }, { action: 'search', time: 1487271537, name: 'Mark' }, { action: 'c', time: 1487098139, name: 'Mike' }, { action: 'b', time: 1487098169, name: 'Mike' }, { action: 'a', time: 1487098199, name: 'Mike' }, { action: 'login', time: 1487098300, name: 'Mike' }, { action: 'search', time: 1, name: 'Robert' }, { action: 'search', time: 2, name: 'Robert' }, { action: 'search', time: 1487098169, name: 'Woody' }, { action: 'search', time: 1487271467, name: 'Woody' } ];
var result = Object.values(users.sort((a, b) => a.name.localeCompare(b.name)).reduce((a, c) => {
(a[c.name] || (a[c.name] = [])).push(c);
return a;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Filter array by obj field and get new array with this obj field

I have const data, and i need filter cards array by obj field company
For example by company: 'Symu.co'
const data = {
lanes: [
{
id: 'lane1',
header: 'Quened',
label: '',
cards: [
{id: 'Task1', title: 'Wordpress theme', company: 'Symu.co', price: 1500, user: 'michelle'},
]
},
{
id: 'lane2',
header: 'Planning',
label: '',
cards: [
{id: 'Task2', title: 'Landing page', company: 'Google', price: 1500, user: 'jolene'},
{id: 'Task3', title: 'New website', company: 'Symu.co', price: 1500, user: 'lyall'},
{id: 'Task4', title: 'Dashboard', company: 'Microsoft', price: 1500, user: 'john'},
{id: 'Task5', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'dominic'},
]
},
{
id: 'lane3',
header: 'Design',
label: '',
cards: [
{id: 'Task6', title: 'New Logo', company: 'Google', price: 1500, user: 'michelle'},
{id: 'Task7', title: 'New website', company: 'JCD.pl', price: 1500, user: 'dominic'},
{id: 'Task8', title: 'New website', company: 'Themeforest', price: 1500, user: 'john'},
{id: 'Task9', title: 'Dashboard', company: 'JCD.pl', price: 1500, user: 'jolene'},
]
},
{
id: 'lane4',
header: 'Development',
label: '()',
cards: [
{id: 'Task10', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'john'},
{id: 'Task11', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle'},
{id: 'Task12', title: 'Dashboard', company: 'Google', price: 1500, user: 'dominic'},
]
},
{
id: 'lane5',
header: 'Testing',
label: '()',
cards: [
{id: 'Task13', title: 'Landing page', company: 'JCD.pl', price: 1500, user: 'lyall'},
]
},
{
id: 'lane6',
header: 'Production',
label: '()',
cards: [
{id: 'Task14', title: 'Landing page', company: 'Google', price: 1500, user: 'jolene'},
{id: 'Task15', title: 'New website', company: 'Themeforest', price: 1500, user: 'michelle'},
{id: 'Task16', title: 'Dashboard', company: 'Facebook', price: 1500, user: 'lyall'},
]
},
{
id: 'lane7',
header: 'Completed',
label: '()',
cards: [
{id: 'Task17', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'john'},
{id: 'Task18', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle'},
]
},
]
};
My code , but i don`t know how to right do it
for(let i = 0; i < data.lanes.length; i++) {
var changeCards = data.lanes[i].cards.filter(function(obj) {
return obj.company === 'Symu.co';
console.log(changeCards);
});
}
in output i need to get new var new array as example
in output i need to get new var new array as example
in output i need to get new var new array as example
in output i need to get new var new array as example
in output i need to get new var new array as example
in output i need to get new var new array as example
in output i need to get new var new array as example
var newArray = {
lanes: [
{
id: 'lane1',
header: 'Quened',
label: '',
cards: [
{id: 'Task1', title: 'Wordpress theme', company: 'Symu.co', price: 1500, user: 'michelle'
},
]
},
{
id: 'lane2',
header: 'Planning',
label: '',
cards: [
{id: 'Task3', title: 'New website', company: 'Symu.co', price: 1500, user: 'lyall'}
]
},
{
id: 'lane3',
header: 'Design',
label: '',
cards: [
]
},
{
id: 'lane4',
header: 'Development',
label: '()',
cards: [
{id: 'Task11', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle'},
]
},
{
id: 'lane5',
header: 'Testing',
label: '()',
cards: [
]
},
{
id: 'lane6',
header: 'Production',
label: '()',
cards: [
]
},
{
id: 'lane7',
header: 'Completed',
label: '()',
cards: [
{id: 'Task18', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle'},
]
},
]
};
But i dont know how to do it
Help please!
Thanks a lot
You can use the functions reduce, forEach and filter to build the desired output.
const data = { lanes: [ { id: 'lane1', header: 'Quened', label: '', cards: [ {id: 'Task1', title: 'Wordpress theme', company: 'Symu.co', price: 1500, user: 'michelle'}, ] }, { id: 'lane2', header: 'Planning', label: '', cards: [ {id: 'Task2', title: 'Landing page', company: 'Google', price: 1500, user: 'jolene'}, {id: 'Task3', title: 'New website', company: 'Symu.co', price: 1500, user: 'lyall'}, {id: 'Task4', title: 'Dashboard', company: 'Microsoft', price: 1500, user: 'john'}, {id: 'Task5', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'dominic'}, ] }, { id: 'lane3', header: 'Design', label: '', cards: [ {id: 'Task6', title: 'New Logo', company: 'Google', price: 1500, user: 'michelle'}, {id: 'Task7', title: 'New website', company: 'JCD.pl', price: 1500, user: 'dominic'}, {id: 'Task8', title: 'New website', company: 'Themeforest', price: 1500, user: 'john'}, {id: 'Task9', title: 'Dashboard', company: 'JCD.pl', price: 1500, user: 'jolene'}, ] }, { id: 'lane4', header: 'Development', label: '()', cards: [ {id: 'Task10', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'john'}, {id: 'Task11', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle'}, {id: 'Task12', title: 'Dashboard', company: 'Google', price: 1500, user: 'dominic'}, ] }, { id: 'lane5', header: 'Testing', label: '()', cards: [ {id: 'Task13', title: 'Landing page', company: 'JCD.pl', price: 1500, user: 'lyall'}, ] }, { id: 'lane6', header: 'Production', label: '()', cards: [ {id: 'Task14', title: 'Landing page', company: 'Google', price: 1500, user: 'jolene'}, {id: 'Task15', title: 'New website', company: 'Themeforest', price: 1500, user: 'michelle'}, {id: 'Task16', title: 'Dashboard', company: 'Facebook', price: 1500, user: 'lyall'}, ] }, { id: 'lane7', header: 'Completed', label: '()', cards: [ {id: 'Task17', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'john'}, {id: 'Task18', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle'}, ] },]};
function filterBy(target) {
return data.lanes.reduce((a, {id, header, label, cards}) => {
a.lanes.push({id, header, label, cards: cards.filter(({company}) => company === target)});
return a;
}, {lanes: []});
}
var result = filterBy('Symu.co');
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const filteredCards = cards.filter({ company } => company === 'Google');
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
var data = { lanes: [ { id: 'lane1', header: 'Quened', label: '', cards: [ { id: 'Task1', title: 'Wordpress theme', company: 'Symu.co', price: 1500, user: 'michelle' }, ] }, { id: 'lane2', header: 'Planning', label: '', cards: [ { id: 'Task2', title: 'Landing page', company: 'Google', price: 1500, user: 'jolene' }, { id: 'Task3', title: 'New website', company: 'Symu.co', price: 1500, user: 'lyall' }, { id: 'Task4', title: 'Dashboard', company: 'Microsoft', price: 1500, user: 'john' }, { id: 'Task5', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'dominic' }, ] }, { id: 'lane3', header: 'Design', label: '', cards: [ { id: 'Task6', title: 'New Logo', company: 'Google', price: 1500, user: 'michelle' }, { id: 'Task7', title: 'New website', company: 'JCD.pl', price: 1500, user: 'dominic' }, { id: 'Task8', title: 'New website', company: 'Themeforest', price: 1500, user: 'john' }, { id: 'Task9', title: 'Dashboard', company: 'JCD.pl', price: 1500, user: 'jolene' }, ] }, { id: 'lane4', header: 'Development', label: '()', cards: [ { id: 'Task10', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'john' }, { id: 'Task11', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle' }, { id: 'Task12', title: 'Dashboard', company: 'Google', price: 1500, user: 'dominic' }, ] }, { id: 'lane5', header: 'Testing', label: '()', cards: [ { id: 'Task13', title: 'Landing page', company: 'JCD.pl', price: 1500, user: 'lyall' }, ] }, { id: 'lane6', header: 'Production', label: '()', cards: [ { id: 'Task14', title: 'Landing page', company: 'Google', price: 1500, user: 'jolene' }, { id: 'Task15', title: 'New website', company: 'Themeforest', price: 1500, user: 'michelle' }, { id: 'Task16', title: 'Dashboard', company: 'Facebook', price: 1500, user: 'lyall' }, ] }, { id: 'lane7', header: 'Completed', label: '()', cards: [ { id: 'Task17', title: 'Mobile App', company: 'Facebook', price: 1500, user: 'john' }, { id: 'Task18', title: 'New website', company: 'Symu.co', price: 1500, user: 'michelle' }, ] },] }
var filter = c => data.lanes.reduce((a, v) =>
(a.push( { ...v, cards: v.cards.filter(v => v.company == c) } ), a), [])
console.log( filter('Symu.co') )

Dojo Tree with checkbox

I made dojo tree with checkbox.
but when I checked parent node, child node was not selected automatically.(not expanded child)
Only when I expand the tree once, after that, Child node can be selected when I click the parent checkbox.
Here is the code.
require([
"dojo/_base/window", "dojo/store/Memory",
"dijit/tree/ObjectStoreModel",
"dijit/Tree", "dijit/form/CheckBox","dojo/dom",
"dojo/domReady!"
], function(win, Memory, ObjectStoreModel, Tree, checkBox, dom){
// Create test store, adding the getChildren() method required by ObjectStoreModel
var myStore = new Memory({
data: [
{ id: 'world', name:'The earth', type:'planet', population: '6 billion'},
{ id: 'AF', name:'Africa', type:'continent', population:'900 million', area: '30,221,532 sq km',
timezone: '-1 UTC to +4 UTC', parent: 'world'},
{ id: 'EG', name:'Egypt', type:'country', parent: 'AF' },
{ id: 'KE', name:'Kenya', type:'country', parent: 'AF' },
{ id: 'Nairobi', name:'Nairobi', type:'city', parent: 'KE' },
{ id: 'Mombasa', name:'Mombasa', type:'city', parent: 'KE' },
{ id: 'SD', name:'Sudan', type:'country', parent: 'AF' },
{ id: 'Khartoum', name:'Khartoum', type:'city', parent: 'SD' },
{ id: 'AS', name:'Asia', type:'continent', parent: 'world' },
{ id: 'CN', name:'China', type:'country', parent: 'AS' },
{ id: 'IN', name:'India', type:'country', parent: 'AS' },
{ id: 'RU', name:'Russia', type:'country', parent: 'AS' },
{ id: 'MN', name:'Mongolia', type:'country', parent: 'AS' },
{ id: 'OC', name:'Oceania', type:'continent', population:'21 million', parent: 'world'},
{ id: 'EU', name:'Europe', type:'continent', parent: 'world' },
{ id: 'DE', name:'Germany', type:'country', parent: 'EU' },
{ id: 'FR', name:'France', type:'country', parent: 'EU' },
{ id: 'ES', name:'Spain', type:'country', parent: 'EU' },
{ id: 'IT', name:'Italy', type:'country', parent: 'EU' },
{ id: 'NA', name:'North America', type:'continent', parent: 'world' },
{ id: 'SA', name:'South America', type:'continent', parent: 'world' }
],
getChildren: function(object){
return this.query({parent: object.id});
}
});
// Create the model
var myModel = new ObjectStoreModel({
store: myStore,
query: {id: 'world'}
});
// Create the Tree.
var tree = new Tree({
model: myModel,
getIconClass:function(item, opened){
console.log('tree getIconClass', item, opened);
console.log('tree item type', item.type);
},
onClick: function(item, node) {
node._iconClass= "dijitFolderClosed";
node.iconNode.className = "dijitFolderClosed";
console.log(node.domNode.id);
var id = node.domNode.id, isNodeSelected = node.checkBox.get('checked');
console.log(isNodeSelected);
dojo.query('#'+id+' .dijitCheckBox').forEach(function(node){
dijit.getEnclosingWidget(node).set('checked',isNodeSelected);
});
},
_createTreeNode: function(args) {
var tnode = new dijit._TreeNode(args);
tnode.labelNode.innerHTML = args.label;
console.log('Tree created', args);
var cb = new dijit.form.CheckBox({id: args.item.id});
cb.placeAt(tnode.labelNode, "first");
tnode.checkBox = cb;
return tnode;
}
});
tree.placeAt(contentHere);
tree.startup();
//tree.expandAll();
});
http://jsfiddle.net/pyz9Lcpv/9/
This happens because before a node is opened in a tree, it's contents do not exist yet. They're loaded after a node is opened up in a tree. What you can do is plug into the tree's onOpen event and then decide there whether you should check the checkboxes of all the nodes that were just created.

How to change the defaults value for ObjectStoreModel in Dojo?

I am using Dojo ObjectStoreModel for a dijit/Tree widget.
I need to configure ObjectStoreModel to use property named parent_id instead of the default parent in order to match my data structure.
Any idea how to set this configuration?
var data = [
{
id: 'world',
name: 'The earth',
type: 'planet',
population: '6 billion'
},
{
id: 'EG',
name: 'Egypt',
type: 'country',
parent_id: 'AF' // does not work if property is called parent_id, only parent by default
},
{
id: 'Nairobi',
name: 'Nairobi',
type: 'city',
parent_id: 'KE'
},
{
id: 'Mombasa',
name: 'Mombasa',
type: 'city',
parent_id: 'KE'
},
{
id: 'SD',
name: 'Sudan',
type: 'country',
parent_id: 'AF'
},
];
var myStore = new Memory({
data: data,
getChildren: function (object) {
return this.query({ parent: object.id });
}
});
// Create the model
var myModel = new ObjectStoreModel({
store: myStore,
query: { id: '0' }
});
// Create the Tree.
var tree = new Tree({
model: myModel
});
tree.placeAt(this.domNode);
tree.startup();
I found the solution to my problem
http://dojotoolkit.org/reference-guide/1.10/dijit/tree/ObjectStoreModel.html
Stating: The dojo.store must implement it’s own getChildren() method.
So with this edit script works fine.
var myStore = new Memory({
data: data,
getChildren: function (object) {
return this.query({ parent_id: object.id });
}
});

Categories