I am trying to make a button submit work after I click submit. Currently the problem is that when I click submit, it did redirect me to the corresponding pages but the data from the arrays is not displayed in the html table. I tried adding it manually and it works but when when I tried implementing adding data to array by means of form. It doesn't work. When I tried putting the code addToHTML() outside of the function submitButton(), it works. But when I remove it now, it's not displayed and there are no errors shown. I am wondering what did I do wrong here ? The following are my html and javascript code.
index.html
<!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 rel="stylesheet" href="style.css">
<title>Book Object</title>
</head>
<body>
<h1>Book template</h1>
<form>
<table id="book-table">
<thead>
<tr>
<th> Title </th>
<th> Author </th>
<th> Pages </th>
<th> Read </th>
</tr>
</thead>
<tbody id="tbody">
<tr id="dataContainer"></tr>
</tbody>
</table>
</form>
<a href="addbook.html">
<button id="add-book"> Add Book </button>
</a>
<script type="text/javascript" src="script.js"></script>
</body>
</html>`
script.js
// Main Book object model
function Book(title, author, pages, read) {
this.title = title;
this.author = author;
this.pages = pages;
this.read = read;
}
// Library object model
function Library() {
this.myLibrary = [];
this.addToLibrary = function(myLibrary) {
this.myLibrary.push(myLibrary);
}
}
// Create new book object
let book1 = new Book('Awaken the Giant Within', 'Tony Robbins', '351', 'already read');
let book2 = new Book('Think and Grow Rich', 'Napoleon Hill', '271', 'currently reading');
let book3 = new Book('Rich Dad Poor Dad', 'Robert T. Kiyosaki', '289', 'finish read');
let book4 = new Book('Atomic Habits', 'James Clear', '279', 'finish read');
let book5 = new Book('The Outliers', 'Malcom Gladwell', '311', 'currently reading');
// Create new library object
let library = new Library();
// Add books to the empty array
library.addToLibrary(book1);
library.addToLibrary(book2);
library.addToLibrary(book3);
library.addToLibrary(book4);
library.addToLibrary(book5);
// Function to add main Book to HTML content
function addToHTML() {
for (let i=0; i < library.myLibrary.length ; i ) {
let tbody = document.querySelector('#tbody');
let content =
`<tr>
<td id='title'> ${library.myLibrary[i].title} </td>
<td id='author'> ${library.myLibrary[i].author} </td>
<td id='pages'> ${library.myLibrary[i].pages} </td>
<td id='read'> ${library.myLibrary[i].read} </td>
</tr>`
tbody.innerHTML = content;
}
}
// Submit button
// Add event listener to submit button
function submitButton() {
let submit = document.getElementById('submit');
submit.addEventListener('click', function() {
let jsTitle = document.getElementById('title').value;
let jsAuthor = document.getElementById('author').value;
let jsPages = document.getElementById('pages').value;
let jsRead = document.getElementById('read').value;
let book1 = new Book(jsTitle, jsAuthor, jsPages, jsRead);
library.addToLibrary(book1);
addToHTML();
})
}
addbook.html
<!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">
<title>Add Book Form</title>
<link rel="stylesheet" href="addbookform.css">
</head>
<body onl oad="submitButton()">
<h1>Add Book Form</h1>
<form action='index.html' method='post'>
<p>Title:</p>
<input type='text' name='title' id='title'>
<p>Author: </p>
<input type='text' name='author' id='author'>
<p>Pages:</p>
<input type='text' name='pages' id='pages'>
<p>Read:</p>
<input type='text' name='read' id='read'>
<br/>
<input type='submit' name='submit' value='submit' id='submit'>
</form>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
CodePudding user response:
It's not working because It's sending a POST request when you click the submit button and hence the page refreshes.
You can ignore that behavior by listening to submit event of form input rather than the button click and preventing the default behavior of the form.js
const submitEventHandler = (e) => {
e.preventDefault();
...
}
function submitButton() {
let form = document.getElementById('formid');
form.addEventListener('submit', submitEventHandler)
}
CodePudding user response:
<!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">
<title>Add Book Form</title>
</head>
<body>
<h1>Add Book Form</h1>
<label for="title">Title:</label>
<input type='text' name='title' id='title'>
<label for="author">Author: </label>
<input type='text' name='author' id='author'>
<label for="pages">Pages:</label>
<input type='text' name='pages' id='pages'>
<label for="read">Read:</label>
<input type='text' name='read' id='read'>
<br />
<button onclick="submitButton()" value='submit' id='submit'>
Submit
</button>
<br>
<table id="book-table" border="1">
<thead>
<tr>
<th> Title </th>
<th> Author </th>
<th> Pages </th>
<th> Read </th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</body>
<script>
function submitButton() {
let jsTitle = document.getElementById('title').value;
let jsAuthor = document.getElementById('author').value;
let jsPages = document.getElementById('pages').value;
let jsRead = document.getElementById('read').value;
let tbody = document.getElementById('tbody');
let tr = document.createElement('tr')
let data = `
<td>
${jsTitle}
</td>
<td>
${jsAuthor}
</td>
<td>
${jsPages}
</td>
<td>
${jsRead}
</td>`
tr.innerHTML = data
document.getElementById('tbody').append(tr)
}
</script>
</html>
CodePudding user response:
you need to prevent your browser from the event action, so you you can use preventDefault() function
to ignore the page redirection.
Edit:
I've just used CSS display property to display the form and then hide it on submit, to show the table,
you can use it on your own, so you can include your input at the same page as it supposed to be, also you can use it in a modal instead of use it like that or just add a button to display it upon click
let next = document.querySelector('input[value="next"]');
let subbtn = document.querySelector(`input[value='submit']`)
let newBook = {
jsTitle: '',
jsAuthor: '',
jsPages: '',
jsRead: '',
jsPrice: '',
jsUrl: ''
}
next.addEventListener('click', function(e) {
e.preventDefault();
newBook.jsTitle = document.getElementById('title').value;
newBook.jsAuthor = document.getElementById('author').value;
newBook.jsPages = document.getElementById('pages').value;
newBook.jsRead = document.getElementById('read').value;
document.querySelector('#page1').style = 'display:none'
document.querySelector('#page2').style = 'display:block'
})
subbtn.addEventListener('click', (e) => {
e.preventDefault();
newBook.jsPrice = document.getElementById('price').value;
newBook.jsUrl = document.getElementById('url').value;
document.querySelector('#page2').style = 'display:none'
document.querySelector('#page3').style = 'display:block'
document.querySelector(`tbody`).innerHTML = `<tr>${Object.entries(newBook).map((arr,index) => '<td>' arr[1] '</td>').toString().replaceAll(',','')}</tr>`
})
#page1 {
display:block;
}
#page2 {
display:none;
}
#page3 {
display:none;
}
<div id="page1">
<form action="page.html" method="post">
<input type="text" id='title' placeholder='title' required />
<input type="text" id='author' placeholder='author' required />
<input type="text" id='pages' placeholder='pages' required />
<input type="text" id='read' placeholder='read' required />
<input type="button" value="next" />
</form>
</div>
<div id="page2">
<form action="page.html" method="post">
<input type="text" id='price' placeholder='price' required />
<input type="text" id='url' placeholder='url' required />
<input type="button" value="submit" />
</form>
</div>
<div id="page3">
<table border="1px">
<thead>
<tr>
<th>title</th>
<th>author</th>
<th>pages</th>
<th>read</th>
<th>price</th>
<th>url</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>