How can I add an element created in Javascript to innerHTML - javascript

const totalBill = document.querySelector(".total-bill");
let errorDiv = document.querySelector(".error");
function isValid(e) {
if (totalBill.value.trim().length == 0) {
let para = document.createElement("div");
para.innerText = "Please enter the total amount of bill";
// para.classList.add("bill-para");
para.setAttribute('class', 'bill-error')
console.log(para);
errorDiv.innerHTML = para;
}
e.preventDefault();
}
HTML:
<div class="container">
<div class="error">
</div>
<div class="box-container">
<h1 class="heading">TIP CALCULATOR</h1>
<form action="">
<div class="box">
<label>How much was your bill?</label><br>
<input type="number" placeholder="Total Bill" class="total-bill">
</div>
</form>
</div>
So I am trying to add a div in div.error section and I want to add div named div.bill-error but whenever I am trying to replace the innerHTML and run the code. It shows me '[Object HTMLDivElement]' instead of "Please enter the total amount of bill". But in the console I see that the div is created. But it is not inserted inside
Can anyone tell me where is the problem and solution. Thanks a lot.

Use errorDiv.appendChild(para);, or, if you want to delete existing content in errorDiv first, then errorDiv.textContent = ''; errorDiv.appendChild(para);.

Have you tried, replace
errorDiv.innerHTML = para;
with
errorDiv.append(para);

use appendChild() , I modified your code, here's the snipppet :
const totalBill = document.querySelector(".total-bill");
let errorDiv = document.querySelector(".error");
function isValid(e) {
if (totalBill.value.trim().length == 0) {
let para = document.createElement("div");
para.innerHTML = "Please enter the total amount of bill";
// para.classList.add("bill-para");
para.setAttribute('class', 'bill-error')
errorDiv.appendChild(para);
}
}
<div class="container">
<div class="error">
</div>
<div class="box-container">
<h1 class="heading">TIP CALCULATOR</h1>
<form action="">
<div class="box">
<label>How much was your bill?</label><br>
<input type="number" placeholder="Total Bill" class="total-bill">
</div>
<button type="button" onclick="isValid();">Check</button>
</form>
</div>

Related

document.getElementById('input').value Returns an empty string

I'm trying to make a button that when clicked adds an input tag to the page and gives it an id. The code to get the id is stored in an object. The code looks like this:
document.getElementById('signup-students-input' + currentInputTagNumber ).value
Then the code is ran through an eval function like so
console.log (eval(theObject.getInfo()))
And the eval creates this code
document.getElementById('input-3').value
However, this returns an empty string in the console and using an alert function.
I've attached a code snippet below:
var newStudentBtn = document.getElementById ("new-student");
var students = document.getElementById ("students");
var signupStudents = 1;
var cost = document.getElementById ("cost");
var confiredStudent = "";
let ids = new Object ();
ids.idNames = "";
ids.getInfo = function () {
return this.idNames;
};
var newStudentBtnOnClick = function () {
signupStudents++;
let newStudent = document.createElement ("input");
newStudent.placeholder="Type your child's first and last name here";
newStudent.id = "signup-students-input" + signupStudents;
let newStudentHeading = document.createElement ("h3");
let studentNewLine = document.createElement ("br");
newStudentHeading.innerHTML = "Child (" + signupStudents + ") First and Last Name";
students.appendChild (newStudentHeading)
students.appendChild (newStudent);
cost.innerHTML = signupStudents*39
if (signupStudents === 2) {
ids.idNames += "document.getElementById(" + "'signup-students-input' + signupStudents " + ").value "
}
else {
ids.idNames += "+ document.getElementById ('signup-students-input' + signupStudents).value "
}
console.log (ids.getInfo())
console.log (eval(ids.getInfo()))
};
newStudentBtn.addEventListener ("click", newStudentBtnOnClick);
<div class="nav-bar">
<nav>
<img src="img_2.jpg" class="nav-img">
<div class="nav-options">
<button class="nav-option">About Us</button>
<button class="nav-option">Classes</button>
<button class="nav-option">Contact Us</button>
</div>
</nav>
</div>
<div class="welcome">
<h1>Signup for the Intermedite Class</h1>
</div>
<div class="info-content">
<div class="diveder"><h2>Please fill out the form</h2></div>
<div class="info-content-blocks">
<form>
<div id="students">
<h3>Parent First and Last Name</h3>
<input placeholder="Type your first and last name here" required id="parent-name">
<h3>Child (1) First and Last Name</h3>
<input placeholder="Type your child's first and last name here" required class="student-names" id="student-1-name">
</div>
<br><br><button class="standard-button" id="new-student" type="button">New Student</button><br><br>
<h3>Parent Email Address</h3>
<input placeholder="Type your email address here" required id="email">
<h3>Parent Phone Number (For Emgerency Contact Only)</h3>
<input placeholder="Type your phone number here" required id="phone">
<p>Please pay $<span id="cost">39</span> cash after your childs first class.</p>
<button class="standard-button" type="submit" id="send-btn">Enroll</button>
</form>
</div>
</div>
</div>
I think the problem is that you are adding a string to ids.idNames instead of the variable signupStudents. I also changed the id of the default input from "student-1-name" to "signup-students-input1" and changed the ids.idNames default value. Here's a demo:
var newStudentBtn = document.getElementById ("new-student");
var students = document.getElementById ("students");
var signupStudents = 1;
var cost = document.getElementById ("cost");
var confiredStudent = "";
let ids = new Object ();
// changed this line
ids.idNames = "document.getElementById('signup-students-input1').value";
ids.getInfo = function () {
return this.idNames;
};
var newStudentBtnOnClick = function () {
signupStudents++;
let newStudent = document.createElement ("input");
newStudent.placeholder="Type your child's first and last name here";
newStudent.id = "signup-students-input" + signupStudents;
let newStudentHeading = document.createElement ("h3");
let studentNewLine = document.createElement ("br");
newStudentHeading.innerHTML = "Child (" + signupStudents + ") First and Last Name";
students.appendChild (newStudentHeading)
students.appendChild (newStudent);
cost.innerHTML = signupStudents*39
/* changed these lines */
ids.idNames += "+ document.getElementById('signup-students-input" + signupStudents + "').value";
console.log (ids.getInfo())
console.log (eval(ids.getInfo()))
};
newStudentBtn.addEventListener ("click", newStudentBtnOnClick);
<div class="nav-bar">
<nav>
<img src="img_2.jpg" class="nav-img">
<div class="nav-options">
<button class="nav-option">About Us</button>
<button class="nav-option">Classes</button>
<button class="nav-option">Contact Us</button>
</div>
</nav>
</div>
<div class="welcome">
<h1>Signup for the Intermedite Class</h1>
</div>
<div class="info-content">
<div class="diveder"><h2>Please fill out the form</h2></div>
<div class="info-content-blocks">
<form>
<div id="students">
<h3>Parent First and Last Name</h3>
<input placeholder="Type your first and last name here" required id="parent-name">
<h3>Child (1) First and Last Name</h3>
<!-- this line changed -->
<input placeholder="Type your child's first and last name here" required class="student-names" id="signup-students-input1">
</div>
<br><br><button class="standard-button" id="new-student" type="button">New Student</button><br><br>
<h3>Parent Email Address</h3>
<input placeholder="Type your email address here" required id="email">
<h3>Parent Phone Number (For Emgerency Contact Only)</h3>
<input placeholder="Type your phone number here" required id="phone">
<p>Please pay $<span id="cost">39</span> cash after your childs first class.</p>
<button class="standard-button" type="submit" id="send-btn">Enroll</button>
</form>
</div>
</div>
</div>

A question about usage of cloneNode and insertBefore

I am trying to learn some javascript in web programming. Starting with a simple school registration webpage: the webpage allows to dynamically create any number of grades by clicking "Grade+" button; under each grade, any number of students can be created by clicking "Student+" button. "Grade+" button works as expected, however clicking "Student+" button does not present the student information, not sure what is happening. Any help will be highly appreciated. Thanks in advance.
The reference codes:
<!DOCTYPE html>
<html>
<body>
<div>
<label>Registration</label>
<div class="form-inline justify-content-center" id="school" style="display:none">
<label for="fname">Grade:</label>
<input type="text" id="grade" name="Grade"><br><br>
<div id="students">
<div id="student">
<label for="fname">First:</label>
<input type="text" id="first" name="First"><br><br>
<label for="lname">Last:</label>
<input type="text" id="last" name="Last"><br><br>
</div>
<div class="text-center" id="add_student">
<span id="idStudentRootCopy">----S----</span>
<button type="button" onclick="addItem('student', 'idGradeRootCopy', false)">Student+</button>
</div>
</div>
</div>
<div class="text-center" id="add_grade">
<span id="idGradeRootCopy">----G----</span>
<button type="button" onclick="addItem('school', 'idGradeRootCopy', true)">Grade+</button>
</div>
</div>
<script>
var count = 0;
function addItem(id, index, root) {
var original = document.getElementById(id);
var before = document.getElementById(index);
var clone = original.cloneNode(true);
clone.style.display='block';
clone.id = id + ++count;
var newFields = clone.childNodes;
for (var i = 0; i < newFields.length; i++) {
var fieldName = newFields[i].name;
if (fieldName)
newFields[i].name = fieldName + count;
}
if (root) {
original.parentNode.insertBefore(clone, before.parentNode);
} else {
original.insertBefore(clone, before);
}
}
</script>
</body>
</html>
If you open up the developer tools of your browsers and click the Student+ button you'll get an error message like:
Uncaught DOMException: Node.insertBefore: Child to insert before is
not a child of this node
So you're actually trying to put the cloned node into the wrong spot. Either way things are a bit confusing. Let's say you have clicked the Grade+ button three times and now you decide to click on Student+ of the first clone - how should it know where to put the student as there are three grades?
Well there's a fix of course. Each Student+ button is a child of an unique clone of the school <div> which you also gave an unique id yet (school1, school2,...). So if you pass the addItem() function a reference to the button you actually clicked, we can get it's parent div like:
clickedElement.parentNode.parentNode.parentNode
and add the cloned node using appendChild() instead of insertBefore().
Here's an example (just click on 'Run code snippet'):
var count = 0;
function addItem(id, index, root, clickedElement) {
var original = document.getElementById(id);
var before = document.getElementById(index);
var clone = original.cloneNode(true);
clone.style.display = 'block';
clone.id = id + ++count;
var newFields = clone.childNodes;
for (var i = 0; i < newFields.length; i++) {
var fieldName = newFields[i].name;
if (fieldName)
newFields[i].name = fieldName + count;
}
if (root) {
original.parentNode.insertBefore(clone, before.parentNode);
} else {
clickedElement.parentNode.parentNode.parentNode.appendChild(clone);
}
}
<div>
<label>Registration</label>
<div class="form-inline justify-content-center" id="school" style="display:none">
<label for="fname">Grade:</label>
<input type="text" id="grade" name="Grade"><br><br>
<div id="students">
<div id="student">
<label for="fname">First:</label>
<input type="text" id="first" name="First"><br><br>
<label for="lname">Last:</label>
<input type="text" id="last" name="Last"><br><br>
</div>
<div class="text-center" id="add_student">
<span id="idStudentRootCopy">----S----</span>
<button type="button" onclick="addItem('student', 'idGradeRootCopy', false,this)">Student+</button>
</div>
</div>
</div>
<div class="text-center" id="add_grade">
<span id="idGradeRootCopy">----G----</span>
<button type="button" onclick="addItem('school', 'idGradeRootCopy', true,this)">Grade+</button>
</div>
</div>
Update
If you click on the Grade+ button, it will automatically also 'create' a student input field as it's div is part of the school div. So move it out of the school div and change it's display mode to none.
If you want the new student input field to appear right before the Student+ button, we indeed need to use .insertBefore().
Here's the modified example:
var count = 0;
function addItem(id, index, root, clickedElement) {
var original = document.getElementById(id);
var before = document.getElementById(index);
var clone = original.cloneNode(true);
clone.style.display = 'block';
clone.id = id + ++count;
var newFields = clone.childNodes;
for (var i = 0; i < newFields.length; i++) {
var fieldName = newFields[i].name;
if (fieldName)
newFields[i].name = fieldName + count;
}
if (root) {
original.parentNode.insertBefore(clone, before.parentNode);
} else {
clickedElement.parentNode.insertBefore(clone, clickedElement);
}
}
<div>
<label>Registration</label>
<div id="student" style="display:none">
<label for="fname">First:</label>
<input type="text" id="first" name="First"><br><br>
<label for="lname">Last:</label>
<input type="text" id="last" name="Last"><br><br>
</div>
<div class="form-inline justify-content-center" id="school" style="display:none">
<label for="fname">Grade:</label>
<input type="text" id="grade" name="Grade"><br><br>
<div id="students">
<div class="text-center" id="add_student">
<span id="idStudentRootCopy">----S----</span>
<button type="button" onclick="addItem('student', 'idStudentRootCopy', false,this)">Student+</button>
</div>
</div>
</div>
<div class="text-center" id="add_grade">
<span id="idGradeRootCopy">----G----</span>
<button type="button" onclick="addItem('school', 'idGradeRootCopy', true,this)">Grade+</button>
</div>
</div>

How can I validate multiple grouped inputs?

I've this structure here:
<div>
<div class="row">
<input id="1a">
<input id="1b">
</div>
<div class="row">
<input id="2a">
<input id="2b">
</div>
<div class="row">
<input id="3a">
<input id="3b">
</div>
<div class="row">
<input id="4a">
<input id="4b">
</div>
</div>
If the user leaves everything empty, there is no problem. But when he enters for example something into 1a and leaves 1b empty, this should cause an error. So how can I find out if a & b is filled for each row? It's a bit tricky and I have no idea how to deal with this.
You can achieve it in this simple way
$('button').on("click", () => {
$('body').find(".row").each(function(index, row){
var count = 0;
$(row).find("input").each(function(i, input) {
if($(input).val() !== "")
count++;
})
if(count === 1)
alert("Row " + (index + 1) + " is invalid");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="row">
<input id="1a">
<input id="1b">
</div>
<div class="row">
<input id="2a">
<input id="2b">
</div>
<div class="row">
<input id="3a">
<input id="3b">
</div>
<div class="row">
<input id="4a">
<input id="4b">
</div>
</div>
<button>Check</button>
something like that ?
const inRow = document.querySelectorAll('.row')
, valida = document.querySelector('button')
, respon = document.querySelector('output')
;
valida.onclick =_=>
{
let OK = true
inRow.forEach(eR=>
{
let vals = 0
eR.querySelectorAll('input').forEach(eI=>{ vals+=eI.value.length ? 1:0 })
if (vals===1) OK=false
})
respon.value = OK ? 'OK' : 'bad'
}
<div>
<div class="row"> <input id="1a"> <input id="1b"> </div>
<div class="row"> <input id="2a"> <input id="2b"> </div>
<div class="row"> <input id="3a"> <input id="3b"> </div>
<div class="row"> <input id="4a"> <input id="4b"> </div>
</div>
<button>validate</button> <output></output>
Normally multiple form controls (ex <input>, <textarea>, <select>, etc) should be inside a <form> tag. Moreover, the behavior described is called form validation which requires said <form> tag to be triggered by a "submit" event.
The following demo features proper HTML
<form> and <fieldset> instead of <div>
added <output> for each <fieldset>
Also the JavaScript is designed to show a message when any pair of <input> has a .value and the other doesn't.
The message: <output>Complete data input</output>
This pseudo-form validation is triggered whenever a user enters data within an <input> and then clicks (aka "blur" event). This entire chain of actions combined is the "change" event.
The <form> tag is registered to the "change" event so if any of the <input> within the <form> is the event origin (aka event.target - the <input> that the user triggers a "change" event on).
const form = document.forms[0];
form.onchange = reqData;
function reqData(event) {
let origin = event.target;
if (origin.tagName === 'INPUT') {
const parent = origin.parentElement;
const output = parent.querySelector('output');
const inputs = [...parent.querySelectorAll('input')];
let total = inputs.length;
let count = 0;
for (let input of inputs) {
if (input.value) {
count++;
}
}
if (count < total && count > 0) {
output.style.opacity = '1';
} else {
output.style.opacity = '0';
}
}
return false;
}
output {
opacity: 0;
color: tomato
}
<form>
<fieldset>
<input><br>
<input> <output>Complete data input</output>
</fieldset>
<fieldset>
<input><br>
<input> <output>Complete data input</output>
</fieldset>
<fieldset>
<input><br>
<input> <output>Complete data input</output>
</fieldset>
<fieldset>
<input><br>
<input> <output>Complete data input</output>
</fieldset>
</form>

how dynamically add new button by javascript

I have two textboxes and one button,
I want to add one new textfield, that should show card name from textbox1 and Link URL append from textbox2 when I click on button
//AddnNewCardNavigator
var counter=2;
var nmecardtxt= document.getElementById("textbox1").value;
var linkurltxt= document.getElementById("textbox2").value;
$("#addbutton").click(function(){
if(nmecardtxt ==""||nmecardtxt ==0||nmecardtxt ==null
&& linkurltxt ==""||linkurltxt ==""|| linkurltxt ==0||linkurltxt ==null){
alert("Please insert value in Card name and Link Url textboxes and must be correct");
return false;
}
var NewCarddiv = $(document.createElement('div')).attr("id",'cardlink'+counter);
NewCarddiv.after().html()
})
</script>
<!-- text boxes-->
<div class="row">
<div class="col-md-12">
<div id="textboxesgroup">
<div id="textboxdiv1">
<label style="color:blanchedalmond">Card Name: </label><input type="textbox" id="textbox1">
</div>
<div id="textboxdiv2">
<label style="color:blanchedalmond">Link Url:    </label><input type="textbox" id="textbox2">
</div>
</div>
</div>
</div>
Your variables nmecardtxt and linkurltxt must be created inside the click function,
because it's empty at the loading of the page.
I also took the liberty to use jQuery for that variables, as you're already using it, and tried to enhance some other things:
(See comments in my code for details)
//AddnNewCardNavigator
var counter = 2;
// On click function
$("#addbutton").click(function() {
// Here it's better
var nmecardtxt = $("#textbox1").val();
var linkurltxt = $("#textbox2").val();
// Modified you test here
if (!nmecardtxt || !linkurltxt) {
alert("Please insert value in Card name and Link Url textboxes and must be correct");
return false;
}
// Modified creation of the card
var link = $(document.createElement('a')).attr("href", linkurltxt).html(linkurltxt);
var NewCarddiv = $(document.createElement('div')).attr("id", 'cardlink' + counter).html(nmecardtxt + ": ").append(link);
$('#cards').append(NewCarddiv);
//NewCarddiv.after().html(); // Was that line an attempt of the above ?
});
body {
background: #888;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- text boxes-->
<div class="row">
<div class="col-md-12">
<div id="textboxesgroup">
<div id="textboxdiv1">
<label style="color:blanchedalmond">Card Name: </label><input type="textbox" id="textbox1">
</div>
<div id="textboxdiv2">
<label style="color:blanchedalmond">Link Url:   </label><input type="textbox" id="textbox2">
</div>
</div>
</div>
</div>
<!-- Added the below -->
<div id="cards">
</div>
<button id="addbutton">Add…</button>
Hope it helps.
Here's a simplified version of what you're trying to accomplish:
function addNewCard() {
var name = $('#name').val();
var url = $('#url').val();
var count = $('#cards > .card').length;
if (!name || !url) {
alert('Missing name and/or URL.');
}
var card = $('<div class="card"></div>').html("Name: " + name + "<br>URL: " + url);
$("#cards").append(card);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<label for="url">URL:</label>
<input type="text" id="url" name="url">
<input type="submit" value="Add Card" onclick="addNewCard();">
<div id="cards">
</div>

jQuery fadeIn div when input is in focus?

I'm trying to change the innerHTML of a div and fade it in when a input in my form comes into focus. I also want to test whether or not it's been faded in at all because when the page loads it will begin faded out.
To summarize, I essentially want to display a tooltip in another div and switch the tooltip with fading in and out as my inputs come into focus on my form.
Here's what I have so far:
<script type="text/javascript">
var visible = 0;
var nameText = "<p>May I get your<br/>full name?</p>";
var emailText = "<p>Could I please<br/>get your email<br/>address?</p>";
var messageText = "<p>What is the<br/>message you<br/>would like to send?</p>";
$('.inp').on("focus", function(event){
if (visible == 0)
{
var fadeTime = 1;
visible = 1;
}
else
fadeTime = 500;
$('bubble').fadeOut(fadeTime).html(function() {
if ($this.attr('id') == "name")
return nameText;
else if ($this.attr('id') == "email")
return emailText;
else if ($this.attr('id') == "message")
return messageText;
}).fadeIn(500);
});
</script>
I'm not receiving any JavaScript errors. My HTML for my bubble and inputs looks like this:
<footer class="container">
<div class="row reveal">
<div class="mailman fourcol">
<img src="images/mailman.png" alt="The Mail Man" />
<div id="bubble">
</div>
</div>
<div class="contact eightcol last">
<h1>CONTACT US FOR</h1> <h1>MORE INFORMATION</h1>
<div class="clear"></div>
<form name="contact-form">
<div class="form-left">
<div class="contact-name inp">
<input type="text" name="name" id="name" value="Name" />
</div>
<div class="contact-email inp">
<input type="text" name="email" id="email" value="Email" />
</div>
<div class="clear"></div>
<div class="contact-message inp">
<input type="text" name="message" id="message" value="Message" />
</div>
</div>
<div class="contact-submit">
</div>
</form>
</div>
</div>
</footer>
I did some fix to you. Check the demo.
The main problems are:
focus event should be fired on input element, $('.inp').on("focus", function(event){ should be $('.inp').on("focus", 'input', function(event){
$this.attr(id), you missed var $this = $(this); outside, or just use var id = this.id;.
$('bubble') should be $(#bubble)

Categories

Resources