I can't figure out how the function showInputE() isn't being prepossessed.
I have some if statements within a function. If the if statements are true then they should preform a function. I want the functions to hide or show the the inputs in the easyAssignments div, depending on what the user inputs in numEAI. (Example: user inputs 3, only 3 input boxes will show) However when i click the enter button nothing appears to happen.
<div id ="numEA">
<p>How many easy assignments do you have to do today?</p>
<input min="0" max="5" type="number" id="numEAI">
<button class="w3-button w3-red" onclick="showInputE()">Enter</button>
</div>
<div id="easyAssignments">
<p>What easy assignments do you have to do today?</p>
<input type="text" id="easyA1">
<input type="text" id="easyA2">
<input type="text" id="easyA3">
<input type="text" id="easyA4">
<input type="text" id="easyA5">
</div>
<script>
/* START of show input functions */
function onlyShowInput1(){
document.getElementById("easyA2").style.display = "none";
document.getElementById("easyA3").style.display = "none";
document.getElementById("easyA4").style.display = "none";
document.getElementById("easyA5").style.display = "none";
}
function onlyShowInput2(){
document.getElementById("easyA3").style.display = "none";
document.getElementById("easyA4").style.display = "none";
document.getElementById("easyA5").style.display = "none";
}
/* END of show input functions */
function showInputE(){
var numEAI = document.getElementById('numEAI');
if (numEAI === 1){
onlyShowInput1();
} else if (numEAI === 2){
onlyShowInput2();
}
}
</script>
You are currently comparing a DOM element to a number in your if statement.
In order to test the value contained in the element you can retrieve it using numEAI.value. This returns a string so if you are going to use ===, which tests for equality of value and type, you need to compare it to a string if (numEAI.value === '1'), otherwise to just test equality of value use ==.
/* START of show input functions */
function onlyShowInput1(){
document.getElementById("easyA2").style.display = "none";
document.getElementById("easyA3").style.display = "none";
document.getElementById("easyA4").style.display = "none";
document.getElementById("easyA5").style.display = "none";
}
function onlyShowInput2(){
document.getElementById("easyA3").style.display = "none";
document.getElementById("easyA4").style.display = "none";
document.getElementById("easyA5").style.display = "none";
}
/* END of show input functions */
function showInputE(){
var numEAI = document.getElementById('numEAI');
if (numEAI.value === '1'){
onlyShowInput1();
} else if (numEAI.value == 2){
onlyShowInput2();
}
}
<div id ="numEA">
<p>How many easy assignments do you have to do today?</p>
<input min="0" max="5" type="number" id="numEAI">
<button class="w3-button w3-red" onclick="showInputE()">Enter</button>
</div>
<div id="easyAssignments">
<p>What easy assignments do you have to do today?</p>
<input type="text" id="easyA1">
<input type="text" id="easyA2">
<input type="text" id="easyA3">
<input type="text" id="easyA4">
<input type="text" id="easyA5">
</div>
Change your script to:
function showHide(n) {
let inputs = document.getElementById("easyAssignments").querySelectorAll("input");
let item = 0;
inputs.forEach(function(i) {
item++;
if (item <= n) {
i.style.display = "inline";
} else {
i.style.display = "none";
}
})
}
function showInputE(){
var numEAI = document.getElementById('numEAI').value;
showHide(numEAI);
}
As all of the input items are named with sequential ids, you can switch the display style depending on whether or not the id matches "easyA" + numEAI. There's no need to have a function for each input item.
Related
I'm building a web app that converts Galloons to Liters and vise versa. Got one textbox to enter gallon/litters, the user selects on a radio button what they want to convert too. Now the problem arises when validating the input:
for liters it must be Greater than 0 but less than 1000 for the gallons it must be greater than 0 but less than 4000. So if I've selected liters it must validate only liters but both validations are coming up. Here's my code:
Form:
<body onload="setup()">
<div data-role="page">
<div style="padding: 20px;">
<div data-role="fieldcontain">
<input type="number" id="temperature" name="temperature">
<label id="label">Gallons</label>
</div>
<fieldset data-role="controlgroup">
<legend>Convert to:</legend>
<input type="radio" name="units" id="Gallons" value="Gallons"
onclick="setUnits('Liters')">
<label for="Gallons">Gallons</label>
<input type="radio" name="units" id="Liters" value="Liters"
checked="checked" onclick="setUnits('Gallons')">
<label for="Liters">Liters</label>
</fieldset>
<input type="button" onclick="convert()" value="Convert">
<p id="answer"></p>
</div>
</div>
</body>
JavaScript:
function setup()
{
var cType;
setUnits("Gallons");
cType = "Gallons";
document.getElementById("Gallons").onclick =
function () {
cType="";
cType="Liters";
setUnits("Liters");
CheckInput(cType);
};
document.getElementById("Liters").onclick =
function () {
cType="";
cType="Gallons";
setUnits("Gallons");
CheckInput(cType);
};
CheckInput(cType);
}
function setUnits(unit) {
var label = document.getElementById("label");
label.innerHTML = unit;
}
function CheckInput(cType) {
var CheckInputcType= cType;
var angleInput = document.getElementById("temperature");
if(CheckInputcType.localeCompare("Gallons")==0)
{
angleInput.addEventListener("blur",validateG);
}
else(CheckInputcType.localeCompare("Liters")==0)
{
angleInput.addEventListener("blur",validateL);
}
}
function validateL(){
var angleInput = document.getElementById("temperature");
if (angleInput.value >= 1000 || angleInput.value<=0)
{
alert('Liters must be between 0 and 1000');
angleInput.value = "";
}
}
function validateG() {
var angleInput = document.getElementById("temperature");
if (angleInput.value >= 4000 || angleInput.value<=0)
{
alert('Gallons must be between 0 and 4000');
angleInput.value = "";
}
}
You have a problem with your method CheckInput(cType), because every time you click on Galons or liters radio button you are adding a new listener event on temperature input.
Just simply create one listener and verify radio state on that validator method.
Problem
The maximum number of players for each position is:
2 out of 4 goalies
6 out of 15 defencemen
12 out of 31 forwards
I've gotten to the point where I'll click on a hockey player and that name gets added to a input field in a form, but if you already have two goalies selected, ie has a class of is-active and then click on one of the other two unselected players with the default is-inactive class, that name will still be added into an input when there should only be two goalies max. And unfortunately, this is also the case with the defencemen and the forwards too.
Goal
When starredGoaltenders === maxGoaltenders or starredDefencemen === maxDefencemen or starredForwards === maxFowards the names of players that do not have not been selected of that specific position and do not have an is-active class should not be added to any input in the form.
scripts.js
function countSelected() {
$(".player").on("click", function(){
// Checks if the maximum number of players have been selected
// If so, return false and then do nothing
// If not, the class will toggle from `is-inactive` to `is-active`
if ($(this).find(".picked.is-inactive.full").length > 0) return false;
$(this).find(".picked").toggleClass("is-inactive is-active");
$(".player").removeClass("not-picked");
$(".player").not(":has(.is-active)").addClass("not-picked");
// Count the number of players with stars
var starredGoaltenders = $(".player--goalie").find(".picked.is-active").length;
var starredDefencemen = $(".player--defencemen").find(".picked.is-active").length;
var starredForwards = $(".player--forward").find(".picked.is-active").length;
console.log(starredGoaltenders, starredDefencemen, starredForwards);
// The number of starred players for each position cannot exceed the following numbers
var maxGoaltenders = 2;
var maxDefencemen = 6;
var maxFowards = 12;
// If the number of starred players hits its max, a class of `is-completed` is adding to the corresponding checkmark to indicate that the task has been completed
if (starredGoaltenders === maxGoaltenders) {
$(".checkmark--goalie").addClass("is-completed");
$(".player--goalie").find(".picked").addClass("full");
} else {
$(".checkmark--goalie").removeClass("is-completed");
$(".player--goalie").find(".picked.is-inactive").removeClass('full');
}
if (starredDefencemen === maxDefencemen) {
$(".checkmark--defencemen").addClass("is-completed");
$(".player--defencemen").find(".picked").addClass("full");
} else {
$(".checkmark--defencemen").removeClass("is-completed");
$(".player--defencemen").find(".picked.is-inactive").removeClass('full');
}
if (starredForwards === maxFowards) {
$(".checkmark--forward").addClass("is-completed");
$(".player--forward").find(".picked").addClass("full");
} else {
$(".checkmark--forward").removeClass("is-completed");
$(".player--forward").find(".picked.is-inactive").removeClass('full');
}
// If all the conditions are met show the submit vote button
if (starredGoaltenders === maxGoaltenders && starredDefencemen === maxDefencemen && starredForwards === maxFowards) {
$(".btn--submit").show();
$(".btn--submit").addClass("slideLeft");
} else{
$(".btn--submit").hide();
$(".btn--submit").removeClass("slideLeft");
}
});
} countSelected();
// Every time a player is clicked, note the name of the player
$(".player").on("click", function(){
var playerNames = [];
$("input:text").each(function(i, t) { playerNames.push(t.value) });
if ($(this).find("picked.is-active")) {
var playerName = $(this).find(".player__name").html();
var index = playerNames.indexOf(playerName);
if (index == -1) // Add player
$("input:text:eq(" + playerNames.indexOf("") + ")").val(playerName);
else // Remove player
$("input:text:eq(" + index + ")").val("");
} else {
$("input").val("");
}
});
index.html - Snippet includes form and one out of the 60 available players to be clicked on
<form id="form">
<input type="text" name="p1" id="p1">
<input type="text" name="p2" id="p2">
<input type="text" name="p3" id="p3">
<input type="text" name="p4" id="p4">
<input type="text" name="p5" id="p5">
<input type="text" name="p6" id="p6">
<input type="text" name="p7" id="p7">
<input type="text" name="p8" id="p8">
<input type="text" name="p9" id="p9">
<input type="text" name="p10" id="p10">
<input type="text" name="p11" id="p11">
<input type="text" name="p12" id="p12">
<input type="text" name="p13" id="p13">
<input type="text" name="p14" id="p14">
<input type="text" name="p15" id="p15">
<input type="text" name="p16" id="p16">
<input type="text" name="p17" id="p17">
<input type="text" name="p18" id="p18">
<input type="text" name="p19" id="p19">
<input type="text" name="p20" id="p20">
<button class="btn btn--submit" type="submit"><img src="src/img/ballot-alt.png" class="image--ballot">Submit Vote</button>
</form>
<div class="player player--forward year--2000 year--2010">
<div class="tooltip">
<p class="tooltip__name">Mark Stone</p>
<p class="tooltip__hometown"><span>Hometown:</span> Winnipeg, Man.</p>
<p class="tooltip__years"><span>Years Played:</span> 2008-2012</p>
<div class="tooltip__stats--inline">
<div class="stats__group stats--games">
<p class="stats__header">GP</p>
<p class="stats__number stats__number--games">232</p>
</div>
<div class="stats__group stats--goals">
<p class="stats__header">G</p>
<p class="stats__number stats__number--goals">106</p>
</div>
<div class="stats__group stats--assists">
<p class="stats__header">A</p>
<p class="stats__number stats__number--assists">190</p>
</div>
<div class="stats__group stats--points">
<p class="stats__header">Pts</p>
<p class="stats__number stats__number--points">296</p>
</div>
<div class="stats__group stats--penalties">
<p class="stats__header">Pim</p>
<p class="stats__number stats__number--penalties">102</p>
</div>
</div>
</div>
<div class="player__headshot player--mstone">
<div class="picked is-inactive"><i class="fa fa-star" aria-hidden="true"></i></div>
</div>
<p class="player__name">Mark Stone</p>
<p class="player__position">Forward</p>
</div>
Probably, the easiest way to approach this problem is to repopulate all your inputs every time someone clicks on a player, rather than trying to populate each input once. This means you can keep your application state in a simple, easily understood data structure that is independent of your DOM/UI, rather than having to consult the DOM each time something new happens.
This is how I would probably write it.
var players = [
{name: 'Ovechkin', type: 'F'},
{name: 'Dubnyk', type: 'G'}
// your complete player list goes here
],
selectedPlayers: []; // these are the players the user has chosen
var getCurrentPlayerCount = function (playerType) {
// return the number of players currently selected of one type
return selectedPlayers.reduce(function (count, player) {
if (player.type === playerType) return count + 1;
return count;
}, 0);
}
var selectPlayer = function (player) {
// You call this when someone clicks on a player
var currentForwardCount = getCurrentPlayerCount('F')
currentDefenceCount = getCurrentPlayerCount('D'),
currentGoalieCount = getCurrentPlayerCount('G');
// Do nothing (or show a UI message) if someone goes over their
// player-type limit
if (player.type === 'F' && currentForwardCount > 12) return;
if (player.type === 'D' && currentDefenceCount > 6) return;
if (player.type === 'G' && currentGoalieCount > 2) return;
// If you get here, it means the player can be added, so add
// it to the user's list
selectedPlayers.push(player);
updateUI();
}
I'm not including updateUI here. You can work that out on your own.
If you need to support IE 8 or any other browser that does not support Array.prototype.reduce, you will need to do getCurrentPlayerCount differently.
When the value in the "tds" field range between 1 to 10 below then the input "TAN" has appeared else it should in should not appear(hidden state)
<input id="tds" type="text" onchange="myFunction()"/>
<input id="myP" name="TAN" style="visibility:hidden;" value="test"/>
<script>
function myFunction() {
tdsvalue = document.getElementById('tds').value;
if (tdsvalue <= 10){
document.getElementById("myP").style.visibility = "";
else
}
}
</script>
Set visibility to visible, not ""
And your code should look like this
<input id="tds" type="text" onchange="myFunction()"/>
<input id="myP" name="TAN" style="visibility:hidden;" value="test"/>
<script>
function myFunction() {
tdsvalue = document.getElementById('tds').value;
if (tdsvalue <= 10) {
document.getElementById("myP").style.visibility = "visible";
}
else {
document.getElementById("myP").style.visibility = "hidden";
}
}
</script>
Note : You can also use display:block to show and display:none to hide.
display:none will not be available in the page and does not occupy any space. visibility:hidden hides an element, but it will still take up the same space as before. The element will be hidden, but still affect the layout.
Try the following code i.e. improved version of yours:
<input id="tds" type="text" onkeyup="myFunction(this)"/>
<input id="myP" name="TAN" style="display:none;" value="test"/>
<script>
function myFunction(el) {
var tdsvalue = el.value;
if (tdsvalue >= 1 && tdsvalue <=10){
document.getElementById("myP").style.display= "block";
} else {
document.getElementById("myP").style.display= "none";
}
}
</script>
It appears you have a syntax error caused by else.
I would also recommend you parse the value as an integer using parseInt()
function myFunction() {
var tdsvalue = parseInt(document.getElementById('tds').value);
if (tdsvalue <= 10) {
document.getElementById("myP").style.visibility = "visible";
} else {
document.getElementById("myP").style.visibility = "hidden";
}
}
<input id="tds" type="text" onchange="myFunction()" />
<input id="myP" name="TAN" style="visibility:hidden;" value="test" />
If you have any questions about the source code above please leave a comment below and I will reply as soon as possible.
I hope this helps. Happy coding!
I've been trying to validate this form using Javascript, however for some weird reason only the first input field seems to be doing what it is supposed to do. Here's the relevant snippet of code:
<form method="post" name="myform" action="www.google.com" onsubmit="return validateForm(this);">
<h3 id="secondarytext"><strong>Your details:</strong></h3>
<div class="label1">
<label for="firstName">First Name</label>
<input type="text" id="name" name="name" onblur="validateName(name)" />
<span id="nameError" style="display: none;">Please enter your name, you can only use alphabetic characters</span>
<label for="ssurname" >Surname</label>
<input type="text" id="surname" name="surname" onblur="validateSurname(surname)" /> <br />
</div>
<input type="reset" value="Reset Form">
<input type="submit" value="Submit">
</form>
Javascript:
function validateName(x)
{
var re = /^[A-Za-z]{2,25}$/;
if(re.test(document.getElementById(x).value)){ /* This checks the input's value corresponds with the regular expression (re) */
document.getElementById(x).style.background ='#ccffcc'; /* If it does it changes the background colour of the field to green*/
document.getElementById(x).style.border="4px solid #ccffcc";
document.getElementById(x + 'Error').style.display = "none"; /* This hides the error message because the function returned as true */
return true;
}
else{ /* If the function doesn't return as true this is what happens */
document.getElementById(x).style.background ='#e35152'; /* The background colour of the field changes to red */
document.getElementById(x).style.border="4px solid #e35152";
document.getElementById(x + 'Error').style.display = "block"; /* This displays the error message */
return false;
}
}
function validateSurname(x)
{
var re = /^[A-Za-z]{2,25}$/;
if(re.test(document.getElementById(x).value)){
document.getElementById(x).style.background ='#ccffcc';
document.getElementById(x + 'Error').style.display = "none";
return true;
}
else{
document.getElementById(x).style.background ='#e35152';
document.getElementById(x + 'Error').style.display = "block";
return false;
}
}
function validateForm()
{
var error = 0;
if(!validateName('name'))
{
document.getElementById('nameError').style.display = "block";
error++;
}
if(!validateSurname('surname'))
{
document.getElementById('surnameError').style.display = "block";
error++;
}
if(error > 0)
{
return false;
}
else if(error < 0) {
return true;
}
}
Maybe these changes will help you:
1) Add the error message you want to show when surname is wrong:
<label for="ssurname" >Surname</label>
<input type="text" id="surname" name="surname" onblur="validateSurname('surname')" /> <br />
<span id="surnameError" style="display: none;">Please enter your surname, you can only use alphabetic characters</span>
2) Pass a string to the parameter instead of a javascript var (e.g. do validateSurname('surname') instead of validateSurname(surname)), as the function you've defined is expecting a string as a parameter.
Fiddle demo: http://jsfiddle.net/uzyLogc1/1/
Objective: Understand a Javascript related IE compatibility problem.
Question: Why does my Javascript break in IE and nowhere else (besides "IE sucks," haha) and is there an easy fix.
Details: I have a payment system that allows the user to select between 3 payment methods (via html radio buttons) and uses Javascript to display the appropriate form to complete payment. In chorme and firefox it works perfectly.
In IE however, once the initial radio button is clicked and the Javascript displays the appropriate div the cursor jumps to the lower middle of the page and the user cannot click on any of the input boxes in the form.
The boxes can be reached if the user right clicks on them, but not easily. There are a variety of ways I can get around this, but I'm trying to understand what causes the problem in IE. Especially if it's poor coding on my part. Also, if there is an easy fix to the existing code I'd be interested in hearing it.
index.phtml
<form name="payo" action="/paymentAction/" method="post" >
<div id="tabs">
<div id="nav">
<input type="radio" name="tab" class="div1" value="Inv" /> Invoice <input type="radio" name="tab" class="div2" value="CC" /> Credit Card <input type="radio" name="tab" class="div3" value="Cpn"/> Coupon
</div>
<div id="div1" class="tab">
<!-- INVOICE TEXT -->
</div>
<div id="div2" class="tab">
<!-- CREDIT CARD FORM -->
Credit Card Number: <input type=text name="CardNo" placeHolder="Credit Card Number" value="" maxlength="16">
Expiration Month / Year: <font color="red">* </font>
<select name="ExpMonth">
<option value=""selected>mm</option>
<option >01</option>
<option >02</option>
<option >03</option>
</select>
<select name ="ExpYear">
<option value=""selected>yy</option>
<option >12</option>
<option >13</option>
<option >14</option>
</select>
Street Address Associated With Card: <input type=text name="Address" placeHolder="Address" value="">
</div>
<div id="div3" class="tab">
<!-- COUPON FORM -->
Coupon Code:
<input type="text" name="cpA" size=4 maxlength=4 > -
<input type="text" name="cpnB" size=6 maxlength=6> -
<input type="text" name="cpnC" size=5 maxlength=5>
<br />
</div>
<script type="text/javascript" charset="utf-8">
(function(){
var tabs =document.getElementById('tabs');
var nav = tabs.getElementsByTagName('input');
function hideTabs(){
document.getElementById('div1').style.display = "none";
document.getElementById('div2').style.display = "none";
document.getElementById('div3').style.display = "none";
}
function showTab(tab){
document.getElementById(tab).className = 'tab';
}
hideTabs();
for(var i=0;i<nav.length;i++){
nav[i].onclick = function(){
hideTabs();
var radios = document.getElementsByName('tab');
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
var here = i;
}
}
if (radios[here].value == "Inv") {
document.getElementById('div1').style.display = "block";
} else if(radios[here].value == "CC") {
document.getElementById('div2').style.display = "block";
} else if(radios[here].value == "Cpn") {
document.getElementById('div3').style.display = "block";
} else {
}
}
}
})();
</script>
<div id="formdiv">
<center><input type=submit name="submit" class="ButtonMain" value=" Authorize Payment "></center>
<br />
</div>
</form>
</div>
You fetch all inputs including the form inputs (card number et al.):
var nav = tabs.getElementsByTagName('input');
Then you assign an onclick to each the first act of which is to hide the tabs then reshow them, so whenever any input is clicked focus is lost immediately.
Chrome will not do anything noticeable & restores the elements focus, IE will reset it so the element effectively becomes uncapturable.
You need to only manage changing tabs when the radio button is clicked;
var radios = document.getElementsByName('tab');
for(var i=0;i<radios.length;i++){
radios[i].onclick = function(){
The issue looks like the line:
var nav = tabs.getElementsByTagName('input');
nav includes not just the radio buttons, but also the text input boxes as well, so when you attach the onclick function to all elements of the nav array it's causing the problem you see with the cursor jumping around. Quickest and easiest solution would be to limit it only to the radio buttons within the div id="nav" element:
var nav = document.getElementById('nav').getElementsByTagName('input');
Not required to fix the problem, but you can also simplify the javascript a little, since radios is not necessary anymore. Inside the onclick function, this will refer to the radio button clicked, so you can simplify:
nav[i].onclick = function(){
hideTabs();
var radios = document.getElementsByName('tab');
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
var here = i;
}
}
if (radios[here].value == "Inv") {
document.getElementById('div1').style.display = "block";
} else if(radios[here].value == "CC") {
document.getElementById('div2').style.display = "block";
} else if(radios[here].value == "Cpn") {
document.getElementById('div3').style.display = "block";
} else {
}
}
to:
nav[i].onclick = function(){
hideTabs();
if (this.value == "Inv") {
document.getElementById('div1').style.display = "block";
} else if(this.value == "CC") {
document.getElementById('div2').style.display = "block";
} else if(this.value == "Cpn") {
document.getElementById('div3').style.display = "block";
}
};