I am trying to create a expanding tree for my web application but I am not able to bring data from a JSON file to dynamically fill the tree. I found this code from another post on SOF.
Here is my JSON file called tree_data.json :
{
"Data": {
"id": "0",
"title": "root-not displayed",
"children": {
"id": "1",
"title": "Option 1",
"children": {
"id": "11",
"title": "Option 11",
"children": {
"id": "111",
"title": "Option 111",
"id": "112",
"title": "Option 112"
}
}
}
}
}
Here is javascript code imbedded within HTML:
$.getJSON("tree_data.json", function(treedata) ){
//$.each(treedata.data, function(i, field){
$(function () {
addItem($('#root'), treedata); //first call to add item which passes the main parent/root.
$(':checkbox').change(function () {
$(this).closest('li').children('ul').slideToggle();
});
$('label').click(function(){
$(this).closest('li').find(':checkbox').trigger('click');
});
});//}
function addItem(parentUL, branch) {
for (var key in branch.children) { //for each key in child in data
var item = branch.children[key]; //assign each child in variable item
$item = $('<li>', { //jquery object
id: "item" + item.id
});
$item.append($('<input>', { //add check boxes
type: "checkbox",
id: "item" + item.id,
name: "item" + item.id
}));
$item.append($('<label>', { //add labels to HTML. For every id, display its title.
for: "item" + item.id,
text: item.title
}));
parentUL.append($item);
if (item.children) {
var $ul = $('<ul>', {
style: 'display: none'
}).appendTo($item);
$item.append();
addItem($ul, item); //recursive call to add another item if there are more children.
}
}
}}
I need a lot of help changing this code in order grab the JSON data and creating the tree. Any help would be very appreciated. Thank you.
First of all, you have to encapsulate every children object in a json array, so you can have single or multiple object in each children (like 111 and 112). So change the json to be like that:
{
"Data": {
"id": "0",
"title": "root-not displayed",
"children": [{
"id": "1",
"title": "Option 1",
"children": [{
"id": "11",
"title": "Option 11",
"children": [{
"id": "111",
"title": "Option 111"
},
{
"id": "112",
"title": "Option 112"
}]
}]
}]
}
}
Now, there is a working code base (with working example):
$(function () {
var treedata = JSON.parse('{"Data": {"id": "0","title": "root-not displayed","children": [{ "id":"1","title":"Option 1","children": [{"id": "11","title": "Option 11","children": [{"id": "111","title": "Option 111"},{"id": "112","title": "Option 112"}]}]}]}}'); //JUST FOR MOCKUP THE JSON CALL
addItem($('#root'), treedata.Data); //first call to add item which passes the main parent/root.
$(':checkbox').change(function () {
$(this).closest('li').children('ul').slideToggle();
});
$('label').click(function(){
$(this).closest('li').find(':checkbox').trigger('click');
});
});//}
function addItem(parentUL, branch) {
$.each(branch.children, function(i){
var item = branch.children[i]; //assign each child in variable item
$item = $('<li>', { //jquery object
id: "item" + item.id
});
$item.append($('<input>', { //add check boxes
type: "checkbox",
id: "item" + item.id,
name: "item" + item.id
}));
$item.append($('<label>', { //add labels to HTML. For every id, display its title.
for: "item" + item.id,
text: item.title
}));
parentUL.append($item);
if (item.children) {
var $ul = $('<ul>', {
}).appendTo($item);
addItem($ul, item); //recursive call to add another item if there are more children.
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="root">
</div>
Now just use your getJSON instead of my mockup data and you will be fine i hope :)
Related
I'm using knockoutjs, but the question is really in Javascript domain.
I have variable vm.filteredSerivces() which contains all services by all employees.
Now, I want to just preserve those filteredSerivces where is vm.filteredSerivces()[0].GroupedServices[x].EmployeeId == 3684 (x is the number of index number of each object in GroupedServices object list)
I tried as follows:
var filteredSrvcs = vm.filteredSerivces()[0].GroupedServices.filter(x => x.EmployeeId != Id).remove();
vm.filteredSerivces(filteredSrvcs );
But I changed structure in that way, and my bindings in html is not corresponding.
Is there any other way to just remove this sub-sub object, and to preserve a structure as it is?
Here is the
Here's an example that maps a new array of new objects and the filter is set to only include the GroupedServices items where Id == 2000
let res = data.map(({ServiceTypeName, GroupedServices}) =>{
GroupedServices= GroupedServices.filter(({Id}) => Id == 2000);
return {ServiceTypeName,GroupedServices }
})
console.log(res)
<script>
let data =
[
{
"ServiceTypeName": "Type 1",
"GroupedServices": [{
"Id": 1,
"Name": "A"
}, {
"Id": 2,
"Name": "A"
},
{
"Id": 28456,
"Name": "AGSADGJS"
}]
},
{
"ServiceTypeName": "Type 2",
"GroupedServices": [{
"Id": 1203,
"Name": "AHASJ"
}, {
"Id": 2000,
"Name": "AHSJD"
},
{
"Id": 284536,
"Name": "UEHNCK"
}]
}];
</script>
I have a JSON file titled stuff.json. I am trying to get the previous json item given a certain item. For example, if I am given the key ["also-random-here"], how do I get the previous JSON item "sample-name"?
My JSON data looks as follows:
{
"random-name-here": {
"name": "name is item1"
},
"sample-name": {
"name": "name is item2"
},
"also-random-here": {
"name": "name is item3"
}
}
try this
var names={
"random-name-here": {
"name": "name is item1"
},
"sample-name": {
"name": "name is item2"
},
"also-random-here": {
"name": "name is item3"
}
};
var prevName= findPrevName(names, "also-random-here") ;
function findPrevName(item, key) {
var prevName;
for (const property in item)
{
if(property==key) break;
prevName=property;
};
return { [prevName]: item[prevName]};
};
I have a Javascript object with a format like below
"items":
{
"Groups":[
{
"title":"group 1",
"SubGroups":[
{
"title":"sub1",
"id" : "1",
"items":[
{
"title":"Ajax request 1",
},
{
"title":"Ajax request 2",
}
]
},
{
"title":"sub2",
"id" : "2",
"items":[
{
"title":"Ajax request 3",
},
{
"title":"Ajax request 4",
}
]
}
]
}
]
There are n 'Groups', n 'subGroups' and n 'items'.
What I want to do firstly is get all the items from a particular group based on id. This is achieved using:
_.each(items.Groups, function(o) {
result = _.where(o.SubGroups, {
'id': '1'
});
});
which returns
"items":[{"title":"Ajax request 1",},{"title":"Ajax request 2",}]
Then I want to get the rest of the data, excluding the items and parent group I have just retrieved.
I tried this:
_.each(items.Groups, function(o) {
arr = _.without(o.SubGroups, _.findWhere(o.SubGroups, {id: '2'}));
});
But this only returns me the items like this:
{
"title":"sub2",
"id" : "2",
"items":[{"title":"Ajax request 3"},{"title":"Ajax request 4",}]
}
whereas what I need is this:
"items":
{
"Groups":[
{
"title":"group 1",
"SubGroups":[
{
"title":"sub2",
"id" : "2",
"items":[
{
"title":"Ajax request 3",
},
{
"title":"Ajax request 4",
}
]
}
]
}
]
Just try this:
_.each(items.Groups, function(o) {
arr = _.without(o, _.findWhere(o.SubGroups, {id: '2'}));
});
o should be enough => you want to get Groups and not SubGroups.
Following is a pure JS implementation:
JSFiddle.
var data = {
"Groups": [{
"title": "group 1",
"SubGroups": [{
"title": "sub1",
"id": "1",
"items": [{
"title": "Ajax request 1",
}, {
"title": "Ajax request 2",
}]
}, {
"title": "sub2",
"id": "2",
"items": [{
"title": "Ajax request 3",
}, {
"title": "Ajax request 4",
}]
}]
}]
}
var items = [];
var group = [];
data.Groups.forEach(function(o) {
var _tmp = JSON.parse(JSON.stringify(o));
_tmp.SubGroups = [];
o.SubGroups.forEach(function(s) {
if (s.id == "1") {
items.push(s.items);
} else {
_tmp.SubGroups.push(s);
group.push(_tmp)
}
});
});
function printObj(label, obj) {
document.write(label + "<pre>" + JSON.stringify(obj, 0, 4) + "</pre>")
}
printObj("group", group);
printObj("items", items);
Using underscore and using your logic to filter all subgroups:
//array to store subgroup with ID 1
var results = [];
var d = _.each(data.items.Groups, function(o) {
result = _.where(o.SubGroups, {
'id': '1'
});
//add to results array
results.push(result);
});
//make a clone of the earlier object so that you get the parent structure.
var data1 = _.clone(data);
//set the filtered results to the group
data1.items.Groups = results;
//your data as you want
console.log(data1)
Working code here
I am adding items from a JSON file using JQuery to an HTML page dynamically.
HTML:
<div id='cssmenu'>
<ul id='options'>
<li class='active'><a href='#'><span>Home</span></a>
<ul id='home'></ul></li>
<li class='has-sub'><a href='#'><span>Products</span></a>
<ul id='product_list'></ul></li>
<li class='has-sub'><a href='#'><span>Company</span></a>
<ul id='company'></ul></li>
<li class='has-sub'><a href='#'><span>Contact</span></a>
<ul id='contact'></ul></li>
</ul>
</div>
JQuery:
$(document).ready(function () {
$.getJSON('../JSON/cwdata.json', function (cwData) {
// Add the product categories
$.each(cwData.product, function (i, product) {
var option_cate = ('<li class="item">' + product.category + '</li>');
$('#product_list').append(option_cate);
// Add the product names
$.each(product.items, function (i, item) {
var option_name = ('<ul class="details" style="display: none;"><li class="name">' + item.name + '</li></ul>');
$(".item").append(option_name);
}); //$.each(...)
}); //$.each(...)
}); //$.getJSON
}); //$document
JSON(cwdata.json file):
{
"product": [
{
"category": "Product 1",
"items": [
{
"name": "Item 1.1",
"name": "Item 1.2"
}
]
},
{
"category": "Product 2",
"items": [
{
"name": "Item 2"
}
]
},
{
"category": "Product 3",
"items": [
{
"name": "Item 3"
}
]
}
]
}
The problem is the data is being added the wrong way. The HTML looks like this after the page has been loaded:
.
Item 1, Item 2 and Item 3 are being added to Product 1, whereas I only want all the "items" under "Product 1" to be in the the Product 1 list.
Basically:
Product 1
- Item 1.1
- Item 1.2
But I am getting:
Product 1
- Item 1.1
- Item 2
- Item 3
Any tips would be appreciated.
Ok.. I found several bugs in your solution..
First this is a modified working version
Now please note that your iteration:
$.each(product.items, function (i, item) {
Does not iterate properly because you have only one object inside the array so instead each item should be an independent object {"name": "bla bla bla"}
Second you append the items to ALL .item and add a UL for every item and that's also buggy.. please review my code and let me know if it helps.
Your json is wrong.
For example:
Instead of
"items": [
{
"name": "Item 1.1",
"name": "Item 1.2"
}
]
It should be:
"items": [
{ "name": "Item 1.1" },
{ "name": "Item 1.2" }
]
Once that is corrected, you can change your code as -
$.each(cwData.product, function (i, product) {
var option_cate = ('<li class="item">' + product.category + '</li>');
$('#product_list').append(option_cate);
var html = '<ul class="details">';
$.each(product.items, function (i, item) {
html += ('<li class="name">' + item.name + '</li>');
});
html += '</ul>'
$('#product_list').append(html);
});
You are appending results to the class item which exists in three places. So it is appended to the three <li class="items">.
Try giving id to your <li> tags like <li id="product1">... instead <li class="item">
This:
$(".item").append(option_name);
selects all html tags with class item. So you are appending the details to all existing <li class="item">.
Use a more especific selector to add the new content to your list element.
As per my view you have to correct your JSON like:
{
"product": [
{
"category": "Product 1",
"items": ["Item 1-1","Item 1-2","Item 1-3"]
},
{
"category": "Product 2",
"items": ["Item 2-1","Item 2-2","Item 2-3"]
},
{
"category": "Product 3",
"items": ["Item 3-1", "Item 3-2","Item 3-3"]
}
]
}
Then use below code I hope it will work for you:
<script>
$(document).ready(function () {
$.getJSON('cwdata.json', function (cwData) {
// Add the product categories
$.each(cwData.product, function (i, product) {
var option_cate = ('<li class="item'+i+'">' + product.category + '</li>');
//alert(dump(product.items));
//alert(product.items.length);
$('#product_list').append(option_cate);
// Add the product names
for(var k=0;k<(product.items.length);k++){
var option_name = ('<ul class="details"><li class="name">' + product.items[k] + '</li></ul>');
//console.log(option_name);
$(".item"+i).append(option_name);
}
}); //$.each(...)
}); //$.getJSON
}); //$document
</script>
Enjoy..... :)
It will be work
Use json formate like this
{
"product": [
{
"category": "Product 1",
"items": [
{ "name": "Item 1.1" },
{ "name": "Item 1.2" }
]
},
{
"category": "Product 2",
"items": [
{
"name": "Item 2"
}
]
},
{
"category": "Product 3",
"items": [
{
"name": "Item 3"
}
]
}
]
}
And correct your script like
$(document).ready(function () {
$.getJSON('test.json', function (cwData) {
// Add the product categories
$.each(cwData.product, function (i, product) {
var option_cate = ('<li class="item">' + product.category + '</li>');
$('#product_list').append(option_cate);
// Add the product names
$.each(product.items, function (i, item) {
var option_name = ('<ul class="details" style=""><li class="name">' + item.name + '</li></ul>');
$(".item:last").append(option_name);
}); //$.each(...)
}); //$.each(...)
}); //$.getJSON
}); //$document
I hope it will work.
If you are getting json data as a string from c#, then you need to parse to json in javascript.
function success(response) {
$('.listboxclass').empty();
$('.listboxclass').append('<option value="0">Select</option>');
$.each(JSON.parse(response.d), function(i, obj) {
$('.listboxclass').append('<option value="'+obj.id+'">'+obj.name+'</option>');
});
}
Here listboxclass is the classname of the listbox.
Here is the c# web method code which returns to ajax call.
[WebMethod]
public static string GetScreenList(string tId)
{
return "[{\"id\":\"1\",\"name\":\"aaa\"},{\"id\":\"2\",\"name\":\"bbb\"}]";
}
I am trying to work with Mustache.js that is really helping.
I am stuck on getting array with specific option and value.
My JSON is looking like that:
{
"departments": [
{
"department": [
{
"id": 114,
"deptName": "Department 1",
"category": [
{
"id": 127,
"catName": "Category Name",
"subCategory": []
},
{
"id": 115,
"catName": "Category Name",
"subCategory": []
}
]
}
]
},
{
"department": [
{
"id": 123,
"deptName": "Department 2",
"category": [
{
"id": 126,
"catName": "Category Name",
"subCategory": []
},
{
"id": 124,
"catName": "Category Name",
"subCategory": []
}
]
}
]
}
]
}
To get main department names it is easy as:
JS:
$.ajax({
url: 'link_to_json',
dataType: 'json',
success: function(data) {
var template = $('#pageHomeTpl').html();
var html = Mustache.to_html(template, data);
$('#category-list').html(html);
}
});
HTML:
<ul id="category-list">
<script id="pageHomeTpl" type="text/template">
{{#departments}}
{{#department}}
<li>{{deptName}}</li>
{{/department}}
{{/departments}}
</script>
</ul>
But now I need to somehow get categories ("category:") from department with specific ID, for example "id": 114.
Any help, please.
You can try in these lines, with jQuery map() and grep()
console.log(JSON.stringify(data));
var filtereddata = {"departments" : []};
var filtereddept= {};
filtereddept.department= $.map(data.departments, function(alldept,indx){
return $.grep(alldept.department, function(deptobj,indx){
return deptobj.id==114;
});
});
filtereddata.departments[0]=filtereddept;
console.log(JSON.stringify(filtereddata));
The template to iterate the category of departments:
<script id="pageHomeTpl" type="text/template">
{{#departments}}
{{#department}}
<li>{{deptName}}</li>
{{#category}}
<ul>
<li>{{catName}}</li>
</ul>
{{/category}}
{{/department}}
{{/departments}}
</script>
I don't test it but it seems to be work...
...
success: function(data) {
var template = $('#pageHomeTpl').html();
var item = data.departments
for(key in item){
if(key == 'id' && item[key] == 114 ){
var html = Mustache.to_html(template, item);
}
}
$('#category-list').html(html);
}
...
with FOR .. IN statement you can cycle in your object or array take look at this link
js_loop_for_in