Displaying part of JSON data using javascript - javascript
I'm trying to use JSON to print content to the screen. I'm trying to print out as two different sections so the "albumData" displays as columns in the "albumData" div and the audio equipment goes in a div further down the page. I have tried having {audio: [ ...]} in the JSON array but that never seems to work. The issue right now is the JS file is outputting too munch data and is not stopping when the the object is not in the array. Ideally, it would put out a 4x4 layout for the albums, and a 4x3 layout for devices but instead both sections are outputting 4x7 and many of the text is 'undefined'.
Do you guys have any tips on targeting specific JSON data? Thanks for your help
HTML Code:
<h1 class="headText">Wall of Fame</h1>
<hr class="style14"></hr>
</br></br>
<h2>Albums: </h2>
<div id="albumData" class="row"></div>
</br></br>
<h2>Equipment: </h2>
<div id="deviceData" class="row"></div>
<script src="js/wall.js"></script>
JS Code:
$.getJSON("jsonDatabase/wall.json",function(data){
console.dir(data);
var html = "";
$.each(data, function(index, item){
html += '<div class="col-md-3">'+
'<img class="albumImage" src=""' + item.albumImage + '"/>' + "<br>" +
'<div class="albumArtist">' + "<strong>Artist: </strong>" + item.artist + '</div>'+
'<div class="albumTitle">' + "<strong>Album: </strong>" + item.albumTitle + '</div>'+
'<div class="albumYear">' + "<strong>Year: </strong>" + item.year + '</div>'+
'<div class="albumGenre">' + "<strong>Genre: </strong>" + item.genre + '</div>'
html += '</div>'; //col-md-3
})//each album
$("#albumData").append(html);
//end record data
var device = "";
$.each(data, function(ind, item){
device += '<div class="col-md-3">'+
'<img class="deviceImage" src=""' + item.deviceImage + '"/>' + "<br>" +
'<div class="deviceName">' + "<strong>Name: </strong>" + item.device + '</div>'+
'<div class="deviceType">' + "<strong>Device: </strong>" + item.type + '</div>'+
'<div class="deviceCompany">' + "<strong>Company: </strong>" + item.comapny + '</div>'+
'<div class="devicePrice">' + "<strong>Price: </strong>" + item.price + '</div>'
device += '</div>'; //col-md-3
})//each device
$("#deviceData").append(device);
})
// closes getJSON
})
JSON Array:
[{"albumImage":"","artist":"Bruce","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Tom Waits","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Alison Krauss","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Pink Floyd","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"Rage Against the Machine","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"albumImage":"","artist":"","albumTitle":"","year":"","genre":""},
{"deviceImage":"","device":"E12","type":"Portable amp","company":"FiiO","price":"$130"},
{"deviceImage":"","device":"GS1000e","type":"Headphone","company":"Grado","price":"$1300"},
{"deviceImage":"","device":"RS1i","type":"Headphone","company":"Grado","price":"$850"},
{"deviceImage":"","device":"SR60e","type":"Headphone","company":"Grado","price":"$80"},
{"deviceImage":"","device":"HD 650","type":"Headphone","company":"Sennheiser","price":"$500"},
{"deviceImage":"","device":"SRH 860","type":"Headphones","company":"Samson","price":"$60"},
{"deviceImage":"","device":"MA750i","type":"In-ear monitors","company":"RHA","price":"$130"},
{"deviceImage":"","device":"Play: 1","type":"WiFi connected speaker","company":"Sonos","price":"$229"},
{"deviceImage":"","device":"Walsh 3","type":"Speakers (passive)","company":"Ohm","price":"$2,000"},
{"deviceImage":"","device":"Evo 2/8","type":"Speakers (passive)","company":"Wharfedale","price":"$400"},
{"deviceImage":"","device":"Asgard 2","type":"Amplifier","company":"Schiit","price":"$299"},
{"deviceImage":"","device":"Modi","type":"DAC","company":"Schiit","price":"$99"}]
Since it's one array don't parse it 2x, use variables instead.
var deviceHtml = "";
var albumHtml = "";
$.each(data, function(index, item){
if(typeof(item.albumImage) != "undefined" && typeof(item.deviceImage == 'undefined')
{
albumHtml += '<div class="col-md-3">'+
'<img class="albumImage" src=""' + item.albumImage + '"/>' + "<br>" +
'<div class="albumArtist">' + "<strong>Artist: </strong>" + item.artist + '</div>'+
'<div class="albumTitle">' + "<strong>Album: </strong>" + item.albumTitle + '</div>'+
'<div class="albumYear">' + "<strong>Year: </strong>" + item.year + '</div>'+
'<div class="albumGenre">' + "<strong>Genre: </strong>" + item.genre + '</div></div>';
}
else if(typeof(item.deviceImage) != "undefined" && typeof(item.albumImage) == 'undefined')
{
deviceHtml += '<div class="col-md-3">'+
'<img class="deviceImage" src=""' + item.deviceImage + '"/>' + "<br>" +
'<div class="deviceName">' + "<strong>Name: </strong>" + item.device + '</div>'+
'<div class="deviceType">' + "<strong>Device: </strong>" + item.type + '</div>'+
'<div class="deviceCompany">' + "<strong>Company: </strong>" + item.comapny + '</div>'+
'<div class="devicePrice">' + "<strong>Price: </strong>" + item.price + '</div>';
deviceHtml += '</div>'; //col-md-3
}
})//each album
$("#albumData").append(albumHtml);
$("#deviceData").append(device);
You will also want to skip records that have no values for any of them so you will need to add an additional if block in there to test that the string isn't empty, else skip that iteration of the loop.
If, as in your comments you change the format of your object to {albums:[ { } ], devices:[ { }] } you can then just use dot notation to access the key you wish to loop through.
$.each(data.albums,function(index, item){})
and
$.each(data.devices,function(index, item){})
Related
How do I get an ID from a click event handler?
I am trying to create an ID to use as a selector for a modal that I will then be able to access the display properties. $.ajax({ url: 'https://randomuser.me/api/?results=12', dataType: 'json', success: function(data) { console.log(data); employees = data.results; $.each(employees, function (i, employee) { newHTML += '<div id="' + i + '" class="container">'; newHTML += '<div class="employee-img-container">'; newHTML += '<img class="employee-img" src="' + employee.picture.large + '" alt="employee image">'; newHTML += '</div>'; newHTML += '<div class="employee-info-container">'; newHTML += '<h3 class="employee-name">' + employee.name.first + ' ' + employee.name.last + '</h3>'; newHTML += '<p class="employee-email">' + employee.email + '</p>'; newHTML += '<p class="employee-location">' + employee.location.city + ', ' + employee.location.state + '</p>'; newHTML += '</div></div></div></div>'; employeeArr.push(employee); modalHTML += '<div id="modal' + i + '" class="modal">'; modalHTML += '<div class="modal-content">'; modalHTML += '<div class="modal-header">'; modalHTML += '<span class="close">×</span>'; modalHTML += '<img class="employee-img" src="' + employee.picture.large + '" alt="employee image">'; modalHTML += '<h2 class= emp-modal-name>' + employee.name.first + ' ' + employee.name.last + '</h2>'; modalHTML += '</div'; modalHTML += '<div class="modal-body">'; modalHTML += '<p>Employee Info</p>'; modalHTML += '</div></div></div>'; modalArr.push(employee); }); $('.grid-container').html(newHTML); $('.modal-container').html(modalHTML); $('.container').on('click', function (event) { console.log(event.currentTarget.id); let newId = '#modal' + event.currentTarget.id; let displayModal = $(newId) let display = document.querySelector(newId); //displayModal.style.display = 'block'; console.log(displayModal); console.log(display); console.log(newId); }); } }); When I log the event.currentTarget.id I get a number, and I can also create a string that I want to use as a selector. I can't figure out how to use it as the actual sector though. Not sure if I need to use an if statement to compare it to the id of the modal class that i want to display. Thanks!
Try like this $(document).ready(function() { $("a").click(function(event) { alert(event.target.id); }); });
Javascript - How to insert html template and use variables in it
I wonder how can I insert html template into a javascript function and use variables in it, like for example here, where I am creating html and inserting variables to it. I would like to know how can I make it cleaner and have a template in a separate file and then use it in the function. { source: autocomplete.sources.hits(videos, { hitsPerPage: 5 }), displayKey: 'title', templates: { header: '<div class="aa-suggestions-category">Videos</div>', suggestion: function(suggestion) { return '<span>' + '<a href="/player/' + suggestion.id + '">' + '<div class="media">' + '<div class="media-left">' + '<img class="media-object" src="https://s3.eu-central-1.amazonaws.com/myUrl/' + suggestion.video_id + '_1.jpg">' + '</div>' + '<div class="media-body">' + '<p>' + suggestion._highlightResult.title.value + '<small><abbr class="timeago" title="' + suggestion.created_at + '">' + suggestion.created_at + '</abbr></small>' + '</p>' + '<small> ' + '</small>' + '</div>' + '</div>' + '</a>' +'</span>'; }
Dynamically created button gets automatically fired
I am creating a dynamic unordered custom List view. In each element, there is one button. I am creating the list elements in the following way: for (i = 0; i < arrayID.length; i++) { var listElement = '<li class="has-form">' + '<div class="row collapse">' + '<div class="small-1 columns" style="margin: 5px">' + '<img src="image/twitter.png">' + '</div>' + '<div class="small-6 columns small-only-text-center">' + '<p>' + '<i>' + arrayText[i] + '</i>' + '</p>' + '</div>' + '<div class="small-3 columns">' + '<button type="button" class="large-10" onclick="' + onClickViewButton() + '">view</button>' + '</div>' + '<div class="small-1 columns">' + '<input id="checkbox1" type="checkbox">' + '</div>' + '</div>' + '</li>'; $("#myList").append(listElement); } The code for button click is: function onClickViewButton() { alert('hello'); } But unfortunately the when the page is loading, the button click is fired and not working on actual button click. Please help.
Where you have: onclick="'+onClickViewButton()+'" you need to have: onclick="onClickViewButton()" instead. Your current code calls the onClickViewButton function in your declaration, when what you really want to do is to just use it as a function reference so it gets called later on onclick.
Try with this snippet: If you concat function name with parenthesis then it will be treated as function execution hence function will get called. for (i = 0; i < arrayID.length; i++) { var listElement = '<li class="has-form">' + '<div class="row collapse">' + '<div class="small-1 columns" style="margin: 5px">' + '<img src="image/twitter.png">' + '</div>' + '<div class="small-6 columns small-only-text-center">' + '<p>' + '<i>' + arrayText[i] + '</i>' + '</p>' + '</div>' + '<div class="small-3 columns">' + '<button type="button" class="large-10" onclick="onClickViewButton()">view</button>' + '</div>' + '<div class="small-1 columns">' + '<input id="checkbox1" type="checkbox">' + '</div>' + '</div>' + '</li>'; $("#myList").append(listElement); }
Better way to use html templete with json response
I am getting json response from my server. I am getting detail of user like school(name,id),major subject(name,id),start ,end etc. I want to show this is appropriate text fields inside a form where user can edit this and after editing user should submit it again to server. I am embadding fetched json code with html code inside the jquery. I am finding it very difficult to manage html inside jquery is there any better way to this with following code. $(document).on('click', '.edit-edu', function(event) { event.preventDefault(); var id = $(this).parents('.row').attr('id'); var id1 = id.split('-'); $.post("SingleEdu", {id: id1[1]}, function(data) { console.log(data); $.each(data.educationList, function(key, value) { $('#' + id).replaceWith('<div id="addNewEdu" class="addorEdit">' + '<legend>Edit education details</legend>' + '<form action="UpdateEducation" id="UpdateEducation" cssClass="form-horizontal">' + '<div class="form-group">' + '<div class="col-md-2">' + '<label>School/College</label>' + '</div>' + '<div class="col-md-6">' + ' <textfield name="ed.pageBySchoolPid.name" value="' + value.pageBySchoolPid.name + '" id="school2" label="School/College" placeholder="College or School Name" cssClass="form-control">' + '</textfield>' + '<input type="hidden" name="ed.pageBySchoolPid.id" value="' + value.pageBySchoolPid.id + '" id="schoolId2" label="School/College" cssClass="form-control">' + '</hidden>' + '</div>' + '</div>' + '<div class="form-group">' + '<div class="col-md-2">' + '<label>Major</label>' + '</div>' + '<div class="col-md-6">' + '<input type="text" name="ed.pageByMajorPid.name" value="' + value.pageByMajorPid.name + '" id="major1" label="Class" placeholder="Major Subject" cssClass="form-control">' + '<input type="hidden" name="ed.pageByMajorPid.id" value="' + value.pageByMajorPid.id + '" id="majorId1" label="Class" cssClass="form-control">' + '</div>' + '</div>' + '<div class="form-group">' + '<div class="col-md-2">' + '<label>Start</label>' + '</div>' + '<div class="col-md-6">' + '<input type="text" name="ed.start" value="' + value.start + '" id="sstart1" label="From" placeholder="eg. Start: July 2007" cssClass="form-control">' + '</div>' + '</div>' + '<div class="form-group">' + '<div class="col-md-2">' + '<label>End</label>' + '</div>' + '<div class="col-md-6">' + '<input type="text" name="ed.end" value="' + value.end + '" id="send1" label="To" placeholder="eg. End : May 2011 or Till" cssClass="form-control">' + '</div>' + '</div>' + '<div class="form-group">' + '<div class="col-md-2">' + '<label>Visibility</label>' + ' </div>' + '<div class="col-md-6">' + '<select label="Visibility" name="ed.visibility" value="' + value.visibility + '" id="svisibility1" value="public" cssClass="form-control">' + '<option>Public</option>' + '<option>Friends</option>' + '<option>Me</option>' + '</select>' + '</div>' + '</div>' + '<div class="form-group">' + '<div class="col-md-2">' + '<label class="sr-only">Submit</label>' + '</div>' + '<div class="col-md-6">' + '<input type="submit" value="add" id="submit_education" cssClass="btn btn-sm btn-success"/>' + '</div>' + '</div>' + '</form>') }); }); }); <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"></script> <script src="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"></script> <div class="row" id="edu-56"> <div>Specialization</div> <div>School</div> <div>start end</div> <i class="fa fa-edit edit-edu">edit</i> <i class="fa fa-times delete-edu"></i> </div>
You could store your code inside another .html file and pull it in using another AJAX call: var FormHTML = ''; $.get('form.html', function(data) { FormHTML = data; }); Then to get your values in you can set up your input HTML with something that can be easily replaced out. I've just wrapped the object name in between some #: <input type="hidden" name="ed.pageByMajorPid.id" value="##pageByMajorPid.id##" id="majorId1" label="Class" cssClass="form-control"> Then to replace out these values with your actual values, just do a loop: for (var name in value) { if (typeof value[name] != 'object') { // If not an object, replace the value formHTML = formHTML.replace('##' + name + '##', value[name]) } else { // Else if it is an object, loop through it for (var name2 in value[name]) { formHTML = formHTML.replace('##' + name + '.' + name2 + '##', value[name][name2]) } } } $('#' + id).replaceWith(formHTML); Hope that works for you, let me know :)
You can use template engine like Mustache https://mustache.github.io/
Jquery / Javascript: There is a NaN on my HTML
I am writing an HTML loop using javascript. It will loop through a series of images and display them with additional information. It appears that there is always a NaN showing on the HTML output as shown here. Here is the javascript in question: var caption = '<p></p>'; if($.isEmptyObject(data[i].caption) !== true) { caption = '<p class="caption" style="top:'+data[i].height+'px;">'+ data[i].caption + '</p>'; } var li = '<li data-uk-modal="{target:#modal-open-image}"' + 'class="open"' + 'image="'+ data[i].photo +'"' + 'caption_height="'+ data[i].height +'"' + 'caption="'+ data[i].caption +'">' + '<a href="#" class="uk-thumbnail uk-overlay-toggle">' + '<div class="uk-overlay">' + '<img src="'+ data[i].photo +'" width="250px"/>' + caption + + '<div class="uk-overlay-caption">' + '<p> Sender: ' + data[i].sender + '</p>' + '<p> Date: ' + data[i].date + '</p>' + '<p> limit: '+ data[i].limit + '</p>' + '<p> counter: ' + data[i].counter + '</p>' + '</div>' + '</div>' + '</a>' +'</li>'; $photo.append(li); I would think the problem would lie on the caption variable. the data[i] is an array of from a database query. I need to check if there is something on the data[i].caption. I tried using length, but that doesn't work, so I check if the object exist. Though I am not sure if that works. My question, is how to display properly check if the caption is empty, and if none it will not add anything on the var li. Thanks.
You can code it in one line: ( (data && data[i] && data[i].caption) ? " your stuff " : "") But pay attention that checking 'data[i].caption' in javascript means that: zero is false, empty string is false. Furthermore if you referring a number you can add a condition using the method isNaN
Please use this one in place of the '+ caption +' isNaN(data[i].caption) ? '' : data[i].caption or if(isNaN(data[i].caption)==true){ //do somthing }else{ //do somthing }
Thanks for the feedback. I manage to gobble up the solutions you game me and I ended up with this. var height = (data[i].height == null)?0:data[i].height; var caption= (data[i].caption== null)?'':data[i].caption; var li = '<li data-uk-modal="{target:\'#modal-open-image\'}"' + 'class="open"' + 'image="'+ data[i].photo +'"' + 'caption_height="'+ height +'"' + 'caption="'+ caption +'">' + '<a href="#" class="uk-thumbnail uk-overlay-toggle">' + '<div class="uk-overlay">' + '<img src="'+ data[i].photo +'" width="250px"/>' + '<p class="caption" style="top:' + height +'px;">' + caption + '</p>' + '<div class="uk-thumbnail-caption">' + '<p> Sender: ' + data[i].sender + '</p>' + '<p> Reciever: '+ data[i].reciever + '</p>' + '<p> Date: ' + data[i].date + '</p>' + '<p> limit: '+ data[i].limit + '</p>' + '</div>' + '</div>' + '</a>' +'</li>';