I can see the array in the console but it doesnt show up on the table i've tried alot of things and it just hasnt worked out and i've been trying to fix this for like 2 days
i think tobodyHtml doesnt get defined but i dont know how to fix it
document.addEventListener("DOMContentLoaded", function(event) {
function loadUsers(){
var userTbody=document.getElementById('user-tbody');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200){
var userJSON=this.responseText;
var usersArray=JSON.parse(userJSON);
console.log(usersArray);
var tobodyHtml="";
for(let index = 0; index < usersArray.lenght; index++) {
const user = usersArray[index];
tobodyHtml+="<tr><td>"+user.id+"</td><td>"+user.username+"</td><td>"+user.password+"</td><td>"+user.birthdate+"</td></tr>";
console.log(tobodyHtml);
}
userTbody.innerHTML=tobodyHtml;
}
};
xhttp.open("GET", "http://localhost:8279/users", true);
xhttp.send();
}
loadUsers();
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/trgames.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.11.5/umd/popper.min.js" integrity="sha512-8cU710tp3iH9RniUh6fq5zJsGnjLzOWLWdZqBMLtqaoZUA6AWIE34lwMB3ipUNiTBP5jEZKY95SfbNnQ8cCKvA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<table id="user-table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Password</th>
<th>Birthday</th>
</tr>
</thead>
<tbody id="user-tbody">
</tbody>
</table>
<script src="js/trgames.js"></script>
</body>
</html>
I've had a similar issue before and I find that when creating HTML elements in JavaScript, it's best to use dom document.createElement to create the elements then add the inner text. Then you can append the final data into the body. Here's a simplified version of your code without the HTTP request since I don't have that data handy. There were also a few minor typos in your for loop (length) and some other issues that I cleaned up.
// grab refs to our html elements
const userTbody = document.getElementById("user-tbody");
const tr = document.createElement("tr");
// test data
const usersArray = [
{
id: 23,
username: "Joe",
password: "123",
birthdate: "01/01/2018"
}
];
// event on dom content loaded
document.addEventListener("DOMContentLoaded", function(event) {
// loop through data of users
usersArray.forEach((user) => {
// simple pattern to create the td and place the data on it
const userIdData = document.createElement("td")
userIdData.innerText = user.id
const userNameData = document.createElement("td")
userNameData.innerText = user.username;
const userPasswordData = document.createElement("td")
userPasswordData.innerText = user.password
const userBirthdateData = document.createElement("td")
userBirthdateData.innerText = user.birthdate
// append all of the data we created to the tbody
userTbody.append(
userIdData,
userNameData,
userPasswordData,
userBirthdateData
);
})
})
Here's a codepen example
Related
I am playing with jQuery and Javascript. Working on a TODOs app using li items and with this API: https://jsonplaceholder.typicode.com/todos. I receive 200 items from this API.
I am trying to post a new item created with a click from the button (btn-add) and everything works as expected, with the exception that the post request is leaving in blank one property which is "title". Here is my HTML and JS code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/CSS/styles.css" rel="stylesheet">
<title>TO DO List</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="/JS/index.js"></script>
</head>
<body>
<div id="inputDIV">
<input id="input" type="text" placeholder="Enter new item">
</div>
<div id="buttons">
<button id="btn-add">Add List Item</button>
<button id="btn-update">Update First Item</button>
<button id="btn-delete">Delete First Item</button>
</div>
<div id="ulDIV">
<ul id="list">
<!-- Here we will insert the list items via JS-->
</ul>
</div>
</body>
</html>
$(document).ready(function(){
let inputNew = $('#input');
let list = $('#list');
let currentInputValue = "";
$('#btn-add').click(createTODOItemAtBackend);
inputNew.on({
"input": function(e){
console.log(e.target.value);
currentInputValue = e.target.value;
},
"keyup": function(e){
if(e.keyCode === 13){
createTODOItemAtBackend();
}
}
})
getTODOListFromBackend();
function clearInputData(){
inputNew.val("");
currentInputValue = "";
}
function createTODODynamically(id, title){
let newListElement = document.createElement("li");
let textNode = document.createTextNode(title);
newListElement.appendChild(textNode);
newListElement.id = id;
return newListElement;
}
function getTODOListFromBackend(){
$.get("https://jsonplaceholder.typicode.com/todos", function(data, status){
let response = data;
for(let i=0; i < response.length; i++){
list.append(createTODODynamically(response[i].id, response[i].title));
}
});
}
let obj = {
"userId": 1,
"title": currentInputValue,
"completed": false
};
function createTODOItemAtBackend(){
$.post("https://jsonplaceholder.typicode.com/todos", obj, function(data, status){
let response = data;
list.append(createTODODynamically(response.id, currentInputValue));
console.log("Item Added to the list!");
clearInputData();
});
}
})
And this is what I see when I read the post information in the web browser:
{userId: "1", title: "", completed: "false", id: 201}
completed: "false"
id: 201
title: ""
userId: "1"
Can somebody help me, why is the property "title" being posted as empty? Thanks in advance
The answer is in what #epascarello hinted on the OP's comment. You set currentInputValue when the input value is changed but there's no code which updates this value to obj.
"input": function(e){
console.log(e.target.value);
currentInputValue = e.target.value;
//Add this line
obj.title = e.target.value;
},
Additional note: You really don't need currentInputValue if you refactor your code, using obj should do the job.
I'm pretty new with coding, and this is really stumping me...
Here is my index.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css">
<link rel="stylesheet" href="owlcarousel/owl.carousel.css">
<link rel="stylesheet" href="owlcarousel/owl.theme.default.css">
</head>
<body>
<div class="owl-carousel owl-theme">
</div>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous" type="text/javascript" language="JavaScript"></script>
<script src="jquery.min.js"></script>
<script src="owlcarousel/owl.carousel.js"></script>
<script src="app.js"></script>
<script>
fetch('https://www.paulschlatter.com/slideshow/slideshows.txt')
.then((response) => response.text().then(yourCallback));
let cache = {}
function yourCallback(retrievedText, callback) {
if (cache[retrievedText]) {
console.log('oops')
} else {
let array = []
console.log(callback)
array = retrievedText.split(/\n|\r/g)
let httpsArray = []
let keysArray = []
let mappedArray = array.map(item => {
if (item.substring(0, 5) === 'https') {
httpsArray.push(item)
} else if (item.substring(0, 3) === '202') {
keysArray.push(item)
}
})
const object = { ...keysArray
}
for (const prop in object) {
window['value' + prop] = []
httpsArray.filter(item => item.includes(object[prop])).map(item => {
window['value' + prop].push(item)
})
}
const owlImages = document.querySelector('.owl-carousel'),
owlDiv = document.createElement('img');
owlDiv.setAttribute('src', window.value0.pop())
owlDiv.setAttribute('alt', '')
owlImages.appendChild(owlDiv)
}
}
</script>
</body>
</html>
I am not using npm or anything, just straight JavaScript, and HTML.
The function yourCallback is firing twice, so even when I only console.log hello world it returns hello world twice to my browser.
Obviously this is not ideal, and I believe that the problem lies in the
fetch('https://www.paulschlatter.com/slideshow/slideshows.txt')
.then((response) => response.text().ten(yourCallback));
This was a silly mistake, in my app.js file I had the same fetch and yourCallback function, so it was firing twice cause I called it twice :)
I received answers regarding the following contents.
Create Todo list with Javascript
If you enter too many characters, the "state" part will be misaligned. Like in the video, I want to expand the width of the "comment" according to the input value. What should I do?
See also the image.
Have already updated my answer to acomodate this additional bit on the same question :). See this and read the comments on the snippets:
https://stackoverflow.com/a/62356950/4650975
document.addEventListener('DOMContentLoaded', function() {
// 必要なDOM要素を取得。
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
//ID用のインデックスを定義
let nextId = 0;
const addTask = (task,id) => {
// 表のタグを生成する
const tableItem=document.createElement('thead');
const addButton = document.createElement('button');
const removeButton = document.createElement('button');
addButton.style.margin = "5px"; //<------- Added a style here
removeButton.style.margin ="5px"; //<------- Added a style here
// それぞれ作業中、削除という言葉をボタンに入れる
addButton.innerText = '作業中';
removeButton.innerText = '削除';
//ボタンを押したら以下の作業をする
removeButton.addEventListener('click', () => removeTask(removeButton));
// IDを表示するspan要素を作成して tableItem に追加
const idSpan = document.createElement('span');
idSpan.innerText = id;
idSpan.style.marginRight = "20px"; //<------- Added a style here
tableItem.append(idSpan);
const taskSpan = document.createElement('span');
taskSpan.style.width = "60px"; //<------- Added a style here
taskSpan.style.display = "inline-block"; //<------- Added a style here
taskSpan.style.overflow = "hidden"; // <----- This styling for trimming the text if it exceeds certain width
taskSpan.style.textOverflow = "ellipsis"; // <------- This will append a (...) to the exceeding text
taskSpan.innerText = task;
taskSpan.title = task; //If you hover on the text full text will be displayed. In production code, you might like to use fancy tooltips, say, from bootstrap, for this
tableItem.append(taskSpan); //<------- changed this
//入力タスクを表示
addTaskTarget.appendChild(tableItem);
// 作業中ボタンを追加
tableItem.appendChild(addButton);
// 削除ボタンを追加
tableItem.appendChild(removeButton);
};
// 追加ボタンに対して、タスク登録イベントを設定
addTaskTrigger.addEventListener('click', event => {
const task = addTaskValue.value;
addTask(task,nextId ++);
addTaskValue.value = '';
});
});
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel ="stylesheet" href="css/style.css">
<title>Todoリスト</title>
</head>
<body>
<h1>Todoリスト</h1>
<p>
<input type="radio" name="status" value="1" checked="checked">全て
<input type="radio" name="status" value="2">作業中
<input type="radio" name="status" value="3">完了
</p>
<p></p>
<table>
<thead>
<tr>ID コメント 状態</tr>
</thead>
<tbody class ="addTask-target">
<tr>
</tr>
</tbody>
</table>
<h2>新規タスクの追加</h2>
<input class="addTask-value" type="text" />
<button class="addTask-trigger" type="button">追加</button>
<script src="js/main.js"></script>
</body>
</html>
This is the sample code given on the blockgeeks, to get it you can:
git clone https://github.com/blockgeeks/eth102.git
The web page comes out blank and never populates with the columns with the block information. The web console does show the block objects getting retrieved and the following two messages:
ReferenceError: web3 is not defined index.html:29:13
TypeError: r is not a function web3.min.js:1:59664
I only have firefox but do not believe this would be an issue.
On the debugger (sources/outline) tab show no error.
Tried using this other line instead as per doc, but same issue:
let web3 = new Web3(new
Web3.providers.HttpProvider("http://localhost:8545");
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Blockchain Explorer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<table id="blocks" width="100%">
<tr>
<th>Number</th>
<th>Hash</th>
<th>Timestamp</th>
</tr>
</table>
<script src="./web3.min.js"></script>
<script>
window.onload = function() {
updateBlocks();
};
//console.log(updateBlocks());
async function updateBlocks() {
let web3 = new Web3(Web3.givenProvider);
let latest = await web3.eth.getBlockNumber();
//console.log(web3);
for (var i=0; i < 10; i++) {
let block = await web3.eth.getBlock(latest-i);
printBlock(block);
//console.log(block);
}
}
//console.log(block);
function printBlock(block) {
var table = document.getElementById('blocks');
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = block.number;
cell2.innerHTML = block.hash;
cell3.innerHTML = block.timestamp;
//console.log(table);
//console.log(printBlock(block));
}
//console.log(printBlock(block));
</script>
Fix was to run ganache-cli
and use:
let web3 = new Web3(new
Web3.providers.HttpProvider("http://localhost:8545");
instead of
let web3 = new Web3(Web3.givenProvider);
I have the code below that returns the rowIndex of the clicked row.
The table uses the info from the WebViewString element, it has an csv formatted data and always have at least one column.
I need to get the value of the first column of that row. How to???
I know nothing about JS... just need this little modification but couldn't find anything by myself.
<!doctype html>
<head>
<meta name="author" content="puravidaapps.com">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<!--Import materialize.css-->
<link type="text/css" rel="stylesheet" href="materialize.min.css" media="screen,projection"/>
<title>Table Layout</title>
</head>
<body>
<div id="myTable"></div>
<script>
// if you have commas inside your text, feel free to use another delimiter, for example |
var delimiter = ",";
// get the table to display from the window.AppInventor object and split at new line
var urlArray = window.AppInventor.getWebViewString().split("\n");
//var urlArray = location.search.slice(1).split("/n");
var doc = document;
var fragment = doc.createDocumentFragment();
var thead = doc.createElement("thead");
var tr = doc.createElement("tr");
// split at delimiter
var rowArray = urlArray[0].split(delimiter);
addRow(thead, "th");
fragment.appendChild(thead);
var tbody = doc.createElement("tbody");
for(i=1;i<urlArray.length;i++){
var tr = doc.createElement("tr");
// split at delimiter
var rowArray = urlArray[i].split(delimiter);
tr.addEventListener ("click", function () {
// return index (add 1 because first row is the header row)
// window.document.title = this.rowIndex + 1;
window.AppInventor.setWebViewString(this.rowIndex + 1);
});
addRow(tbody, "td");
}
fragment.appendChild(tbody);
var table = doc.createElement("table");
table.appendChild(fragment);
doc.getElementById("myTable").appendChild(table);
// http://stackoverflow.com/a/9236195/1545993
doc.getElementById("myTable").getElementsByTagName('table')[0].className = "striped";
function addRow(dom, tag) {
for(j=0;j<rowArray.length;j++){
var el = doc.createElement(tag);
el.innerHTML = rowArray[j];
tr.appendChild(el);
dom.appendChild(tr);
}
}
</script>
</body>
</html>