Is it possible to have the tables inside this snippet to be styled dynamically? Instead of splitting the data fetched each time and hardcoding it? They have different number of columns and rows. I'd like them to have the same style using only one split(), so I can have my code DRY. The approach to the solution would be on a complete different way than my code is written now? Thank you very much for the help.
function loadMountsVehicles() {
fetch('https://api.open5e.com/sections/mounts-and-vehicles/'
).then(function (responses) {
return responses.json();
}).then(function (data) {
displayMountsVehicles(data);
});
};
function displayMountsVehicles(data) {
let html = "";
html += `<h3>Mounts and Vehicles</h3>`;
for (let i = 0; i < data.desc.split(/\n/).length; i++) {
if (i < 16) {
html += `<p>${data.desc.split(/\n/)[i]}</p>`;
}
};
let mountsTable = data.desc.split(/[\n|]+/).splice(8, 40);
let index = mountsTable.indexOf("----------------");
if (index > -1) {
mountsTable.splice(index, 4);
};
let perrow = 4;
html += "<table><thead><tr>";
for (let i = 0; i < mountsTable.length; i++) {
html += `<td>${mountsTable[i]}</td>`;
let next = i + 1;
if (i === 3) {
html += `</thead>`;
} else if (next % perrow == 0 && next != mountsTable.length) {
html += "</tr><tr>";
}
};
html += "</tr></table>";
for (let i = 0; i < data.desc.split(/\n/).length; i++) {
if (i < 28 && i > 25) {
html += `<p>${data.desc.split(/\n/)[i]}</p>`;
}
};
let tackTable = data.desc.split(/[\n|]+/).splice(49, 51);
let indexTack = tackTable.indexOf("--------------------");
if (indexTack > -1) {
tackTable.splice(indexTack, 3);
};
let perrowTack = 3;
html += "<table><thead><tr>";
for (let i = 0; i < tackTable.length; i++) {
html += `<td>${tackTable[i]}</td>`;
let next = i + 1;
if (i === 2) {
html += `</thead>`;
} else if (next % perrowTack == 0 && next != tackTable.length) {
html += "</tr><tr>";
}
};
html += "</tr></table>";
for (let i = 0; i < data.desc.split(/\n/).length; i++) {
if (i > 45 && i < 49) {
html += `<p>${data.desc.split(/\n/)[i]}</p>`;
}
};
let waterboneTable = data.desc.split(/[\n|]+/).splice(101);
let indexWaterbone = waterboneTable.indexOf("--------------");
if (indexWaterbone > -1) {
waterboneTable.splice(indexWaterbone, 3);
};
let perrowWaterbone = 3;
html += "<table><thead><tr>";
for (let i = 0; i < waterboneTable.length; i++) {
html += `<td>${waterboneTable[i]}</td>`;
let next = i + 1;
if (i === 2) {
html += `</thead>`;
} else if (next % perrowWaterbone == 0 && next != waterboneTable.length) {
html += "</tr><tr>";
}
};
html += "</tr></table>";
html = html.replace(/\*\*\_([\w\(\)][\s\w\,\(\)\.]+)\_\*\*/g, "<span>$1</span>");
html = html.replace(/\*\*([\w\(\)\_][\s\w\,\(\)\_\.]+)\*\*/g, "<span>$1</span>");
document.querySelector(".content-text").innerHTML = html;
};
<body onload="loadMountsVehicles()">
<div class="content-text"></div>
</body>
This is the data returned from the API:
function loadMountsVehicles() {
fetch('https://api.open5e.com/sections/mounts-and-vehicles/'
).then(function (responses) {
return responses.json();
}).then(function (data) {
console.log(data.desc)
});
};
<body onload="loadMountsVehicles()">
</body>
Related
I'm playing around with some HTML and Javascript. I'm trying to print out 100 numbers on a screen after I press a button on a webpage. I can get the numbers to print on the screen but when I want to replace a number with a string like "Apple" if the number is divisible by 5. The code is below:
function testFunction() {
var wrapper = document.getElementById("Test");
var myHTML = '';
for (var i = -1; i < 20; i++) {
if (i % 5 == 0 && i % 3 == 0) {
myHTML += '<span class="test">Pineapple</span><br/>';
} else if (i % 5 == 0) {
myHTML += '<span class="test">Apple</span><br/>';
} else if (i % 3 == 0) {
myHTML += '<span class="test">Pine</span><br/>';
} else {
myHTML += '<span class="test">' + (i + 1) + '</span><br/>';
}
}
wrapper.innerHTML = myHTML
}
The output is always off by one element so it would print "5" and then the next line would be "Apple" instead of replacing "5" with "Apple" and then printing "6"
Here is the output:
0
Pineapple
2
3
Pine
5
Apple
Pine
8
9
Pine
Apple
12
Pine
14
15
Pineapple
17
18
Pine
20
You are printing i+1, instead of i.
var wrapper = document.getElementById("Test");
var myHTML = '';
for (var i = -1; i < 20; i++) {
if (i % 5 == 0 && i % 3 == 0) {
myHTML += '<span class="test">Pineapple</span><br/>';
} else if (i % 5 == 0) {
myHTML += '<span class="test">Apple</span><br/>';
} else if (i % 3 == 0) {
myHTML += '<span class="test">Pine</span><br/>';
} else {
myHTML += '<span class="test">' + (i ) + '</span><br/>';
}
}
wrapper.innerHTML = myHTML
}
The trouble is in the starting point of your for loop, where you initialize with -1 instead of 0. While you use (i + 1) at the end when you print a number, which is why it causes your results to be one number off.
Use for(var i = 0; i <= 20; i++) instead of for (var i = -1; i < 20; i++) when you want to loop 20 times.
function testFunction() {
var wrapper = document.getElementById("Test");
var myHTML = '';
for (var i = 0; i <= 20; i++) {
if (i % 5 == 0 && i % 3 == 0) {
myHTML += '<span class="test">Pineapple</span><br/>';
} else if (i % 5 == 0) {
myHTML += '<span class="test">Apple</span><br/>';
} else if (i % 3 == 0) {
myHTML += '<span class="test">Pine</span><br/>';
} else {
myHTML += '<span class="test">' + i + '</span><br/>';
}
}
wrapper.innerHTML = myHTML
}
Using this code I was able to replace 5 with Apple.
function testFunction() {
var wrapper = document.getElementById("Test");
var myHTML = '';
for (var i = -1; i < 20; i++){
if (i % 5 == 0) {
myHTML += '<span class="test">Apple</span><br>';
} else{
myHTML += '<span class="test">' + i + '</span><br>'
}
}
wrapper.innerHTML = myHTML
}
testFunction();
<div id="Test"></div>
Use this snippet to follow what exactly happens within your loop. It should give you some clues.
const log = Logger();
testFunction();
function testFunction() {
for (let i = -1; i < 20; i += 1) {
if (i % 5 == 0 && i % 3 == 0) {
log(`${i} % 5 === 0 && ${i} % 3 === 0 => Pineapple`);
} else if (i % 5 == 0) {
log(`${i} % 5 === 0 => Apple` );
} else if (i % 3 == 0) {
log(`${i} % 3 === 0 => Pine`);
} else {
log(`i = ${i}, i + 1 = ${i + 1}`);
}
}
}
function Logger() {
let logEl;
if (typeof window === "object") {
logEl = document.querySelector("#log") || (() => {
document.body.appendChild(Object.assign( document.createElement('pre'), { id: "log" }) );
return document.querySelector("#log");
})();
return (...logLines) => logLines.forEach(s => logEl.textContent += `${s}\n`);
} else {
return (...logLines) => logLines.forEach(ll => console.log(`* `, ll));
}
}
I'm making a gem-puzzle. I have a save button that after clicking on page reload shows the last saved state of the game. But when I reload the page, the table is rendered but the move click event doesn't work. How can this be fixed? What new arguments need to be passed to the function moveThisTile? Or should I save something else in localstorage? To explain my code: the startNewGame function is called to create the fifteen puzzle. showTable cycles through the two-dimensional array arrayForBoard and generates the necessary HTML for the fifteen puzzle board. moveThisTile takes two arguments that tell the program which tile of the fifteen puzzle needs to be moved
let moves = 0;
let table;
let rows;
let columns;
let textMoves;
let arrayForBoard;
let volumeOn = true;
function start() {
let button = document.getElementById('newGame');
button.addEventListener('click', startNewGame, false );
textMoves = document.getElementById('moves');
table = document.getElementById('table');
rows = 4;
columns = 4;
startNewGame();
}
function startNewGame() {
let arrayOfNumbers = new Array();
let arrayHasNumberBeenUsed;
let randomNumber = 0;
let count = 0;
moves = 0;
rows = document.getElementById('rows').value;
columns = document.getElementById('columns').value;
textMoves.innerHTML = moves;
arrayForBoard = new Array(rows);
for (let i = 0; i < rows; i++){
arrayForBoard[i] = new Array(columns);
}
arrayHasNumberBeenUsed = new Array( rows * columns );
for (let i = 0; i < rows * columns; i++){
arrayHasNumberBeenUsed[i] = 0;
}
for (let i = 0; i < rows * columns; i++){
randomNumber = Math.floor(Math.random()*rows * columns);
if (arrayHasNumberBeenUsed[randomNumber] == 0) {
arrayHasNumberBeenUsed[randomNumber] = 1;
arrayOfNumbers.push(randomNumber);
}else {
i--;
}
}
count = 0;
for (let i = 0; i < rows; i++){
for (let j = 0; j < columns; j++){
arrayForBoard[i][j] = arrayOfNumbers[count];
count++;
}
}
showTable();
}
let tbody = document.createElement('tbody');
document.querySelector('#table').appendChild(tbody);
function showTable() {
for (let tr of document.querySelectorAll("#table tr")) {
tr.remove();
}
for (let i = 0; i < rows; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < columns; j++) {
let cell = document.createElement('td');
if (arrayForBoard[i][j] == 0) {
cell.className = 'blank';
} else {
cell.className = 'tile';
cell.draggable = true;
cell.addEventListener('click', () => {
moveThisTile(i, j);
if(volumeOn) {
sound()
}
})
cell.innerHTML =arrayForBoard[i][j];
}
tr.appendChild(cell);
}
tbody.appendChild(tr);
}
};
function moveThisTile(tableRow, tableColumn) {
if (checkIfMoveable(tableRow, tableColumn, 'up') ||
checkIfMoveable(tableRow, tableColumn, 'down') ||
checkIfMoveable(tableRow, tableColumn, 'left') ||
checkIfMoveable(tableRow, tableColumn, 'right') ) {
incrementMoves();
} else {
alert('ERROR: Cannot move tile!\nTile must be next to a blank space.');
}
if (checkIfWinner()) {
stopTimer();
alert(`Congratulations! You solved the puzzle in ${moves} moves and in ${document.querySelector('#timespan').innerText}.`);
startNewGame();
}
}
function checkIfMoveable(rowCoordinate, columnCoordinate, direction) {
let rowOffset = 0;
let columnOffset = 0;
if (direction == 'up') {
rowOffset = -1;
} else if (direction == 'down') {
rowOffset = 1;
} else if (direction == 'left') {
columnOffset = -1;
} else if (direction == 'right') {
columnOffset = 1;
}
if (rowCoordinate + rowOffset >= 0 && columnCoordinate + columnOffset >= 0 &&
rowCoordinate + rowOffset < rows && columnCoordinate + columnOffset < columns
) {
if ( arrayForBoard[rowCoordinate + rowOffset][columnCoordinate + columnOffset] == 0) {
arrayForBoard[rowCoordinate + rowOffset][columnCoordinate + columnOffset] = arrayForBoard[rowCoordinate][columnCoordinate];
arrayForBoard[rowCoordinate][columnCoordinate] = 0;
showTable();
return true;
}
}
return false;
}
document.querySelector('.save-btn').addEventListener('click', () => {
localStorage.setItem('currentGame', document.querySelector('tbody').innerHTML);
localStorage.setItem('currentMoves', document.querySelector('#moves').innerHTML);
localStorage.setItem('currentTime', document.querySelector('#timespan').innerHTML);
})
window.addEventListener('load', () => {
if(localStorage.getItem('currentGame') !== null) {
tbody.innerHTML = localStorage.getItem('currentGame');
document.querySelector('#moves').innerHTML = localStorage.getItem('currentMoves');
document.querySelector('#timespan').innerHTML = localStorage.getItem('currentTime');
} else {
start();
}
}, false );
Someone please help what is wrong in the following code. It is saying "Unexpected token else" while validating javascript code on Java Validate website - esprima.org
`
function add1()
{
var size = 8;
var widthOfGrid = size;
var lenthOfGrid = size;
var linenumber = 1;
for (i = 1 ; i<=size ; i += 1 )
{
for (j = 1 ; j<=size ; j += 1)
{
If (i % 2 === 0)
{
console.log(" " + "#");
}
else
{
console.log("#" + " ");
}
}
}
}
`
In Javascript there is no If statement. Javascript is a case-sensitive language Write it in the lower case - if. And also refactor your code, you have some unused variables.
The problem is that If should be lowercase.
The code should be like this:
function add1() {
var size = 8;
var widthOfGrid = size;
var lenthOfGrid = size;
var linenumber = 1;
for (i = 1; i <= size; i += 1) {
for (j = 1; j <= size; j += 1) {
if(i % 2 === 0)
{
console.log(" " + "#");
}
else
{
console.log("#" + " ");
}
}
}
}
function add1()
{
var size = 8;
var widthOfGrid = size;
var lenthOfGrid = size;
var linenumber = 1;
for (i = 1 ; i<=size ; i += 1 )
{
for (j = 1 ; j<=size ; j += 1)
{
if (i % 2 === 0)
{
console.log(" " + "#");
}
else
{
console.log("#" + " ");
}
}
}
}
working code,you forget make your if in lowercase
How can I remove the last comma from this function.
for(var i = 0; i <= 100; i++) {
if(i % 2 === 0) {
div.innerHTML += l + ",";
}
else {
div.innerHTML += " ";
}
}
First, use arrays instead strings for sum strings, its faster.
Second:
var arr = [];
for (var i = 0 ;i <= 100; i+=2) arr.push(l);
dividedThree.innerHTML = arr.join(', ');
function loop {
for (var i = 0; i <= 100; i++) {
if (i % 2 === 0) {
dividedThree.innerHTML += l;
if (i < 100)
{
dividedThree.innerHTML += ",";
}
} else {
dividedThree.innerHTML += " ";
}
}
}
Try using and (&&) condition for 100 and show only i value for 100.
function loop() {
var dividedThree = document.getElementById('MY_ID');
for (var i = 0; i <= 100; i++) {
if (i % 2 === 0 && i !== 100) {
dividedThree.innerHTML += i + ", ";
} else if (i === 100) {
dividedThree.innerHTML += i;
} else {
dividedThree.innerHTML += " ";
}
}
}
loop();
<p id="MY_ID">
<p>
does this version work for you?
function loop() {
var data = '';
for (var i = 0; i <= 49; i++) {
data += l + ',' + ' ';
}
data += l;
dividedThree.innerHTML = data;
}
What are you trying to do? where does 'l' come from?
My javascript code:
var footer = document.getElementsByTagName('footer');
for (var i = 0; i < footer.length; ++i) {
var appendTo = footer[0].getElementsByTagName('p'); //get only the p in the first footer to select
if(language.indexOf('nl') <= -1 && location.href.indexOf("/") >= 0 && location.href.indexOf("/en/") <= -1) {
for (var i = 0; i < appendTo.length; ++i) {
appendTo[0].innerHTML += '<div class="language item switch en">english</div>';
}
} else if(language.indexOf('nl') == 0 && location.href.indexOf("/en/") >= 0 ) {
for (var i = 0; i < appendTo.length; ++i) {
appendTo[0].innerHTML += '<div class="language item switch nl">nederlands</div>';
}
} else {}
}
I don't get any console errors. I want to add a 'change language' button when a user is not on the correct language site. Where did I go wrong in my code?
the variable language isn't defined in your function. If you declare it, it seems to work fine.
var language = window.navigator.userLanguage || window.navigator.language;
language = language.split("-");
var footer = document.getElementsByTagName('footer');
for (var i = 0; i < footer.length; ++i) {
var appendTo = footer[0].getElementsByTagName('p'); //get only the p in the first footer to select
if(language.indexOf('nl') <= -1 && location.href.indexOf("/") >= 0 && location.href.indexOf("/en/") <= -1) {
for (var i = 0; i < appendTo.length; ++i) {
appendTo[0].innerHTML += '<div class="language item switch en">english</div>';
}
} else if(language.indexOf('nl') == 0 && location.href.indexOf("/en/") >= 0 ) {
for (var i = 0; i < appendTo.length; ++i) {
appendTo[0].innerHTML += '<div class="language item switch nl">nederlands</div>';
}
} else {}
}
Updated fiddle: http://jsfiddle.net/ecsuZ/2/