Using onblur event for mutiple form fields - javascript

I have a simple function that applies formatting to a form field using an onblur event - if 7 characters have been input into the field, the field's border turns green. Fewer than 7 character results in a red border. I'd like to be able to apply the function to each form field individually as the user tabs through. Currently, if I fill in the first form field, both form fields are formatted at the same time. I think the answer is using a for loop that iterates through the inputs, I just don't know how to update my code to reflect that; any help is much appreciated.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function charCount() {
var char = document.getElementById("numb").value.toString().length
if (char == 7) {
$("input").addClass("green").removeClass("red");
} else {
$("input").addClass("red").removeClass("green");
}
}
</script>
<style>
.green {border-color:#009900;}
.red {border-color:#990000;}
</style>
</head>
<body>
<p>Please input ID numbers:</p>
<input id="numb" maxlength = 7 onblur="charCount()">
<input id="numb" maxlength = 7 onblur="charCount()">
</body>
</html>

some points mate:
First thing, elements should not have same id in one html document. They can have same class but not ids.
document.getElementById("numb").value.toString().length you are trying to find the input from user using this statement. This will always pick the value from one particular item. Better use $(this) in the event handler(i suppose you are using jquery and know how to do it)
$("input").addClass using this.. you are targeting all the input elements present in the document. Be specific to what you want to target to.
Do it like this:
html:
<input class="numb" maxlength = 7 onblur="charCount()">
<input class="numb" maxlength = 7 onblur="charCount()">
JS:
$('.numb').on('blur', function() {
// you access the current input elem with $(this)
var inputElem = $(this);
var char = inputElem.val().length;
if (char == 7) {
inputElem.addClass("green").removeClass("red");
} else {
inputElem.addClass("red").removeClass("green");
}
});

1.- You cannot have the same id for multiple inputs. Use a class instead.
2.- Then use "this" to have a reference of the input that is being used
Here's a working solution. Hope it helps!
$(".numb").blur(function(){
var char = $(this).val().length;
if (char == 7) {
$(this).addClass("green").removeClass("red");
} else {
$(this).addClass("red").removeClass("green");
}
});
.green {border-color:#009900;}
.red {border-color:#990000;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<p>Please input ID numbers:</p>
<input class="numb" maxlength = 7>
<input class="numb" maxlength = 7>

There are couple of issues in your code:
1) When you use this selector $("input") You are applying the class to all inputs instead of a specific input. You need to create a selector which targets the specific input which is blurred.
$("input").addClass("green").removeClass("red");
2) You are using same id for both input elements
<input id="numb" maxlength = 7 onblur="charCount()">
<input id="numb" maxlength = 7 onblur="charCount()">
3) You are mixing selectors of vanilla javascript and jQuery which can cause problems, it's better to use one or the other for your clarity.
VERSION:
This is the version with least changes to what you have already come up with, but the way you have attached the event is quite inefficient.
<script>
function charCount(num) {
var elem = $("#numb" + num);
var char = elem.value.toString().length;
if (char == 7) {
$(elem).addClass("green").removeClass("red");
} else {
$(elem).addClass("red").removeClass("green");
}
}
</script>
<style>
.green {border-color:#009900;}
.red {border-color:#990000;}
</style>
</head>
<body>
<p>Please input ID numbers:</p>
<input id="numb1" maxlength = 7 onblur="charCount(1)">
<input id="numb2" maxlength = 7 onblur="charCount(2)">
BETTER VERSION:
<html>
</head>
<script>
function init() {
$('input').on('blur', function() {
var elem = $(this);
if(elem.val().length < 7) {
elem.addClass('red').removeClass('green');
}
else {
elem.removeClass('red').addClass('green');
}
});
}
$( document ).ready(init);
</script>
<style>
.green {border-color:#009900;}
.red {border-color:#990000;}
</style>
</head>
<body>
<p>Please input ID numbers:</p>
<input maxlength = 7>
<input maxlength = 7>
</body>
</html>
An event better solution would be to use IIFEs.
I would suggest you go through some resources for learning event handling:
https://learn.jquery.com/events/handling-events/
https://api.jquery.com/category/events/
http://gregfranko.com/blog/jquery-best-practices/
Hope it helps!

Related

Count down from user entered number in HTML and Javascript

So i have an input box that a user can enter a number into and upon clicking Commit, that number displays in a tag.
I then want this number to start counting down when I click Start.
I am new to Javascript and this is essentially a little project to help me learn, maybe I've thrown myself in too far, but I'm too invested now and would appreciate any help.
My HTML:
<span style="font-size: 36pt; font-family: homiziothin; color: black; padding-right: 20px;">£</span>
<input id="inputvalue" type="number" name="Value" min="0" max="500">
<button id="commitprice" type="submit" onclick="submitPrice()">Commit Price</button>
<p id="submittedprice"></p>
<button id="startauction" type="submit" onclick="startAuction()">Start Auction</button>
and my current Javascript to get the user value into the tag (and a rough guess going from multiple searches on google of how to start the countdown)
<script type="text/javascript">
function submitPrice()
{
var $pricesubmitted = $("#inputvalue").val();
$("#submittedprice").text($pricesubmitted);
}
function startAuction()
{
debugger;
var $startingprice = $("#inputvalue").val();
var $bidcountdown = setInterval(function()
{
$startingprice--;
document.getElementById("#inputvalue").textContent = $startingprice;
if($startingprice <= 0)
clearInterval($bidcountdown);
}, 1000);
}
</script>
At the moment it's erroring and saying that textContent can't be NULL.
Also just to point out the Actual populating of the P tag is working, its the countdown that isn't.
textContent property represents the text between opening and closing tags of an element. With your input, you need value property, because you don't have any text between those tags.
More info: How do I get the value of text input field using JavaScript?
I have implemented your requirement in a fiddle, you can check
function submitPrice() {
var $pricesubmitted = document.getElementById("inputvalue");
document.getElementById("submittedprice").innerText = $pricesubmitted.value;
}
function startAuction() {
var msgElement = document.getElementById("showMessage");
msgElement.innerText = "Count Down Started..";
var _el = document.getElementById("inputvalue");
var $startingprice = parseInt(_el.value);
var $bidcountdown = setInterval(function() {
msgElement.innerText = "Count Value " + $startingprice;
$startingprice--;
msgElement.innerText = $startingprice;
if ($startingprice < 0) {
msgElement.innerText = "Count Down ends ...";
clearInterval($bidcountdown);
}
}, 1000);
}
<span style="font-size: 36pt; font-family: homiziothin; color: black; padding-right: 20px;">£</span>
<input id="inputvalue" type="number" name="Value" min="0" max="500" value="">
<button id="commitprice" onclick="submitPrice()">Commit Price</button>
<p id="submittedprice"></p>
<button id="startauction" type="button" onclick="startAuction()">Start Auction</button>
<div id="showMessage"></div>
jsfiddle link
You have a couple of issues in your code. First, as noted by Mladen, you should be using .value instead of .textContent. Second, you should not use the "#" in the .getElementById selector.
This should fix it for you.
function startAuction()
{
debugger;
var $startingprice = document.getElementById("inputvalue").value;
var $bidcountdown = setInterval(function()
{
$startingprice--;
// document.getElementById("inputvalue").value = $startingprice;
document.getElementById("submittedprice").innerHTML= $startingprice;
if($startingprice <= 0)
clearInterval($bidcountdown);
}, 1000);
}
By the way, I highly recommend not jumping back and forth between jQuery and vanilla JS DOM selectors to avoid this kind of confusion.
Edit:
Commented out the line targeting the text input and added a line targeting the <p> tag. Note that instead of .value, you will need to use .innerHTML to make the change to the <p> tag (because it is updating the HTML contained within the opening and classing brackets of the <p>).

Dynamically adding HTML form fields based on a number specified by the user [duplicate]

This question already has answers here:
Dynamically creating a specific number of input form elements
(2 answers)
Closed 1 year ago.
I've a form field named Number of messages, and based on what number the user specifies, I want the exact number of text fields to be dynamically generated below to allow users to enter specified number of messages.
I have browsed through some examples where JQuery is used to generate dynamic form fields, but since I'm not acquainted with JQuery, those examples are a bit too complex for me to grasp. I do know the basics of JavaScript, and would really appreciate if I could find a solution to my query using JavaScript.
function addinputFields(){
var number = document.getElementById("member").value;
for (i=0;i<number;i++){
var input = document.createElement("input");
input.type = "text";
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
}
and html code will be
Number of members:<input type="text" id="member" name="member" value=""><br />
<button id="btn" onclick="addinputFields()">Button</button>
<div id="container"/>
fiddle here
You can try something similar to this...
var wrapper_div = document.getElementById('input_set');
var btn = document.getElementById('btn');
btn.addEventListener('click', function() {
var n = document.getElementById("no_of_fields").value;
var fieldset = document.createElement('div'),
newInput;
for (var k = 0; k < n; k++) {
newInput = document.createElement('input');
newInput.value = '';
newInput.type = 'text';
newInput.placeholder = "Textfield no. " + k;
fieldset.appendChild(newInput);
fieldset.appendChild(document.createElement('br'));
}
wrapper_div.insertBefore(fieldset, this);
}, false);
No. of textfields :
<input id="no_of_fields" type="text" />
<div id="input_set">
<p>
<label for="my_input"></label>
</p>
<button id="btn" href="#">Add</button>
</div>
It is a simple task which is made simpler with jQuery. You need to first get the value from the input field for which you can use .val() or .value. Once you get the value, check if it is an integer. Now, simply use .append() function to dynamically add the elements.
HTML
<form id="myForm">
Number of Messages: <input id="msgs" type="text"> </input>
<div id="addmsg">
</div>
</form>
JAVASCRIPT
$("#msgs").on('change', function()
{
var num = this.value;
if(Math.floor(num) == num && $.isNumeric(num))
{
$("#addmsg").text('');
for(var i = 0; i < num; i++)
{
$("#addmsg").append("<input type='text'/><br/>");
}
}
});
Fiddle
Note, everytime the value in the input changes, I am first clearing the div by:
$("#addmsg").text('');
And then I loop and keep adding the input field. I hope this helps!

How do I use window.find to change css style?

Through a combination of AJAX and PHP, I put some text data in a span at the bottom of the page. Now I want to search this text for a string. My page is full of checkboxes, and their values are the strings I will search for.
Goal: Using a loop, cycle through the values of all checkboxes on the page. Search the page for each checkbox's value (ideally, within the text in the AJAX-informed span). If the checkboxes value is found, change that checkboxes CSS style color.
My code so far: I have a form full of checkboxes all named "comment" each with unique IDs:
<input type="checkbox" name="comment" id="hjl1" value="the comment."
onclick="createOrder()"><label for="hjl1" onclick="createOrder()"
title="comment"> onscreen text for this checkbox </label>
When triggered , using Javascript, I go through every checkbox in that form.
var comment=document.forms[0].comment;
var txt="";
var ii;
for (ii=0;ii<comment.length;ii++)
{str=comment[ii].value;}
Now I want to insert window.find in that loop to check if that value is on my page.
if (window.find) {
var found = window.find (str);
if (!found) {
document.getElementById("?????").style["color"] = "red";
}
}
The idea is that when the checkbox is checked, the javascript would search for the value "the comment." on page. If found, the checkbox label will add the CSS style color red.
Somehow, I want to combine these ideas, but there are so many problems. How do I get the element by ID in this loop? Can window.find search the text created by php in my span?
Would it be better to not use window.find at all?
var source = document.getElementsByTagName('html')[0].innerHTML;
var found = source.search("searchString");
I'm so confused and new. Please be patient. Thank you for reading this far.
I misunderstood at first, and wrote code to highlight text within the page.
Yes, window.find is fine to use for this as you only need to know if the value exists or not. It might behave a bit odd (scroll to bottom) when used in frames though.
Also, I added a function for your onClick, but I'm not sure if this is wanted. It will change color of the label if text if found when clicked (also).
Below is a small example:
function checkThis(ele) {
var str = ele.value;
if (window.find) {
var found = window.find(str);
if (found) {
var id = ele.getAttribute('id');
var lbl = document.querySelectorAll('label[for="' + id + '"]');
if (lbl) lbl[0].style.color = "red";
}
}
}
window.onload = function() {
var comment = document.form1.getElementsByTagName('input');
for (var x = 0; x < comment.length; x++) {
if (comment[x].type == 'checkbox') {
var str = comment[x].value;
if (window.find) {
var found = window.find(str);
if (found) {
var id = comment[x].getAttribute('id');
var lbl = document.querySelectorAll('label[for="' + id + '"]');
if (lbl) lbl[0].style.color = "red";
}
}
}
}
}
<form name="form1">
<input type="checkbox" name="comment" id="hjl1" value="the comment." onclick="checkThis(this);" />
<label for="hjl1" onclick="createOrder()" title="comment">onscreen text for this checkbox</label>
<input type="checkbox" name="comment" id="hjl2" value="the comment2." onclick="checkThis(this);" />
<label for="hjl2" onclick="createOrder()" title="comment">onscreen text for this checkbox</label>
<br/>
<b>first comment.</b><br/>
<b>other comment.</b><br/>
<b>some comment.</b><br/>
<b>the comment.</b><br/>
<b>whatever comment.</b><br/>
<b>not this comment.</b><br/>
</form>
try this as your function code
function loopy() {
var comment=document.forms[0].comment;
var txt="";
var ii;
for (ii=0;ii<comment.length;ii++) {
if (comment[ii].checked) {
str=comment[ii].value;
id = comment[ii].id;
nextLabelId = comment[ii].nextSibling.id;
if (window.find) { // Firefox, Google Chrome, Safari
var found = window.find (str);
if (found == true) {
// found string
//comment[ii].style['outline']='1px solid red';
document.getElementById(nextLabelId).className = 'selected';
}
} else {
// this browser does not support find()
alert('not supported');
}
}
}
}
So, in order to get the checkbox id, you just add id = comment[ii].id in your loop.
To change the color, it's best to use class name and use styling in the css file. so if you want to change the label that is after the checkbox to red you will first find the label's id using nextSiblings and then add the .selected class name. Just remember that you need to remove the coloring if the user un-check the box
Regarding the usage of find(), not supported by all browser so this could be an issue and also not sure it will be able to find on the content you injected to the DOM by AJAX so this needs some testing.
I would suggest moving this code to jQuery as some features seems to be easier using their functionality.

Calculate form inputs onChange

I have a dynamic form that is being generated based on what the user adds to the cart.
For example, the form will looks something like this,
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test Form</title>
</head>
<body>
<form action="" name="cart" id="cart">
<input type="text" name="sku1">
<input type="text" name="sku2">
<input type="text" name="sku3">
<input type="text" name="sku4">
<input type="text" name="sku5">
<div class="sum" id="sum"> Total: {SUM SHOULD SHOW UP HERE)</div>
<button name="submit">Send</button>
</form>
</body>
</html>
But those input fields are generated automatically and may be more or less than 5 fields.
How to calculate those input SUM value and output to SUM div without page refresh?
JavaScript/jQuery?
$('button[name="submit"]').click(function () {
var sum = 0;
$('#cart input[name^="sku"]').each(function () {
var val = isNaN(+this.value) ? 0 : +this.value;
sum += val;
});
$('#sum').text(sum);
});
Or
var inp = $('#cart input[name^="sku"]');
inp.change(function () {
var sum = 0;
inp.each(function () {
var val = isNaN(+this.value) ? 0 : +this.value;
sum += val;
});
$('#sum').text(sum);
});
Attribute Starts With Selector [name^="value"]
.change()
isNaN()
You can use the onsubmit attribute of the form to do whatever you want to before the form gets submitted. You can change action attribute also. You can also preventDefault as said here-
jQuery on submit preventDefault() does not works
You can give the elements a class, amountForTotal, and use a function to calc the total, which you can add to a button, or onchange event of an input.
function calcTotal( $elements ){
var total = 0;
$elements.each(function(){
// if the input has no value, add 0, if it has, add the value
total+= this.value.length===0 ? 0 : parseInt(this.value);
})
return total; // return the total
}
$elements = $('.amountForTotal'); // select them
// Bind an event to recalc the total
$elements.on('keyup', function(){
alert( calcTotal($elements) );
});
In this code I provided the selector as input. This is luxery, not needed, you can add that selector in the function, but this way it can be used more flexible. You can use the [name^=*] selector here, but its slower than a class, which you might notice in large documents.
Also, In my code I check if it has to no value to prevent errors. You can expand this to test if the input is actualy a number.

Retrieving the value of Dynamically Created elements

i Have created a HTML form , in this form when i Click on a button it creates input text fields based on a predefined criteria , this works fine .
now when i try and retrieve the value entered in those created text fields using alert i am not able to do so .
i have two questions
What is the best way to retrieve inputs from the dynamically created text fields?
can you tell me why the code i have written does not work
HTML code
<BODY>
<FORM>
<BR/>
<div align = "center">
<br /><br />
<INPUT type="button" value="Click To Enter Values" onclick="getkeywords()"/>
</div>
<div align="center" id="d_div">
<form name="permavalues" id="d_form">
</form>
<br/> <br/>
</div>
</FORM>
THe javascript code that i am using is this :
function getkeywords() {
var index_array = new Array();
var myString = "one and a two and a three = $ and four = $ and five = $";
var splitresult = myString.split(" ");
for(i = 0; i < splitresult.length; i++)
{
if (splitresult[i] == "$" && i > 1 ) //retireving the keywords..
{
add(splitresult[i-2]);
}
}
}
The add function which is called in getkeywords:
function add(s) {
//Create an input type dynamically.
var element = document.createElement("input");
//Assign different attributes to the element.
element.setAttribute("type", "text");
element.setAttribute("value", s);
element.setAttribute("name", s);
element.setAttribute("id", s);
var foo = document.getElementById("d_form");
//Append the element in page (in span).
foo.appendChild(element);
alert("Value=" + document.getElemebtById(s).value);
}
I think that i must have a mistake with element.setAtrribute("id",s);
The major problem is you can't put form inside another form. Please remove you HTML code line 2 and line 13.
Another problem is your typo, as IvanL said.
Other code are fine.
Give you fully tested work code as below.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>test</title>
<script language="javascript">
function getkeywords() {
var index_array = new Array();
var myString = "one and a two and a three = $ and four = $ and five = $";
var splitresult = myString.split(" ");
for(i = 0; i < splitresult.length; i++)
{
if (splitresult[i] == "$" && i > 1 ) //retireving the keywords..
{
add(splitresult[i-2]);
}
}
}
function add(s) {
//Create an input type dynamically.
var element = document.createElement("input");
//Assign different attributes to the element.
element.setAttribute("type", "text");
element.setAttribute("value", s);
element.setAttribute("name", s);
element.setAttribute("id", s);
var foo = document.getElementById("d_form");
//Append the element in page (in span).
foo.appendChild(element);
alert("Value=" + document.getElementById(s).value);
}
</script>
</head>
<BODY>
<BR/>
<div align = "center">
<br /><br />
<INPUT type="button" value="Click To Enter Values" onclick="getkeywords()"/>
<br><br><br>
<input type="button" value="add" onclick="add('tt')">
</div>
<div align="center" id="d_div">
<form name="permavalues" id="d_form">
</form>
<br/> <br/>
</div>
</body>
</html>
What is the best way to retrieve inputs from the dynamically created
text fields?
I would use JQuery to traverse the form for all text input elements and retrieve their respective values.
Alternatively, you could give each of the text fields a common name like "txt_" and then append an incremental ID to the string (I.E. -- txt_1, txt_2, txt_3, ...) then programmatically iterate over your form fields that match until you've reached a value that represents the total number of available form fields. That value could be a javascript integer.
For example...
$("form input[type='text']").each( function()
{
// gets text value for each field in the form
var textFieldValue = this.value;
// do stuff
});
Have a look on the Jquery code for getting All Input Value.
$(document).ready(function()
{
$('form#d_form input[type="text"]').each(
function()
{
alert($(this).val());
});
});

Categories

Resources