implementing insertbefore() in loop - javascript

I am trying to show error messages below an array of textboxes that I have selected using Javascript. The error messages are being put by creating a new span element and using the insertBefore() method. The span element is created in the function since I don't want to hard code it into the DOM. The span messages do show but each time I submit the form, they are appended over and over again. I'd like to show the span messages only once and each time the form is submitted, they are shown once only. Below is my code.
HTML
<div class="slideshow">
<form id="form">
<input type="text" name="1" class="textbox" />
<input type="text" name="2" class="textbox" />
<input type="text" name="3" class="textbox" />
<input type="submit" name="submit" value="submit" id="submit" />
</form>
</div>
JAVASCRIPT
<script>
var slideshow = document.querySelector('.slideshow');
// var span = document.createElement('span');
var form = document.querySelector('#form');
var inputs = form.querySelectorAll('.textbox');
form.addEventListener('submit', function(e)
{
e.preventDefault();
for( var i=0; i<inputs.length; i++ )
{
var span = document.createElement('span');
(function(index)
{
span.innerHTML = 'error ' + index;
inputs[index].parentNode.insertBefore(span, inputs[index].nextElementSibling);
})(i);
}
}, false);
</script>
Each time I submit, I'd like the error messages to be shown below the textbox and not appended over and over again. They should be shown just once and I'd like to do this without using jQuery or any sort of library.

I rewerite your example to create available 3 span tags instead of crate them in code. If there are some errors, populate them to span rather than creating/deleting the spans in code.
var slideshow = document.querySelector('.slideshow');
var form = document.querySelector('#form');
var inputs = form.querySelectorAll('.textbox');
form.addEventListener('submit', function (e) {
e.preventDefault();
for (var i = 0; i < inputs.length; i++) {
(function (index) {
document.getElementsByTagName('span')[index]
.innerHTML = 'error ' + index;
})(i);
}
}, false);
<div class="slideshow">
<form id="form">
<input type="text" name="1" class="textbox" /><span></span>
<input type="text" name="2" class="textbox" /><span></span>
<input type="text" name="3" class="textbox" /><span></span>
<input type="submit" name="submit" value="submit" id="submit" />
</form>
</div>
Hope this help.

Just do a check before you insert. Here is one way to do it.
form.addEventListener('submit', function (e) {
e.preventDefault();
for (var i = 0; i < inputs.length; i++) {
var span = document.createElement('span');
(function (index) {
span.innerHTML = 'error ' + index;
if (inputs[index].nextElementSibling.tagName !== 'SPAN')
inputs[index].parentNode.insertBefore(span, inputs[index].nextElementSibling);
})(i);
}
}, false);

You have to wait for page to be load, the you should run JavaScript.
PageLoad Event : window.onload=function(){}
Code :
<script type="text/javascript">
window.onload = function () {
var slideshow = document.querySelector('.slideshow');
var form = document.getElementById('form');
var inputs = document.querySelectorAll('.textbox');
form.addEventListener('submit', function (e) {
e.preventDefault();
for (var i = 0; i < inputs.length; i++) {
var span = document.createElement('span');
(function (index) {
span.innerHTML = 'error ' + index;
inputs[index].parentNode.insertBefore(span, inputs[index].nextElementSibling);
})(i);
}
}, false);
}
</script>
Put your code in window.onload event.

Related

Reading Text From Dynamic Input Field JavaScript

I have a website where you can enter text into an input field, and press "Add new row" to add another input field.
When the user presses the submit button, I want to be able to read all of the text inside of the text field, but I can't seem to figure out how to access the text within the text fields.
Here is my code:
<head>
<script src = "https://code.jquery.com/jquery-3.3.1.min.js"
crossorigin="anonymous"> </script>
</head>
<script type ="text/javascript">
var array = []
var track = 0;
$(document).on("click", ".btn-add-row", function(){
var row = $(".row").eq(0).clone().show();
$(".element-wrapper").append(row);
var ye = $(".element-wrapper")
})
$(document).on("click", ".btn-remove-row", function(){
var index = $(".btn-remove-row").index(this);
$(".row").eq(index).remove();
})
</script>
<body>
<h1>upload file</h1>
<form method = "post" enctype="multipart/form-data" action = "/">
<input type = "file" name = "filename">
<input type = "submit" value = "upload">
</form>
<div class = "element-wrapper">
<div class = "row" style = "display: none;">
<input type = "text" placeholder = "Attribute" id = "ye">
<button class = "btn-remove-row">
Remove Row
</button>
</div>
</div>
<button class = "btn-add-row"> Add New Row </button>
</body>
</html>
And here is a CodePen to go along with it:
https://codepen.io/etills/pen/qBdEKPV
Would appreciate it if someone could tell me how to read all the text from the input rows when the user presses submit.
I ultimately want to put the text into an array and make a .txt file with that text that is entered.
Thanks
You need this selector to capture only the visible textboxes:
div.row:not([style='display: none;']) input[type=\"text\"]"
Something like this:
$("form").on("submit", function(e) {
e.preventDefault();
var inputs = document.querySelectorAll("div.row:not([style='display: none;']) input[type=\"text\"]");
var len = inputs.length;
for (var i = 0; i < len; i++) {
array.push({
input: i,
value: inputs[i].value
});
}
console.log(array);
});
You'll get this result:
See in this example:
$(function() {
var array = [];
var track = 0;
$(document).on("click", ".btn-add-row", function() {
var row = $(".row").eq(0).clone().show();
$(".element-wrapper").append(row);
var ye = $(".element-wrapper")
});
$(document).on("click", ".btn-remove-row", function() {
var index = $(".btn-remove-row").index(this);
$(".row").eq(index).remove();
});
$("form").on("submit", function(e) {
e.preventDefault();
var inputs = document.querySelectorAll("div.row:not([style='display: none;']) input[type=\"text\"]");
var len = inputs.length;
for (var i = 0; i < len; i++) {
array.push({
input: i,
value: inputs[i].value
});
}
console.log(array);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>upload file</h1>
<form method="post" enctype="multipart/form-data" action="/">
<input type="file" name="filename">
<input type="submit" value="upload">
</form>
<div class="element-wrapper">
<div class="row" style="display: none;">
<input type="text" placeholder="Attribute">
<button class="btn-remove-row">
Remove Row
</button>
</div>
</div>
<button class="btn-add-row"> Add New Row </button>
Remember: Element Id must be unique in a page. Avoid using the same id="ye" in <input type="text" placeholder="Attribute" id="ye">.
On submit check for all the inputs that you want and collect their values.
$(document).on("click", "input[type=submit]", function(e){
e.preventDefault()
$('input[type=text]').each((i, input) => {
console.log(input.value)
})
})
Example: https://codepen.io/jzabala/pen/vYOErpa?editors=1111

Change HTML tag with Javascript

I asking the user to select given emails, and getting them with javascript from a form on click.
If I have an href like
And I have a bunch of checkboxes for every email obtained from the database
Using javascript, how can I add this value into the emails="" tag by clicking the checkbox?
You can listen to change event for each checkbox to keep track of checked emails:
var boxes = document.querySelectorAll('input[name=email]');
var link = document.getElementById('myHref');
var emails = [];
boxes.forEach(box => box.addEventListener('change', function(e) {
var v = e.target.value;
if (e.target.checked === true) {
if (!emails.includes(v)) emails.push(v);
} else {
emails.splice(emails.indexOf(v), 1);
};
link.setAttribute('emails', emails.join(', '));
console.log(link.attributes.emails.value)
}))
<input type="checkbox" value="1#d.com" name="email">
<input type="checkbox" value="2#d.com" name="email">
<input type="checkbox" value="3#d.com" name="email">
Link
You can set a click event on the checkbox.
var arr_el = document.getElementsByClassName('check-boxes');
for(var i = 0; i < arr_el.length; i++){
arr_el[i].addEventListener('click', function(){
var el = document.getElementById('myHref');
var emails = el.getAttribute('emails');
var userSelectedEmail = this.value;
if(this.checked){
el.setAttribute('emails', emails + ';' + userSelectedEmail);
} else {
// debugger;
emails = emails.split(';');
var index = emails.indexOf(userSelectedEmail);
emails.splice(index, 1);
el.setAttribute('emails', emails.join(';'));
}
document.getElementById('emails').innerText = el.getAttribute('emails');
});
}
<html>
<head>
</head>
<body>
<a id="myHref" href="#" emails="test#email.com">Link</a>
<br>
<input class="check-boxes" type="checkbox" value="email2#gmail.com">email2#gmail.com<br>
<input class="check-boxes" type="checkbox" value="email3#gmail.com">email3#gmail.com<br>
<input class="check-boxes" type="checkbox" value="email4#gmail.com">email4#gmail.com<br>
<input class="check-boxes" type="checkbox" value="email5#gmail.com">email5#gmail.com<br>
<p id="emails"></p>
</body>
</html>

Mouseover function on dynamically created list items

I'm working on a simple user input form that has users input their ID, first name, and last name into 3 separate input boxes. My main objective is to get the data input by user, add it to the "person" object, and display to an unordered list. I've figured that much out.
What I'm trying to do now, is somehow style the content of the list item that was dynamically created, using a mouseover function. I have been trying simple color changes, but I'm super rusty with javascript, and must do this without any jQuery. Any help is appreciated. Just need a push in the right direction, can't get mouseover to work at all for some reason.
Here's what I've got so far:
<form>
ID Number:<br>
<input type="text" id="idNumber">
<br>
First name:<br>
<input type="text" name="firstName" id="fName">
<br>
Last name:<br>
<input type="text" name="lastName" id="lName">
</form>
<br>
<button type ="submit" onclick="myFunction(list)">Submit</button>
<div id = "container">
<ul id="list"></ul>
</div>
<script>
function myFunction(list){
var text = "";
var person = {idNo:"", firstName:"", lastName:""};
var inputs = document.querySelectorAll("input[type=text]");
for (var i = 0; i < inputs.length; i++) {
idNo = inputs[0].value;
firstName = inputs[1].value;
lastName = inputs[2].value;
text = " "+idNo+" "+firstName+" "+lastName;
}
var li = document.createElement("li");
li.addEventListener("mouseover", mouseOver, false);
li.addEventListener("click", mouseClick, false);
var node = document.createTextNode(text);
li.appendChild(node);
document.getElementById("list").appendChild(li);
}
function mouseOver(){
li.style.backgroundColor="red";
}
</script>
li is not defined in the function mouseover use this instead -> this.style.backgroundColor = "red";
Variables are defined at function scope therefore var li is available in myFunction but not in mouseover function.
Try this sinppet:
function myFunction(list) {
var text = "";
var person = {
idNo: "",
firstName: "",
lastName: ""
};
var inputs = document.querySelectorAll("input[type=text]");
for (var i = 0; i < inputs.length; i++) {
idNo = inputs[0].value;
firstName = inputs[1].value;
lastName = inputs[2].value;
text = " " + idNo + " " + firstName + " " + lastName;
}
var li = document.createElement("li");
li.addEventListener("mouseover", mouseOver, false);
//li.addEventListener("click", mouseClick, false);
var node = document.createTextNode(text);
li.appendChild(node);
document.getElementById("list").appendChild(li);
}
function mouseOver() {
this.style.backgroundColor = "red";
}
<form>
ID Number:
<br>
<input type="text" id="idNumber">
<br>First name:
<br>
<input type="text" name="firstName" id="fName">
<br>Last name:
<br>
<input type="text" name="lastName" id="lName">
</form>
<br>
<button type="submit" onclick="myFunction(list)">Submit</button>
<div id="container">
<ul id="list"></ul>
</div>
Why use JS when you can use CSS?
JavaScript:
var li = document.createElement("li");
li.classList.add('my-li-class')
CSS:
.my-li-class:hover {
background-color: red;
}
Anyway if you want to know why your JS doesn't work it's because the li variable is defined outside the mouseOver function scope, do this instead:
function mouseOver() {
this.style.backgroundColor = 'red'
}
Or event this (may not work if li has children):
function mouseOver(evt) {
evt.target.backgroundColor = 'red'
}

Sum of values in fields got by change function in form with Javascript

I have form as follows :
<input name="website_charges" id="website_charges" type="text" value="" /><br>
<input name="monthly_fixed_charges" id="monthly_fixed_charges" type="text" value="" />
<input name="members_registered" id="members_registered" type="text" value="" /><br>
<input name="per_member" id="per_member" type="text" value="" /><br>
<input name="member_total_charges" id="member_total_charges" type="text" value="" /><br>
<input name="monthly_sessions" id="monthly_sessions" type="text" value="" /><br>
<input name="per_session" id="per_session" type="text" value="" /><br>
<input name="session_total_charges" id="session_total_charges" type="text" value="" /><br>
<input name="total_dues" id="total_dues" type="text" value="" /><br>
<input name="paid_amount" id="paid_amount" type="text" value="" /><br>
<input name="balance" id="balance" type="text" value="" /><br>
Out of These #website_charges, #monthly_fixed_charges, #members_registered, #per_member, #monthly_sessions, #per_session fields are manually entered.
currently my javascript code adding #member_total_charges and #session_total_charges dynamically.
But I am not getting How To Sum And Add These Two Dynamically added field values (i.e. #member_total_charges and #session_total_charges) + #website_charges + #monthly_total_charges in #total_dues field And Then Show Final Balance in #balance field after entering #paid_amount Fiield?
Current Javascript code is as follows :
<script type="text/javascript">
$(document).ready(function() {
$('#member_registered, #per_member').change(function(){
var mem = parseInt($('#member_registered').val()) || 0;
var permem = parseInt($('#per_member').val()) || 0;
$('#member_total_charges').val(mem * permem);
});
$('#monthly_sessions, #per_session').change(function(){
var month = parseInt($('#monthly_sessions').val()) || 0;
var perses= parseInt($('#per_session').val()) || 0;
$('#session_total_charges').val(month * perses);
});
});
</script>
JSFIDDLE Is Here****
To bind elements which generated dynamicly, use .live() function to binding events:
$("#member_total_charges, #session_total_charges").live("change", function () {
//do sum work
});
Note that change event only triggers after the <input> lost focus, so if you want to run the sum function as soon as you type a char, use keyup event instead.
Try using this code
<script type="text/javascript">
$(document).ready(function() {
$('#member_registered, #per_member').on('input change',function(){
var mem = parseInt($('#member_registered').val()) || 0;
var permem = parseInt($('#per_member').val()) || 0;
$('#member_total_charges').val(mem * permem);
});
$('#monthly_sessions, #per_session').on('input change',function(){
var month = parseInt($('#monthly_sessions').val()) || 0;
var perses= parseInt($('#per_session').val()) || 0;
$('#session_total_charges').val(month * perses);
});
$('#member_total_charges, #session_total_charges').on('change',function(){
var memtc = parseInt($('#member_total_charges').val()) || 0;
var sestc = parseInt($('#session_total_charges').val()) || 0;
$('#total_dues').val(memtc + sestc);
});
});
</script>
using the on() method will work better and you can use multiple arguments input, change, mouseover etc...
So basicly if you want to change a dynamically added values select theri id'and call .on() method with the string of parameters that you need and then your statement, like you did for your previous elements.
And if you have any troubles you can check this.
I hope this was helpfull
I Solved it as follows:
1) I removed all readonly attributes as suggested by #Bandon
2) Updated Code (By Editing code given by #Bandon jsfiddle) Is As Follows :
<script>
$(document).ready(function () {
$('#website_charges, #monthly_fixed_charges').on('input change', function () {
var web = parseInt($('#website_charges').val()) || 0;
var mfc = parseInt($('#monthly_fixed_charges').val()) || 0;
$('#subtotal').val(web + mfc);
});
$('#member_registered, #per_member').on('input change', function () {
var mem = parseInt($('#member_registered').val()) || 0;
var permem = parseInt($('#per_member').val()) || 0;
$('#member_total_charges').val(mem * permem);
});
$('#monthly_sessions, #per_session').on('input change', function () {
var month = parseInt($('#monthly_sessions').val()) || 0;
var perses = parseInt($('#per_session').val()) || 0;
$('#session_total_charges').val(month * perses);
});
$("input").live("keyup focus blur", "#subtotal_dues, #total_dues, #balance", function () {
var memtc = parseInt($('#member_total_charges').val()) || 0;
var sestc = parseInt($('#session_total_charges').val()) || 0;
$('#subtotal_dues').val(memtc + sestc);
var memtca = parseInt($('#subtotal').val()) || 0;
var sestca = parseInt($('#subtotal_dues').val()) || 0;
$('#total_dues').val(memtca + sestca);
var td = parseInt($('#total_dues').val()) || 0;
var paid = parseInt($('#paid_amount').val()) || 0;
$('#balance').val(td - paid);
});
});
</script>
UPDATED JSFIDDLE IS HERE
Thank to #Bandon

Hiding multiple form fields using checkboxes

I have this code that I need to edit so I can use it on multiple chkBox's and txtBox's.
Currently I can only hide one input field with one check box.
I know HTML and CSS but I am not familiar with JS.
I would like to be able to add a number at the end of each ID.
chkBox1, chkBox2, chkBox3... txtBox1, txtBox2, txtBox3...
Do I need to change getElementById to getElementsByTagName()?
JSFIDDLE for some reason it does not work here...?
This is my current code which hide the text field unless the checkbox is checked:
function showHide(){
var chkBox = document.getElementById("chkBox");
var txtBox = document.getElementById("txtBox");
if (chkBox.checked){
txtBox.style.visibility = "visible";
} else {
txtBox.style.visibility = "hidden";
}
}
The reason your code wasn't working is because it was running onLoad. Your DOM and the onclick were created before the load was complete. You could just move your code into your <head></head> tags and it will work as is. See here, all I did was select the "No wrap - in head", no code changes.
You could also continue to have your javascript run onLoad and remove your onclick and add an eventlistener in the javascript like this:
JSFiddle
var txtBox = document.getElementById("txtBox");
document.getElementById("chkBox").addEventListener("click", function() {
if (this.checked) {
txtBox.style.visibility = "visible";
} else {
txtBox.style.visibility = "hidden";
}
});
If you have multiple instances of this, I would change your DOM a bit sort of like this:
<form>
<div class="option">
<input type="text" name="txtBox1" class="hiddenInput" />
<br/>
<input type="checkbox" name="chkBox1" id="chkBox1" class="showHideCheck" />
<label for="chkBox1">Click me to show the text box</label>
</div>
<div class="option">
<input type="text" name="txtBox2" class="hiddenInput" />
<br/>
<input type="checkbox" id="chkBox2" name="chkBox2" class="showHideCheck" />
<label for="chkBox2">Click me to show the text box</label>
</div>
</form>
and do your JQuery like this (since you previously tagged jquery):
$(".hiddenInput").hide();
$(".showHideCheck").on("change", function() {
$this = $(this);
$input = $this.parent().find(".hiddenInput");
if($this.is(":checked")) {
$input.show();
} else {
$input.hide();
}
});
JSFiddle
Or with pure javascript and the similar DOM as above:
var checkBoxes = document.getElementsByClassName("showHideCheck");
for (var i = 0; i < checkBoxes.length; i++) {
checkBoxes[i].addEventListener('click', function () {
var txtBox = getAssociatedTextBox(this);
if (this.checked) {
txtBox.style.visibility = "visible";
} else {
txtBox.style.visibility = "hidden";
}
}, false);
}
function getAssociatedTextBox(ele) {
var childNodes = ele.parentNode.childNodes;
for (i = 0, j = childNodes.length; i < j; i++) {
if (childNodes[i].className == "hiddenInput") {
return childNodes[i];
}
}
}
JSFiddle
Try this,
Javascript
$(document).ready(function(){
$("input[type=checkbox]").change(function(){
var oTxt = $("#txtBox" + $(this).attr("id").replace("chkBox", ""));
if($(this).is("checked"))
oTxt.show()
else
oTxt.hide();
});
});
HTML
<input type="checkbox" id="chkBox1"/>
<input type="textbox" id="txtBox1"/>
<input type="checkbox" id="chkBox2"/>
<input type="textbox" id="txtBox2"/>

Categories

Resources