Remove disabled function of Submit button when condition fulfills - javascript

I have a form. Here in the submit button which is disabled, I have made the following function that when balance value will be greater than 10, it will remove its disabled function. My script is not working. Is there any way to remove the disabled function of submit button, when balance value will be greater than 10?
<script >
function startCalc(){
interval = setInterval("calc()",1);
}
function calc(){
one = document.add_form.obalance.value;
two = document.add_form.debit.value;
document.add_form.balance.value = (one * 1) - (two * 1);
}
function stopCalc(){
clearInterval(interval);
}
</script>
My html form:
<html>
<form name="add_form" action="ebill.php" method="post" >
<input type="text" name="obalance" id="obal" value="" onFocus="startCalc();"
onBlur="stopCalc();" >
<input type="text" name="debit" id="totl" value="" onFocus="startCalc();"
onBlur="stopCalc();" />
<input type="text" name="balance" id="totl" value="" />
<input type="submit" id="submit" name="submit" disabled="disabled" />
</html>
Script to remove disabled attribute of Submit button:
<script >
setInterval(function () {
if ($('#balance').val() >= 10){
$(":submit").removeAttr("disabled");
}
else{
$(":submit").attr("disabled", "disabled");
alert('Your Balance is less than 10');
}
}, 1);
</script>

(comments in the code itself — you'll also find below your code some "best practice advices" to avoid a lot of headhaches ;))
function startCalc(){
interval = setInterval("calc()",1);
}
function calc(){
one = document.add_form.obalance.value;
two = document.add_form.debit.value;
document.add_form.balance.value = (one * 1) - (two * 1);
}
function stopCalc(){
clearInterval(interval);
}
setInterval(function () {
/*************************************
v----------- ID error (fixed) */
if ($('#tot2').val() >= 10){
$(":submit").removeAttr("disabled");
}
else{
$(":submit").attr("disabled", "disabled");
// alert('Your Balance is less than 10');
}
}, 10); // 1 is too much?
input#submit[disabled] {
background-color: red; color: white; opacity:.2;
}
input#submit:not(disabled) {
background-color: green; color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="add_form" action="ebill.php" method="post" >
<input type="text" name="obalance" id="obal" value="" onFocus="startCalc();"
onBlur="stopCalc();" >
<input type="text" name="debit" id="tot1" value="" onFocus="startCalc();" onBlur="stopCalc();" />
<!-- ID error (fixed) -------------^ -->
<input type="text" name="balance" id="tot2" value="" /> <!--
<!-- ID error (fixed) -------------^ -->
<input type="submit" id="submit" name="submit" disabled="disabled" />
By the way, you should use jQuery or not. The use of jQuery for a bunch of code and pure DOM for another is REALLY errors prone.
In your code above for instance, document.add_form.balance and $('#tot2') address the same DOM Element, but their names are fully different, with no reason.
Hard to read, hard to debug, errors prone.
If your code works after document is ready, you should for example put your fields in variables with self-explanatory names:
let balanceField /* or whatever name you want */ = $('#balance') ;
let debitField = $('#debit') ;
let totalField = $('#total') ;
Then, in your code, you use these variables instead of hard value:
let one = balanceField.val() || 0 ;
let two = debitField.val() || 0 ;
totalField.val( one + two ) ;
Or, shorter, still readable and expressive (but only if you don't need the one and two values further):
totalField.val( (balanceField.val()||0) + (debitField.val()||0) ) ;
and further:
if ( debitField.val() > 9 ) { ... }

Related

Error messages for form validation not appearing

I am currently building a window on a website where users can book a boat trip, which requires multiple steps, and 3/5 steps include forms (I only included the first form in the html since it would get too long otherwise - see below).
I am currently handling the validation of the first form, which you can see below (".availability step1"). I've spent quite some time on this validation, however, I can't seem to figure out how to make only the "empty", so the fields that are not valid, take on the error message (.error). Right now it is recognising the ones that are invalid, and I'm getting the CSS connected to invalid (I am getting the red border around the input field), however, I am not getting through the html tag, which is a paragraph that goes underneath the input field.
function init() {
setUpBooking();
}
function setUpBooking(){
formValidation();
}
function formValidation() {
/* ------------ form & elements ----------- */
const form1 = document.querySelector(".availability");
window.form1 = form1;
const elements = form1.elements;
window.elements = elements;
/* --------- delete default validation ------- */
form1.setAttribute("novalidate", true);
/* ------------ custom validation ------------ */
document.querySelector(".next").addEventListener("click", (e) => {
e.preventDefault();
// 1. select all inputs
const formElements = form1.querySelectorAll("input, select");
/* ------------ date ------------ */
if (form1.checkValidity()) {
console.log("form is valid");
// loop through form elements and check if are valid or not
formElements.forEach((el) => {
if (el.checkValidity()) {
el.classList.add("valid");
}
// enable "next" btn when form is valid
var counter = 1, step = "step";
step = ".step" + counter;
if (counter <= 5) {
document.querySelector(step).classList.add("show");
}
counter++;
if (counter > 5) {
counter = 5;
}
step = ".step" + counter; // step is the class and we are appending counter with step so that it looks like the same class in the given class(like counter 1 means step1)
document.querySelector(step).classList.remove("show");
// enable "previous" btn when form is valid
document.querySelector(".previous").addEventListener('click', function () {
if (counter > 1) { // we don't want to remove the first step, it will always be shown
step = ".step" + counter;
document.querySelector(step).classList.add("show");
}
counter--;
if (counter < 1) {
counter = 1;
}
step = ".step" + counter;
document.querySelector(step).classList.remove("show");
});
});
} else {
formElements.forEach((el) => {
if (!el.checkValidity()) {
console.log("form is invalid");
el.classList.add("invalid");
document.querySelector(".error").style.display = "block";
} else {
el.classList.remove("invalid");
}
})
}
})
}
.valid {
border: 1px solid green;
}
.invalid {
border: 1px solid red;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.error {
text-transform: initial;
margin-bottom: 20px;
margin-top: -1px;
border: 1px solid red;
padding: 4px;
z-index: 10;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
display: none;
}
<!-- AVAILABILITY -->
<form class="availability step1">
<label for="date">Choose a date
<input type="date" required>
<p class="error date-err">Please pick a date for your tour</p>
<label for="number">Choose passengers
<input type="number" required>
<p class="error passengers-err">Please pick a number of passengers</p>
</label>
<!-- PERSONAL DATA -->
<form class="personalData step2">
</form>
<!-- ORDER OVERVIEW -->
<div class="orderOverview step3">
</div>
<!-- PAYMENT -->
<form class="payment step4">
</form>
<!-- buttons -->
<button class="previous hide">Previous</button>
<button class="next">Next</button>
Firstly, sorry. I've made some modifications to your forms.
Ideas are as follows:
Appended a span field in every form.
Before going to the next form just check every field is filled in the current form by passing the form number to the validateForm function and check all its input fields are filled.
If yes, return true else return false.
Have a look at the snippet below:
function validateForm(step) {
// console.log(document.forms[step - 1].elements);
var i, l = document.forms[step - 1].elements.length;
for (i = 0; i < l; i++) {
// console.log(document.forms[step - 1].elements[i].value);
if (!document.forms[step - 1].elements[i].value) {
// console.log("All fields should be filled");
document.getElementById("error" + step).textContent = "Fill all the fields please";
document.getElementById("error" + step).style.color = "red";
return false;
}
}
document.getElementById("error" + step).textContent = "Form is completed";
document.getElementById("error" + step).style.color = "green";
return true;
}
var counter = 1,
step = "step";
document.querySelector(".next").addEventListener('click', function() {
step = ".step" + counter;
if (validateForm(counter)) {
if (counter <= 5) {
document.querySelector(step).classList.add("show");
}
counter++;
if (counter > 5) {
counter = 5;
}
step = ".step" + counter; // step is the class and we are appending counter with step so that it looks like the same class in the given class(like counter 1 means step1)
//console.log(step);
document.querySelector(step).classList.remove("show");
}
});
document.querySelector(".previous").addEventListener('click', function() {
if (counter > 1) { // we don't want to remove the first step, it will always be shown
step = ".step" + counter;
//console.log(step);
document.querySelector(step).classList.add("show");
}
counter--;
if (counter < 1) {
counter = 1;
}
step = ".step" + counter;
document.querySelector(step).classList.remove("show");
});
.show {
display: none;
}
<!-- AVAILABILITY -->
<form name="availability" class="availability step1">
<h1>Step1</h1>
<label for="date">Choose a date</label>
<input type="date" name="DATE" required>
<label for="firstname">Enter a firstname</label>
<input type="text" name="FIRSTNAME" required>
<br/>
<span id="error1"> </span>
</form>
<!-- PERSONAL DATA -->
<form class="personalData step2 show">
<h1>Step2</h1>
<label for="date">Choose a date</label>
<input type="date" name="DATE" required>
<label for="firstname">Enter a firstname</label>
<input type="text" name="FIRSTNAME" required>
<br/>
<span id="error2"></span>
</form>
<!-- ORDER OVERVIEW -->
<div class="orderOverview step3 show">
<h1>Step3</h1>
<label for="date">Choose a date</label>
<input type="date" name="DATE" required>
<label for="firstname">Enter a firstname</label>
<input type="text" name="FIRSTNAME" required>
<br/>
<span id="error3"></span>
</div>
<!-- PAYMENT -->
<form class="payment step4 show">
<h1>Step4</h1>
<label for="date">Choose a date</label>
<input type="date" name="DATE" required>
<label for="firstname">Enter a firstname</label>
<input type="text" name="FIRSTNAME" required>
<br/>
<span id="error4"></span>
</form>
<!-- buttons -->
<button class="previous hide">Previous</button>
<button class="next">Next</button>

HTML onclick isn't running function

I am new to Javascript and just getting into it for my web design class. I am working on a project with Javascript inside HTML. I have it all written, but the HTML doesn't seem to call the Javascript function. I've been searching for a solution but can't seem to get anything to work. The code is:
<html>
<head>
<script>
var calculateInterest = function(){
var rate;
var total;
var years = document.getElementById("years").value;
var principleAmount = document.getElementById("principal").value;
var interestRate = document.getElementById("intrest").value;
if ((interestRate >= 0) && (interestRate <= 15)) {
rate = interestRate / 100;
if ((principleAmount >= 0) && (principleAmount <= 10000)) {
total = principleAmount * (1 + rate * years);
document.getElementById("total_with_intrest").value = total;
}
else {
message-box ("Invalid data for principle amount.");
}
}
else {
message-box ("Invalid data for interest rate.");
}
}
</script>
<style>
form{ border: solid blue;
width:40em;
padding:0.5em;}
input{padding: 0.5em;}
</style>
</head>
<body>
<form>
Enter Principal Ammount : <input type="text" id ="principal" />
</br>
Enter Intrest Rate : <input type="text" id ="intrest" />
</br>
Enter Number of Years : <input type="text" id ="years" />
</br>
Grand Ammount : <input type="text" id ="total_with_intrest" disabled /></br>
</br>
<input type="button" id="click" value="Calculate" onclick=calculateInterest()/> </br>
</form>
</body>
</html>
The browser error is "SyntaxError: expected expression, got '}' " on line 2 but I just can't see what the issue is. Any help is greatly appreciated!
Side note, I am aware there are some weird spelling mistakes. My instructor is from India and not totally fluent in English. She made the HTML file for us to use and we just have to put in the Javascript.
There is no message-box function. Did you mean alert()? Your code currently works, with those changes:
var calculateInterest = function(){
var rate;
var total;
var years = document.getElementById("years").value;
var principleAmount = document.getElementById("principal").value;
var interestRate = document.getElementById("intrest").value;
if ((interestRate >= 0) && (interestRate <= 15)) {
rate = interestRate / 100;
if ((principleAmount >= 0) && (principleAmount <= 10000)) {
total = principleAmount * (1 + rate * years);
document.getElementById("total_with_intrest").value = total;
}
else {
alert("Invalid data for principle amount.");
}
}
else {
alert("Invalid data for interest rate.");
}
}
form{ border: solid blue;
width:40em;
padding:0.5em;}
input{padding: 0.5em;}
<form>
Enter Principal Amount : <input type="text" id ="principal" />
</br>
Enter Interest Rate : <input type="text" id ="intrest" />
</br>
Enter Number of Years : <input type="text" id ="years" />
</br>
Grand Amount : <input type="text" id ="total_with_intrest" disabled /></br>
</br>
<input type="button" id="click" value="Calculate" onclick="calculateInterest()" /> </br>
</form>
Small Nitpick: Fixed some small typos not related to code. Ammount => Amount. Intrest => Interest.

When use backspace or delete button submit button color not changes

I have an HTML form where submit button is disabled when input value is less than 10. The button changes its color when input value becomes greater than 10.
Problem comes when I use backspace or delete button to remove input value, submit button color does not change to disabled button until I refresh the page.
setInterval(function () {
if ($('#tot2').val() >= 10){
$("#submit").removeAttr("disabled");
$("#submit").css({"background-color": "blue", "color": "white"});
} else {
$("#submit").attr("disabled", "disabled");
}
}, 10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="add_form" action="ebill.php" method="post" >
<input type="text" name="balance" id="tot2" value="" />
<input type="submit" id="submit" name="submit" disabled="disabled" />
</form>
You change the colors once the value reaches 10, but you never change them back. You can set them to an empty string ("") to get back to the original colors before you set them. (See jQuery - remove style added with .css() function).
Fixed code below:
setInterval(function () {
if ($('#tot2').val() >= 10){
$("#submit").removeAttr("disabled");
$("#submit").css({"background-color": "blue", "color": "white"});
} else {
$("#submit").attr("disabled", "disabled");
// Remove the custom colors we added.
$('#submit').css({"background-color": "", "color": ""});
}
}, 10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="add_form" action="ebill.php" method="post" >
<input type="text" name="balance" id="tot2" value="" />
<input type="submit" id="submit" name="submit" disabled="disabled" />
</form>
(Note that, as others point out, it's better to monitor the input for changes rather than use a timer.)
Here you go with a solution
$('#tot2').keyup(function(){
if(parseInt($(this).val()) < 10 || $(this).val().length === 0) {
$('#submit')
.attr('disabled', 'disabled')
.removeClass('active');
} else {
$('#submit')
.removeAttr('disabled')
.addClass('active');
}
});
.active {
background: black;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="add_form" action="ebill.php" method="post" >
<input type="text" name="balance" id="tot2" value="" />
<input type="submit" id="submit" name="submit" disabled="disabled" />
</form>
Try keyup event. Use class for styling and toggle it.
$("#tot2").on("keyup", function() {
var elem = $(this);
if (elem.val() >= 10) {
$("#submit").removeAttr("disabled").addClass("active");
} else {
$("#submit").attr("disabled", "disabled").removeClass("active");
}
});
CSS:
active {
background-color: blue;
color: white
}
Demo: http://jsfiddle.net/GCu2D/2207/
You should use keyup or keypress function, and instead of set inline style use addClass like this:
$('#tot2').keyup(function() {
var val = $(this).val();
if (val >= 10) {
$("#submit").removeAttr("disabled");
$("#submit").addClass('NewSub');
} else {
$("#submit").attr("disabled", "disabled");
$("#submit").removeClass('NewSub');
}
});
.NewSub {
background: blue;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="add_form" action="ebill.php" method="post">
<input type="text" name="balance" id="tot2" value="" />
<input type="submit" id="submit" name="submit" disabled="disabled" />
</form>
Rather than using time interval, you can simply do it like this:
$('#tot2').on('change', function(){
if($('#tot2').val() < 10)
$('#submit').attr('disabled', 'disabled');
else $('#submit').removeAttr('disabled');
});

I am trying to write the array to HTML but it keeps coming up as undefined

<body>
<h1>Find the Even #'s</h1>
<p>Starting Number:</p>
<input id="start" type="number" name="start" min="1" value="1"><br>
<p>Ending Number:</p>
<input id="end" type="number" name="end" min="1" value="1"><br>
<p>Step Number:</p>
<input id="step" type="number" name="step" min="1" value="1"><br>
<button onclick="playGame()">Play Game</button>
<br><br>
<p id="result">#</p>
<script type="text/javascript">
function playGame(){
var startNum = document.getElementById("start").value;
var endNum = document.getElementById("end").value;
var stepNum = document.getElementById("step").value;
var Enumbers = new Array();
for(var i = startNum; i <= endNum; i += stepNum){
if(i % 2 == 0){
Enumbers.push(i);
}
}
document.getElementById("result").innerHTML = Enumbers[];
}
</script>
</body>
If the array is already filled with data of any kind then I am able to write the array data to the html. I feel like the problem is that I am starting with an empty array and I am not filling the array correctly maybe. I just can't seem to figure out what I am doing wrong here.
When using <input> you must remember that the values are strings not numbers (even from type="number"). So you must ensure that the values are converted just in case cohersion isn't working in your favor. I used parseFloat() to convert the string values into numbers, parseInt() and Number are options as well.
Instead of a <p> try displaying results with <output>, these elements are a form control like <input> among it's unique traits is the ability to display it's contents with the .value property like a form control or HTML/Text like a <div> or a <p>, etc.
I added 2 conditions in order to avoid bad input.
Snippet
html {
font: 100 12px/1.3 Consolas;
}
input,
output,
button {
font: inherit;
}
input {
width: 10ch
}
<label>Starting Number: </label>
<input id="start" type="number" name="start" min="1" value="1"><br>
<label>Ending Number: </label>
<input id="end" type="number" name="end" min="2" value="2"><br>
<label>Step Number: </label>
<input id="step" type="number" name="step" min="1" value="1"><br>
<button onclick="playGame()">Play Game</button>
<br><br> #
<output id="result"></output>
<script>
function playGame() {
var start = parseFloat(document.getElementById("start").value);
var end = parseFloat(document.getElementById("end").value);
var step = parseFloat(document.getElementById("step").value);
var even = [];
if (end <= start) {
alert('Starting Number must be less than Ending Number');
return false
} else if (step > (end - start)) {
alert('Step Number cannot exceed ' + (end - start) + ' which is the difference between ' + start + ' and ' + end);
return false
} else
for (let i = start; i <= end; i += step) {
if (i % 2 === 0) {
even.push(i);
}
}
document.getElementById("result").value = even;
}
</script>
Try
document.getElementById("result").innerHTML = Enumbers.toString();
You can't just use Enumbers[].
Note, you can probably omit the .toString() and just use Enumbers. From MDN:
JavaScript calls the toString method automatically when an array is to
be represented as a text value or when an array is referred to in a
string concatenation.

How do i get rid of the NaN in the text box in my JavaScript and HTML code?

I'm trying to make a triangle Hypotenuse calculator. First you put one leg, then the other leg, then you will get the Hypotenuse. But, if you fill in the second box first, It will say NaN. I know its not that important, but is there a way to get rid of it so it says "0" until both boxes are filled? And here is the code:
<html>
<head>
<script type="text/javascript">
function hypotenuse(a,b){
return Math.sqrt(a*a + b*b);
}
</script>
</head>
<body>
<input type="button" value="Hypoteneuse";" />
A:<input type="text" id="leg1" size="2";" />
B:<input type="text" id="leg2" size="2" onChange="document.getElementById('result').value=hypotenuse(parseInt(document.getElementById('leg1').value),parseInt(document.getElementById('leg2').value));" />
Hypotenuse:<input type="text" placeholder="0" id="result" size="2" />
</body>
</html>
You could set a default value on the first input:
<input type="text" id="leg1" size="2" value="0" />
Or you could bind your function to the click of a button and do some validation before you attempt the calculation (fiddle):
var leg1 = document.getElementById('leg1');
var leg2 = document.getElementById('leg2');
function hypotenuse(a,b){
return Math.sqrt(a*a + b*b);
}
document.getElementById('submit').addEventListener('click', function() {
// Check both fields are populated. This validation could
// be more sophisticated if you needed it to be.
if (leg1.value !== '' && leg2.value !== '') {
document.getElementById('result').value = hypotenuse(parseInt(leg1.value),parseInt(leg2.value));
} else {
// You could display an error message here
console.log('Please fill out both fields');
}
});
You can use isNaN() to check whether your values exist or not:
<script type="text/javascript">
function hypotenuse(a,b){
if (isNaN(a) || isNaN(b)) {
return 0;
}
return Math.sqrt(a*a + b*b);
}
</script>
You could do something like this:
Javascript:
function hypotenuse(){
var angleA = document.getElementById['leg1'].val;
var angleB = document.getElementById['leg2'].val;
if(angleA != '' && angleB != ''){
var angleC = Math.sqrt(a*a + b*b);
document.getElementById['result'].val = angleC;
}
}
Your HTML would look like
A:<input type="text" id="leg1" size="2" onblur="hypotenuse()" />
B:<input type="text" id="leg2" size="2" onblur="hypotenuse()" />
Hypotenuse:<input type="text" placeholder="0" id="result" size="2" />

Categories