I am creating a treeview UI from the below Json, I have added the properties node-id, parentId to capture
the current expanded structure
I am planning to add a breadcrumb UI component from the selected tree structure.
var tree = [
{ name:"Insights", nodeId :"tree-node-0"},
{ name:"Level1", nodeId :"tree-node-1", parentId: "tree-node-0"},
{ name:"Level2", nodeId :"tree-node-2", parentId:"tree-node-1"},
{ name:"Details", nodeId :"tree-node-10"},
{ name:"SubDetails", nodeId :"tree-node-11", parentId:"tree-node-10"},
{ name:"Summary", nodeId :"tree-node-12", parentId:"tree-node-11"},
];
Below is the tree
Insights
|
|---Level1
|
|--Level2
Details
|
|--SubDetails
|
|--Summary
If the user selectes Summary then i want to create a breadCrumb which display links like Details-->SubDetails-->Summary
. I am assuming to populate the selected structure nodes into an array and then it would be easy to populate breadcrumb from the array.
If the user selects Summary then from the selected node parentId i want to traverse through the JSON array and find the path.
Need help in above logic
var tree = [{
name: "Insights",
nodeId: "tree-node-0"
}, {
name: "Level1",
nodeId: "tree-node-1",
parentId: "tree-node-0"
}, {
name: "Level2",
nodeId: "tree-node-2",
parentId: "tree-node-1"
}, {
name: "Details",
nodeId: "tree-node-10"
}, {
name: "SubDetails",
nodeId: "tree-node-11",
parentId: "tree-node-10"
}, {
name: "Summary",
nodeId: "tree-node-12",
parentId: "tree-node-11"
},
];
function test(Name, testData) {
var testData = testData || [];
var node = tree.find(function(item) {
return item.name == Name;
});
if (node) {
testData.push(node.name);
var parent = tree.find(function(item) {
return item.nodeId == node.parentId;
});
if (parent) {
return test(parent.name, testData);
} else {
return testData;
}
} else {
return testData;
}
}
console.log(test('Summary'));
i added it to display in console , you can check in console
Updated the code
Related
Hey I'm trying to implement nested drag&drop within re-order sequencesin my MERN app. I working to find ideal approach for mongodb data model and implement to Lexicographic order or linked lists for infinite sub folders. I used Model Tree Structures in this link but every node have limitless children for that require recursion and recursive functions or currying. Documentations not clear enough for make do that.
I want show all tree once and not sohuld appear after than click to arrow icon.There is my doodles for front side generation that working with only one depth such like graph nodes. Maybe Modified Preorder Tree Traversal implementation examples you have for this scenario.
const tree = data => { // immutable array
let ascendants = data.filter(d=>d.parent==null)
let descandants = data.filter(d=>d.parent)
**strong text**
let form = []
ascendants.map(a=>{
let node1 = {...a}; /// copying
let node1Children = [];
descandants.map(b=>{
let node2 = {...b};
if(node1._id == b.parent){
node1Children.push(node2)
}
})
node1.children = node1Children;
form.push(node1);
})
return form;
}
I cant take result with using $graphLookup because list format is not what i want.Could you give me some mongodb playground or grouping aggregate solutions? Below json examples shown my expecting results. I can do before but hardcode is unapropriate and performless. Is comparing good way?
[
// mongo database
{_id:123, title:'Books', slug:'books', parent:null },
{_id:124, title:'Programming', slug:'programming', parent:null },
{_id:125, title:'JavaScript', slug:'javascript', parent:'programming' },
{_id:126, title:'C++',slug:'cpp', parent:'programming' },
{_id:127, title:'React', slug:'react', parent:'javascript' },
{_id:128, title:'Redux', slug:'redux', parent:'react' },
{_id:129, title:'Toolkit', parent:'redux' },
{_id:130, title:'Saga', parent:'redux' },
{_id:131, title:'Nodejs', parent:'programming' },
{_id:132, title:'Databases', slug:'databases' },
{_id:133, title:'MongoDB', parent:'databases' },
]
[
// what i want
{ title: "Books"},
{ title: "Programming", parent:"computer-science", children: [
{ title: "JavaScript", children: [
{ title: "React", children: [
{ title: "Redux", children: [
{ title: "Saga" },
{ title: "Thunk" },
{ title: "Mobx" },
{ title: "Observable" },
{ title: "Context" },
{ title: "GraphQL" },
{ title: "Toolkit", children:[
{ title: "typescript" },
{ title: "slices", children:[
{ title: "createAsyncThunk" },
{ title: "createSlice" },
] },
] },
] },
{ title: "Nextjs" },
]},
{ title: "Vue", },
{ title: "angular", },
]},
{ title: "C++", },
{ title: "NodeJS", },
] },
{ title: "MongoDB", parent: "databases"},
]
You could create a Map to key your objects by slug. The values per key will be the result objects for parent objects. Include an entry for null, which will collect the top-level elements.
Then iterate the data again to populate children arrays -- when that property does not exist yet, create it on the fly. Finally output the top-level elements.
function makeTree(data) {
let children = []; // Top-level elements
let map = new Map(data.map(({title, slug}) => [slug, { title }]))
.set(null, {children});
for (let {slug, parent, title} of data) {
(map.get(parent || null).children ??= [])
.push(slug ? map.get(slug) : {title});
}
return children;
}
// Your mongodb data:
const data = [{_id:123, title:'Books', slug:'books', parent:null },{_id:124, title:'Programming', slug:'programming', parent:null },{_id:125, title:'JavaScript', slug:'javascript', parent:'programming' },{_id:126, title:'C++',slug:'cpp', parent:'programming' },{_id:127, title:'React', slug:'react', parent:'javascript' },{_id:128, title:'Redux', slug:'redux', parent:'react' },{_id:129, title:'Toolkit', parent:'redux' },{_id:130, title:'Saga', parent:'redux' },{_id:131, title:'Nodejs', parent:'programming' },{_id:132, title:'Databases', slug:'databases' },{_id:133, title:'MongoDB', parent:'databases' }];
console.log(makeTree(data));
Hi i am using openui5 tree.by default first my first node to be selected.
for that i would like to use fireSelect event of tree.
what are the parameters to be pass for fireSelect?
var oData = {
root:{
name: "root",
0: {
name: "item1",
0: {
name: "subitem1",
0: {
name: "subsubitem1"
},
1: {
name: "subsubitem2"
}
},
1: {
name: "subitem2",
0: {
name: "subsubitem3"
}
}
},
1:{
name: "item2",
0: {
name: "subitem3"
}
}
}
};
var oModel = new sap.ui.model.json.JSONModel();
// set the data to the model
oModel.setData(oData);
var oTree = new sap.ui.commons.Tree("tree");
oTree.setWidth("100%");
// set the model to the tree
oTree.setModel(oModel);
var oTreeNodeTemplate = new sap.ui.commons.TreeNode("node");
oTreeNodeTemplate.bindProperty("text", "name");
oTreeNodeTemplate.setExpanded(true);
oTree.bindAggregation("nodes", "/root", oTreeNodeTemplate);
//oTree.fireSelect(item1,/root/1);
oTree.placeAt("body");
here item1 to be selected by default.and then user can select any node.
i am using this as dropdown box which contains hierarchical options.
is it possible to add filter for tree nodes?
here my exmple https://jsbin.com/gekazarife/edit?html,js,output
To select first node of Tree invoke setIsSelected on a first node of tree.
oTree.getNodes()[0].setIsSelected(true);
Demo
First of all i am very new to React JS. So that i am writing this question. I am trying this for three days.
What I have to do, make a list of category, like-
Category1
->Sub-Category1
->Sub-Category2
Categroy2
Category3
.
.
.
CategoryN
And I have this json data to make the listing
[
{
Id: 1,
Name: "Category1",
ParentId: 0,
},
{
Id: 5,
Name: "Sub-Category1",
ParentId: 1,
},
{
Id: 23,
Name: "Sub-Category2",
ParentId: 1,
},
{
Id: 50,
Name: "Category2",
ParentId: 0,
},
{
Id: 54,
Name: "Category3",
ParentId: 0,
},
];
I have tried many open source examples, but their json data format is not like mine. so that that are not useful for me. I have build something but that is not like my expected result. Here is my jsfiddle link what i have done.
https://jsfiddle.net/mrahman_cse/6wwan1fn/
Note: Every subcategory will goes under a category depend on "ParentId",If any one have "ParentId":0 then, it is actually a category, not subcategory. please see the JSON
Thanks in advance.
You can use this code jsfiddle
This example allows to add new nested categories, and do nested searching.
code with comments:
var SearchExample = React.createClass({
getInitialState: function() {
return {
searchString: ''
};
},
handleChange: function(e) {
this.setState({
searchString: e.target.value.trim().toLowerCase()
});
},
isMatch(e,searchString){
return e.Name.toLowerCase().match(searchString)
},
nestingSerch(e,searchString){
//recursive searching nesting
return this.isMatch(e,searchString) || (e.subcats.length && e.subcats.some(e=>this.nestingSerch(e,searchString)));
},
renderCat(cat){
//recursive rendering
return (
<li key={cat.Id}> {cat.Name}
{(cat.subcats && cat.subcats.length) ? <ul>{cat.subcats.map(this.renderCat)}</ul>:""}
</li>);
},
render() {
let {items} = this.props;
let {searchString} = this.state;
//filtering cattegories
if (searchString.length) {
items = items.filter(e=>this.nestingSerch(e,searchString))
console.log(items);
};
//nesting, adding to cattegories their subcatigories
items.forEach(e=>e.subcats=items.filter(el=>el.ParentId==e.Id));
//filter root categories
items=items.filter(e=>e.ParentId==0);
//filter root categories
return (
<div>
<input onChange={this.handleChange} placeholder="Type here" type="text" value={this.state.searchString}/>
<ul>{items.map(this.renderCat)}</ul>
</div>
);
}
});
I'm trying to get the id or name of the selected folder in a fuelux tree but couldnt manage to get it done.
My tree is a classic folder/file type tree and I want to be able to see the id of the folder when I click on a file.
this is my datasource for tree
var treeDataSource = new DataSourceTree({
data: [
{ name: 'Elektronik Belgelerim', type: 'folder', 'icon-class': 'blue', additionalParameters: { id: 'F1' } },
{ name: 'Gelen Kutusu', type: 'folder', 'icon-class': 'blue', additionalParameters: { id: 'F2' } },
{ name: 'Giden Kutusu', type: 'folder', 'icon-class': 'blue', additionalParameters: { id: 'F3' } },
{ name: 'Çöp Kutusu', type: 'folder','icon-class':'green', additionalParameters: { id: 'I1' } },
//{ name: 'Çöp Kutusu', type: 'item', 'icon-class': 'success', additionalParameters: { id: 'F4' } },
//{ name: 'Reports', type: 'item', additionalParameters: { id: 'I1' } },
//{ name: 'Finance', type: 'item', additionalParameters: { id: 'I2' } }
],
delay: 400
});
js function for tree begins like this inside tree-custom.js
var e = function (e, i) {
this.$element = t(e), this.options = t.extend({}, t.fn.tree.defaults, i), this.$element.on("click", ".tree-item", t.proxy(function (t) {
this.selectItem(t.currentTarget)
}, this)), this.$element.on("click", ".tree-folder-header", t.proxy(function (t) {
this.selectFolder(t.currentTarget)
}, this)), this.render()
};
and this is where I add the links under folders again inside trree-custom.js. Very primitive I know but that's all I can do with my current skillset. The part I added is between quotes. Rest came with beyondadmin theme and looks like usual fuelux.
selectFolder: function (e) {
//alert("testselectFolder");
//
//alert($('#myTree').tree({ dataSource: dataSource }));
var i, n, r, o = t(e),
s = o.parent(),
a = s.find(".tree-folder-content"),
l = a.eq(0);
//-----------------------------------------------
var li = $('<li>');
var TcgbLink = $('<a href=/E-Belge/Main/Folder/Inbox/?Type=1&DocumentTypeId=3>e-TCGB</div>' +"</br>");
var FaturaLink = $('<a href=/E-Belge/Main/Folder/Inbox/?Type=1&DocumentTypeId=4>e-Fatura</div>' + "</br>");
var Dolasim = $('<a href=>e-Dolasim Belgesi</div>');
li.append(FaturaLink);
a.append(li);
li.append(TcgbLink);
a.append(li);
li.append(Dolasim);
a.append(li);
//-----------------------------------------------
o.find(".fa.fa-folder").length ? (i = "opened", n = ".fa.fa-folder", r = "fa fa-folder-open", l.show(), a.children().length || this.populate(o)) : (i = "closed", n = ".fa.fa-folder-open", r = "fa fa-folder", l.hide(), this.options.cacheItems || l.empty()), s.find(n).eq(0).removeClass("fa fa-folder fa-folder-open").addClass(r), this.$element.trigger(i, o.data())
},
Now these links are being generated under all 4 folders. I want to be able to get the id (or name, preferably Id) of the folder so I can assign new Type parameters to querystring.
So far I tried to reach the id with this.data.id to no avail.
Instead of injecting the folder's children in the selectFolder callback, it is recommended to add the children via the dataSource callback (as in this example code: http://getfuelux.com/javascript.html#tree-usage-javascript).
The first argument to the dataSource is the "parent data" when you click on a tree node (with the second argument being the callback that you send the new array of child data).
This way you can use the selected event for getting your ID, because it gets the jQuery data passed to it.
I'm currently struggling with implementing a jQuery plugin to my site for tags (with custom data objects) with autocomplete. jQuery TextExt can be found here (http://textextjs.com/). I'm currently struggling with using custom data objects for each tag, which can only be chosen from what autocompletes. Based on this example (http://textextjs.com/manual/examples/tags-with-custom-data-objects.html) I'm trying to figure out how to return both "name" and "id" when a tag is chosen. Does anyone know how to achieve this or point me in the correct direction?
Perhaps the answer is somewhere in this example (http://textextjs.com/manual/examples/filter-with-suggestions.html)?
Here's what I have written, which isn't working (it only returns the name, I've tried adding 'item.id' to the functions but that didn't work for me either):
<script type="text/javascript">
jQuery(document).ready(function( $ ){
jQuery('#textarea').textext({
plugins: 'tags',
items: [
{ name: 'PHP', id: '1' },
{ name: 'Closure', id: '2' },
{ name: 'Java', id: '3' }
],
ext: {
itemManager: {
stringToItem: function(str)
{
return { name: str };
},
itemToString: function(item)
{
return item.name ;
},
compareItems: function(item1, item2)
{
return item1.name == item2.name;
}
}
}
});
})
</script>
Your itemManager code should probably look like this, you will need to store the suggestions in a custom array to look up their relevant ids in the stringToItem Method
itemManager: {
items: [], // A custom array that will be used to lookup id
stringToItem: function(str)
{
//Lookup id for the given str from our custom array
for (var i=0;i<this.items.length;i++)
if (this.items[i].name == str) {
id = this.items[i].id;
break;
}
return { name: str, id: id };
},
itemToString: function(item)
{
//Push items to our custom object
this.items.push(item);
return item.name ;
},
compareItems: function(item1, item2)
{
return item1.name == item2.name;
}
}