I'm using bootstrap-treeview to display a tree-like view of my data. The initial and basic implementation is working but I need it to when I click the text value, i get redirected to the link.
The JS function that renders the tree is:
function initTree(treeData) {
$('#treeview_json').treeview({
data: treeData,
enableLinks: true
});
// collapses all nodes
$('#treeview_json').treeview('collapseAll', { silent: true });
}
The enableLinks: true node property renders the link. But I could not find any documentation or example on the href property.
Does the link has to be supplied with the data or can it be built by the javascript?
You pass href as node attribute (see https://github.com/jonmiles/bootstrap-treeview#node-properties), so it is supplied with the data:
var tree = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1",
nodes: [
{
text: "Google",
href: "https://www.google.com"
},
{
text: "Twitter",
href: "https://www.twitter.com"
}
]
},
{
text: "Facebook",
href: "https://www.facebook.com"
}
]
}
];
Check this example: https://jsfiddle.net/beaver71/bvpncxko/
Remember you must have enableLinks:true
function initTree(treeData) {
$('#treeview_json').treeview({
data: treeData,
enableLinks: true,
});
}
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));
I am using fancytree with sortable extensions and I found 2 problems which I am trying to fight for hours. Maybe someone might help me.
The goal is to be able to sort between elements in the same nest level, but now I am only able to sort root nodes.
Second think is more important and I have no idea why it works like that. When I am trying to get fancytree nodes (of course i would like to get them in current sorted order), all the time I get same order without relying on view display.
I am using these event to get nodes: $('#tree').fancytree("getTree").toDict()
html:
<div id="tree"></div>
Javascript:
$(function() { // on page load
$("#tree").fancytree({
debugLevel: 0,
selectMode: 1,
extensions: ["dnd"],
source: [{
title: "Node 1",
key: "1",
"baloney": 44
},
{
title: "Node 2",
key: "2432"
},
{
title: "Folder 2",
key: "2",
folder: true,
children: [{
title: "Node 2.1",
key: "3",
myOwnAttr: "abc"
},
{
title: "Node 2.2",
key: "4"
},
{
title: "Node 2.3",
key: "5"
}, {
title: "Node 2.4",
key: "6"
}, {
title: "Node 2.5",
key: "7"
}
]
}
],
dnd5: {
preventForeignNodes: true,
preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
dragStart: function(node, data) {
return true;
},
dragEnter: function(node, data) {
return true;
},
dragDrop: function(node, data) {
data.otherNode.moveTo(node, data.hitMode);
},
activate: function(event, data) {
},
draggable: {
appendTo: "body",
connectToSortable: '#tree > ul',
containment: "parent",
revert: "invalid"
}
},
});
$('#tree > ul').sortable({
connectWith:"#fancytree",
out: function(event, ui) {
if (event.originalEvent.type === "mousemove") {
$(ui.item).data('drugout', true);
}
}
});
});
And here is fiddle link: Link
You need to add sortable to the child nodes also. Add the below code to fancytree initialization. This function basically observes child node expands and then activates sortable for the child nodes.
expand: function() {
$('.fancytree-has-children').siblings().sortable();
},
I have updated the jsfiddle also. Check the link: https://jsfiddle.net/3zmLfe1h/11/
Answer to your 2nd Question: I am not sure about it but I guess maybe fancytree is saving the order in some way and returning it to you whenever you are trying to get it. You can get all the values using jQuery and Sortable though.
I have to draw a representation of data using collapsible tree structure, i am using below example link for my purpose :
http://fperucic.github.io/treant-js/examples/collapsable/
But the problem i am facing is the above link had images at every node, i want to replace it with text which when i am doing it is generating the tree with correct branches but the text is not appearing.I am using my json like this:
{
"name":"sourcetable",
"children":[{"name":"MARD"},{"name":"MARD"},{"name":"MARD"},{"name":"MARD"}]
}
It comes something like this:
Let me know how i can show the name labels on the collapsible tree.
I think you are missing a bit:
nodeStructure: {
text: { name: "Parent node" },
children: [
{
text: { name: "First child" }
},
{
text: { name: "Second child" }
}
]
}
Taken from here:
http://fperucic.github.io/treant-js/
var simple_chart_config = {
chart: {
container: "#OrganiseChart-simple"
},
nodeStructure: {
text: { name: "Parent node" },
children: [
{
text: { name: "First child" }
},
{
[enter image description here][1]text: { name: "Second child" }
}
]
}
};
Demo Link:
https://fperucic.github.io/treant-js/examples/super-simple
I am using jquery's DataTables which is really working great. Then only problem I got is, that I am facing (in non-edit-view) the value of the select-field (which is an id). The user of course doesn't want to see the id of course.
Therefore I am looking for a possibility to configure that column in a way to show always the value of label property.
Here a some snippets:
$(document).ready(function() {
var table = $('#overviewTable').DataTable({
dom: "Tfrtip",
ajax: "/Conroller/GetTableData",
columns: [
{ data: "Id", className: "readOnly", visible: false },
{
data: "LoanTransactionId",
className: "readOnly readData clickable",
"fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='#'>" + oData.LoanTransactionId + "</a>");
}
},
{ data: "Id", className: "readOnly" },
{ data: "property_1", className: "readOnly" },
{ data: "Priority" },
{ data: null, className: "action readOnly", defaultContent: 'Info' }
],
order: [1, 'asc'],
tableTools: {
sRowSelect: "os",
sRowSelector: 'td:first-child',
aButtons: []
}
});
// data reload every 30 seconds
setInterval(function() {
table.ajax.reload();
}, 30000);
editor = new $.fn.dataTable.Editor({
ajax: "PostTable",
table: "#overviewTable",
fields: [
{
label: "Id",
name: "Id"
},
{
label: "Column 1",
name: "property_1"
},
{
label: "Priority",
name: "Priority",
type: "select",
options: [
{ label: "low", value: 0 },
{ label: "mid", id: 1 },
{ text: "high", id: 2 }
]
}
]
});
// Inline Edit - only those who are not readOnly
$('#overviewTable').on('click', 'tbody td:not(:first-child .readOnly)', function(e) {
editor.inline(this, {
submitOnBlur: true
});
});
How it looks in the display mode
How it looks in the edit mode
See the documentation on columns.render
You want to modify your column options for priority
Preferred Option: Your data source has a field with the priority as a string
This is the best option, as you don't want to have two places with this business logic. Keep it out of the client code.
Also, you will want to modify the editor as well so that the options used have been retrieved dynamically from the server to keep this business logic out of the client too. This is left as an exercise for the reader.
Since you don't provide details on what your data structure looks lik, I'm assuming it is an object, and it has an attribute priorityAsString so use the string option type for render.
columns: [
...
{
data: "Priority" ,
render: "priorityAsString",
},
Option 2) You write a function to map priority to string
Do this if you can't get the data from the server. But remember you will need to update many places when the priority list changes.
columns: [
...
{
data: "Priority" ,
render: renderPriorityAsString,
},
...
function renderPriorityAsString(priority) {
const priorityToString = {
0: 'low',
1: 'med',
2: 'high',
};
return priorityToString[priority] || `${priority} does not have a lookup value`;
}
"render": function ( data, type, full ) { return label;}
I have a kenodui treeview that I am trying to expand the top level nodes if they have the following values: "Active" or "Closed", the remaining nodes can remain closed. I am using the following code to create my treeview:
if (CI.Popup.treeview == null) {
CI.Popup.treeview = $("#RelatedPropertyListing").kendoTreeView({
template: "#= item.Name #",
dataImageUrlField: "image",
dataSource: CI.Popup.treeDS,
dataTextField: ["Name", "Name"],
encoded: true
}).data("kendoTreeView");
}
My datasource is defined as a json kendo.data.HierarchicalDataSource. I have tried generating the treeview using html instead of a datasource but it was unbareably slow so I have to use this method.
Any ideas how I can expand only those nodes that have a value of "Active" or "Closed"???
Thanks in advance for any help.
If you can slightly change your returned data, you can set expanded to true for each node that you want expanded and KendoUI will automatically take care of it.
Example:
var data = [
{
text : "node 1",
expanded: true,
items : [
{ text: "node 1.1" },
{
text : "node 1.2",
expanded: false,
items : [
{ text: "node 1.2.1" },
{ text: "node 1.2.2" },
{ text: "node 1.2.3" }
]
},
{ text: "node 1.3" }
]
}
];
var treeview = $("#treeview-left").kendoTreeView({
dataSource : data,
loadOnDemand: true
}).data("kendoTreeView");
JSFiddle in here