I am creating a sign-in page. I am currently busy with validation part in JS.
What I wan to know, if this is the correct way in doing it.
I did a logic that says if username is not entered error message should appear below the username stating Please add your username.
This is how I did the HTML element and js logic
HTML
<div class="container">
<form action="" class="form">
<div class="heading">
<h1>Log In</h1>
<p>Welcome to your finacial smart decision making</p>
</div>
<div class="row mb-3 align-item-center">
<label for="formGroupEampleInput" class="form-label" id="username">Username</label>
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="User Name" required>
<div class="username-error"></div>
</div>
<div class="row mb-3 align-item-center">
<label for="formGroupEampleInput" class="form-label" id="password">Password</label>
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="Password" required>
<div class="password-error"></div>
</div>
<button type="button" class="btn btn-primary" onclick ="validate()">Login</button>
</form>
<div class="side-image-container">
</div>
JS
function validate(){
let username = document.querySelector("#username");
let password = document.querySelector("#username");
let usernameError = document.querySelector(".username-error");;
const createdEl = document.createElement("div");
createdEl = document.createTextNode("Please add your username");
if(!username){
createdEl.appendChild(usernameError);
}
}
First of all I would recommend you using id instead of class to get querySelector, because, with id you will get a single element. but with class you may get list of elements.
After, I think you are appending in wrong way the child, you should do next:
usernameError.appendChild(usernameError);
Or you can use innerHtml.
The best way to do that:
Normally, if you have a fixed text to show or hide, you don’t need to create it dynamically and append to a div.
You can create a class to hide it.
html:
<div class="username-error hide">
Please add your username
</div>
css:
.hide{
display:none;
}
So, when you want to show the error just remove this class from your error element (div), otherwise add it.
js:
if(!username){
element.classList.remove("hide");
}
let username = document.querySelector("#username");
let password = document.querySelector("#username");
let usernameError = document.querySelector(".username-error");;
let createdEl = document.createElement("div");
let createdE2 = document.createTextNode("Please add your username");
createdEl.appendChild(createdE2);
if(!username.value){
usernameError.appendChild(createdEl);
}
}
Use this instead
There are multiple issues with your code:
username and password id is set on <label> element, not <input>
validate() function is trying assign a textNode element to a constant
you are trying to append existing .username-error element to a newly created textElement instead of vise-versa
when error printed there is no way remove the error
since your error placeholder element contains just text, you don't need create textNode, you can simply change the text via textContent property.
Here is simplified version that fixes all the above:
function validate(){
let username = document.querySelector("#username");
let password = document.querySelector("#password");
let usernameError = document.querySelector(".username-error");;
let passwordError = document.querySelector(".password-error");;
usernameError.textContent = username.value == "" ? "Please add your username" : "";
passwordError.textContent = password.value == "" ? "Please add your password" : "";
}
<div class="container">
<form action="" class="form">
<div class="heading">
<h1>Log In</h1>
<p>Welcome to your finacial smart decision making</p>
</div>
<div class="row mb-3 align-item-center">
<label for="formGroupEampleInput" class="form-label">Username</label>
<input type="text" class="form-control" id="username" placeholder="User Name" required>
<div class="username-error"></div>
</div>
<div class="row mb-3 align-item-center">
<label for="formGroupEampleInput" class="form-label" >Password</label>
<input type="text" class="form-control" id="password" placeholder="Password" required>
<div class="password-error"></div>
</div>
<button type="button" class="btn btn-primary" onclick ="validate()">Login</button>
</form>
<div class="side-image-container">
</div>
Related
there is a piece of my html code:
<!-- STEP 1: class .active is switching steps -->
<div data-step="1" class="">
<h3>Załóż fundację:</h3>
<div class="form-group form-group--inline">
<label> Nazwa <input type="text" name="name" id="name" /> </label>
<label> Opis <input type="text" name="description" id="description" /> </label>
</div>
<div class="form-group form-group--buttons">
<button type="button" class="btn next-step">Dalej</button>
</div>
</div>
<!-- STEP 2 -->
<div data-step="2">
<h3>Podaj typ fundacji</h3>
<div class="form-group form-group">
{{form1}}
</div>
<div class="form-group form-group--buttons">
<button type="button" class="btn prev-step">Wstecz</button>
<button type="button" class="btn next-step">Dalej</button>
</div>
</div>
In the step1, i am able to get the values from inputs by id, like:
var name = document.getElementById('name').value;
How can i do such a thing with the {{form1}}, it is kind of select field:
class AddFundationTypeForm(forms.Form):
type = forms.ChoiceField(choices=type_of_organization)
type_of_organization is a a dict, with 3 key-value pairs.
you can do this with any form field by adding prefix id_
so for your type field:
var type = document.getElementById('id_type').value;
django by default makes id for each field by using 'id_'+ your_field_name
and you want to obtain whole form then you should do this in your template.html
Template
<form id="myForm" action="" method="post">
{{form1}}
</form>
and then in javascript:
var form = document.getElementById('myForm')
Thanks, however, i've added new field to my form:
class AddFundationForm(forms.Form):
type = forms.ChoiceField(choices=type_of_organization)
categories = forms.MultipleChoiceField(choices=category_choices, widget=forms.CheckboxSelectMultiple)
JS:
var type = document.getElementById('id_type').value; (that works)
var category = document.getElementById('id_categories').value; (it doesn't)
Could you tell me what's the difference between defining two variables above?
For a Flask app I am trying to set the cursor into an input text field in a form. The form looks like this:
<form method="get" autocomplete="off">
<div class="row">
<div class="four columns">
<label for="from-currency">Exchange:</label>
<input type="text" placeholder="currency to exchange from" value="{{ from_curr }}" name="from_currency" id="from-currency" class="input-field"/>
</div>
<div class="four columns">
<label for="to-currency">To:</label>
<input type="text" placeholder="currency to exchange to" value="{{ to_curr }}" name="to_currency" id="to-currency" class="input-field"/>
</div>
<div class="four columns">
<label for="calculate-button"> </label>
<input type="submit" value="Calculate" id="calculate-button" class="input-field">
</div>
</div>
</form>
I tried using JavaScript (element.focus();), but it did not move the cursor into my input field.
<script>
function submit_param(inp) {
inp.addEventListener("input", function(event) {
var val = this.value;
var urlParams = new URLSearchParams(window.location.search);
urlParams.set(inp.name, val);
var queryString = urlParams.toString();
history.pushState({}, "", "?"+queryString);
location.reload();
inp.focus();
});
}
submit_param(document.getElementById("from-currency"));
submit_param(document.getElementById("to-currency"));
</script>
What am I doing wrong, or how else can I move the cursor back into the input filed at the end of my script block?
How can I set cursor into html text input field?
<input type="text" autofocus>
The autofocus attribute is a boolean attribute.
When present, it specifies that an element should automatically get focus when the page loads.
Hope this helps. Good luck.
I have an HTML form with 4 inputs fields inside it. All these input fields have the same class and ID, the only differences are the "divs" surounding the inputs.
One form is in the header the other one in the content, and inside each of them, one field is a username field to login, and the other one to register.
<div class=theheader>
<h1> The Header</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field" name="username" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field" name="username" size="30" type="text" >
</div>
</div>
</div>
</div>
<div class=thecontent>
<h1> Form Content</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field" name="username" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field" name="username" size="30" type="text" >
</div>
</div>
</div>
</div>
Here is an example of what it looks like : http://jsfiddle.net/M6R7K/78/.
I need to add a placeholder inside each of these fields, but the tricky thing is, I don't have any direct access to this HTML code, because this one is automatically generated by a third party plugin. So I can only add javascript or css, using the existing classes and ids.
So I used the javascript :
document.getElementById("username_field").setAttribute("placeholder", "Username");
And it has indeed add the correct placeholder in the correct field. The problem is, it only add the placeholder in the 1st field found, not all of them. Even if I add several lines of javascript.
So the question : How to fill up all these field with a placeholder without touching the HTML code ? (With javascript or anything else) And at the best possible, having a different placeholder for each field ? (One needs to be "username and email", and the other one "username" only). We should be able to use the classes of the div's, just like we can do in CSS. But I wasn't able to figure it out.
Thanks !
Your code set placeholder one of them. Standard don't define which of them will get the placeholder because standard forces you tou use ID only once per page. You need to set placeholders for all elements with input_text class. You can do it by array with placeholders and iterating fields: In each iteration set i-th placeholder from array by this code
var placeholders = ["Username", "Email", "Phone", "Credit card"]
var elements = document.getElementsByClassName("input_text");
for (var i = 0; i < elements.length; i++) {
elements[i].setAttribute("placeholder", placeholders[i]);
}
Example: http://jsfiddle.net/M6R7K/81/
The best practice is set placeholders normally in HTML.
First of all you cannot use the same id for more then one element.
Second: try to use as input name attribute meaningful values. If you cannot touch the HTML you can always use the index parameter inside the forEach loop, this could be an idea. Another idea could be to look for the root element in order to distinguish the input fields.
I tried to do for you, right to give you an idea on how to solve your problem:
window.onload = function() {
Array.prototype.slice.call(document.getElementsByClassName("input_text")).forEach(function(currentValue, index) {
currentValue.setAttribute("placeholder", currentValue.getAttribute('name'));
});
}
<div class=theheader>
<h1> The Header</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field1" name="username" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field2" name="password" size="30" type="text" >
</div>
</div>
</div>
</div>
<div class=thecontent>
<h1> Form Content</h1>
<div class="fullform">
<div class="container register">
<div class="form_group required">
<input class="input_text" id="username_field3" name="email" size="30" value="" type="text">
</div>
</div>
<div class="container login">
<div class="form_group">
<input class="input_text" id="username_field4" name="other" size="30" type="text" >
</div>
</div>
</div>
</div>
I have been able to find the solution, using the "attr" function, and the Jquery framework.
This is the function that I applied to each of the inputs, in order to create a unique placeholder (example for the 1st field) :
$(".theheader .register input").attr('placeholder', 'Username Header')
This code allows to retrieve the DIV CLASS of each input field, and apply a customized field.
So for my example, it would be this :
$(".theheader .register input").attr('placeholder', 'Username Header')
$(".theheader .login input").attr('placeholder', 'Username or Email Header');
$(".thecontent .register input").attr('placeholder', 'Username Content');
$(".thecontent .login input").attr('placeholder', 'Username or Email Content');
And each field has his customized placeholder !
Here is the result : https://jsfiddle.net/3ddo465n/9/
Thank you all for the contribution !
This is my first real-world JavaScript project. Please be kind...
I'm creating a form with required fields. With JavaScript, I am collecting the required fields as objects in an Array, each object having the properties "object" (the HTML objects themselves, from which I can get object.id and object.value) "description" (to display to users) and "error" (the HTML objects beneath each input field where corresponding validation errors appear).
Then I have a function (to be used onBlur, for instant feedback) that checks to see if the value of the field is null, and if so, it displays the validation error beneath the corresponding field.
I'm trying to set the onblur attribute for each input field using a FOR loop that runs through the array of required fields. I have a setAttribute statement that works perfectly if I create an individual statement for each object in the Array, individually. But as soon as I change it to a FOR loop, the onblur event for ANY field pops up the validation error for the FIRST input field, only. This has got to be a freshman mistake, but I've searched high and low and rewritten this thing ten different ways and can't make it work with a loop...
I put my code in a Fiddle so you can see it -- but it doesn't actually work in the fiddle, only in my local dev environment (maybe that indicates another problem?). Here's the code:
//create array with constructor to identify all required fields
var allRequired = [];
function RequiredField(theID, theDescription) {
this.object = document.getElementById(theID);
this.description = theDescription;
this.error = document.getElementById("error-" + theID);
allRequired.push(this);
}
var fieldFname = new RequiredField("fname", "First Name");
var fieldLname = new RequiredField("lname", "Last Name");
var fieldEmail = new RequiredField("email", "Email");
var fieldPhone = new RequiredField("phone", "Phone");
var fieldRole = new RequiredField("role", "Desired Role");
var fieldPortfolio = new RequiredField("portfolio", "Portfolio/Website URL");
function requireField(theDescription, theValue, theError) {
if (theValue === "") {
theError.innerHTML = "<p>" + theDescription + " is required.</p>";
} else {
theError.innerHTML = "";
}
} //end function
for (i = 0; i < allRequired.length; i++) {
allRequired[i].object.setAttribute("onBlur", "requireField(allRequired[i].description, allRequired[i].object.value, allRequired[i].error);");
}
/* THIS WORKS IN MY LOCAL DEV ENVIRONMENT...
allRequired[0].object.setAttribute("onBlur", "requireField(allRequired[0].description, allRequired[0].object.value, allRequired[0].error);");
allRequired[1].object.setAttribute("onBlur", "requireField(allRequired[1].description, allRequired[1].object.value, allRequired[1].error);");
allRequired[2].object.setAttribute("onBlur", "requireField(allRequired[2].description, allRequired[2].object.value, allRequired[2].error);");
allRequired[3].object.setAttribute("onBlur", "requireField(allRequired[3].description, allRequired[3].object.value, allRequired[3].error);");
allRequired[4].object.setAttribute("onBlur", "requireField(allRequired[4].description, allRequired[4].object.value, allRequired[4].error);");
allRequired[5].object.setAttribute("onBlur", "requireField(allRequired[5].description, allRequired[5].object.value, allRequired[5].error);");
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="form-careers" id="form-careers" action="form-process.php" enctype="multipart/form-data" onsubmit="return validateForm()" method="post">
<div class="form_labels">
<p>
<label for="fname">First Name:</label>
</p>
</div>
<div class="form_inputs">
<p>
<input type="text" name="fname" id="fname" required />
</p>
<div class="error" id="error-fname"></div>
</div>
<div class="form_labels">
<p>
<label for="lname">Last Name:</label>
</p>
</div>
<div class="form_inputs">
<p>
<input type="text" name="lname" id="lname" required />
</p>
<div class="error" id="error-lname"></div>
</div>
<div class="form_labels">
<p>
<label for="email">Email:</label>
</p>
</div>
<div class="form_inputs">
<p>
<input type="email" name="email" id="email" required />
</p>
<div class="error" id="error-email"></div>
</div>
<div class="form_labels">
<p>
<label for="phone">Phone:</label>
</p>
</div>
<div class="form_inputs">
<p>
<input type="tel" name="phone" id="phone" placeholder="###-###-####" pattern="\d{3}[\-]\d{3}[\-]\d{4}" required />
</p>
<div class="error" id="error-phone"></div>
</div>
<div class="form_labels">
<p>
<label for="role">Desired Role:</label>
</p>
</div>
<div class="form_inputs">
<p>
<input type="text" name="role" id="role" required />
</p>
<div class="error" id="error-role"></div>
</div>
<div class="form_labels">
<p>
<label for="portfolio">Portfolio/Website:</label>
</p>
</div>
<div class="form_inputs">
<p>
<input type="url" name="portfolio" id="portfolio" placeholder="http://" pattern="[a-z0-9.-]+\.[a-z]{2,63}$" required />
</p>
<div class="error" id="error-portfolio"></div>
</div>
<div class="clearboth"></div>
<input type="hidden" name="formtype" id="formtype" value="careers">
<div class="form_labels">
<p> </p>
</div>
<div class="form_inputs">
<a href="#">
<input type="submit" value="Submit" class="btn-red">
</a>
</div>
</form>
If someone would help point me in the right direction I would really appreciate it.
Code
for (i = 0; i < allRequired.length; i++) {
allRequired[i].object.setAttribute("onBlur", "requireField(allRequired[i].description, allRequired[i].object.value, allRequired[i].error);");
}
sets onblur event with value like requireField(allRequired[i].description.
So - what is it - i? No one knows.
Proper code is:
for (i = 0; i < allRequired.length; i++) {
allRequired[i].object.setAttribute("onBlur", "requireField(allRequired[" +i + "].description, allRequired[" + i + "].object.value, allRequired[" + i + "].error);");
}
See? I get real i value for each iteration.
As u_mulder said concat problem.
As for code I suggest to look up factory functions. It's more natural javascript then constructor.
Im kinda new to js, trying to change value of "email" input field
<div class="input-group type-email">
<div class="input-label has-placeholder-label">
<label for="">Your Email Address</label>
</div>
<div class="inputs">
<input name="email" value="" placeholder="" type="email">
</div>
</div>
I've found a bunch of articles saying how to find an element by id. How can I do it without id, by type maybe?
Thank you.
You can use query selectors, for example:
var input = document.querySelector("input[name=email]");
input.value = "Your new value";
More on query selectors here and also here.
Hope it helps!