How i can filter my JSON object with array.
FIDDLE
This is an sample of my json object and code, i want to filter final render HTML by selected checkbox.
Thanks for your help
function init(arr){
var li = '';
$.each(jsn, function (key, value) {
if (arr.length == 0) {
li += '<li>' + jsn[key].name + '</li>';
}else{
$(arr).each(function (i, v) {
// this section must be filter "pack's" but i can't writ correct query
li += '<li>' + jsn[key].name + '</li>';
});
};
$('#container').html(li);
})
}
var CheckArr = new Array();
init(CheckArr);
$('#btnFilter').click(function(){
var CheckArr = new Array();
$('input[type=checkbox]').each(function () {
if ($(this).is(':checked')) {
CheckArr.push($(this).attr('value'))
}
});
init(CheckArr);
First of all, you have to verify length of array outside of init function. (for case when function is called for first time).Then, you need to iterate your checkboxes array and search every item in your json array(called jsn) to verify condition you need.
Here is solution:
$(document).ready(function(){
var jsn = [
{
"name":"pack01",
"caplessthan100mb":"False",
"cap100to500mb":"True",
"cap500mbto2g":"False",
"cap2gto10g":"False"
},
{
"name":"pack02",
"caplessthan100mb":"True",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"False"
},
{
"name":"pack03",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"True"
},
{
"name":"pack04",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"True",
"cap2gto10g":"False"
},
{
"name":"pack05",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"True"
},
{
"name":"pack06",
"caplessthan100mb":"True",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"False"
},
{
"name":"pack07",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"True"
}
];
function init(arr){
var li = '';
if(arr.length==0)
{
$.each(jsn, function (key, value) {
li+= '<li>' + jsn[key].name + '</li>';
});
}
else{
$(arr).each(function (i, v) {
$.each(jsn, function (key, value) {
if(jsn[key][v]=="True")
li+= '<li>' + jsn[key].name + '</li>';
});
});
}
$('#container').html(li);
}
var CheckArr = new Array();
init(CheckArr);
$('#btnFilter').click(function(){
var CheckArr = new Array();
$('input[type=checkbox]').each(function () {
if ($(this).is(':checked')) {
CheckArr.push($(this).attr('value'))
}
});
init(CheckArr);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li><input type="checkbox" value="caplessthan100mb">caplessthan100mb</li>
<li><input type="checkbox" value="cap100to500mb">cap100to500mb</li>
<li><input type="checkbox" value="cap500mbto2g">cap500mbto2g</li>
<li><input type="checkbox" value="cap2gto10g">cap2gto10g</li>
<li><input type="button" id="btnFilter" value="Filter"></li>
</ul>
<br />
<ul id="container">
</ul>
There are quite a few things in your code that could use improvement so I've taken the liberty of largely rewriting it (see jsFiddle link below).
1) First thing is in your data (jsn) you are using "False" and "True" instead of false and true. That'll make it hard to write your filter condition because true != "True".
2) It's quite hard to debug your code because the variable names aren't very meaningful. I'd highly recommend putting some energy into improving your variable names especially when code isn't working.
For example:
packsData instead of jsn
checkedBoxes instead of arr
3) If you try to filter within the .each() below you'll run into trouble when it matches more than one filter condition (it'll be displayed more than once).
$(arr).each(function (i, v) {
// this section must be filter "pack's" but i can't writ correct query
li += '<li>' + jsn[key].name + '</li>';
});
Here is a working jsFiddle
I have a table with three different levels of data, when I call the child level of data using an ng-click the data is diplayed ok but when I call the grandson level the data is not displayed, the response of my WS is ok because I can see it loged in my console so I after some time I realized that I need to nest my ng-repeat's in order to display the data from the grandson level but I don get how to do it, I checked also the ng-repeat-start directive but dont know if it apply to my htlm structure, this is what I have on my view.
<table class="table table-bordered drilldown-table" id="fixTable" style="height: 505px">
<tbody ng-repeat="cat in (exportData.result.slice(0, exportData.result.length-2))" >
<tr class="parent">
<td ng-click="drillDownSubcategoriesCat(cat.merchMetrics.DEPT_NBR,cat.merchMetrics.CATG_GRP_NBR,cat.merchMetrics.DEPT_CATG_NBR)" drill-down>+</td>
<td style="text-align: left">{{cat.merchMetrics.DEPT_CATG_DESC}}</td>
<!--SALES-->
<td>{{cat.merchMetrics.SALES_AMOUNT_LW | number : 2}}</td>
<td>{{cat.merchMetrics.SALES_LW_CHG_LY}}%</td>
<td>{{cat.merchMetrics.SALES_L4W_CHG_LY}}%</td>
<td>{{cat.merchMetrics.SALES_L13W_CHG_LY}}%</td>
<td>{{cat.merchMetrics.SALES_L52W_CHG_LY}}%</td>
<td>{{cat.merchMetrics.SALES_LW_VS_L13W}}</td>
</tr>
<tr ng-repeat="subcat in drillDownSubcatCatList['D' + cat.merchMetrics.DEPT_NBR + 'CG' + cat.merchMetrics.CATG_GRP_NBR + 'C' + cat.merchMetrics.DEPT_CATG_NBR]" class="child" ng-if="!$last" style="background-color: #f3eee9">
<td ng-click="drillDownCategoryItemsCat(subcat.merchMetrics.DEPT_NBR, subcat.merchMetrics.CATG_GRP_NBR, subcat.merchMetrics.DEPT_CATG_NBR, subcat.merchMetrics.DEPT_SUBCATG_NBR)" drill-down>+</td>
<td style="text-align: left; padding-left: 25px">{{subcat.merchMetrics.DEPT_SUBCATG_DESC}}</td>
<!--SALES-->
<td>{{subcat.merchMetrics.SALES_AMOUNT_LW | number : 2}}</td>
<td>{{subcat.merchMetrics.SALES_LW_CHG_LY}}%</td>
<td>{{subcat.merchMetrics.SALES_L4W_CHG_LY}}%</td>
<td>{{subcat.merchMetrics.SALES_L13W_CHG_LY}}%</td>
<td>{{subcat.merchMetrics.SALES_L52W_CHG_LY}}%</td>
<td>{{subcat.merchMetrics.SALES_LW_VS_L13W}}</td>
</tr>
<tr ng-repeat="items in drillDownCategoryItemCatList[nbrSubcatItem]" class="grandson" ng-if="!$last" style="background-color: #f3eee9">
<td></td>
<td style="text-align: left; padding-left: 45px">{{items.merchMetrics.DEPT_SUBCATG_DESC}}}</td>
<!--SALES-->
<td>{{items.merchMetrics.SALES_AMOUNT_LW | number : 2}}</td>
<td>{{items.merchMetrics.SALES_LW_CHG_LY}}%</td>
<td>{{items.merchMetrics.SALES_L4W_CHG_LY}}%</td>
<td>{{items.merchMetrics.SALES_L13W_CHG_LY}}%</td>
<td>{{items.merchMetrics.SALES_L52W_CHG_LY}}%</td>
<td>{{items.merchMetrics.SALES_LW_VS_L13W}}</td>
</tr>
</tbody>
To generate the data from the child and grandson level I call to functions.
$scope.drillDownSubcatCatList = {};
$scope.subcatNbr = '';
$scope.drillDownSubcategoriesCat = function (dept,group,catg) {
$scope.nbr1 = [dept];
$scope.nbr2 = [group];
$scope.nbr3 = [catg];
$scope.nbrSubcat = 'D' + $scope.nbr1 + 'CG' + $scope.nbr2 + 'C' + $scope.nbr3;
$scope.nbrSubcat.toString();
$scope.subCategoryConst = ['Product Sales (Subcategory Rank)'];
$scope.drillDownRecords = "5";
console.log($scope.nbr1);
console.log($scope.nbr2);
console.log($scope.nbr3);
console.log("NBR: " + $scope.nbrSubcat);
if (!($scope.nbrSubcat in $scope.drillDownSubcatCatList)) {
$scope.loadViewCategories = false;
$scope.graphLoading = "loading";
searchFactory.search('merchandise',
{
timeStamp: $scope.dateTime,
timeFrameType: $scope.whenType,
custMembSelectionType: $scope.customerType,
locationSelectionType: $scope.locationType,
merchandiseSelectionType: "Category",
startYear: $scope.whenStartParentYear,
endYear: $scope.whenStartParentYear,
startUnit: $scope.whenStartValue,
endUnit: $scope.whenStartValue,
comparator: $scope.locationType.indexOf('(Comp)', $scope.locationType.length - '(Comp)'.length) !== -1,
locationSelections: $scope.locationSelected,
merchandiseSelections: [$scope.nbrSubcat],
custMembSelections: $scope.customerSelected,
metricSelections: $scope.subCategoryConst,
rankOrder: $scope.drillDownRecords
}).success(function (data) {
console.log("drillDownSubcategories OK");
$scope.loadViewCategories = true;
$scope.graphLoading = "white";
$scope.canvasContent = true;
$scope.exportDataCategoryDrillDown = data;
$scope.metricSelected = $scope.filters.baropt.displayName;
if (data.error) {
$scope.noData = "There are no results based on your selected dropdowns. Please change your selection.";
$scope.data = undefined;
$scope.hasError = true;
}
$scope.isExportDisabled = 'auto';
if (!$scope.drillDownSubcatCatList[$scope.nbrSubcat]) {
$scope.drillDownSubcatCatList[$scope.nbrSubcat] = $scope.exportDataCategoryDrillDown.result;
}
}).error(function (ret, status) {
console.log(ret, status);
if (status == 500 || status == 0) {
if (ret.error.indexOf("Filter criteria not found!") > -1 || ret.error.indexOf("Bad Selections!") > -1) {
$scope.errorMessage = "The combination of dropdowns you selected is invalid. Please select a different combination.";
} else {
$scope.errorMessage = "The database may be down. Please contact Data Cafe Development Team - Applications for help.";
}
} else if (status == 400) {
$scope.errorMessage = "There was a bad request sent to the database. Please contact Data Cafe Development Team - Applications for help.";
} else {
$scope.errorMessage = "There was an error while trying to process your request. Please contact Data Cafe Development Team - Applications for help.";
}
$scope.hasError = true;
$scope.graphLoading = "white";
$scope.canvasContent = true;
$scope.showCaptions = false;
}
);
}
if($scope.nbrSubcat in $scope.drillDownSubcatCatList) {
console.log("--------------- " + $scope.nbrSubcat);
console.log("RETURN DD SUBCATEGORY LIST: ", $scope.drillDownSubcatCatList);
}
}
And this is the second function:
$scope.drillDownCategoryItemCatList = {};
$scope.drillDownCategoryItemsCat = function (dept,group,catg,subcat) {
$scope.nbr1 = [dept];
$scope.nbr2 = [group];
$scope.nbr3 = [catg];
$scope.nbr4 = [subcat];
$scope.nbrSubcatItem = 'D' + $scope.nbr1 + 'CG' + $scope.nbr2 + 'C' + $scope.nbr3 + 'SC' + $scope.nbr4;
$scope.nbrSubcatItem.toString();
$scope.ItemsConst = ['Product Sales (Item Rank)'];
$scope.drillDownRecords = "5";
console.log($scope.nbr1);
console.log($scope.nbr2);
console.log($scope.nbr3);
console.log($scope.nbr4);
console.log("NBR: " + $scope.nbrSubcatItem);
if (!($scope.nbrSubcatItem in $scope.drillDownCategoryItemCatList)) {
$scope.loadViewCategories = false;
$scope.graphLoading = "loading";
searchFactory.search('merchandise',
{
timeStamp: $scope.dateTime,
timeFrameType: $scope.whenType,
custMembSelectionType: $scope.customerType,
locationSelectionType: $scope.locationType,
merchandiseSelectionType: "SubCategory",
startYear: $scope.whenStartParentYear,
endYear: $scope.whenStartParentYear,
startUnit: $scope.whenStartValue,
endUnit: $scope.whenStartValue,
comparator: $scope.locationType.indexOf('(Comp)', $scope.locationType.length - '(Comp)'.length) !== -1,
locationSelections: $scope.locationSelected,
merchandiseSelections: [$scope.nbrSubcatItem],
custMembSelections: $scope.customerSelected,
metricSelections: $scope.ItemsConst,
rankOrder: $scope.drillDownRecords
}).success(function (data) {
console.log("drillDownCategortyItems OK");
$scope.loadViewCategories = true;
$scope.graphLoading = "white";
$scope.canvasContent = true;
$scope.exportDataCategoryItemDrillDown = data;
$scope.metricSelected = $scope.filters.baropt.displayName;
if (data.error) {
$scope.noData = "There are no results based on your selected dropdowns. Please change your selection.";
$scope.data = undefined;
$scope.hasError = true;
}
$scope.isExportDisabled = 'auto';
if (!$scope.drillDownCategoryItemCatList[$scope.nbrSubcatItem]) {
$scope.drillDownCategoryItemCatList[$scope.nbrSubcatItem] = $scope.exportDataCategoryItemDrillDown.result;
}
}).error(function (ret, status) {
console.log(ret, status);
if (status == 500 || status == 0) {
if (ret.error.indexOf("Filter criteria not found!") > -1 || ret.error.indexOf("Bad Selections!") > -1) {
$scope.errorMessage = "The combination of dropdowns you selected is invalid. Please select a different combination.";
} else {
$scope.errorMessage = "The database may be down. Please contact Data Cafe Development Team - Applications for help.";
}
} else if (status == 400) {
$scope.errorMessage = "There was a bad request sent to the database. Please contact Data Cafe Development Team - Applications for help.";
} else {
$scope.errorMessage = "There was an error while trying to process your request. Please contact Data Cafe Development Team - Applications for help.";
}
$scope.hasError = true;
$scope.graphLoading = "white";
$scope.canvasContent = true;
$scope.showCaptions = false;
}
);
}
if($scope.nbrSubcatItem in $scope.drillDownCategoryItemCatList) {
console.log("LIST FROM CATEGORY TO ITEM LEVEL: ", $scope.drillDownCategoryItemCatList);
}
}
As I mentioned before, the parent and the child level are displayed ok, so any idea on how can I nest the ng-repeat's in order to allow my grandson level to be displayed?
There is something strange here that you require a single table in the UI, but the underlying model is of a triply nested object. ng-repeat is not meant to be nested at sibling DOM levels.
The way I would recommend implementing this is to use an angular filter that will wrap all of your data into a single array that you can call ng-repeat on.
Your controller has wayyyyy too much logic in it. And I think this is contributing to the difficulties. In general, the controller should be in charge of displaying data that is being provided by angular services. The angular services should provide the data in a way that is easy for the controllers to consume.
If you find yourself creating nested if statements, xhr requests, and error handling inside of the controller, then you are doing something wrong. All of this should be refactored to several services (each service should have a SINGLE responsibility). Then you should have one of the services provide data to the controller that is easy for it to consume.
This is a bit of a vague answer, and not really a simple one. I think that the problems you are having come from not fully understanding how Angular implements the MVC pattern.
One of the common patterns I've come across in my many years of coding is the structuring/binding of the data coming from the server response (XMLHttpRequest). This problem of creating elements and appending them in a particular order as well as binding (attributes,events,content) is what I'm am trying to achieve here.
For example purposes and simplicity I am trying to create a tr --- td nested structure as well as bind the attributes from the var instructs object (table-row,table-data).
JSON Response (dummy data)
var response =[{"employeeNumber":"1002","lastName":"Murphy","firstName":"Diane","extension":"x5800","email":"dmurphy#classicmodelcars.com","officeCode":"1","reportsTo":null,"jobTitle":"President"},{"employeeNumber":"1056","lastName":"Patterson","firstName":"Mary","extension":"x4611","email":"mpatterso#classicmodelcars.com","officeCode":"1","reportsTo":"1002","jobTitle":"VP Sales"},{"employeeNumber":"1076","lastName":"Firrelli","firstName":"Jeff","extension":"x9273","email":"jfirrelli#classicmodelcars.com","officeCode":"1","reportsTo":"1002","jobTitle":"VP Marketing"},{"employeeNumber":"1088","lastName":"Patterson","firstName":"William","extension":"x4871","email":"wpatterson#classicmodelcars.com","officeCode":"6","reportsTo":"1056","jobTitle":"Sales Manager (APAC)"},{"employeeNumber":"1102","lastName":"Bondur","firstName":"Gerard","extension":"x5408","email":"gbondur#classicmodelcars.com","officeCode":"4","reportsTo":"1056","jobTitle":"Sale Manager (EMEA)"},{"employeeNumber":"1143","lastName":"Bow","firstName":"Anthony","extension":"x5428","email":"abow#classicmodelcars.com","officeCode":"1","reportsTo":"1056","jobTitle":"Sales Manager (NA)"},{"employeeNumber":"1165","lastName":"Jennings","firstName":"Leslie","extension":"x3291","email":"ljennings#classicmodelcars.com","officeCode":"1","reportsTo":"1143","jobTitle":"Sales Rep"},{"employeeNumber":"1166","lastName":"Thompson","firstName":"Leslie","extension":"x4065","email":"lthompson#classicmodelcars.com","officeCode":"1","reportsTo":"1143","jobTitle":"Sales Rep"},{"employeeNumber":"1188","lastName":"Firrelli","firstName":"Julie","extension":"x2173","email":"jfirrelli#classicmodelcars.com","officeCode":"2","reportsTo":"1143","jobTitle":"Sales Rep"},{"employeeNumber":"1216","lastName":"Patterson","firstName":"Steve","extension":"x4334","email":"spatterson#classicmodelcars.com","officeCode":"2","reportsTo":"1143","jobTitle":"Sales Rep"},{"employeeNumber":"1286","lastName":"Tseng","firstName":"Foon Yue","extension":"x2248","email":"ftseng#classicmodelcars.com","officeCode":"3","reportsTo":"1143","jobTitle":"Sales Rep"},{"employeeNumber":"1323","lastName":"Vanauf","firstName":"George","extension":"x4102","email":"gvanauf#classicmodelcars.com","officeCode":"3","reportsTo":"1143","jobTitle":"Sales Rep"},{"employeeNumber":"1337","lastName":"Bondur","firstName":"Loui","extension":"x6493","email":"lbondur#classicmodelcars.com","officeCode":"4","reportsTo":"1102","jobTitle":"Sales Rep"},{"employeeNumber":"1370","lastName":"Hernandez","firstName":"Gerard","extension":"x2028","email":"ghernande#classicmodelcars.com","officeCode":"4","reportsTo":"1102","jobTitle":"Sales Rep"},{"employeeNumber":"1401","lastName":"Castillo","firstName":"Pamela","extension":"x2759","email":"pcastillo#classicmodelcars.com","officeCode":"4","reportsTo":"1102","jobTitle":"Sales Rep"},{"employeeNumber":"1501","lastName":"Bott","firstName":"Larry","extension":"x2311","email":"lbott#classicmodelcars.com","officeCode":"7","reportsTo":"1102","jobTitle":"Sales Rep"},{"employeeNumber":"1504","lastName":"Jones","firstName":"Barry","extension":"x102","email":"bjones#classicmodelcars.com","officeCode":"7","reportsTo":"1102","jobTitle":"Sales Rep"},{"employeeNumber":"1611","lastName":"Fixter","firstName":"Andy","extension":"x101","email":"afixter#classicmodelcars.com","officeCode":"6","reportsTo":"1088","jobTitle":"Sales Rep"},{"employeeNumber":"1612","lastName":"Marsh","firstName":"Peter","extension":"x102","email":"pmarsh#classicmodelcars.com","officeCode":"6","reportsTo":"1088","jobTitle":"Sales Rep"},{"employeeNumber":"1619","lastName":"King","firstName":"Tom","extension":"x103","email":"tking#classicmodelcars.com","officeCode":"6","reportsTo":"1088","jobTitle":"Sales Rep"},{"employeeNumber":"1621","lastName":"Nishi","firstName":"Mami","extension":"x101","email":"mnishi#classicmodelcars.com","officeCode":"5","reportsTo":"1056","jobTitle":"Sales Rep"},{"employeeNumber":"1625","lastName":"Kato","firstName":"Yoshimi","extension":"x102","email":"ykato#classicmodelcars.com","officeCode":"5","reportsTo":"1621","jobTitle":"Sales Rep"},{"employeeNumber":"1702","lastName":"Gerard","firstName":"Martin","extension":"x2312","email":"mgerard#classicmodelcars.com","officeCode":"4","reportsTo":"1102","jobTitle":"Sales Rep"}];
Binding (instructions)
var instructs={
tag:"tr",
attributes:{class:"table-row"},
props:{
email:{
tag:"td",
content: null,
attributes:{class:"table-data",id:"table-data-id"}
},
employeeNumber:{
tag:"td",
attributes:{class:"table-data"},
content: null,
props:{
x:{
tag: "input",
attributes:{class:"table-input"},
content: "test"
}
}
},
extension:{
tag:"td",
content: null,
attributes:{class:"table-data"}
},
firstName:{
tag:"td",
content: null,
attributes:{class:"table-data"}
},
jobTitle:{
tag:"td",
content: null,
attributes:{class:"table-data"}
},
lastName:{
tag:"td",
content: null,
attributes:{class:"table-data"}
},
officeCode:{
tag:"td",
content: null,
attributes:{class:"table-data"}
},
reportsTo:{
tag:"td",
content: null,
attributes:{class:"table-data"}
}
}
};
My Function (assemble)
function assemble(r,s,n){
var n = n || new DocumentFragment();
if(typeof r !== 'string'){ //HAS CHILDREN
r.forEach((o)=>{
for(y in s){
switch(y){
case "tag":
var tag = document.createElement(s[y]);
n.appendChild(tag);
break;
case "attributes":
for(a in s[y]) tag.setAttribute(a,s[y][a]);
break;
case "content":
if(s.content === null){
//append current property value
}
else{
tag.innerHTML = s.content;
}
break;
case "props":
for(k in o) assemble(k,s[y][k],tag); //EXECUTE PER CHILDREN
break;
}
}
});
}
else{
for(x in s){
switch(x){
case "tag":
var tag = document.createElement(s[x]);
n.appendChild(tag);
break;
case "content":
if(s.content === null){
//append current property value
}
else{
tag.innerHTML = s.content;
}
break;
case "attributes":
for(a in s[x]) tag.setAttribute(a,s[x][a]);
break;
case "props":
for(c in s[x]) assemble(r,s[x][c],tag);
break;
}
}
return n;
}
return n;
}
document.addEventListener('DOMContentLoaded',()=>{
var data = assemble(response,instructs);
console.log(data);
});
The end result I'm looking for is an array/fragment of nested tr>td both with a class attribute and the values append to the innerHTML.
<tr class ="table-row">
<td class="table-data">how do I bind the response values?</td>
<td class="table-data">how do I bind the response values?</td>
<td class="table-data">how do I bind the response values?</td>
<td class="table-data">how do I bind the response values?</td>
<td class="table-data">how do I bind the response values?</td>
<td class="table-data">how do I bind the response values?</td>
<td class="table-data">how do I bind the response values?</td>
</tr>
QUESTION:
How can I bind the property values from the response to the innerHTML of the td's?
Give a try to the following one. Sorry, I started refactoring Yours and in the end I had rewritten it. Take care that the content is always taken as innerHTML, it would not be a bad idea at all to differentiate text(append createTextNode func outcome) and html(innerHTML prop). In your data instructs.props.employeeNumber.props.x.content should be moved into instructs.props.employeeNumber.props.x.attributes.value seen how works the input[text] tag. Btw I see there are a lot of stuff that could be discussed here. Hope it helps!
function assemble (data, instr) {
var n = document.createDocumentFragment(), i;
function create(d) {
var objData = d;
return (function _(_instr, _key, _n) {
var innerHTML = !!_key && _key in objData ? objData[_key] : null,
tag = null, i;
if ('tag' in _instr) {
tag = document.createElement(_instr.tag);
tag.innerHTML = 'content' in _instr && !!_instr.content ? _instr.content : innerHTML;
if ('attributes' in _instr) {
for (i in _instr.attributes) tag.setAttribute(i, _instr.attributes[i]);
}
//recur finally
if ('props' in _instr) {
for (i in _instr.props) _(_instr.props[i], i, tag);
}
!!_n && _n.appendChild(tag);
}
return tag;
})(instr, null);
}
return (function (){
for (i in data) {
n.appendChild(create(data[i]));
}
return n;
})();
}
Though my answer does not address the code context from the question, but for structuring and binding json response i usually use regex templating. I find it simple in declaration and concise. ex,
html:
<table>
<tbody id="employee">
</tbody>
</table>
js:
var template = function(tpl, data) {
return tpl.replace(/\$\{([^\}]+)?\}/g, function($1, $2) {
return data[$2];
});
};
var rowTemplate = '<tr class ="table-row">\
<td class="table-data">${email}</td>\
<td class="table-data"><input type="text" value=' ${employeeNumber}' /></td>\
<td class="table-data">${firstName}</td>\
<td class="table-data">${lastName}</td>\
<td class="table-data">${email}</td>\
<td class="table-data">${jobTitle}</td>\
<td class="table-data">${extension}</td>\
</tr>';
var response = [{"employeeNumber":"1002","lastName":"Murphy","firstName":"Diane","extension":"x5800","email":"dmurphy#classicmodelcars.com","officeCode":"1","reportsTo":null,"jobTitle":"President"}, ....]
var b = document.getElementById('employee');
for (var i = 0; i < response.length; i++) {
var tr = document.createElement('x');
b.appendChild(tr);
tr.outerHTML = template(rowTemplate, response[i]);
}
fiddle
hope this helps.