Generate a New HTML Document with Javascript - javascript

Ok, so all I want to do is : whenever I write something in the Input and press the Button, a new HTML page gets created. But I also want to set the page's name and location. Tried searching it, couldn't find any results...
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Books test</title>
<link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v3.0.1/dist/mini-default.min.css">
</head>
<body>
<input type="text" id="book-input">
<button id="book-button">Create a book</button>
<h1>All the books</h1>
<ul id="books-list"></ul>
<script src="/app.js" defer></script>
</body>
</html>
Javascript
const bookNameInput = document.getElementById("book-input");
const bookCreateButton = document.getElementById("book-button");
var bookName;
var bookId;
bookCreateButton.addEventListener('click', createBook);
function generateRandomNumber() {
var randomNumber = Math.floor(1000000000 + Math.random() * 900000000);
var rn = randomNumber.toString();
return rn;
}
function createBook() {
bookName = bookNameInput.value;
bookId = generateRandomNumber();
fbn = bookName + '_' + bookId
var bookLi = document.createElement("li");
bookLi.classList.add("book-li")
var bookLiA = document.createElement("a");
bookLiA.innerText = bookName;
bookLiA.href = fbn + ".html";
document.getElementById("books-list").appendChild(bookLi);
bookLi.appendChild(bookLiA);
bookNameInput.value = "";
}
Tried using :
const newDoc = document.implementation.createHTMLDocument(title)
But doesn't creates any page...

I already answered your question in comments, so I'm writing this down as a answer so it might be helpful for others too.
So as i was saying it is totally possible to save the file directly from the client side without any need of server or special file system permission on client side -
In Short You can do something like this, Follow this step-by-step -
Get the value of the text input using input.value
Create a Blob out of It
Create a DOM element of anchor element with download attribute
Convert the Blob to an URL Using URL.createObjectURL and Chane the href of previously created anchor element to the returning url
Click on the anchor element without appending it to the DOM
Here is the Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Generate HTML Page</title>
<style>
* {
padding: 0;
box-sizing: border-box;
margin: 0;
}
</style>
</head>
<body style="padding: 20px">
<textarea
placeholder="Enter Your Content Here"
style="width: 100%; height: 500px; font-size: 18px; padding: 18px"
></textarea>
<br /><br />
<button>Download Text as HTML page</button>
<script>
let btn = document.querySelector("button");
let text = document.querySelector("textarea");
btn.addEventListener("click", () => {
if (!/^\s*$/.test(text.value)) {
let a = document.createElement("a");
a.setAttribute("download", "download.html");
let blob = new Blob(text.value.split(""));
let url = URL.createObjectURL(blob);
a.href = url;
a.click();
text.value = "";
} else {
alert("Blank text");
text.value = "";
}
});
</script>
</body>
</html>

Related

Replace HTML Tag and it's content with JS

I don't know quite anything about JS so i need your help. I've just searched on internet but i didn't found anything about what i will ask you. I need to change an html tag and all it's content and i think that the best way to do this could be JS. For example:
I need that the tag
<p id="usernameText">My Username</p>
will be changed with this
<input type="text" name="uname" id="uname" placeholder="Inserire qui l\'username" style="width:100%">
with the click of an item so i think that i should use onclick="myfunction()", but i don't have any idea where to start with the JS code! There's someone who can help me please?
<!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>Document</title>
</head>
<body>
<div id="div1">
<p id="toggleItem">My Username</p>
<button onclick="onClick()">Toggle</button>
</div>
<script>
const onClick = () => {
const div1 = document.getElementById("div1");
const toggleItem = document.querySelector("#toggleItem");
if (toggleItem.tagName === "INPUT") {
const p = document.createElement("p");
p.innerText = "Username";
p.id = "toggleItem";
div1.appendChild(p);
} else {
const input = document.createElement("input");
input.name = "uname";
input.placeholder = "Username";
input.type = "text";
input.id = "toggleItem";
div1.appendChild(input);
}
toggleItem.remove();
};
</script>
</body>
</html>
I've found an easyest way, i have multiple elements to change so ive added also some var
function edit(id, type, name, placeholder){
var element = document.getElementById(id);
var final = document.createElement('td');
final.innerHTML = '<input type="'+type+'" name="'+name+'" id="'+name+'"
placeholder="Inserire qui '+placeholder+'" style="width:100%">';
element.parentNode.replaceChild(final, element);
}
and in html i've made like this:
<td id="indirizzoText">
<p>Address<i class="fas fa-pen" onClick="edit('indirizzoText', 'text', 'indirizzo', 'l\'indirizzo')"></i>
</p>
</td>
I've used a wrong way?

My EDIT button is not working properly? (Javascript Todo List) Beginner

I am a beginner in Javascript and is currently trying to make a todo list web app. But currently stucked at the edit button.
As you can see, I wanted to make an editable checklist but somehow everytime I hit the edit button, a new input comes out instead of replacing the current one. It also removes the 'checkbox' somehow.
Can anyone tell me where I did wrong? Thank you for your time!
Somehow the edit button doesn't work at all when I try to run it on VSCode. Here it works, but not as I wanted though.
const ul = document.querySelector('#invitedList');
ul.addEventListener('click', (event) => {
if(event.target.tagName === 'BUTTON') {
const button = event.target;
const li = button.parentNode;
if(button.textContent === 'edit') {
const span = li.firstElementChild;
const input = document.createElement('input');
input.type = 'text';
input.value = span.textContent;
li.insertBefore(input, span);
li.removeChild(span);
button.textContent = 'save';
} else if(button.textContent === 'save') {
const input = li.firstElementChild;
const span = document.createElement('span');
span.textContent = input.value;
li.insertBefore(span, input);
li.removeChild(input);
button.textContent = 'edit';
}
}
});
<!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>Document</title>
<script src="test.js"></script>
</head>
<body>
<!-- TASK LIST THAT IS SUPPOSED TO BE EDITABLE GOES DOWN HERE, AS A TEMPLATE -->
<div id="taskit" class="task">
<ul id="invitedList">
<input type="checkbox"/>
<label>
<span id="editable" class="custom-checkbox">Edit This</span>
</label>
<button type="submit" id="editbtn">edit</button>
</ul>
</div>
</body>
</html>
Have you considered trying Node.ReplaceChild() instead of creating a new element? Not sure how to tell you exactly how to do it but here is a link to the documentation:
https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild
I'd suggest to change styling instead of creating and removing elements. Here is possible solution:
let isEditState = false;
const editButton = document.querySelector('#editbtn');
editButton.addEventListener('click', (event) => {
const span = document.querySelector('#editable');
const checkbox = document.querySelector('#checkbox');
const text = document.querySelector('#text');
if (isEditState) {
span.innerText = text.value;
checkbox.style.display = 'inline';
text.style.display = 'none';
editButton.innerText = 'edit';
} else {
checkbox.style.display = 'none';
text.style.display = 'inline';
editButton.innerText = 'save';
}
isEditState = !isEditState;
});
<!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>Document</title>
</head>
<body>
<div id="taskit" class="task">
<ul id="invitedList">
<input type="checkbox" id="checkbox"/>
<input type="text" id="text" style="display: none"/>
<label>
<span id="editable" class="custom-checkbox">Edit This</span>
</label>
<button type="submit" id="editbtn">edit</button>
</ul>
</div>
</body>
</html>

cannot change css property of desired amount of elements using eventListener due to elements being created by javascript

I am attempting to change the backgroundColor of "gridElement" once "button" is clicked.
What was attempted, changing the way the elements are created to later include the event:
cloneNode() // doesn't work with eventListeners unless you use eventDelegation, in this case there is no parentElement to delegate the event too.
jQuery.clone() // the event is not tied directly to "gridElement" rather it is tied to "button" so jQuery.clone() would not be deep copying any associated events.
Also, attempting to make references to all gridElements:
used window.globalVarRef = localVar. // only references the first element and not all.
How can I modify the code so that the eventListener will change all "gridElement" and not just the first?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="CSS/main.css">
<title> Method 1 // appendChild() </title>
</head>
<body>
<div id="container">
<div id="gridContainer"></div>
</div>
<script>
const gridContainer = document.getElementById('gridContainer');
function createPixels(){
let pixels = 256;
for(let k=0;k<pixels;k++) {
const gridElement = document.createElement('div');
gridElement.classList.add('gridElement');
gridContainer.appendChild(gridElement);
window.allGridElements = gridElement;
}
}
createPixels();
const button = document.createElement('button');
button.classList.add('button');
button.textContent = 'button';
gridContainer.appendChild(button);
function changeBkg(){
window.allGridElements.style.backgroundColor = 'blue';
}
button.addEventListener('click', changeBkg);
</script>
</body>
</html>
The problem lies in your changeBkg function. To select all of the elements with the class of "gridElement", you want to use a for loop to find those elements and then change their styles. I added some basic css to the grid element so we can see the color change in action. Does that solve your issue?
.gridElement {
width: 100px;
height: 100px;
background: red;
display: inline-block;
margin-right: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="CSS/main.css">
<title> Method 1 // appendChild() </title>
</head>
<body>
<div id="container">
<div id="gridContainer"></div>
</div>
<script>
const gridContainer = document.getElementById('gridContainer');
function createPixels(){
let pixels = 256;
for(let k=0;k<pixels;k++) {
const gridElement = document.createElement('div');
gridElement.classList.add('gridElement');
gridContainer.appendChild(gridElement);
window.allGridElements = gridElement;
}
}
createPixels();
const button = document.createElement('button');
button.classList.add('button');
button.textContent = 'button';
gridContainer.appendChild(button);
function changeBkg(){
var items = document.getElementsByClassName('gridElement');
for (let i=0; i < items.length; i++) {
items[i].style.backgroundColor = 'blue';
}
}
button.addEventListener('click', changeBkg);
</script>
</body>
</html>

Keep body scrolled at the bottom unless user scrolls up in javascript

I have a program where the user types in something and then something outputs in the "console." The most recent entered thing stays at the bottom unless the user scrolls up
The body of my document seems to be where I can dd effects like hidden scroll to it. I read another post and used scrollTop and scrollHeight and it is not working.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href = "style.css">
</head>
<body id = "scroll">
<div id="game">
<div id="console">
</div>
</div>
<div id = "command-box">
<div id = "cmd">
<input id = "command" onkeypress = "doAThing(event);">
</div>
</div>
</div>
<script src = "variables.js"></script>
<script src = "code.js"></script>
</body>
</html>
var input = document.querySelector("#command");
var theConsole = document.querySelector("#console");
theConsole.scollTop = theConsole.scrollHeight;
var myScroll = document.getElementById("scroll");
function doAThing(event) {
var theKeyCode = event.keyCode;
if(theKeyCode === 13) acceptCommand();
setInterval(scrollUpdate, 1000);
}
function scrollUpdate() {
myScroll.scrollTop = myScroll.scrollHeight;
}
function acceptCommand() {
var p = document.createElement("p");
if(input.value === "hi") theConsole.append("Hi!", p);
if(input.value === "ping") theConsole.append("Pong!", p);
}

After a button is clicked/form submit, the CSS stylesheet doesn't appear

After the use button is clicked, the sources when I inspect the page show that the style.css page goes away, and no styles are applied. I can't figure out why this is happening.
My index.html page looks like this:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#400;500&family=Roboto:wght#100;300;400;700&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<input type="text" placeholder="First name" class="fname">
<input type="submit" value="Use" class="submit">
<script src="app.js"></script>
</body>
</html>
And my app.js is this:
const useBtn = document.querySelector('.submit');
const reloadBtn = document.querySelector('.btn__reload')
document.body.style.fontFamily = "Roboto;"
useBtn.addEventListener('click', function(){
let person = document.querySelector('.fname').value;
document.write(`<h2>It's ${person}'s turn!</h2>`)
document.write(`<h4>How long will they live?</h4>`)
let oldAge = `<p>${Math.floor((Math.random() * 10)+ 30)}</p>`
document.write(oldAge)
document.write(`<h4>What will be their yearly salary?</h4>`)
let salary = `<p>${Math.floor(Math.random() * 10000)}</p>`
document.write(salary)
document.write(`<h4>What will be their career</h4>`)
const jobs = [ 'plumber', 'doctor', 'witch', 'president', 'trump supporter']
let job = Math.floor(Math.random() * jobs.length)
document.write(jobs[job])
redoBtn();
})
function redoBtn(){
let tryAgain = document.createElement('button')
document.body.appendChild(tryAgain)
let buttonText = document.createTextNode('Try Again')
tryAgain.appendChild(buttonText)
tryAgain.addEventListener('click', function(){
window.location.href = window.location.href;
})
}
Any help is so appreciated!
Your document.write is overwriting all your html, including your linked stylesheet.
From https://developer.mozilla.org/en-US/docs/Web/API/Document/write:
Note: as document.write writes to the document stream, calling document.write on a closed (loaded) document automatically calls document.open, which will clear the document.
If you really want to use document.write, you'll need to rewrite your stylesheet link into the new document. But it might be better to just replace the html of some container element on your page, like the body element.
Instead of using document.write which overwrites your html you could try this approach:
<input type="submit" value="Use" class="submit">
<!-- add new div to show the result -->
<div id="result"></div>
<script src="app.js"></script>
And in the click event:
useBtn.addEventListener('click', function(){
let person = document.querySelector('.fname').value;
let res = document.getElementById('result');
res.innerHTML = "<h2>It's "+person+"'s turn!</h2>";
// add further information to innerHTML here
// hide input fname and submit button
redoBtn();
})

Categories