How to insert multiple HTML elements using jQuery - javascript

I have a webpage that is taking data from the Yahoo! Weather API. I am using this query. I would like to build a table using jQuery that inserts elements with IDs. Here is my current code:
$.get("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22canberra%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys", function(data) {
$("#title").append(data.query.results.channel.title);
$("#sunrise").append(data.query.results.channel.astronomy.sunrise);
$("#sunset").append(data.query.results.channel.astronomy.sunset);
$("#title-2").append(data.query.results.channel.item.title);
for (var i = 0; i < 10; i += 1) {
var newRow = $("<tr></tr>").attr("id", "row-" + (i + 1));
var newDate = $("<td></td>").attr("id", "date-" + (i + 1));
var newMin = $("<td></td>").attr("id", "min-" + (i + 1));
var newMax = $("<td></td>").attr("id", "max-" + (i + 1));
var newConditions = $("<td></td>").attr("id", "conditions-" + (i + 1));
$("#weather").append(newRow);
$("#row-" + (i + 1)).append(newDate, newMin, newMax, newConditions);
$("#date-" + (i + 1)).append(data.query.results.channel.item.forecast[i].day + " " + data.query.results.channel.item.forecast[i].date);
$("#min-" + (i + 1)).append((Math.floor(((data.query.results.channel.item.forecast[i].low) - 32) / 1.8)) + "°C");
$("#max-" + (i + 1)).append((Math.floor(((data.query.results.channel.item.forecast[i].high) - 32) / 1.8)) + "°C");
$("#conditions-" + (i + 1)).append(data.query.results.channel.item.forecast[i].text);
}
$("#lastBuild").append(data.query.results.channel.lastBuildDate);
}, "json");
div#main {
width: 595px;
}
table#weather {
border-collapse: collapse;
width: 595px;
}
table#headers {
width: 595px;
}
td,
th {
width: 148.75px;
text-align: center;
}
tr {
height: 28px;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<div id="main">
<h1 id="title"></h1>
<ul id="sun">
<li id="sunrise"><strong>Sunrise: </strong></li>
<li id="sunset"><strong>Sunset: </strong></li>
</ul>
<h2 id="title-2"></h2>
<table id="headers">
<tr>
<th id="date">Date</th>
<th id="min">Min</th>
<th id="max">Max</th>
<th id="conditions">Conditions</th>
</tr>
</table>
<table id="weather" border="1"></table>
<br />
</div>
<em id="lastBuild">Data last built at: </em>
My question is this:
Am I going about the correct way of doing this? It works, but it might just be an autofill by the interpreter (like leaving off semicolons). Is this right, and if not, how can I fix it? All help appreciated.

Currently it looks good to me. If your page will only ever query the information once, then it should be fine as long as it is working now. If you want to allow multiple queries (like allowing the user to select a date and press a button to retrieve information of another day), you might want to empty the relevant elements before appending new items to them.

Related

javascript table alignment

I'm trying to align the tables' titles with the items form another page using a js loop, tried padding, spacing etc.. nothing worked!
$(document).ready(function() {
let products = ['bread', 'sweets', 'coffee'];
$('#prepurchased').html('<table class ="thead"id="items" ><tr><th>Item</th><th> </th><th>Price</th><th>quantity</th></tr>');
products.forEach(function(i) {
let p = sessionStorage.getItem(i);
if (p !== null) {
p = JSON.parse(p);
$('#prepurchased').append('<table id="items" class="cart" align="center"><tr><td>' + i + '</td>' + '<td>$' + p.price + '</td>' + '<td>' + p.quantity + '</td></tr>');
$('#purchase').css('display', 'block');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.2/sweetalert.min.js" integrity="sha512-AA1Bzp5Q0K1KanKKmvN/4d3IRKVlv9PYgwFPvm32nPO6QS8yH1HO7LbgB1pgiOxPtfeg5zEn2ba64MUcqJx6CA==" crossorigin="anonymous"></script>
All your data should be in the same <table>. That's what tables are for. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
Also:
It seems you wanted to separate <thead> and <tbody>
I removed an empty <th> that was confusing
You made your "purchase" button visible at each data row, which doesn't seem useful
if (p !== null) doesn't prevent rendering the JSON when p is undefined. Just write if (p) instead
$(document).ready(...) is longer to write. You may use the shorthand $(...)
I had to fake sessionStorage for the snippet to run live.
$(_e => {
const products = ['bread', 'sweets', 'coffee'];
$('#prepurchased').html('<table class="cart" id="items"><thead><tr><th>Item</th><th>Price</th><th>quantity</th></tr></thead><tbody></tbody></table>');
products.forEach(i => {
//let p = sessionStorage.getItem(i); //TODO: restore this
let p = fakeStorage[i]; //TODO: remove this
if (p) {
p = JSON.parse(p);
$('#prepurchased .cart tbody').append('<tr><td>' + i + '</td>' + '<td>$' + p.price + '</td>' + '<td>' + p.quantity + '</td></tr>');
}
});
if (products.length)
$('#purchase').css('display', 'block');
});
//TODO: remove, for testing only (sessionStorage rises error with cross-domain js)
fakeStorage = {
'bread': '{"price": 21.2, "quantity": 25}',
'coffee': '{"price": 34.55, "quantity": 32}',
/*'sweets': '{"price": 6.12, "quantity": 1}',*/
};
body {
text-align: center;
}
.cart {
text-align: center;
}
.cart th {
width: 15em;
}
.buttons {
margin-top: 2rem;
display: flex;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.2/sweetalert.min.js" integrity="sha512-AA1Bzp5Q0K1KanKKmvN/4d3IRKVlv9PYgwFPvm32nPO6QS8yH1HO7LbgB1pgiOxPtfeg5zEn2ba64MUcqJx6CA==" crossorigin="anonymous"></script>
<div id="prepurchased"></div>
<div class="buttons">
<button id="purchase" style="display: none">Purchase</button>
</div>

Table Not Populating as I expected using Jquery

I am trying to populate a table using a JSON file. When I run this through the browser, my first row populates. However the other rows do not. Can someone please point out to me what I am doing wrong? Am I not looping this correctly? Thank you in advance.
$(document).ready(function() {
$.getJSON( "data.json", function(data) {
var htmlToRender= [];
var item;
for (var i = 0; i < data.length; i++) {
item = data[i];
console.log(data[i]);
htmlToRender = '<tr><td>' + item.name + '</td>'
'<td>' + item.description + '</td>'
console.log(item.description)
'<td>Open In Google Mapspwd</td></tr>';
console.log(item.location);
$('#hot-spots').append(htmlToRender);
console.log(htmlToRender);
};
});
});
The lines following htmlToRender = '<tr><td>' + item.name + '</td>' look a bit suspicious--you're missing a + sign to concatenate these additional strings, and sprinkled console.logs amidst the string build isn't helping the cause.
I recommend using a string template:
const item = {
name: "hello",
description: "world",
location: "somewhere"
};
const htmlToRender = `
<tr>
<td>${item.name}</td>
<td>${item.description}</td>
<td>
Open In Google Maps
</td>
</tr>
`;
$('#hot-spots').append(htmlToRender);
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 0.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="hot-spots"></table>

How to Select an Element of An Appended Table With Jquery

I built a table by using .append on a div (id = calendarData) that is in the html:
$j('#calendarData').append(
'<table class="grid" id="calendar" href="#" style="max-width:1200px"><th colspan="7" align=""center">' +
months[currentMonth] + " " + currentYear + '</div></th><tbody>'+
'<tr><td>Sun</td><td>Mon</td><td>Tues</td><td>Wed</td><td>Thurs</td><td>Fri</td><td>Sat</td>'
);
Then I added all of the cells to the table:
for(var i=0; i<6; i++){
$j('#calendar > tbody:last-child').append(
'</tr><tr>'
);
for(var j=0;j<7;j++){
if(inMonth == 0 && day > getDaysInMonth(startDate.getMonth()-1)){
day = 1;
inMonth = 1;
}
else if(inMonth == 1 && day > getDaysInMonth(startDate.getMonth())){
day = 1;
inMonth == 2;
}
$j('#calendar > tbody:last-child').append(
'<td class="square">' + day + '</td>'
);
day++;
}
}
$j('#calendarData > tbody:last-child').append(
'</tr></tbody></table>'
);
After this I need to go back and select each td and give it a color if that day is active(determined in a later function) but every time I try to grab it the system comes back with undefined.
Everything from:
$j('#calendarData tbody:last-child').style.backgroundColor = 'green';
to
var t = document.getElementById("calendar");
var r = t.getElementsByTagName("tr")[0];
var d = r.getElementsByTagName("td")[0];
d.style.backgroundColor ='green';
Every time it throws an Error 'Cannot change Background Color of Undefined"
Any ideas what I am doing wrong?
Not sure why it's doubling-up the dates in my example, but that's not the point.
To style the injected HTML class after the fact, you can either add the class ahead of time to the CSS, or you can use jQuery .css() to add the styling via jQuery:
setTimeout(function(){
$('.active').css({'color':'maroon','font-weight':'bold','background':'yellow'});
},3000);
$('#calendarData').append('\
<table class="grid" id="calendar" href="#" style="max-width:1200px">\
<th colspan="7" align=""center">' +'June'+ "" + '2016' + '</div></th><tbody>\
<tr><td>Sun</td><td>Mon</td><td>Tues</td><td>Wed</td><td>Thurs</td><td>Fri</td><td>Sat</td></tr>'
);
setTimeout(function(){
//This mimics your generated / injected code
$('#calendarData > table > tbody').append('\
<tr><td class="square">1</td><td class="square">2</td><td class="square">3</td><td class="square">4</td><td class="square">5</td><td class="square">6</td><td class="square">7</td></tr>\
<tr><td class="square">8</td><td class="square">9</td><td class="square">10</td><td class="square active">11</td><td class="square">12</td><td class="square">13</td><td class="square">14</td></tr>\
<tr><td class="square">15</td><td class="square">16</td><td class="square">17</td><td class="square">18</td><td class="square">19</td><td class="square">20</td><td class="square">21</td></tr>\
<tr><td class="square">22</td><td class="square">23</td><td class="square">24</td><td class="square">25</td><td class="square">26</td><td class="square">27</td><td class="square">28</td></tr>\
</tbody></table>'
);
},1500);
.square{text-align:center;}
.active{font-style:italic;font-size:larger;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="calendarData"></div>

getJSON JSON Array - Search Functionality Crashing Client

I'm running into a problem when trying to add in the search functionality, showList().
It seems to bog down the client so much that Chrome wants to kill the page each time I type into the input field. I'm clearly a novice JS writer, so could I be running an infinite loop somewhere I don't see? Also, any advice to get the search functionality working properly would be hugely appreciated. I don't think I'm using the correct selectors below for the show/hide if statement, but I can't think what else to use.
$(document).ready(function(){
showList();
searchBar();
});
function showList() {
$("#show-records").click(function(){
$.getJSON("data.json", function(data){
var json = data;
$("show-list").append("<table class='specialists'>")
for(var i = 0; i < json.length; i++) {
var obj = json[i],
tableFormat = "</td><td>";
$("#show-list").append("<tr><td class=1>" +
obj.FIELD1 + tableFormat +
obj.FIELD2 + tableFormat +
obj.FIELD3 + tableFormat +
obj.FIELD4 + tableFormat +
obj.FIELD5 + tableFormat +
obj.FIELD6 + tableFormat +
obj.FIELD7 + tableFormat +
obj.FIELD8 + "</td></tr>");
$("show-list").append("</table>");
}
//end getJSON inner function
});
//end click function
});
//end showList()
};
function searchBar() {
//AJAX getJSON
$.getJSON("data.json", function(data){
//gathering json Data, sticking it into var json
var json = data;
for(var i = 0; i < json.length; i++) {
//putting the json objects into var obj
var obj = json[i];
function contains(text_one, text_two) {
if (text_one.indexOf(text_two) != -1)
return true;
}
//whenever anything is entered into search bar...
$('#search').keyup(function(obj) {
//grab the search bar content values and...
var searchEntry = $(this).val().toLowerCase();
//grab each td and check to see if it contains the same contents as var searchEntry - if they dont match, hide; otherwise show
$("td").each(function() {
if (!contains($(this).text().toLowerCase(), searchEntry)) {
$(this).hide(400);
} else {
$(this).show(400);
};
})
})
}
});
};
body {
background-color: lightblue;
}
tr:first-child {
font-weight: bold;
}
td {
padding: 3px;
/*margin: 10px;*/
text-align: center;
}
td:nth-child(6) {
padding-left: 50px;
}
td:nth-child(7) {
padding-left: 10px;
padding-right: 10px;
}
#filter-count {
font-size: 12px;
}
<html>
<head>
<script language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script language="javascript" src="process.js"></script>
<link rel="stylesheet" type="text/css" href="./mystyle.css">
</head>
<body>
<a href="#" id='show-records'>Show Records</a><br>
<label id="searchBar">Search: <input id="search" placeholder="Enter Specialist Name"></label>
<span id="search-count"></span>
<div id="show-list"></div>
</body>
</html>
Problem appears to be that you can't treat append as if it was a text editor and you are writing html.
Anything that gets inserted needs to be a proper element ... not a start tag, then some text...then a close tag.
We can however modify your code slightly to produce html strings and then add that at the end
$.getJSON("data.json", function(data){
var json = data;
var html="<table class='specialists'>")
for(var i = 0; i < json.length; i++) {
var obj = json[i],
tableFormat = "</td><td>";
html+= "<tr><td class=1>" +
obj.FIELD1 + tableFormat +
obj.FIELD2 + tableFormat +
obj.FIELD3 + tableFormat +
obj.FIELD4 + tableFormat +
obj.FIELD5 + tableFormat +
obj.FIELD6 + tableFormat +
obj.FIELD7 + tableFormat +
obj.FIELD8 + "</td></tr>";
}
html+= '</table>';
$("#show-list").html(html);
//end getJSON inner function
});

Writing random values from function to generated table using JS?

I have a table that generates 5 columns and X rows based on an input by the user. In the rows I am trying to generate random numbers to simulate data. Currently my content for the table is generated by this JS for loop:
for(i = dur; i >= 0; i -= 15)
{
document.write('<tr>')
document.write('<td>reading ' + i + ', column 0;</td>')
document.write('<td>reading ' + i + ', column 1</td>')
document.write('<td>reading ' + i + ', column 2</td>')
document.write('<td>reading ' + i + ', column 3</td>')
document.write('<td>reading ' + i + ', column 4</td>')
document.write('</tr>')
}
I have a function that creates random numbers with 2 decimal places as long as the min and max are >10k and <99k:
function randomNumber (min, max)
{
var random = Math.floor((Math.random() * (max - min) + min))/100;
}
What I want to happen is during the for loop insert randomly created numbers using the function instead of my i value that is currently there as a place holder.
EDIT: I would also like to be able to manipulate the data within the table. I.E. column 3 = column 1 + column2.
One another solution I tried here:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
td {
border: 1px solid #000;
padding: 20px;
}
</style>
</head>
<body>
<script type="text/javascript">
var table = document.createElement('table');
for(let i = 0; i < 5; i++) {
var tr = document.createElement('tr');
for(let j = 0; j < 5; j++) {
var td = document.createElement('td');
td.innerHTML = Math.floor((Math.random()*100) + 1);
tr.appendChild(td)
}
table.appendChild(tr)
}
document.body.appendChild(table)
</script>
</body>
</html>

Categories

Resources