items not within the <ul></ul> - javascript

I create a menu with a javascript object and jquery. I have certain items that needs to be in the <ul></ul> but instead they're beneath it.
http://jsfiddle.net/MWBt6/
I have 'Index' for example. In there I want to append a list of items.
I know the category id is 0 and the item id is 2, i stored those things in the data attribute.
Now how can I append a ul to that one?

That's not how append works. You need to create the elements on their own. Here:
var loadPath = "resources/books/book1/";
var menu = {
data: [{
name: "the book",
id: 0,
items: [{
name: "Introduction",
id: 0,
target: "inleiding.html"
}, {
name: "Content",
id: 1
}, {
name: "Index",
id: 2
}]
}, {
name: "my stuff",
id: 1,
items: [{
name: "Notes",
id: 0
}, {
name: "Marks",
id: 1
}]
}, {
name: "other",
id: 2,
items: [{
name: "Search",
id: 0
}, {
name: "Continue Reading",
id: 1
}]
}]
}
$(document).ready(function() {
var $menu = $('#menu');
for(var i = 0; i < menu.data.length; i++) {
var categorie = menu.data[i];
var categorieName = categorie.name;
var categorieId = categorie.id;
var items = categorie.items;
console.log("categorieName: " + categorieName);
var list = $('<ul>');
for(var j = 0; j < items.length; j++) {
var itemId = items[j].id;
list.append($('<li>').attr('data-itemId', itemId).text(items[j].name));
}
$menu.append(
$('<li>').attr('data-categorieId', categorieId).append(categorieName, list)
);
}
});​
Here's the updated jsFiddle.

You are trying to append as if the DOM is a text editor. You can't append the beginning of an element with it's opening tag, then later close that element with an append of a closing tag. Only full valid elements can be inserted into the DOM.
Instead, build an html string, then only make one append after the string is completed. This method is far more efficient than doing multiple appends also
Working demo: http://jsfiddle.net/MWBt6/3/

Related

Traverse through JSON to find tree path

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

Getting id or name of folder in fuelux tree

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.

Nested menu using parent id in knockoutJs

I am try to create nested menu using given json data by the client.
Data :
var serverData = [
{
Id: "menuColorSearch",
Text: "Color search"
},
{
Id: "menuAncillaryProductMix",
Text: "Ancillary product mix"
},
{
Id: "menuDocuments",
Text: "Documents"
},
{
Id: "menuColorInfo",
ParentId: "menuDocuments",
Text: "Color info"
},
{
Id: "menuReports",
ParentId: "menuDocuments",
Text: "Reports"
},
{
Id: "menuMaintenance",
Text: "Maintenance"
},
{
Id: "menuPriceManagement",
ParentId: "menuMaintenance",
Text: "Price management"
}
];
I am trying like this :
var Menu = function(dept, all) {
var self = this;
this.id = dept.Id;
this.name = ko.observable(dept.Text);
this.parentId = dept.ParentId;
this.children = ko.observableArray();
ko.utils.arrayForEach(all || [], function(menu) {
if(menu.ParentId){
if (menu.ParentId === self.id) {
self.children.push(new Menu(menu, all));
}
}else{
new Menu(menu, all)
}
});
};
var ViewModel = function(data) {
this.root = new Menu(data[0], data);
};
$(function() {
ko.applyBindings(new ViewModel(serverData));
});
Templates :
<div data-bind="with: root">
<ul data-bind="template: 'deptTmpl'">
</ul>
</div>
<script id="deptTmpl" type="text/html">
<li>
<a data-bind="text: name"></a>
<ul data-bind="template: { name: 'deptTmpl', foreach: children }">
</ul>
</li>
</script>
problem is that its only work when 2nd and 3rd object has parent ID. i am trying something like it should make nested menu according to given json data. so id there is no parent id on object it should add on root. and if object has parent id it should add according to parent id.
Please help me to correct my code or guide me if these is another way to do this in KnockoutJS.
Thanks
This should help you http://jsfiddle.net/MCNK8/3/, the main idea is to rebuild main data array, by placing child inside parent
HTML
<script id="nodeTempl" type="text/html">
<li>
<a data-bind="text: Text"></a>
<ul data-bind="template: {name: nodeTemplate, foreach: children }"></ul>
</li>
</script>
<script id="nodeLeafTempl" type="text/html">
<li>
<a data-bind="text: Text"></a>
</li>
</script>
<ul data-bind="template: {name: nodeTemplate, foreach: children }"></ul>
Javascript (#see fiddle)
var serverData = [
{
Id: "menuColorSearch",
Text: "Color search"
},
{
Id: "menuAncillaryProductMix",
ParentId: 'menuColorSearch',
Text: "Ancillary product mix"
},
{
Id: "menuDocuments",
Text: "Documents"
},
{
Id: "menuColorInfo",
ParentId: "menuReports",
Text: "Color info"
},
{
Id: "menuReports",
ParentId: "menuDocuments",
Text: "Reports"
},
{
Id: "menuMaintenance",
ParentId: 'menuReports',
Text: "Maintenance"
},
{
Id: "menuPriceManagement",
ParentId: "menuMaintenance",
Text: "Price management"
}
];
function getNestedMenu(index, all) {
var root = all[index];
if(!root){
return all;
}
if(!all[index].children){
all[index].children = [];
}
for(var i = 0; i < all.length; i++){
//<infinity nesting?>
//put children inside it's parent
if(all[index].Id == all[i].ParentId){
all[index].children.push(all[i]);
all[i].used = true;
}
//this is needed for each item, to determine which template to use
all[index].nodeTemplate = function(node) {
return node.children.length > 0 ? 'nodeTempl' : 'nodeLeafTempl';
}
//</infinity nesting?>
}
return getNestedMenu(++index, all);
};
function getModel(data) {
var items = getNestedMenu(0, data);
//<remove duplicates, for infinity nesting only>
for(var i = 0; i < items.length; i++){
if(items[i].used){
items.splice(i, 1);
i--;
}
}
//</remove duplicates, for infinity nesting only>
//<build root item>
var model = {};
model.children = ko.observableArray(items);
model.nodeTemplate = function(node) {
return node.children.length > 0 ? 'nodeTempl' : 'nodeLeafTempl';
}
//</build root item>
console.log(items);
return model;
};
(function() {
//new ViewModel(serverData);
ko.applyBindings(getModel(serverData));
})();

Tree is not displayed propery in DOJO

I am new to DOJO 1.6
I trying to display tree with sub folders.
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dijit.form.Button");
dojo.require("dijit.tree.TreeStoreModel");
dojo.require("dojo.store.Memory");
dojo.require("dijit.Tree");
dojo.addOnLoad(function() {
// Create test store, adding the getChildren() method required by ObjectStoreModel
var data = [ { id: 1, name: "answerTypeLabel", type:'scenario', children:[{_reference: 2}]},
{ id: 2, name: "acceptRequestLabel", type:'paragraph', data: "acceptRequestLabel"},
{ id: 3, name: "rejectRequestLabel", type:'scenario', children:[{_reference: 5},{_reference: 6}]},
{ id: 4, name: "MoreInformationLabel", type:'scenario', children:[{_reference: 7},{_reference: 8}]},
{ id: 5, name: "rejectRequestStatusLabel", type:'paragraph', data: "rejectRequestStatusLabel"},
{ id: 6, name: "rejectRequestNotCoveredLabel", type:'paragraph', data: "rejectRequestNotCoveredLabel" },
{ id: 7, name: "MoreInformationDocumentLabel", type:'paragraph', data: "MoreInformationDocumentLabel"},
{ id: 8, name: "MoreInformationDataLabel", type:'paragraph', data: "MoreInformationDataLabel"}
];
// Building the store object
var sortableStore = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'id',
label: 'name',
items: data
},
});
// building the model
var model = new dijit.tree.ForestStoreModel({
store: sortableStore,
query: {
id: "*"
},
rootId: "root",
rootLabel: "sorting of tree"
});
// Building the tree
var tree = new dijit.Tree({
model:model,
'class': "tundra"
},
"resourceTree");
});
.
Here Id 2 in a child of Id 1 , so while displaying Id 2 must be inside Id 1.
But here Id 2 appears inside id 1 and also on the same level of id 1.(There is a duplication of all the all the child ids ).
This is case with id 2,5,6,7,8.
I want to remove the duplication.
Ouptput should be like
Reason is that you apply a non-hierachial store onto a tree which is not supposed to display items that has parents as a sibling to the root.
To 'fix' this, the referenced id's needs to not get matched by the model query.
In your case of data, it looks like the type:'paragraph' is supposed to be leaves. Therefore set the query to match type:'scenario' as opposed to your current ' id: "*" '
var model = new dijit.tree.ForestStoreModel({
store: sortableStore,
query: {
type:'scenario'
},
rootId: "root",
rootLabel: "sorting of tree"
});

Dynamic ListSelector Array problem

all
i am working now days on WebOs 3.0
This question may not require WebOs knowledge.
My problem is i am using a list selector is like a HTML dropdown.
its static code
{kind: "ListSelector", name: "mySelector"}
this.$.mySelector.setItems( [ { caption: "test 1", value: 1 }, { caption: "test 2", value: 2 } ]);
this.$.mySelector.setValue(2);
Dynamic way to display
for (var j=0; j<this.cnt; j++)
{
//alert(this.data[j].channelName);
this.$.mySelector.setItems( [ { caption: this.data[j].channelName, value: this.data[j].channelId }]);
}
Because i am keep replacing all of your items with 'setItems'. it show me only last value of my db.
Why not change the loop to build up a temporary array and then call the setItems function?
var items = [];
for (var j=0; j<this.cnt; j++)
{
items.push({caption: this.data[j].channelName, value: this.data[j].channelId});
}
this.$.mySelector.setItems( items );

Categories