Javascript: Focus is not a function - javascript

I'm writing a registration form and am trying to sort out some validation. I got this same problem when my validate button was inside the <form> however to fix this I just moved it out as I guessed the button was causing the form to refresh.
However now after inserting multiple if statement into the "ValidateForm()" function this error message has seemed to come back.
Error: Uncaught TypeError: Forename.focus is not a function
at ValidateForm (Login Form Complex.html?Forename=&Surname=&Username=&Password=&Email=:79)
at HTMLButtonElement.onclick (Login Form Complex.html?Forename=&Surname=&Username=&Password=&Email=:63)**
function ValidateForm() {
var Forename = document.getElementById("Forename").value;
var Surname = document.getElementById("Surname").value;
var Username = document.getElementById("Username").value;
var Password = document.getElementById("Password").value;
var Email = document.getElementById("Email").value;
var Errors = 0
if (Forename == "") {
document.LoginForm.Forename.focus();
Forename.focus();
Errors = Errors + 1
}
if (Surname == "") {
document.LoginForm.Forename.focus();
Surname.focus();
Errors = Errors + 1
}
if (Username == "") {
document.LoginForm.Forename.focus();
Username.focus();
Errors = Errors + 1
}
if (Password == "") {
document.LoginForm.Forename.focus();
Password.focus();
Errors = Errors + 1
}
if (Errors != 0) {
alert("Please fill in the highlighted boxes")
return false;
}
}
body {
margin: 0;
padding: 0;
background: url(LoginBack.jpg);
background-size: cover;
background-position: center;
font-family: century gothic;
}
.loginbox {
width: 420px;
height: 680px;
background: #5CDB95;
color: #05386B;
top: 50%;
left: 50%;
position: absolute;
transform: translate(-50%, -50%);
box-sizing: border-box;
padding: 70px 30px;
border-radius: 30px;
}
.avatar {
width: 150px;
height: 150px;
border-radius: 50%;
position: absolute;
top: -75px;
left: calc(50% - 75px);
}
h1 {
margin: 0px;
padding: 0 0 20px;
text-align: center;
font-size: 40px;
}
.loginbox p {
margin: 0;
padding: 0;
font-weight: bold;
}
.loginbox input {
width: 100%;
margin-bottom: 20px;
}
.loginbox input[type="text"],
input[type="password"],
input[type="email"] {
border: none;
border-bottom: 1px solid #05386B;
background: transparent;
outline: none;
height: 40px;
font-size: 20px;
color: #379683;
}
.loginbox button[type="Submit"] {
border: 2px solid #05386B;
background: #379683;
height: 40px;
width: 362px;
font-size: 20px;
color: ;
border-radius: 20px;
}
.loginbox button[type="submit"]:hover {
cursor: pointer;
background: #8EE4AF;
}
.loginbox a {
text-decoration: none;
font-size: 15px;
line-height: 20px;
color: #379683;
}
.loginbox a:hover {
cursor: pointer;
color: #8EE4AF;
}
.loginbox input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus {
border: none;
border-bottom: 1px solid #8B0000;
background: transparent;
outline: none;
height: 40px;
font-size: 20px;
color: #8B0000;
}
<div class="loginbox">
<img src="Logo.jpg" class="avatar">
<h1> Create Account </h1>
<form name="LoginForm">
<p>Forename<p><input type="text" name="Forename" id="Forename" placeholder="Enter Forename here">
<p>Surname<p><input type="text" name="Surname" id="Surname" placeholder="Enter Surname here">
<p>Username<p><input type="text" name="Username" id="Username" placeholder="Enter Username here">
<p>Password<p><input type="password" name="Password" id="Password" placeholder="Enter Password here">
<p>Email<p><input type="email" name="Email" id="Email" placeholder="Enter Email here">
<!--
<p>Gender<p><input type="radio" id="Male" name="Gender" value="Male">Male</input>
<input type="radio" id="Female" name="Gender" value="Female">Female</input>
-->
<button onclick="ButtonSubmit()" type="Submit" value="True" name="ButtonSubmit"> Submit </button><br /><br />
Forgot your password? <br />
Already got an account? <br /><br />
</form>
<button onclick="ValidateForm()"> Validate </button>
</div>

Your Forename variable is not holding a reference to a DOM element. It is referencing the .value of that element. The same is true for all of your other DOM variables.
var Forename = document.getElementById("Forename").value;
The value doesn't have a .focus() method. The element does.
In general, it's best not to set variables to properties of DOM elements because, if you determine later that you need a different DOM property, you have to scan the DOM again for a reference you already scanned for. Additionally, setting variables to the DOM elements themselves, and not properties of the elements, will prevent your error, which is very common.
So, change your variables to be set up like this:
var Forename = document.getElementById("Forename");
And then, when you need the value, you can just write:
Forename.value
And, when you want to use the focus() method, just write:
Forename.focus();
You can access whatever aspect of the element you want if you always start from the element itself.

E.g.Forename var have the value of Forename input element then:
var Forename = document.getElementById("Forename"); //DOM element
var fornameValue = Forename.value //value
Forename.focus() //focus function

Related

HTML Number Input: Only Allow Arrow Buttons

Here is what I mean:
Is it possible to only allow input via clicking the arrow buttons, and NOT from actually typing?
Ie: I could not type in "11", but if I click the up arrow 11 times then it will go to 11?
Here is my input field right now:
<input type="number" min="00" max ="99" id="timer02_min"
maxlength="2" value="00">
Is there some native way of doing this? Or should I look more into buttons and some styling?
Use event.preventDefault() in keydown event;
// no keyboard
document.getElementById("timer02_min").addEventListener("keydown", e => e.preventDefault());
// allow up/down keyboard cursor buttons
document.getElementById("timer02_min2").addEventListener("keydown", e => e.keyCode != 38 && e.keyCode != 40 && e.preventDefault());
no keyboard:
<input type="number" min="00" max ="99" id="timer02_min"
maxlength="2" value="00">
<br>
with up/down cursor keys:
<input type="number" min="00" max ="99" id="timer02_min2"
maxlength="2" value="00">
function change(n){
var num = document.getElementById("num");
var number1 = num.innerHTML;
var number = Number(number1);
var num2 = number.toString();
if(n == "s"){
}else{
number = number+n;
}
if(number <= 0){
number = 0;
}
if(number > 99){
number = 99;
}
if(num2.length == 1){
var num1 = number;
number = "0"+num1;
}
document.getElementById("num").innerHTML = number;
}
change("s");
.input{
border-style: solid;
border-color: gray;
border-width: 1px;
border-radius: 2px;
padding: 1px;
height: 26px;
width: 40px;
text-align: left;
position: relative;
padding-left: 10px;
}
.spinner-button {
position: absolute;
top: 0px;
right: 0px;
}
#inc-button{
padding-top: 3.5px;
background-color: #ccc;
width: 14.5px;
text-align: center;
margin-bottom: 1px;
height: 10px;
line-height: 10px;
cursor: pointer;
border: none;
user-select: none; /* Standard */
}
#dec-button{
cursor: pointer;
padding-top: 3px;
background-color: #ccc;
width: 14.5px;
text-align: center;
margin: 0px;
height: 10px;
line-height: 10px;
border: none;
user-select: none; /* Standard */
}
#inc-button:hover,#dec-button:hover{
background-color: #b5b5b5;
}
<div id="timer02_min" class="input">
<div id="num">00</div>
<div class="spinner-button">
<div onclick="change(1);" id="inc-button">+</div>
<div onclick="change(-1);" id="dec-button">-</div>
</div>
</div>
Try This!
The Number you want to start put it in the #num div.

How to trigger HTML password input on enter press

I'd like to build a password prompt screen that redirects you somewhere after entering the correct password and pressing Enter. However, currently it only works by clicking the "Submit" button. I'd appreciate any help on how to adapt this code:
Here's what my code looks like for now:
function checkPswd() {
var confirmPassword = "asdf";
var password = document.getElementById("pswd").value;
if (password == confirmPassword) {
window.location.replace('http://www.google.com');
}
}
#import url('https://fonts.googleapis.com/css?family=VT323');
body {
background-color: #ffffff;
display: table;
}
.div1 {
height: 100%;
width: 100%;
display: table;
position: absolute;
top: 0;
left: 0;
}
.div2 {
text-align: center;
display: table-cell;
vertical-align: middle;
font-family: VT323;
font-size: 25px;
color: #656262;
}
.box {
text-align: center;
font-size: 20px;
font-family: VT323;
outline: none;
width: 250px;
height: 35px;
border: none;
border-bottom: 2px solid #656262;
}
.confirm {
border: none;
font-size: 20px;
font-family: VT323;
margin-top: 10px;
color: #656262;
background-color: rgba(0, 0, 0, 0);
cursor: pointer;
}
<div class="div1">
<div class="div2">
<form>
<input class="box" type="password" placeholder="123" id="pswd">
<br>
<input class="confirm" type="button" value="SUBMIT" onclick="checkPswd();" />
</form>
</div>
</div>
You can use the keyup event to detect when a key is pressed and then check if its code is 13, the code of Enter. If so, you can submit your form, or in your case call checkPswd.
Code:
/* Cache the password input. */
var pswd = document.getElementById("pswd");
/* Call 'checkPswd' when the 'Enter' key is released. */
pswd.onkeyup = function (e) {
if (e.which == 13) checkPswd();
};
/* Prevent the form from submitting. */
pswd.parentElement.onsubmit = function () {
return false;
};

How to create placeholder with text

I want to create form like above attached image. Can add placeholder to text box. But when user press keys placeholders missing. I need to show placeholders above the text box when key press inside the text box.
You can use html required, autofocus and pattern attribute with RegExp ^[a-zA-Z]+(?:\s[a-zA-Z]+$|$) to match one or more a-z characters case insensitive at beginning of input, followed by space character, followed one or more a-z characters case insensitive by end of input, or end of input to handle two first names, for example "Billy Joe", "Norma Jean", "Sarah Jane"; <label> element adjacent to <input> element; css :invalid, :valid, :before; :after.
When input is :invalid set border to red, outline to none; set adjacent label element :before content of to "das", label :after content to !; at :valid:focus set label :before content to "First Name", label :after to UTF-8 "CHECK MARK" ✓
#charset "UTF-8";
#input {
height: 3.14em;
left: 0px;
outline: none;
padding: 6px;
margin: 4px;
width: 150px;
}
#input:valid {
border: 1px solid green;
box-shadow: .015em .015em .015em green;
}
#input:invalid {
border: 1px solid red;
box-shadow: .015em .015em .015em red;
}
#input:invalid + [for="input"]:before {
content: "das";
}
#input + [for="input"]:after {
font-weight: bold;
left: 160px;
top: 12px;
position: absolute;
}
#input:invalid + [for="input"]:after {
content: "!";
color: red;
}
#input:valid + [for="input"]:after {
content: "\2713";
color: green;
}
#input:valid + [for="input"]:before {
content: "First Name";
color: #ccc;
}
label[for="input"]:before {
position: absolute;
left: 12px;
padding: 6px;
}
<meta charset="UTF-8" />
<input id="input" type="text" pattern="^[a-zA-Z]+(?:\s[a-zA-Z]+$|$)" required autofocus/>
<label for="input"></label>
#lbl{
color:green;
}
#in{
border:none
}
#in,#in_container,#lbl{
background:white
}
#in_container{
display:inline-block;
border:solid 1px black;
}
<div id="in_container">
<span id="lbl">First Name</span>
<br>
<input type='text' id="in">
</div>
Some CSS magic:
.input-group * {
left: 0;
position: absolute;
font-family: sans-serif;
}
.input-group input {
height: 30px;
font-size: 20px;
padding-top: 12px;
}
.input-group label {
padding-left: 3px;
padding-top: 2px;
opacity: .5;
}
<div class="input-group">
<input id="first-name" type="text">
<label for="first-name">First Name</label>
</div>
Basically, just play around with the sized until you get a solution working for you. I'd group each "input box" section, they are composed of a label superimposed onto a text input.
#container {
position: relative;
}
#container * {
font-size: 20px;
}
#my-input {
height: 30px;
}
#lbl-my-input {
line-height: 1.5;
position: absolute;
color: #bebebe
}
#my-input:focus {
padding-top: 40px;
}
<div id="container">
<label id="lbl-my-input" for="my-input">First</label>
<input id="my-input" type="text">
</div>
Here is my idea:
I put the label and the input in a div
I make div position relative, label position absolute => label will overlapped input
I use css for input:focus. When focusing happens, I extend padding-top of input.
The rest is styling (choosing) right line-height, font-size, and padding to make it beautiful
I have a solution for this.
<label style="visibility: hidden;" id="label">User Name</label>
<input id="textField" type="text" placeholder="User Name" onfocus="showLabel()" onblur="hideLabel()"></input>
<script>
function showLabel() {
var label = document.getElementById("label");
var textField = document.getElementById("textField");
textField.placeholder="";
label.style.visibility = "inherit";
}
function hideLabel() {
var label = document.getElementById("label");
var textField = document.getElementById("textField");
textField.placeholder="User Name";
if (!textField.value) {
label.style.visibility = "hidden";
}
}
</script>

Can't get .removeChild to work on newly dynamically created div

I'm attempting to make a remove button for my dynamically created input boxes, however I can't seem to get it to work. I get the feeling its because the "child" didn't exist upon initially loading the script, but I'm not sure.
Any help would be appreciated. Thanks.
var addButton = document.getElementById("add-button");
var removeButton = document.getElementById("remove-button");
var incomeSection = document.getElementById("income");
var incomeRow = document.getElementById("income-row");
var itemCounter = 2
incomeSection.addEventListener("click", activateItem);
function activateItem(e) {
if (e.target.id == "add-button") {
incomeSection.innerHTML += '<div id="income-row"><input class="input" type="text" name="income-type-1" placeholder="Income source ' + itemCounter + '"><span class="currency">£</span><input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount"><input id="remove-button" class="button" type="button" value="-"></div>';
itemCounter++;
}
if (e.target.id == "remove-button") {
incomeSection.removeChild(incomeRow);
}
}
html body {
background-color: #c9c9c9;
font-family: 'Montserrat', sans-serif;
color: #686868;
}
#income {
padding: 10px;
}
.input {
padding: 8px;
font-size: 14px;
margin-right: 10px;
margin-bottom: 5px;
width: 30%;
}
.button {
width: 25px;
height: 25px;
}
.currency {
padding: 10px;
font-size: 14px;
margin-right: -4px;
margin-bottom: 5px;
background-color: darkgray;
color: white;
}
<div id="income">
<div id="income-displayed">
<h2>Income: <span></span></h2>
</div>
<div id="income-row">
<input class="input" type="text" name="income-type-1" placeholder="Income source">
<span class="currency">£</span>
<input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount">
<input id="add-button" class="button" type="button" value="+">
</div>
</div>
Just replace the following line it will resolved your issue :-
incomeSection.removeChild(incomeRow);
with the following
e.target.parentNode.remove();
var addButton = document.getElementById("add-button");
var removeButton = document.getElementById("remove-button");
var incomeSection = document.getElementById("income");
var incomeRow = document.getElementById("income-row");
var itemCounter = 2
incomeSection.addEventListener("click", activateItem);
function activateItem(e) {
if (e.target.id == "add-button") {
incomeSection.innerHTML += '<div id="income-row"><input class="input" type="text" name="income-type-1" placeholder="Income source '+itemCounter+'"><span class="currency">£</span><input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount"><input id="remove-button" class="button" type="button" value="-"></div>'; itemCounter ++;
}
if (e.target.id == "remove-button") {
e.target.parentNode.remove();
}
}
html body {
background-color: #c9c9c9;
font-family: 'Montserrat', sans-serif;
color: #686868;
}
#income {
padding: 10px;
}
.input {
padding: 8px;
font-size: 14px;
margin-right: 10px;
margin-bottom: 5px;
width: 30%;
}
.button {
width: 25px;
height: 25px;
}
.currency {
padding: 10px;
font-size: 14px;
margin-right: -4px;
margin-bottom: 5px;
background-color: darkgray;
color: white;
}
<div id="income">
<div id="income-displayed"><h2>Income: <span></span></h2></div>
<div id="income-row">
<input class="input" type="text" name="income-type-1" placeholder="Income source"><span class="currency">£</span><input class="input income-amount" type="text" name="income-amount-1" placeholder="Amount"><input id="add-button" class="button" type="button" value="+"></div>
</div>
This Snippet demonstrates how to add and remove elements to and from the DOM utilizing:
cloneNode
.children
parentNode
Further details are commented in the source
SNIPPET
// #incFormA element will bind with eventListener
var form = document.getElementById("incFormA");
// #setA will contain the #dupes
var set = document.getElementById("setA");
// Reference to clone template #dupe
var dupe = document.getElementById('dupe');
// Increment counter that will ensure unique ids
var cntr = 0;
// If any part of the form is clicked call actDeact
form.addEventListener("click", actDeact);
/*
| actDeact()
| -If the clicked button's id === addA
| then clone #dupe and add an id (#dupe+cntr)
| -Iterate through it's children
| and assign unique ids and names to
| the 1st and 3rd children of (#dupe+cntr)
| -Append #dupe+cntr to #setA
*/
/*
| -If the clicked button was a .remA
| find it's parentNode and remove it.
*/
function actDeact(e) {
cntr++;
if (e.target.id === 'addA') {
var clone = dupe.cloneNode(true);
clone.id = 'dupe' + cntr;
var i;
var grp = clone.children;
var qty = grp.length;
for (i = 0; i < qty; i++) {
switch (i) {
case 0:
grp[0].id = 'inc' + cntr;
grp[0].name = 'inc' + cntr;
break;
case 2:
grp[2].id = 'amt' + cntr;
grp[2].name = 'amt' + cntr;
break;
default:
break;
}
}
setA.appendChild(clone);
} else if (e.target.className === "remA") {
var clone = e.target.parentNode;
setA.removeChild(clone);
} else return false;
}
html body {
background-color: #c9c9c9;
font-family: 'Montserrat', sans-serif;
color: #686868;
}
#setA {
padding: 10px;
}
/* The clone template is out of the way
| yet still accessible for cloning.
*/
#dupe {
display: none;
}
.input {
padding: 8px;
font-size: 14px;
margin-right: 10px;
margin-bottom: 5px;
width: 30%;
}
button {
width: 25px;
height: 25px;
float: right;
}
.currency {
padding: 10px;
font-size: 14px;
margin-right: -4px;
margin-bottom: 5px;
background-color: darkgray;
color: white;
}
/*
| This ruleset is for positioning #addA
*/
.block {
position: relative;
display: block;
min-height: 100%;
width: 20%;
left: 80%;
bottom: 15px;
}
<!--Use <form> to post collect and send data*-->
<form id='incFormA' name='incFormA'>
<fieldset id="setA">
<legend class="display">
<!--Use <output> to calculate and display data*-->
<h2>Income: <output id='outA'></output></h2>
</legend>
<div class='block'>
<!--One add <button>-->
<button id="addA" type='button'>+</button>
</div>
<!--#dupe is the group of elements kept as a clone template-->
<span id='dupe'>
<input id='inc' class="input" name="inc" type="text" placeholder="Income source">
<span class="currency">£</span>
<input id="amt" class="input" name="amt" type="text" placeholder="Amount">
<button class="remA">-</button>
</span>
</fieldset>
</form>
<!--*Choice of elements optional-->

Adding Inputs to a Form Dynamically Via Javascript

I'm fixing up a form that had a series of areas with two or three duplicate inputs for things like employer name, position, etceteras. I thought it would be easier to just dynamically add them with an onclick button but I am having two major problems: (1) When the onclick event create a new line of inputs the label attributes seems to abandon their css and (2) When you click into the input of the form the label should raise up, but the inputs no longer raise their respective labels.
My questions are (1) What is required to amend the css to keep the labels relative to their inputs and (2) Why/How are the inputs working in the first level of inputs and then not the second? Also, how can I fix this?
Any help would be great!
I've recreated the problem in a minor way in the code pen below. If you click inside the inputs you'll understand what I mean by "raising."
CodePen Example : http://codepen.io/theodore_steiner/pen/WGOaAR
HTML:
<p class="subtitleDirection">Please list your employment histroy in chronological order, beginning with your current position (Limit of Three)</p>
<div class="clearFix"></div>
<div id="employmentHistory">
<div class="input-group" id="employment-history-1">
<input type="text" name="job_1" />
<label class="schoolBoard">School Board</label>
<input type="text" name="position_1" />
<label class="position">Position</label>
<input type="text" name="years_1" />
<label class="years">Years</label>
<button type="button" id="add_job()" onclick="addJob()" value="+">+</button>
</div>
</div><!--end of employmentHistory Div-->
CSS:
input
{
background: none;
border: 1px solid #21a1e1;
margin: 15px;
margin-top: 25px;
margin-left: 15px;
margin-bottom: 25px;
display: inline-block;
height: 30px;
width: 320px;
float: left;
}
.input-group label
{
position: absolute;
left: 17px;
top: 42px;
font-style: italic;
font-size: 17.5px;
color: #999;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
pointer-events: none;
transition: all 0.2s ease;
}
.input-group input:focus+label,
.input-group input.has-value+label {
top: 20px;
font-size: 12px;
color: #aaa;
}
input:focus,
input:active
{
outline: none;
}
input[type="text"],
input[type="email"]
{
border: none;
border-bottom: 1px solid #b3c1cc;
}
.input-group
{
position: relative;
}
#teaching-experience-years input
{
margin-left: 70px;
}
#teaching-experience-years label
{
left: 421px;
}
#employment-history-1 input
{
width: 220px;
float: left;
}
#employment-history-1 label.position
{
left: 265px;
}
#employment-history-1 label.schoolBoard
{
left: 15px;
}
#employment-history-1 label.years
{
left: 514px;
}
JS:
var i = 1;
function addJob()
{
if( i <= 3 )
{
i++;
var div = document.createElement("div");
div.innerHTML = '<div class="input-group" id="employment-history-1"><label class="schoolBoard">School Board</label><input type="text" name="job_'+i+'"><label class="position">Position</label><input type="text" name="position_'+i+'"><label class="years">Years</label><input type="text" name="years_'+i+'"><button type="button" id="add_job()" onclick="addJob()" value="+"></button></div>';
document.getElementById("employmentHistory").appendChild(div);
}
};

Categories

Resources