I would like to build a tree dynamically in angularjs, the structure is retrieved as follows from the database.
[{
"TreeName":"String content",
"Level":0,
}],
[{
"TreeName":"String content",
"Level":0,
}],
[{
"TreeName":"String content",
"Level":1,
}],
[{
"TreeName":"String content",
"Level":2,
}],
[{
"TreeName":"String content",
"Level":2,
}],
[{
"TreeName":"String content",
"Level":1,
}],
[{
"TreeName":"String content",
"Level":2,
}],
[{
"TreeName":"String content",
"Level":3,
}],
[{
"TreeName":"String content",
"Level":1,
}]
If level 0 then its main node and level 1 becomes parent node and level 2 becomes that parents child node and level 3 becomes that childs child node and so forth.
I have tried many examples and doesnt work, the only thing is that I thought was to do a lot of if statements but i need a shorter and more efficient way.
You can use jsTree.jsTree is jquery plugin, that provides interactive trees. It is absolutely free, open source and distributed under the MIT license. jsTree is easily extendable, themable and configurable, it supports HTML & JSON data sources and AJAX loading. You can find more detail on https://www.jstree.com/
Here is the code
$('#jstree_demo').jstree({
"core" : {
"animation" : 0,
"check_callback" : true,
"themes" : { "stripes" : true },
'data' : {
'url' : function (node) {
return node.id === '#' ?
'ajax_demo_roots.json' : 'ajax_demo_children.json';
},
'data' : function (node) {
return { 'id' : node.id };
}
}
},
"types" : {
"#" : {
"max_children" : 1,
"max_depth" : 4,
"valid_children" : ["root"]
},
"root" : {
"icon" : "/static/3.3.2/assets/images/tree_icon.png",
"valid_children" : ["default"]
},
"default" : {
"valid_children" : ["default","file"]
},
"file" : {
"icon" : "glyphicon glyphicon-file",
"valid_children" : []
}
},
"plugins" : [
"contextmenu", "dnd", "search",
"state", "types", "wholerow"
]
});
Also you can find working demo on https://www.jstree.com/demo/
And here is the format of data to use jstree https://www.jstree.com/docs/json/
Related
Right now, the code is working for all the strings I passed however, I can't retrieve my images from storage and see the fieldId needed. I followed the documentation of flamelink-js-sdk but it doesn't seem to clarify what should be done for images.
Here's a sample of my code:
async created() {
app.content
.get({
schemaKey: "teamPage",
populate: [
{
field: "title"
},
{
field: "description"
},
{
field: "executiveBoard",
fields: [
"title",
"position",
"image",
"facebook",
"github",
"linkedin"
]
}
]
})
.then(teamPage => {
this.teamPage = teamPage;
console.log(this.teamPage.executiveBoard[0].image);
})
.catch(error => console.log(error));},
Here's where I render them
<team-circle
v-for="board in teamPage.executiveBoard"
:key="board.title"
class="col-12 col-sm-12 col-md-4"
:name="board.title"
:image="board.image"
:facebook="board.facebook"
:linkedin="board.linkedin"
:github="board.github"
>{{ board.position }}</team-circle>
Check this link to see what data is passed in the src of the img tag
Thank you again. Hope you can help me out on this!
You can do the following
app.content
.get({
schemaKey: "teamPage",
populate: [
{
field: "title"
},
{
field: "description"
},
{
field: "executiveBoard",
fields: [
"title",
"position",
"image",
"facebook",
"github",
"linkedin"
],
populate: ["image"]
}
]
})
note the populate: ["image"] addition (see this)
this.teamPage.executiveBoard[0].image will now be an array of objects example
[{
contentType: "image/png",
id: "xxx",
...
url: "https://firebasestorage.googleapis.com/v0/b/....."
}]
you can then access the url for example like this
this.teamPage.executiveBoard[0].image[0].url
I have a simple dojo treeGrid that is categorized just by first column. But how to make it categorized/collapsible by second as well? Note the treeGrid has totals shown in each category. Also, is there a way to move totals to the category level but not to the bottom?
var layout = [
{ cells: [
[ {field: "year", name: "Year"},
{field: "childItems",
children: [ { field: "unid", name: "unid", hidden: true},
{ field: "geography", name: "Geography"},
{ field: "country", name: "Coungtry"},
{ field: "status", name: "Status"},
{ field: "credit", name: "Credit"},
{ field: "debit", name: "Debit"}
],
aggregate: "sum"
}
]] } ]
var jsonStore = new dojo.data.ItemFileWriteStore({ url: <...............>});
var grid = new dojox.grid.TreeGrid({
structure: layout,
store: jsonStore,
query: {type: 'year'},
queryOptions: {deep: true},
rowSelector: true,
openAtLevels: [false],
autoWidth: true,
autoHeight: true
},
dojo.byId("treeGrid"));
grid.startup();
dojo.connect(window, "onresize", grid, "resize");
sample JSON store:
{
"identifier": "id",
"label": "name",
"items": [
{
"id": "2018",
"type": "year",
"year": "2018",
"childItems": [
{
"id": "id0",
"geography": "Asia Pacific",
"country": "Australia",
"programname": "Program 1",
"totalPlanned": 0,
"totalForecasted": 0
},
{
.....
}
]
},
{
.....
}
]
}
You can find completely working example over here:
Now, let me try to explain it:
Data
First of all to support multiple levels in the grid you must have your data in the same format. For tree with n levels, you need to have n-1 level grouping in your data itself.
For example, JSON object below have 2 levels of grouping (year, geography) to support tree with 3 levels (root, parent, and child).
{
"identifier":"id",
"label":"name",
"items":[
{
"id":"2018",
"type":"year",
"year":"2018",
"geography":[
{
"id":"id1",
"geography":"Asia Pacific",
"childItems":[
{
"id":"ci1",
"country":"Australia",
"programname":"Program 1",
"credit":100,
"debit":50
}
]
}
]
}
]
}
Layout
To render a tree with n-levels you have to make sure layout of the tree is properly configured with same nesting as your data. To support data structure from JSON object above you need to set layout to:
[
{
cells:
[
[
{ field:"year", name:"Year" },
{
field:"geography",
children:
[
{ field:"geography", name:"Geography" },
{
field:"childItems",
children:[
{ field:"unid", name:"unid", hidden:true },
{ field:"country", name:"Country" },
{ field:"programname", name:"Program" },
{ field:"credit", name:"Credit" },
{ field:"debit", name:"Debit" }
],
aggregate:"sum",
},
]
}
]
]
}
]
You can see that, for each child level(s) you have to add a group (as I would like to call it) field and set first field within that group to your actual group field.
I hope this example will clear your doubt.
PS: In the jsfiddle version I have used formatters just to hide aggregate values for string fields.
I've got a sample document that I'm trying to project within a MongoDB aggregate pipeline. I'm testing with a single document that looks roughly like this:
{
"_id" : "",
"title" : "Questions",
"sortIndex" : 0,
"topics" : [
{
"_id" : "",
"title" : "Creating a Question",
"sortIndex" : 1,
"thumbnail" : "CreatingAQuestion.jpg",
"seenBy" : [ "user101", "user202" ],
"pages" : [
{
"visual" : "SelectPlanets.gif",
"text" : "Some Markdown"
}
]
},
{
"_id" : "",
"title" : "Deleting a Question",
"sortIndex" : 0,
"thumbnail" : "DeletingAQuestion.jpg",
"seenBy" : [ "user101" ],
"pages" : [
{
"visual" : "SelectCard.gif",
"text" : "Some Markdown"
}
]
}
]
}
The output I'm trying to obtain is something along these lines:
{
"_id" : "",
"title" : "Questions",
"topics" : [
{
"title" : "Creating a Question",
"thumbnail" : "CreatingAQuestion.jpg",
"seen" : true
},
{
"title" : "Deleting a Question",
"thumbnail" : "DeletingAQuestion.jpg",
"seen" : false
}
]
}
Specifically the bit I'm struggling with is the seen flag.
I've read the docs which state:
When projecting or adding/resetting a field within an embedded document...
... Or you can nest the fields:
contact: { address: { country: <1 or 0 or expression> } }
I wish to use an expression and I took note of the following:
When nesting the fields, you cannot use dot notation inside the embedded document to specify the field, e.g. contact: { "address.country": <1 or 0 or expression> } is invalid.
So I'm trying to work out how to "reference" a subdocument field within an expression. That quote suggests I can't use dot notation but when I can't seem to get it working with nested notation either. Here's what I've got so far:
db
.getCollection('chapters')
.aggregate([
{
$project: {
title: 1,
topics: {
title: 1,
thumbnail: 1,
publishedAt: 1,
test: "$seenBy",
seen: { $in: ["user202", "$seenBy"] },
}
}
}
])
So I've hard coded user202 into my query for now, and expected to see true and false for the 2 documents. I've also put in a test field to map out the seenBy field from the sub-document. What this produces is:
{
"_id" : "",
"title" : "Questions",
"topics" : [
{
"title" : "Creating a Question",
"thumbnail" : "CreatingAQuestion.jpg",
"test" : [
"user101",
"user202"
],
"seen" : true
},
{
"title" : "Deleting a Question",
"thumbnail" : "DeletingAQuestion.jpg",
"test" : [
"user101",
"user202"
],
"seen" : true
}
]
}
So obviously my "$seenBy" isn't accessing the correct topic because the test field contains the data from the 1st document.
So ultimately my question is, how can I access the seenBy field within a subdocument, referring to the current subdocument so I can create an expression?
Note: I have got this working with multiple $project and an $unwind but wanted to try compress/clean it up a bit.
You really need to use $map here. Simply notating the array in projection ( which is a bit of a boon since MongoDB 3.2 ) does not really cut it when you need a localized value for the current element. That is what you need and it's what $map provides:
db.getCollection('chapters').aggregate([
{ $project: {
title: 1,
topics: {
$map: {
input: "$topics",
as: "t",
in: {
title: "$$t.title",
thumbnail: "$$t.thumbnail",
publishedAt: "$$t.publishedAt",
test: "$$t.seenBy",
seen: { $in: ["user202", "$$t.seenBy"] },
}
}
}}
])
So for each element the current value of "seenBy" as a property is being tested by the expression. Without the $map that is not possible, and you can only really notate the "whole" array. Which is really not what you want to test here.
I'm creating a tree using the jstree javascript library while using two jstree plugins:
checkbox plugin
types plugin
Here is a code example with
var mydata=[
id: "1",
parent: "#",
text: "node1",
},
{
id: "2",
parent: "#",
text: "node2",
type: "nodeattribute",
}];
$('#dqResultsJSTree').jstree(
{
'core' : {
'themes' : {
'variant' : 'large',
'icons' : false,
},
'data' : mydata,
},
'types' : {
'nodeattribute' : {
'icon' : 'http://icons.iconarchive.com/icons/hydrattz/multipurpose-alphabet/24/Letter-A-lg-icon.png',
},
},
'checkbox' : {
cascade : "",
three_state : false,
},
'plugins' : [ 'checkbox', 'types'],
});
The problem I'm having is that the type is not working. The node with id=2 does not show the icon defined at type nodeattribute. Does anybody have had this problem using while using the checkbox at the same time?
Thanks in advance.
Source: https://www.jstree.com/plugins/
You have to set 'icons': true in the core section of jsTree config.
I also fixed your JSON - need a { for first object in mydata.
See demo: JS Fiddle
I'm trying to programmatically create a dojo tree from a json file. The problem is that my json objects reference to their parents not children as in some examples.
Unfortunately my output looks only like this:
I have the following javascript code:
<script type="text/javascript">
require(["dijit/Tree", "dojo/data/ItemFileReadStore", "dijit/tree/ForestStoreModel", "dijit/tree/ObjectStoreModel", "dojo/domReady!"],
function(Tree, ItemFileReadStore, ObjectStoreModel, ForestStoreModel){
var store = new ItemFileReadStore({
url: "/_data/test.json",
getChildren: function(object){
return this.query({F_TopLevelCategoryID: object.P_CategoryID});
}
});
var myModel = new ObjectStoreModel({
store: store,
labelAttr:'CategoryName',
query: {"P_CategoryID": 0}
});
var myTree = new Tree({
model: myModel
}, "treeOne");
myTree.startup();
});
</script>
The json file looks like the following:
{ "identifier" : "P_CategoryID",
"label" : "CategoryName",
"items" : [ { "CategoryName" : "Category 1",
"F_TopLevelCategoryID" : 0,
"P_CategoryID" : 1
},
{ "CategoryName" : "Category 2",
"F_TopLevelCategoryID" : 1,
"P_CategoryID" : 2
},
{ "CategoryName" : "Category 3",
"F_TopLevelCategoryID" : 1,
"P_CategoryID" : 3
},
{ "CategoryName" : "Category 4",
"F_TopLevelCategoryID" : 1,
"P_CategoryID" : 4
},
{ "CategoryName" : "Category 5",
"F_TopLevelCategoryID" : 3,
"P_CategoryID" : 5
},
{ "CategoryName" : "Category 6",
"F_TopLevelCategoryID" : 4,
"P_CategoryID" : 6
},
{ "CategoryName" : "Category 7",
"F_TopLevelCategoryID" : 4,
"P_CategoryID" : 7
},
{ "CategoryName" : "Category 8",
"F_TopLevelCategoryID" : 0,
"P_CategoryID" : 8
},
{ "CategoryName" : "Top Level Category",
"P_CategoryID" : 0
}
]
}
Where is the problem?
I believe it was a fluke that you received a partial result.
You have forestStoreModel and objectStoreModel transposed in the require block, and referencing parents is fine!
Also, use dojo/store instead of ItemFileReadStore, as the latter is deprecated. Use the data parameter on Memory:
var store = new Memory({
data: testJson,
getChildren: ...
});
See my working fiddle here, using dojo/store/Memory: https://jsfiddle.net/yubp45sa/
You can get your data into the memory store using dojo/request:
request("testData.json").then(...);
http://dojotoolkit.org/reference-guide/1.10/dojo/request.html
I had another request example in previously, which requested the data through a GET from a custom nodeJS route (returning JSON):
request.get("/configInfo", {
handleAs: "json"
}).then(...);