jQuery DataTables - Force the Empty Table message after AJAX Call - javascript
I have a jquery-datatables set up, and using a custom search filter that functions as the standard keyword filter and a custom Item ID search which uses an ajax call to ping the back end and return a value, if any and then use that value to search the table in a specific column.
$.ajax({
url: 'the_url_to_lookup_itemID',
data: {
'engravingId': search(search is the value from the input field assigned to this variable)
},
dataType: 'jsonp',
success: function(data) {
console.log(data.assetId);
var assetId = data.assetId;
if (assetId != 0) {
searchResults.columns(2).search(assetId).draw();
} else {
searchResults.search(assetId).draw();
}
}
});
If the assetId equals "0" then the search just assumes its a keyword, since there is no record of the assetId existing. But instead of clearing out the table records and showing no results, there is no change. I'm assuming because "0" isn't enough for the filter to operate, so how can I force it? I want the user to see some result, "No matching records found" or something like that.
How can I force my jquery-datatables to display "No matching records found" after this custom search has failed to produce any results?
I am NOT looking for a custom message when there are no results. I am just looking for a way to force the display of this "No matching records found" when I execute my Ajax call and that function generates no results.
One way to force to display "No matching records found" message is by using the clear() and draw() methods.
If you need to change in runtime the message, you could use datatables.context[0].oLanguage.sEmptyTable attribute.
In your case is:
searchResults.context[0].oLanguage.sEmptyTable = "No matching records found...";
searchResults.clear().draw();
Something like this:
$(function() {
var dataSet = [
["Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800"],
["Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750"],
["Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000"],
["Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060"],
["Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700"],
["Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000"],
["Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500"],
["Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900"],
["Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500"],
["Sonya Frost", "Software Engineer", "Edinburgh", "1667", "2008/12/13", "$103,600"],
["Jena Gaines", "Office Manager", "London", "3814", "2008/12/19", "$90,560"],
["Quinn Flynn", "Support Lead", "Edinburgh", "9497", "2013/03/03", "$342,000"],
["Charde Marshall", "Regional Director", "San Francisco", "6741", "2008/10/16", "$470,600"],
["Haley Kennedy", "Senior Marketing Designer", "London", "3597", "2012/12/18", "$313,500"],
["Tatyana Fitzpatrick", "Regional Director", "London", "1965", "2010/03/17", "$385,750"],
["Michael Silva", "Marketing Designer", "London", "1581", "2012/11/27", "$198,500"],
["Paul Byrd", "Chief Financial Officer (CFO)", "New York", "3059", "2010/06/09", "$725,000"],
["Gloria Little", "Systems Administrator", "New York", "1721", "2009/04/10", "$237,500"],
["Bradley Greer", "Software Engineer", "London", "2558", "2012/10/13", "$132,000"],
["Dai Rios", "Personnel Lead", "Edinburgh", "2290", "2012/09/26", "$217,500"],
["Jenette Caldwell", "Development Lead", "New York", "1937", "2011/09/03", "$345,000"],
["Yuri Berry", "Chief Marketing Officer (CMO)", "New York", "6154", "2009/06/25", "$675,000"],
["Caesar Vance", "Pre-Sales Support", "New York", "8330", "2011/12/12", "$106,450"],
["Doris Wilder", "Sales Assistant", "Sidney", "3023", "2010/09/20", "$85,600"],
["Angelica Ramos", "Chief Executive Officer (CEO)", "London", "5797", "2009/10/09", "$1,200,000"],
["Gavin Joyce", "Developer", "Edinburgh", "8822", "2010/12/22", "$92,575"],
["Jennifer Chang", "Regional Director", "Singapore", "9239", "2010/11/14", "$357,650"],
["Brenden Wagner", "Software Engineer", "San Francisco", "1314", "2011/06/07", "$206,850"],
["Fiona Green", "Chief Operating Officer (COO)", "San Francisco", "2947", "2010/03/11", "$850,000"],
["Shou Itou", "Regional Marketing", "Tokyo", "8899", "2011/08/14", "$163,000"],
["Michelle House", "Integration Specialist", "Sidney", "2769", "2011/06/02", "$95,400"],
["Suki Burks", "Developer", "London", "6832", "2009/10/22", "$114,500"],
["Prescott Bartlett", "Technical Author", "London", "3606", "2011/05/07", "$145,000"],
["Gavin Cortez", "Team Leader", "San Francisco", "2860", "2008/10/26", "$235,500"],
["Martena Mccray", "Post-Sales support", "Edinburgh", "8240", "2011/03/09", "$324,050"],
["Unity Butler", "Marketing Designer", "San Francisco", "5384", "2009/12/09", "$85,675"]
];
var columnDefs = [{
title: "Name"
}, {
title: "Position"
}, {
title: "Office"
}, {
title: "Extn."
}, {
title: "Start date"
}, {
title: "Salary"
}];
var searchResults;
searchResults = $('#example').DataTable({
"sPaginationType": "full_numbers",
data: dataSet,
columns: columnDefs,
dom: 'Bfrtip', // Needs button container
select: 'single',
responsive: true,
buttons: []
});
// Setting the required behaviour to this question.
document.getElementById("btnSetEmptyResults").onclick = function() {
searchResults.context[0].oLanguage.sEmptyTable = "No matching records found...";
searchResults.clear().draw();
};
});
table.dataTable tbody>tr.selected,
table.dataTable tbody>tr>.selected {
background-color: #A2D3F6;
}
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.0.2/css/responsive.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.11/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.1.2/css/buttons.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.1.2/css/select.dataTables.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.1.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/select/1.1.2/js/dataTables.select.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/responsive/2.0.2/js/dataTables.responsive.min.js"></script>
<div class="container">
<button id="btnSetEmptyResults" class="dt-button" type="button">
Set empty results
</button>
<table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
</table>
</div>
Update:
If you need to print back all the data, you need to use the rows.add(data) method where the data parameter is the previous data that you used to print in the datatable plugin initially. Then use the .draw() method again to render the table:
searchResults.rows.add(assetId).draw();
In this demo: After 2 seconds will print back all the data in the table after the cleaning the datatable.
$(function() {
var dataSet = [
["Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800"],
["Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750"],
["Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000"],
["Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060"],
["Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700"],
["Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000"],
["Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500"],
["Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900"],
["Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500"],
["Sonya Frost", "Software Engineer", "Edinburgh", "1667", "2008/12/13", "$103,600"],
["Jena Gaines", "Office Manager", "London", "3814", "2008/12/19", "$90,560"],
["Quinn Flynn", "Support Lead", "Edinburgh", "9497", "2013/03/03", "$342,000"],
["Charde Marshall", "Regional Director", "San Francisco", "6741", "2008/10/16", "$470,600"],
["Haley Kennedy", "Senior Marketing Designer", "London", "3597", "2012/12/18", "$313,500"],
["Tatyana Fitzpatrick", "Regional Director", "London", "1965", "2010/03/17", "$385,750"],
["Michael Silva", "Marketing Designer", "London", "1581", "2012/11/27", "$198,500"],
["Paul Byrd", "Chief Financial Officer (CFO)", "New York", "3059", "2010/06/09", "$725,000"],
["Gloria Little", "Systems Administrator", "New York", "1721", "2009/04/10", "$237,500"],
["Bradley Greer", "Software Engineer", "London", "2558", "2012/10/13", "$132,000"],
["Dai Rios", "Personnel Lead", "Edinburgh", "2290", "2012/09/26", "$217,500"],
["Jenette Caldwell", "Development Lead", "New York", "1937", "2011/09/03", "$345,000"],
["Yuri Berry", "Chief Marketing Officer (CMO)", "New York", "6154", "2009/06/25", "$675,000"],
["Caesar Vance", "Pre-Sales Support", "New York", "8330", "2011/12/12", "$106,450"],
["Doris Wilder", "Sales Assistant", "Sidney", "3023", "2010/09/20", "$85,600"],
["Angelica Ramos", "Chief Executive Officer (CEO)", "London", "5797", "2009/10/09", "$1,200,000"],
["Gavin Joyce", "Developer", "Edinburgh", "8822", "2010/12/22", "$92,575"],
["Jennifer Chang", "Regional Director", "Singapore", "9239", "2010/11/14", "$357,650"],
["Brenden Wagner", "Software Engineer", "San Francisco", "1314", "2011/06/07", "$206,850"],
["Fiona Green", "Chief Operating Officer (COO)", "San Francisco", "2947", "2010/03/11", "$850,000"],
["Shou Itou", "Regional Marketing", "Tokyo", "8899", "2011/08/14", "$163,000"],
["Michelle House", "Integration Specialist", "Sidney", "2769", "2011/06/02", "$95,400"],
["Suki Burks", "Developer", "London", "6832", "2009/10/22", "$114,500"],
["Prescott Bartlett", "Technical Author", "London", "3606", "2011/05/07", "$145,000"],
["Gavin Cortez", "Team Leader", "San Francisco", "2860", "2008/10/26", "$235,500"],
["Martena Mccray", "Post-Sales support", "Edinburgh", "8240", "2011/03/09", "$324,050"],
["Unity Butler", "Marketing Designer", "San Francisco", "5384", "2009/12/09", "$85,675"]
];
var columnDefs = [{
title: "Name"
}, {
title: "Position"
}, {
title: "Office"
}, {
title: "Extn."
}, {
title: "Start date"
}, {
title: "Salary"
}];
var searchResults;
searchResults = $('#example').DataTable({
"sPaginationType": "full_numbers",
data: dataSet,
columns: columnDefs,
dom: 'Bfrtip', // Needs button container
select: 'single',
responsive: true,
buttons: []
});
// Setting the required behaviour to this question.
document.getElementById("btnSetEmptyResults").onclick = function() {
searchResults.context[0].oLanguage.sEmptyTable = "No matching records found...";
searchResults.clear().draw();
// Get back all the data after 2 seconds.
setTimeout(function() {
searchResults.rows.add(dataSet).draw();
}, 2000);
};
});
table.dataTable tbody>tr.selected,
table.dataTable tbody>tr>.selected {
background-color: #A2D3F6;
}
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.0.2/css/responsive.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.11/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.1.2/css/buttons.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.1.2/css/select.dataTables.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.1.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/select/1.1.2/js/dataTables.select.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/responsive/2.0.2/js/dataTables.responsive.min.js"></script>
<div class="container">
<button id="btnSetEmptyResults" class="dt-button" type="button">
Set empty results
</button>
<table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
</table>
</div>
Related
HTML Elements (tr &td) are showing on the client side
This is my first question on stack overflow, so I hope that I'm doing this correctly! I'm working with pulling some data from an API, and then displaying that data in a table. So far my table is showing the HTML elements of <tr><td> + </tr></td> Here is a photo to show my issue : Photo of issue Here is the code that I'm using : const fetchUserz = async() => { const response = await fetch(`https://jsonplaceholder.typicode.com/users`); const data = await response.json(); for (let i = 0; i < data.length; i++) { let table = document.getElementById(`myTable`); let row = `<tr> <td>${data[i].name}</td> <td>${data[i].email}</td> </tr>`; table.innerHTML += row; table.append(row); } } fetchUserz(); Here is the HTML : <body class="text-white bg-secondary mb-3 bg-gradient" id="body"> <main> <header id="head"> <h2>API Project</h2> </header> <table> <thead> <tr> <th> Names of People </th> <th> Emails of People </th> </tr> </thead> const fetchUserz = async() => { const response = await fetch(`https://jsonplaceholder.typicode.com/users`); const data = await response.json(); // console.log(data) for(let i = 0; i < data.length; i++){ let table = document.getElementById(`myTable`); let row = `<tr> <td>${data[i].name}</td> <td>${data[i].email}</td> </tr>`; table.innerHTML += row; table.append(row); } } fetchUserz(); <!DOCTYPE html> <html lang="en"> <head> <meta charset = "UTF-8"> <title>Native Awakenings</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.css" rel="stylesheet" crossorigin="anonymous"> <link href="/css/stylesheet.css" rel="stylesheet"> </head> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="/index.html">Native Awakenings</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav me-auto mb-2 mb-lg-0"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="/index.html">Home</a> </li> <li class="nav-item"> About Me </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> Concious Creations </a> <ul class="dropdown-menu" aria-labelledby="navbarDropdown"> <li><a class="dropdown-item" href="blog-posts.html">Blog Posts</a></li> <li><a class="dropdown-item" href="offerings.html">Offerings</a></li> <li><a class="dropdown-item" href="podcasts.html">Podcasts</a></li> <li><a class="dropdown-item" href="yoga-videos.html">Yoga Videos</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="https://gitlab.com/Gregg-Hendrix/how-i-became-a-software-engineer" target="_blank">How I Became A Software Engineer</a></li> </ul> </li> </ul> <span class="navbar-text"> May Presence Be Our Purpose </span> </div> </div> </nav> <body class="text-white bg-secondary mb-3 bg-gradient" id="body"> <main> <header id="head"> <h2>API Project</h2> </header> <table> <thead> <tr> <th> Names of People </th> <th> Emails of People </th> </tr> </thead> <tbody id="myTable"> </tbody> </main> <footer class="card-footer bg-dark bg-gradient navbar-dark text-light" id="footer"> If you want to support Native Awakenings, please do one kind act! Remember that you are unconditionally loved. My social media: Insta: #Greggyogi, Email: gregg#gregghendrix.com, Facebook: Gregg Hendrix</footer> <script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script> <script src="/js/weather.js"></script> </body> </html> I've also added a snippet of EVERYTHING, any help would be massively appreciated :).
You immediate problem is using both innerHTML and append as covered in the comments Let's go with innerHTML... It's probably better to create your HTML string in one go rather than el.innerHTML += .... My gut feeling it that .innerHTML += will have pretty bad performance as each round will require an HTML parse and an HTML serialize. const table = document.getElementById(`myTable`); const rows = data.map(d=>`<tr> <td>${data[i].name}</td> <td>${data[i].email}</td> </tr>`); table.innerHTML = rows.join("");
You can create your HTML string as below. const fetchUserz = async() => { const data = [ { "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "Sincere#april.biz", "address": { "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", "geo": { "lat": "-37.3159", "lng": "81.1496" } }, "phone": "1-770-736-8031 x56442", "website": "hildegard.org", "company": { "name": "Romaguera-Crona", "catchPhrase": "Multi-layered client-server neural-net", "bs": "harness real-time e-markets" } }, { "id": 2, "name": "Ervin Howell", "username": "Antonette", "email": "Shanna#melissa.tv", "address": { "street": "Victor Plains", "suite": "Suite 879", "city": "Wisokyburgh", "zipcode": "90566-7771", "geo": { "lat": "-43.9509", "lng": "-34.4618" } }, "phone": "010-692-6593 x09125", "website": "anastasia.net", "company": { "name": "Deckow-Crist", "catchPhrase": "Proactive didactic contingency", "bs": "synergize scalable supply-chains" } }, { "id": 3, "name": "Clementine Bauch", "username": "Samantha", "email": "Nathan#yesenia.net", "address": { "street": "Douglas Extension", "suite": "Suite 847", "city": "McKenziehaven", "zipcode": "59590-4157", "geo": { "lat": "-68.6102", "lng": "-47.0653" } }, "phone": "1-463-123-4447", "website": "ramiro.info", "company": { "name": "Romaguera-Jacobson", "catchPhrase": "Face to face bifurcated interface", "bs": "e-enable strategic applications" } }, { "id": 4, "name": "Patricia Lebsack", "username": "Karianne", "email": "Julianne.OConner#kory.org", "address": { "street": "Hoeger Mall", "suite": "Apt. 692", "city": "South Elvis", "zipcode": "53919-4257", "geo": { "lat": "29.4572", "lng": "-164.2990" } }, "phone": "493-170-9623 x156", "website": "kale.biz", "company": { "name": "Robel-Corkery", "catchPhrase": "Multi-tiered zero tolerance productivity", "bs": "transition cutting-edge web services" } }, { "id": 5, "name": "Chelsey Dietrich", "username": "Kamren", "email": "Lucio_Hettinger#annie.ca", "address": { "street": "Skiles Walks", "suite": "Suite 351", "city": "Roscoeview", "zipcode": "33263", "geo": { "lat": "-31.8129", "lng": "62.5342" } }, "phone": "(254)954-1289", "website": "demarco.info", "company": { "name": "Keebler LLC", "catchPhrase": "User-centric fault-tolerant solution", "bs": "revolutionize end-to-end systems" } }, { "id": 6, "name": "Mrs. Dennis Schulist", "username": "Leopoldo_Corkery", "email": "Karley_Dach#jasper.info", "address": { "street": "Norberto Crossing", "suite": "Apt. 950", "city": "South Christy", "zipcode": "23505-1337", "geo": { "lat": "-71.4197", "lng": "71.7478" } }, "phone": "1-477-935-8478 x6430", "website": "ola.org", "company": { "name": "Considine-Lockman", "catchPhrase": "Synchronised bottom-line interface", "bs": "e-enable innovative applications" } }, { "id": 7, "name": "Kurtis Weissnat", "username": "Elwyn.Skiles", "email": "Telly.Hoeger#billy.biz", "address": { "street": "Rex Trail", "suite": "Suite 280", "city": "Howemouth", "zipcode": "58804-1099", "geo": { "lat": "24.8918", "lng": "21.8984" } }, "phone": "210.067.6132", "website": "elvis.io", "company": { "name": "Johns Group", "catchPhrase": "Configurable multimedia task-force", "bs": "generate enterprise e-tailers" } }, { "id": 8, "name": "Nicholas Runolfsdottir V", "username": "Maxime_Nienow", "email": "Sherwood#rosamond.me", "address": { "street": "Ellsworth Summit", "suite": "Suite 729", "city": "Aliyaview", "zipcode": "45169", "geo": { "lat": "-14.3990", "lng": "-120.7677" } }, "phone": "586.493.6943 x140", "website": "jacynthe.com", "company": { "name": "Abernathy Group", "catchPhrase": "Implemented secondary concept", "bs": "e-enable extensible e-tailers" } }, { "id": 9, "name": "Glenna Reichert", "username": "Delphine", "email": "Chaim_McDermott#dana.io", "address": { "street": "Dayna Park", "suite": "Suite 449", "city": "Bartholomebury", "zipcode": "76495-3109", "geo": { "lat": "24.6463", "lng": "-168.8889" } }, "phone": "(775)976-6794 x41206", "website": "conrad.com", "company": { "name": "Yost and Sons", "catchPhrase": "Switchable contextually-based project", "bs": "aggregate real-time technologies" } }, { "id": 10, "name": "Clementina DuBuque", "username": "Moriah.Stanton", "email": "Rey.Padberg#karina.biz", "address": { "street": "Kattie Turnpike", "suite": "Suite 198", "city": "Lebsackbury", "zipcode": "31428-2261", "geo": { "lat": "-38.2386", "lng": "57.2232" } }, "phone": "024-648-3804", "website": "ambrose.net", "company": { "name": "Hoeger LLC", "catchPhrase": "Centralized empowering task-force", "bs": "target end-to-end models" } } ] let table = document.getElementById(`myTable`); for(let i = 0; i < data.length; i++){ let row = ''; row +='<tr>'; row +='<td>'+data[i].name+'</td>'; row +='<td>'+data[i].email+'</td>'; row +='</tr>'; table.innerHTML += row; } } fetchUserz(); <table> <thead> <tr> <th> Names of People </th> <th> Emails of People </th> </tr> </thead> <tbody id="myTable"> </tbody> <tbody id="myTable2"> </tbody> </table>
const fetchUserz = async() => { const response = await fetch(`https://jsonplaceholder.typicode.com/users`); const data = await response.json(); // console.log(data) for(let i = 0; i < data.length; i++){ let table = document.getElementById(`myTable`); let row = `<tr> <td>${data[i].name}</td> <td>${data[i].email}</td> </tr>`; table.innerHTML += row; } } fetchUserz();
Multiple bootstrap tabs with DataTables. Child row only opening on one of the tabs
I have DataTables with child rows inside of 2 bootstrap tabs. The child rows do not consistently open inside the tab. They sometimes open on the first tab and sometimes on the second. I want to create the container every time I click on the row and have it open. It sometimes opens in the second and sometimes in the first. It does not open in both tabs. Here is my code: let json1 = [{ "data": [ { "id": "1", "name": "Tiger Nixon", "position": "System Architect", "salary": "$320,800", "start_date": "2011/04/25", "office": "Edinburgh", "extn": "5421" }, { "id": "2", "name": "Garrett Winters", "position": "Accountant", "salary": "$170,750", "start_date": "2011/07/25", "office": "Tokyo", "extn": "8422" }, { "id": "3", "name": "Ashton Cox", "position": "Junior Technical Author", "salary": "$86,000", "start_date": "2009/01/12", "office": "San Francisco", "extn": "1562" }, { "id": "4", "name": "Cedric Kelly", "position": "Senior Javascript Developer", "salary": "$433,060", "start_date": "2012/03/29", "office": "Edinburgh", "extn": "6224" }, { "id": "5", "name": "Airi Satou", "position": "Accountant", "salary": "$162,700", "start_date": "2008/11/28", "office": "Tokyo", "extn": "5407" } ] }]; let json2 = [{ "data": [ { "id": "1", "name": "Harry Potter", "position": "System Architect", "salary": "$234,800", "start_date": "2013/04/25", "office": "Edinburgh", "extn": "5421" }, { "id": "2", "name": "Ron Weasley", "position": "Accountant", "salary": "$170,777", "start_date": "2011/09/25", "office": "Tokyo", "extn": "8422" }, { "id": "3", "name": "Herminone Granger", "position": "Junior Technical Author", "salary": "$175,000", "start_date": "2019/01/12", "office": "San Francisco", "extn": "1562" }, { "id": "4", "name": "Neville Logbottom", "position": "Senior Javascript Developer", "salary": "$555,060", "start_date": "2015/03/29", "office": "Edinburgh", "extn": "6224" }, { "id": "5", "name": "Luna Lovegood", "position": "Accountant", "salary": "$200,700", "start_date": "2017/11/28", "office": "Tokyo", "extn": "5407" } ] }]; var table; const create_datatable =(js, tab) => { js.forEach(d => { table = $(`#${tab}`).DataTable( { "bDestroy": true, "responsive": true, "autoWidth": false, "data": d.data, columns: [{ className: 'details-control', orderable: false, data: null, defaultContent: '', }, { data: 'name', className:'names' }, { data: 'position', className:'position' }, { data: 'office', className:'office' }, { data: 'salary', className:'salary' }] } ); }); } create_datatable(json1, 'example'); create_datatable(json2, 'example2'); const create_cont = (tab) => { var containers = document.createElement('div'); containers.setAttribute("id", `${tab}_scatter`); $(`#${tab} tbody`).on('click', 'td.details-control', function () { var tr = $(this).closest('tr'); var row = table.row( tr ); if ( row.child.isShown() ) { // This row is already open - close it row.child.hide(); tr.removeClass('shown'); } else { if ( table.row( '.shown' ).length ) $('.details-control', table.row( '.shown' ).node()).click(); $(`#${tab}_scatter`).html('test'); row.child(containers).show(); tr.addClass('shown'); } }); } create_cont('example'); create_cont('example2'); td.details-control { background: url('../resources/details_open.png') no-repeat center center; cursor: pointer; } tr.shown td.details-control { background: url('../resources/details_close.png') no-repeat center center; } <link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script> <ul class="nav nav-tabs"> <li class="active"><a data-toggle="tab" href="#home">Home</a></li> <li><a data-toggle="tab" href="#menu1">Menu 1</a></li> </ul> <div class="tab-content"> <div id="home" class="tab-pane fade in active"> <h3>Tab 1</h3> <table id="example" class="display" style="width:100%"> <thead> <tr> <th>Show Child Row</th> <th>Name</th> <th>Position</th> <th>Office</th> <th>Salary</th> </tr> </thead> <tbody></tbody> </table> </div> <div id="menu1" class="tab-pane fade"> <h3>Tab 2</h3> <table id="example2" class="display" style="width:100%"> <thead> <tr> <th>Show Child Row</th> <th>Name</th> <th>Position</th> <th>Office</th> <th>Salary</th> </tr> </thead> <tbody></tbody> </table> </div> </div> How do I fix it so that the row opens with my text('test') whenever I click the left-most column, a child row always happens? I am creating a container every time I click on the row because I want to eventually add dynamic charts inside child row.
The issue is because you set table within the loop. Therefore it will only ever contain a reference to the last DataTable which was created. To fix this, get the DataTable reference from the table element within the click handler: let json1 = [{data:[{id:"1",name:"Tiger Nixon",position:"System Architect",salary:"$320,800",start_date:"2011/04/25",office:"Edinburgh",extn:"5421"},{id:"2",name:"Garrett Winters",position:"Accountant",salary:"$170,750",start_date:"2011/07/25",office:"Tokyo",extn:"8422"},{id:"3",name:"Ashton Cox",position:"Junior Technical Author",salary:"$86,000",start_date:"2009/01/12",office:"San Francisco",extn:"1562"},{id:"4",name:"Cedric Kelly",position:"Senior Javascript Developer",salary:"$433,060",start_date:"2012/03/29",office:"Edinburgh",extn:"6224"},{id:"5",name:"Airi Satou",position:"Accountant",salary:"$162,700",start_date:"2008/11/28",office:"Tokyo",extn:"5407"}]}]; let json2 = [{data:[{id:"1",name:"Harry Potter",position:"System Architect",salary:"$234,800",start_date:"2013/04/25",office:"Edinburgh",extn:"5421"},{id:"2",name:"Ron Weasley",position:"Accountant",salary:"$170,777",start_date:"2011/09/25",office:"Tokyo",extn:"8422"},{id:"3",name:"Herminone Granger",position:"Junior Technical Author",salary:"$175,000",start_date:"2019/01/12",office:"San Francisco",extn:"1562"},{id:"4",name:"Neville Logbottom",position:"Senior Javascript Developer",salary:"$555,060",start_date:"2015/03/29",office:"Edinburgh",extn:"6224"},{id:"5",name:"Luna Lovegood",position:"Accountant",salary:"$200,700",start_date:"2017/11/28",office:"Tokyo",extn:"5407"}]}]; const create_datatable = (js, tab) => { js.forEach(d => { $(`#${tab}`).DataTable({ "bDestroy": true, "responsive": true, "autoWidth": false, "data": d.data, columns: [{ className: 'details-control', orderable: false, data: null, defaultContent: '', }, { data: 'name', className: 'names' }, { data: 'position', className: 'position' }, { data: 'office', className: 'office' }, { data: 'salary', className: 'salary' }] }); }); } create_datatable(json1, 'example'); create_datatable(json2, 'example2'); const create_cont = (tab) => { var containers = document.createElement('div'); containers.setAttribute("id", `${tab}_scatter`); $(`#${tab} tbody`).on('click', 'td.details-control', function() { var tr = $(this).closest('tr'); let table = tr.closest('table').DataTable(); // retrieve Datatable reference here var row = table.row(tr); if (row.child.isShown()) { // This row is already open - close it row.child.hide(); tr.removeClass('shown'); } else { if (table.row('.shown').length) $('.details-control', table.row('.shown').node()).click(); $(`#${tab}_scatter`).html('test'); row.child(containers).show(); tr.addClass('shown'); } }); } create_cont('example'); create_cont('example2'); td.details-control { background: url('../resources/details_open.png') no-repeat center center; cursor: pointer; } tr.shown td.details-control { background: url('../resources/details_close.png') no-repeat center center; } <link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script> <ul class="nav nav-tabs"> <li class="active"><a data-toggle="tab" href="#home">Home</a></li> <li><a data-toggle="tab" href="#menu1">Menu 1</a></li> </ul> <div class="tab-content"> <div id="home" class="tab-pane fade in active"> <h3>Tab 1</h3> <table id="example" class="display" style="width:100%"> <thead> <tr> <th>Show Child Row</th> <th>Name</th> <th>Position</th> <th>Office</th> <th>Salary</th> </tr> </thead> <tbody></tbody> </table> </div> <div id="menu1" class="tab-pane fade"> <h3>Tab 2</h3> <table id="example2" class="display" style="width:100%"> <thead> <tr> <th>Show Child Row</th> <th>Name</th> <th>Position</th> <th>Office</th> <th>Salary</th> </tr> </thead> <tbody></tbody> </table> </div> </div>
accessing nested array in nested object in angular js
I am using angularjs 1.I have a pretty complex json object with a lot of nesting . I want to use ng-repeat on a json to access a nested array. [{ "information": { "name": "simdi jinkins", "phone": "08037775692", "email": "sim04ful#gmail", "whatsapp": "8349493420", "residential": "gwarinpa", "office": "dansarari plaza" }, "jobs": [{ "name": "jeans and shirt", "measurement": { "shoulder": "34", "waist": "44", "neck": "86", "front": "42", "length": "33", "boost": "80", "cap": "30", "sleeves": "12", "tommy": "30", "thigh": "30", "chest": "34", "back": "40" }, "account": { "method": "cheque", "amount": "2334", "advance": "3945", "date": "2016-07-22T09:54:06.395Z" }, "date": { "incharge": "2016-07-22T09:54:06.395Z", "collection": "2016-07-22T09:54:06.395Z" }, "style": "english", "material": "our" }, { "name": "skirt and blouse", "measurement": { "shoulder": "35", "waist": "45", "neck": "85", "front": "52", "length": "53", "boost": "85", "cap": "50", "sleeves": "52", "tommy": "50", "thigh": "35", "chest": "35", "back": "50" }, "account": { "method": "cheque", "amount": "2334", "advance": "5045", "date": "2016-07-22T09:54:06.395Z" }, "date": { "incharge": "2016-07-22T09:54:06.395Z", "collection": "2016-07-22T09:54:06.395Z" }, "style": "native", "material": "bought" }] }, { "information": { "name": "Paula Odama", "phone": "08034698692", "email": "paulyd#gmail", "whatsapp": "8348733420", "residential": "inpa", "office": "dansaza" }, "jobs": [{ "name": "gown", "measurement": { "shoulder": "74", "waist": "44", "neck": "76", "front": "42", "length": "73", "boost": "80", "cap": "37", "sleeves": "72", "tommy": "30", "thigh": "70", "chest": "37", "back": "70" }, "account": { "method": "cheque", "amount": "2334", "advance": "3945", "date": "2016-07-22T09:54:06.395Z" }, "date": { "incharge": "2016-07-22T09:54:06.395Z", "collection": "2016-07-22T09:54:06.395Z" }, "style": "english", "material": "our" }, { "name": "robes", "measurement": { "shoulder": "35", "waist": "45", "neck": "85", "front": "52", "length": "53", "boost": "85", "cap": "50", "sleeves": "52", "tommy": "50", "thigh": "35", "chest": "35", "back": "50" }, "account": { "method": "cheque", "amount": "2334", "advance": "5045", "date": "2016-07-22T09:54:06.395Z" }, "date": { "incharge": "2016-07-22T09:54:06.395Z", "collection": "2016-07-22T09:54:06.395Z" }, "style": "native", "material": "bought" }] }]; i am trying to access the name property in jobs i have tried the following <div ng-repeat="customer in customers" class="card rich-card" z="2"> <div class="card-hero" style=""> <h1>{{customer.jobs.name}} <span>{{}}</span> </h1> </div> <div class="divider"></div> <div class="card-footer"> <button class="button flat">View</button> <button class="button flat color-orange-500">Explore</button> </div> </div>
Because customer.jobs is an array, you must access it using and index or key. In your example, the way to do this would be using customer.jobs[0].name. The resulting HTML would like this: <div ng-repeat="customer in customers" class="card rich-card" z="2"> <div class="card-hero" style=""> <div data-ng-repeat="job in customer.jobs"> <h1>{{job.name}} <span>{{}}</span> </h1> </div> </div> <div class="divider"></div> <div class="card-footer"> <button class="button flat">View</button> <button class="button flat color-orange-500">Explore</button> </div> </div> UPDATE It's an array of customers, with each containing an array of jobs. As such, you need a double repeater to cycle through the first AND second array. UPDATE 2 I figured you might want a 'card' per job a customer has, that code would be as follows: <div data-ng-repeat="customer in customers"> <div ng-repeat="job in customer.jobs" class="card rich-card" z="2"> <div class="card-hero" style=""> <h1>{{job.name}} <span>{{}}</span> </h1> </div> <div class="divider"></div> <div class="card-footer"> <button class="button flat">View</button> <button class="button flat color-orange-500">Explore</button> </div> </div> </div>
You did not explicitly say that your array is called customers, so I am assuming that it is. You have an array of customers, and each customer has one or more jobs. If you want to display the name of ALL jobs for each customer, you need to use nested ng-repeats. I'm not sure which part of your UI you want to repeat but I'm just going with the 'card-hero' div. <div ng-repeat="customer in customers" class="card rich-card" z="2"> <h1>{{customer.information.name}}</h1> <div ng-repeat="job in customer.jobs" class="card-hero" style=""> <h2>{{job.name}} <span>{{}}</span> </h2> </div> <div class="divider"></div> <div class="card-footer"> <button class="button flat">View</button> <button class="button flat color-orange-500">Explore</button> </div> </div> EDIT: added h1 customer name, and changed job name to h2, to show that each job under each customer is displayed
Cannot access items in JSON array?
I am sending a request which returns the following: { "title": "Recent Uploads", "link": "http://www.flickr.com/photos/", "description": "", "generator": "http://www.flickr.com/", "items": [ { "title": "Title 1", "link": "http://www.flickr.com/photos/123" } ] } Yet when I try to access things within, I get a 'undefined' value: xml.onreadystatechange = function () { if (xml.readyState == 4 && xml.status == 200) { var rsp = xml.rspTxt console.log(rsp.title); } } What am I doing wrong? As far as I can tell, this should work... EDIT: Fiddle.
It's because your JSON is not a valid JSON at all.. var test = { "title": "Recent Uploads", "link": "http://www.flickr.com/photos/", "description": "", "generator": "http://www.flickr.com/", "items": { "title": "Title 1", "link": "http://www.flickr.com/photos/123" } }; console.log(test.title); This works fine and results in "Recent Uploads" in the console. You cannot have '[' there and ',' at the end.
As other people have stated before, the JSON response you get from that call is invalid. { "title": "Recent Uploads tagged potato", "link": "https://www.flickr.com/photos/tags/potato/", "description": "", "modified": "2015-10-14T09:17:25Z", "generator": "https://www.flickr.com/", "items": [ { "title": "French fries", "link": "https://www.flickr.com/photos/87608453#N06/22159555595/", "media": {"m":"https://farm1.staticflickr.com/758/22159555595_0a1ba32e44_m.jpg"}, "date_taken": "2008-06-18T16:50:34-08:00", "description": " <p><a href=\"https://www.flickr.com/people/87608453#N06/\">Chulpa<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/87608453#N06/22159555595/\" title=\"French fries\"><img src=\"https://farm1.staticflickr.com/758/22159555595_0a1ba32e44_m.jpg\" width=\"240\" height=\"160\" alt=\"French fries\" /><\/a><\/p> <p>Heap of crisp French fries - detail<\/p>", "published": "2015-10-14T09:17:25Z", "author": "nobody#flickr.com (Chulpa)", "author_id": "87608453#N06", "tags": "hot detail macro closeup studio fastfood tasty sidedish frenchfries chips crisp potato snack junkfood takeaway portion sliced popular unhealthy baked roasted deepfried fattening accompaniment pommefrites takeoutfood" }, { "title": "potatowedges", "link": "https://www.flickr.com/photos/64474673#N08/22131498326/", "media": {"m":"https://farm1.staticflickr.com/700/22131498326_05d9f67dac_m.jpg"}, "date_taken": "2015-10-14T00:23:48-08:00", "description": " <p><a href=\"https://www.flickr.com/people/64474673#N08/\">amandahar<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/64474673#N08/22131498326/\" title=\"potatowedges\"><img src=\"https://farm1.staticflickr.com/700/22131498326_05d9f67dac_m.jpg\" width=\"240\" height=\"240\" alt=\"potatowedges\" /><\/a><\/p> ", "published": "2015-10-14T07:23:48Z", "author": "nobody#flickr.com (amandahar)", "author_id": "64474673#N08", "tags": "potato potatowedges" }, { "title": "Shadows and Potato van in Preston", "link": "https://www.flickr.com/photos/tonyworrall/21968606450/", "media": {"m":"https://farm1.staticflickr.com/758/21968606450_3a9c70e5bc_m.jpg"}, "date_taken": "2015-09-30T13:12:20-08:00", "description": " <p><a href=\"https://www.flickr.com/people/tonyworrall/\">Tony Worrall Foto<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/tonyworrall/21968606450/\" title=\"Shadows and Potato van in Preston\"><img src=\"https://farm1.staticflickr.com/758/21968606450_3a9c70e5bc_m.jpg\" width=\"240\" height=\"171\" alt=\"Shadows and Potato van in Preston\" /><\/a><\/p> <p>© 2015 Tony Worrall<\/p>", "published": "2015-10-14T06:34:58Z", "author": "nobody#flickr.com (Tony Worrall Foto)", "author_id": "10089490#N06", "tags": "county street uk england people urban food lunch stream tour shadows open place northwest unitedkingdom candid country north visit location lancashire eat potato queue area buy preston van northern update streetfood attraction lancs welovethenorth :copyright:2015tonyworrall" }, { "title": "thực phẩm giàu dinh dưỡng", "link": "https://www.flickr.com/photos/134900096#N07/22156604725/", "media": {"m":"https://farm6.staticflickr.com/5751/22156604725_882ca5642d_m.jpg"}, "date_taken": "2012-08-06T16:59:38-08:00", "description": " <p><a href=\"https://www.flickr.com/people/134900096#N07/\">hoaithuong0115<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/134900096#N07/22156604725/\" title=\"thực phẩm giàu dinh dưỡng\"><img src=\"https://farm6.staticflickr.com/5751/22156604725_882ca5642d_m.jpg\" width=\"240\" height=\"160\" alt=\"thực phẩm giàu dinh dưỡng\" /><\/a><\/p> <p>Xem: <a href=\"http://emdep.vn/thuc-don-giam-can-s275.htm\" rel=\"nofollow\">emdep.vn/thuc-don-giam-can-s275.htm<\/a><\/p>", "published": "2015-10-14T06:25:03Z", "author": "nobody#flickr.com (hoaithuong0115)", "author_id": "134900096#N07", "tags": "red food orange green apple mushroom fruits vegetables tomato pepper healthy natural display market sweet tomatoes olive banana supermarket lettuce potato pineapple asparagus crop snack carrot pear cauliflower garlic produce onion feed organic grocery fiber eats edible goodies eatable groceries arrangement grape combination nutrition lowfat nourishment nutrients nonfat provision lowcalorie nutriment" }, { "title": "", "link": "https://www.flickr.com/photos/underthetuliptree/21959671820/", "media": {"m":"https://farm6.staticflickr.com/5803/21959671820_f60c0cd98f_m.jpg"}, "date_taken": "2012-07-12T14:22:38-08:00", "description": " <p><a href=\"https://www.flickr.com/people/underthetuliptree/\">julianna smith<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/underthetuliptree/21959671820/\" title=\"\"><img src=\"https://farm6.staticflickr.com/5803/21959671820_f60c0cd98f_m.jpg\" width=\"160\" height=\"240\" alt=\"\" /><\/a><\/p> <p>Potato cakes with onions and spinach<\/p>", "published": "2015-10-13T22:42:18Z", "author": "nobody#flickr.com (julianna smith)", "author_id": "34306073#N07", "tags": "food cakes dinner vegan smith potato julianna" }, { "title": "Prague 14", "link": "https://www.flickr.com/photos/131811220#N07/22106050326/", "media": {"m":"https://farm6.staticflickr.com/5636/22106050326_67983e253b_m.jpg"}, "date_taken": "2015-10-04T14:44:43-08:00", "description": " <p><a href=\"https://www.flickr.com/people/131811220#N07/\">MichaelWard82<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/131811220#N07/22106050326/\" title=\"Prague 14\"><img src=\"https://farm6.staticflickr.com/5636/22106050326_67983e253b_m.jpg\" width=\"240\" height=\"160\" alt=\"Prague 14\" /><\/a><\/p> ", "published": "2015-10-13T10:46:54Z", "author": "nobody#flickr.com (MichaelWard82)", "author_id": "131811220#N07", "tags": "food republic czech prague potato twirl" }, { "title": "My Dinner", "link": "https://www.flickr.com/photos/sarahjdhue/21941657920/", "media": {"m":"https://farm6.staticflickr.com/5701/21941657920_53387b668c_m.jpg"}, "date_taken": "2015-10-11T15:17:25-08:00", "description": " <p><a href=\"https://www.flickr.com/people/sarahjdhue/\">SarahJDhue<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/sarahjdhue/21941657920/\" title=\"My Dinner\"><img src=\"https://farm6.staticflickr.com/5701/21941657920_53387b668c_m.jpg\" width=\"240\" height=\"181\" alt=\"My Dinner\" /><\/a><\/p> <p>Weinerschnitzel ala Holstein -Sarah J Dhue<\/p>", "published": "2015-10-13T08:11:25Z", "author": "nobody#flickr.com (SarahJDhue)", "author_id": "92310074#N06", "tags": "red food pancakes dinner restaurant illinois october yum egg cellphone samsung palace il potato german ala cabbage fried dreamland applesauce holstein veal weinerschnitzel galaxys6 sarahjdhuephotos sarahjdhue" }, { "title": "Open Faced at Old Vine Cafe", "link": "https://www.flickr.com/photos/55017688#N00/22136102231/", "media": {"m":"https://farm6.staticflickr.com/5651/22136102231_984461d378_m.jpg"}, "date_taken": "2015-09-19T22:02:02-08:00", "description": " <p><a href=\"https://www.flickr.com/people/55017688#N00/\">deeeelish<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/55017688#N00/22136102231/\" title=\"Open Faced at Old Vine Cafe\"><img src=\"https://farm6.staticflickr.com/5651/22136102231_984461d378_m.jpg\" width=\"240\" height=\"149\" alt=\"Open Faced at Old Vine Cafe\" /><\/a><\/p> <p>Fresh Biscuit, Chicken Sausage, Scrambled Eggs, Chipotle Gravy & Queso Fresco with Potatoes <br /> <br /> Costa Mesa, CA<\/p>", "published": "2015-10-13T04:30:52Z", "author": "nobody#flickr.com (deeeelish)", "author_id": "55017688#N00", "tags": "gravy potato eggs quesofresno" }, { "title": "Omelette at Old Vine Cafe", "link": "https://www.flickr.com/photos/55017688#N00/21938083198/", "media": {"m":"https://farm1.staticflickr.com/593/21938083198_046a230259_m.jpg"}, "date_taken": "2015-09-19T22:02:47-08:00", "description": " <p><a href=\"https://www.flickr.com/people/55017688#N00/\">deeeelish<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/55017688#N00/21938083198/\" title=\"Omelette at Old Vine Cafe\"><img src=\"https://farm1.staticflickr.com/593/21938083198_046a230259_m.jpg\" width=\"240\" height=\"156\" alt=\"Omelette at Old Vine Cafe\" /><\/a><\/p> <p>Costa Mesa, CA<\/p>", "published": "2015-10-13T04:30:54Z", "author": "nobody#flickr.com (deeeelish)", "author_id": "55017688#N00", "tags": "potato eggs omelette" }, { "title": "Chicken", "link": "https://www.flickr.com/photos/jorkew/22106677661/", "media": {"m":"https://farm6.staticflickr.com/5710/22106677661_00d43a64bc_m.jpg"}, "date_taken": "2015-09-05T00:00:00-08:00", "description": " <p><a href=\"https://www.flickr.com/people/jorkew/\">Jorkew<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/jorkew/22106677661/\" title=\"Chicken\"><img src=\"https://farm6.staticflickr.com/5710/22106677661_00d43a64bc_m.jpg\" width=\"160\" height=\"240\" alt=\"Chicken\" /><\/a><\/p> <p>Kodak Ektar 100<br /> Canon eos 1<br /> Canon EF 24-70mm f/2.8 L USM<br /> <br /> A few test shots from the new camera. <br /> <br /> <a href=\"http://jorkew.com/\" rel=\"nofollow\">Website<\/a> | <a href=\"http://facebook.com/jorkewphotography\" rel=\"nofollow\">Facebook<\/a><\/p>", "published": "2015-10-12T20:40:00Z", "author": "nobody#flickr.com (Jorkew)", "author_id": "28568131#N06", "tags": "camera red food chicken film analog canon photography eos 1 potatoes oven kodak kip potato l produce 100 usm filmcamera 135 done canoneos f28 canonef2470mmf28lusm ef baked eos1 ektar foodphotography 2470mm analogcamera llens kodak100 filmisnotdead canoneos1 canonllens kodakektar canon2470mmf28 kodakcolorfilm canonef2470mm ektar100 canonanalogcamera staybrokeshootfilm canoneos1analog canoneos1filmcamera" }, { "title": "Alice in Wonderland Pitstop", "link": "https://www.flickr.com/photos/magicattic88/21491271583/", "media": {"m":"https://farm1.staticflickr.com/746/21491271583_5113d90565_m.jpg"}, "date_taken": "2015-10-07T00:00:00-08:00", "description": " <p><a href=\"https://www.flickr.com/people/magicattic88/\">Darling Starlings<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/magicattic88/21491271583/\" title=\"Alice in Wonderland Pitstop\"><img src=\"https://farm1.staticflickr.com/746/21491271583_5113d90565_m.jpg\" width=\"240\" height=\"240\" alt=\"Alice in Wonderland Pitstop\" /><\/a><\/p> <p>After seeing Terry Wogan in the Waterstones tent - CheltLitFest 2015 - Jue [https://www.flickr.com/photos/pyride] and I wandered around a bit - we found this lovely little Alice in Wonderland themed café on the Festival site. It called for a Penelope Pitstop of crunchy lattice chips with dips and a coffee each - yum. Just what was needed :)).<\/p>", "published": "2015-10-12T16:17:19Z", "author": "nobody#flickr.com (Darling Starlings)", "author_id": "8649118#N08", "tags": "food coffee festival hearts town cafe penelope poinsettia hats literature chips potato pitstop cheltenham lattice aliceinwonderland dips imperialgardens 2015 candlebra bigteacup cheltlitfest" }, { "title": "Giant potatomobile", "link": "https://www.flickr.com/photos/asciident/22079616896/", "media": {"m":"https://farm6.staticflickr.com/5765/22079616896_c1bedd0a4a_m.jpg"}, "date_taken": "2015-10-04T17:10:42-08:00", "description": " <p><a href=\"https://www.flickr.com/people/asciident/\">asciident<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/asciident/22079616896/\" title=\"Giant potatomobile\"><img src=\"https://farm6.staticflickr.com/5765/22079616896_c1bedd0a4a_m.jpg\" width=\"240\" height=\"202\" alt=\"Giant potatomobile\" /><\/a><\/p> <p>Near Wendell, Idaho<br /> <br /> Excuse the thumb, I was in a hurry to catch the potatomobile!<\/p>", "published": "2015-10-12T06:59:23Z", "author": "nobody#flickr.com (asciident)", "author_id": "12616001#N00", "tags": "idaho potato wendell potatomobile" }, { "title": "Giant potatomobile", "link": "https://www.flickr.com/photos/asciident/22115860151/", "media": {"m":"https://farm1.staticflickr.com/646/22115860151_c18609aa78_m.jpg"}, "date_taken": "2015-10-04T17:10:45-08:00", "description": " <p><a href=\"https://www.flickr.com/people/asciident/\">asciident<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/asciident/22115860151/\" title=\"Giant potatomobile\"><img src=\"https://farm1.staticflickr.com/646/22115860151_c18609aa78_m.jpg\" width=\"186\" height=\"240\" alt=\"Giant potatomobile\" /><\/a><\/p> <p>Near Wendell, Idaho<\/p>", "published": "2015-10-12T06:59:24Z", "author": "nobody#flickr.com (asciident)", "author_id": "12616001#N00", "tags": "idaho potato wendell potatomobile" }, { "title": "Giant potatomobile", "link": "https://www.flickr.com/photos/asciident/21917906328/", "media": {"m":"https://farm1.staticflickr.com/684/21917906328_fb679fb950_m.jpg"}, "date_taken": "2015-10-04T17:10:44-08:00", "description": " <p><a href=\"https://www.flickr.com/people/asciident/\">asciident<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/asciident/21917906328/\" title=\"Giant potatomobile\"><img src=\"https://farm1.staticflickr.com/684/21917906328_fb679fb950_m.jpg\" width=\"240\" height=\"180\" alt=\"Giant potatomobile\" /><\/a><\/p> <p>Near Wendell, Idaho<\/p>", "published": "2015-10-12T06:59:24Z", "author": "nobody#flickr.com (asciident)", "author_id": "12616001#N00", "tags": "idaho potato wendell potatomobile" }, { "title": "Giant potatomobile", "link": "https://www.flickr.com/photos/asciident/22093267702/", "media": {"m":"https://farm1.staticflickr.com/749/22093267702_5f51f6e60e_m.jpg"}, "date_taken": "2015-10-04T17:10:47-08:00", "description": " <p><a href=\"https://www.flickr.com/people/asciident/\">asciident<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/asciident/22093267702/\" title=\"Giant potatomobile\"><img src=\"https://farm1.staticflickr.com/749/22093267702_5f51f6e60e_m.jpg\" width=\"240\" height=\"180\" alt=\"Giant potatomobile\" /><\/a><\/p> <p>Near Wendell, Idaho<\/p>", "published": "2015-10-12T06:59:25Z", "author": "nobody#flickr.com (asciident)", "author_id": "12616001#N00", "tags": "idaho potato wendell potatomobile" }, { "title": "Giant potatomobile", "link": "https://www.flickr.com/photos/asciident/21917907758/", "media": {"m":"https://farm6.staticflickr.com/5744/21917907758_f1130f8768_m.jpg"}, "date_taken": "2015-10-04T17:10:40-08:00", "description": " <p><a href=\"https://www.flickr.com/people/asciident/\">asciident<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/asciident/21917907758/\" title=\"Giant potatomobile\"><img src=\"https://farm6.staticflickr.com/5744/21917907758_f1130f8768_m.jpg\" width=\"240\" height=\"200\" alt=\"Giant potatomobile\" /><\/a><\/p> <p>Near Jerome, Idaho<\/p>", "published": "2015-10-12T06:59:23Z", "author": "nobody#flickr.com (asciident)", "author_id": "12616001#N00", "tags": "idaho potato jerome potatomobile" }, { "title": "Twister Potato Chip", "link": "https://www.flickr.com/photos/jimmychuah/22104255305/", "media": {"m":"https://farm6.staticflickr.com/5714/22104255305_abe56671da_m.jpg"}, "date_taken": "2015-09-11T16:22:14-08:00", "description": " <p><a href=\"https://www.flickr.com/people/jimmychuah/\">Jimmy Chuah<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/jimmychuah/22104255305/\" title=\"Twister Potato Chip\"><img src=\"https://farm6.staticflickr.com/5714/22104255305_abe56671da_m.jpg\" width=\"240\" height=\"160\" alt=\"Twister Potato Chip\" /><\/a><\/p> ", "published": "2015-10-12T05:23:56Z", "author": "nobody#flickr.com (Jimmy Chuah)", "author_id": "67226751#N02", "tags": "travel food holiday stall korea potato snack seoul koreanfood myeongdong 2015" }, { "title": "Potato Rolled Shrimp", "link": "https://www.flickr.com/photos/jimmychuah/21917351019/", "media": {"m":"https://farm1.staticflickr.com/694/21917351019_d93527d6d7_m.jpg"}, "date_taken": "2015-09-11T17:18:27-08:00", "description": " <p><a href=\"https://www.flickr.com/people/jimmychuah/\">Jimmy Chuah<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/jimmychuah/21917351019/\" title=\"Potato Rolled Shrimp\"><img src=\"https://farm1.staticflickr.com/694/21917351019_d93527d6d7_m.jpg\" width=\"240\" height=\"160\" alt=\"Potato Rolled Shrimp\" /><\/a><\/p> ", "published": "2015-10-12T05:24:05Z", "author": "nobody#flickr.com (Jimmy Chuah)", "author_id": "67226751#N02", "tags": "travel food holiday stall shrimp korea potato snack seoul koreanfood myeongdong 2015" }, { "title": "fzk_188_28082015_09\'48", "link": "https://www.flickr.com/photos/eduard_buerge-rafz/21901809028/", "media": {"m":"https://farm1.staticflickr.com/619/21901809028_7637fa8cd4_m.jpg"}, "date_taken": "2015-08-28T09:48:46-08:00", "description": " <p><a href=\"https://www.flickr.com/people/eduard_buerge-rafz/\">eduard43<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/eduard_buerge-rafz/21901809028/\" title=\"fzk_188_28082015_09\'48\"><img src=\"https://farm1.staticflickr.com/619/21901809028_7637fa8cd4_m.jpg\" width=\"240\" height=\"135\" alt=\"fzk_188_28082015_09\'48\" /><\/a><\/p> <p>Die Kartoffel (Solanum tuberosum).<br /> The potato (Solanum tuberosum).<\/p>", "published": "2015-10-11T12:22:17Z", "author": "nobody#flickr.com (eduard43)", "author_id": "40303029#N08", "tags": "potato kartoffeln naturalproducts solanumtuberosum potatoplants naturprodukte kartoffelstauden" }, { "title": "fzk_189_28082015_09\'48", "link": "https://www.flickr.com/photos/eduard_buerge-rafz/22077208832/", "media": {"m":"https://farm1.staticflickr.com/761/22077208832_e1616a4351_m.jpg"}, "date_taken": "2015-08-28T09:48:51-08:00", "description": " <p><a href=\"https://www.flickr.com/people/eduard_buerge-rafz/\">eduard43<\/a> posted a photo:<\/p> <p><a href=\"https://www.flickr.com/photos/eduard_buerge-rafz/22077208832/\" title=\"fzk_189_28082015_09\'48\"><img src=\"https://farm1.staticflickr.com/761/22077208832_e1616a4351_m.jpg\" width=\"135\" height=\"240\" alt=\"fzk_189_28082015_09\'48\" /><\/a><\/p> <p>Die Kartoffel (Solanum tuberosum).<br /> The potato (Solanum tuberosum).<\/p>", "published": "2015-10-11T12:22:16Z", "author": "nobody#flickr.com (eduard43)", "author_id": "40303029#N08", "tags": "potato kartoffeln naturalproducts solanumtuberosum potatoplants naturprodukte kartoffelstauden" } ] } You can check that out on jsonlint.com, the last two objects in the array have bad escaping and other problems...if I delete them manually the rest of the response is a valid JSON. You can't fix that on your end but have to ask flickr to provide valid JSON.
bootstrap carousel does not work with handelbars (prev button )
I'm using bootstrap v3 the process works fine without using js template , once I'm using handelbars , the previous button will crash and throw error ( Uncaught TypeError: Cannot read property 'slice' of undefined ) with index position is 0 I guess the problem occur while transition from the first element to the last element using previous button of course , the 'active class is lost somewhere' could anyone help here is my html <!doctype html> <html> <head> <meta charset="utf-8"> <title>test</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> </head> <body> <div id="carouselWrap" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#carouselWrap" data-slide-to="0" class="active"></li> <li data-target="#carouselWrap" data-slide-to="1"></li> <li data-target="#carouselWrap" data-slide-to="2"></li> </ol> <!-- Wrapper for slides --> <div class="carousel-inner"> <script id="template" type="text/x-handlebars-template"> {{#each this}} {{#if counter}} <div class="item active"> {{else}} <div class="item "> {{/if}} <table> <tbody> <tr> <td> {{product1.name}} {{decode product1.surname}}</td> <td>{{price product1.lastprice}} </td> <td>{{decodeproduct1.supplier}} </td> <td>{{product1.nation}} </td> <td>{{product1.sport}} </td> <td>{{product1.divStart}} - {{product1.divEnd}} </td> <td>{{{decode product1.divScenarioGood}}}</td> <td>link</td> </tr> <tr> <td>{{product2.name}} {{decode product2.surname}}</td> <td>{{price product2.lastprice}} </td> <td>{{decode product2.supplier}} </td> <td>{{product2.nation}} </td> <td>{{product2.sport}} </td> <td>{{product2.divStart}} - {{product1.divEnd}} </td> <td>{{decode product2.divScenarioGood}}</td> <td>link</td> </tr> </tbody> </table> </div> {{/each}} </script> </div> <!-- Controls --> <a class="left carousel-control" href="#carouselWrap" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> <a class="right carousel-control" href="#carouselWrap" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> <script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script> <script> (function() { var Hbs = { init: function( config ) { this.url = config.url; this.container = config.container; this.template = config.template; this.fetch(); }, fetch: function() { var self = this; $.getJSON( self.url, function( data ) { var template = Handlebars.compile( self.template ); Handlebars.registerHelper('toLowerCase', function(str) { return str.toLowerCase(); }); Handlebars.registerHelper('price', function(val) { return Math.round(val); }); Handlebars.registerHelper('elmId', function(id) { return id; }); Handlebars.registerHelper('decode', function(str) { try{ return decodeURIComponent(escape(str)); }catch(e){ // catch the error console.log(e.message); } }); var positionCounter = 0; Handlebars.registerHelper('counter', function() { positionCounter++; if (positionCounter == 1 ) return positionCounter; else return false; }); self.container.append( template( data ) ); }); } } Hbs.init({ url : 'athletes.json', container: $('.carousel-inner'), template: $('#template').html() }); })(); </script> </body> </html> athletes.json [ { "#class": "com.tradeinsports.domain.product.ProductPair", "product1": { "#class": "com.tradeinsports.domain.product.ProductSubset", "name": "Alexander", "surname": "Bj\u00c3\u00b6rk", "shortname": "A Bj\u00c3\u00b6rk", "sport": "Golf", "nation": "Sweden", "supplier": "V\u00c3\u00a4xj\u00c3\u00b6 GK", "status": "Locked", "lastprice": 50.497987979, "divStart": "2012-07-19", "divEnd": "2013-12-25", "contractType": "Travprodukt standard", "divScenarioGood": "Topp 10 p\u00c3\u00a5 European tour 2016\r\n", "divScenarioGoodRevenue": -10000, "smallImage": "litenNyBjork.jpg" }, "product2": { "#class": "com.tradeinsports.domain.product.ProductSubset", "name": "Felix", "surname": "Rosenqvist", "shortname": "F Rosenqvist", "sport": "Motor", "nation": "Sweden", "supplier": "Mercedes", "status": "Locked", "lastprice": 100, "divStart": "2012-12-29", "divEnd": "2021-02-24", "contractType": "Motor standard", "divScenarioGood": "4 s\u00c3\u00a4songer i Formel 1 fram till 2021\r\n", "divScenarioGoodRevenue": 12960, "smallImage": "FelixFarg.jpg" } }, { "#class": "com.tradeinsports.domain.product.ProductPair", "product1": { "#class": "com.tradeinsports.domain.product.ProductSubset", "name": "sabri", "surname": "zouari", "shortname": "Wild Life", "sport": "Trotting", "nation": "Sweden", "supplier": "R Bj\u00c3\u00b6rkroth", "status": "Locked", "lastprice": 200, "divStart": "2014-04-16", "divEnd": "2016-05-14", "contractType": "Travprodukt standard", "divScenarioGood": "2.000.000 i insprugna prispengar + 5.000.000 fr\u00c3\u00a5n f\u00c3\u00b6rs\u00c3\u00a4ljning\r\n", "divScenarioGoodRevenue": 27900, "smallImage": "wildLifeProd2.jpg" }, "product2": { "#class": "com.tradeinsports.domain.product.ProductSubset", "name": "Rasmus", "surname": "Lindh", "shortname": "R Lindh", "sport": "Motor", "nation": "Sweden", "supplier": "Captimax", "status": "Locked", "lastprice": 100, "divStart": "2019-01-01", "divEnd": "2029-12-15", "contractType": "Motor Total", "divScenarioGood": "10 s\u00c3\u00a4songer i Formel 1 fram till 2029\r\n", "divScenarioGoodRevenue": 4840, "smallImage": "rasmusSmallSyst.jpg" } }, { "#class": "com.tradeinsports.domain.product.ProductPair", "product1": { "#class": "com.tradeinsports.domain.product.ProductSubset", "name": "Andreas", "surname": "Siljestr\u00c3\u00b6m", "shortname": "A Siljestr\u00c3\u00b6m", "sport": "Tennis", "nation": "Sweden", "supplier": "KLTK", "status": "Market", "lastprice": 100, "divStart": "2013-12-01", "divEnd": "2016-12-01", "contractType": "Tennis", "divScenarioGood": "Topp 10 ATP dubbelranking 2016\r\n", "divScenarioGoodRevenue": 1050, "smallImage": "siljestromLiten.jpg" }, "product2": { "#class": "com.tradeinsports.domain.product.ProductSubset", "name": "Gabriel", "surname": "Axell", "shortname": "G Axell", "sport": "Golf", "nation": "Sweden", "supplier": "Vadstena GK", "status": "Market", "lastprice": 100, "divStart": "2014-04-15", "divEnd": "2018-04-15", "contractType": "Travprodukt standard", "divScenarioGood": "Topp 10 p\u00c3\u00a5 Europatouren 2017", "divScenarioGoodRevenue": 1990, "smallImage": "litenGabbeSyst.jpg" } } ]
I have had the same problem with Django template system but i solved rewriting the if statement like this (assuming that counter starts in 1) {{#if counter = 1}} <div class="item active"> {{else}} <div class="item "> {{/if}}
I had the same problem and did looking for solution several hour, but it was ... little mistake - my controls was in div class="item" inside.))) Be sure that controls are outside couresel's item