I have a javascript function that display and hide a div after select.
The div contains fields of a form. The div test2 has the fields of the div test1 plus other fields. All the fields are required.
I have 2 problems:
1) When I display test2 and I complete the fields, saving the form is impossible because some fields in test2 are found in test1. This means some fields have the same name.
2) All the fields are required, which means even if I complete the fields in test2 I still can't save because the fields in test1 are not completed and hidden. How can I create a code structure to allow this to save?
function visibilite1(_this) {
var id = _this.value;
var divs = document.getElementsByTagName('div');
for(var no=0;no<divs.length;no++) {
if (divs[ no].className=='divs') {
'divs'
divs[ no].style.display = "none";
}
}
document.getElementById(id).style.display = "block";
}
<select name="role" id="role"
onchange="visibilite1(this);hide()" >
<option value='test1'>Year1</option>
<option value='test2'>Year2</option>
</select>
<div id="test1" class="divs">
<label>Name </label>
<input type="text" name= "name" id= "name" required> </br>
<label>User name </label>
<input type="text" name= "username" id= "username" required></br>
<label >Password <em>*</em></label>
<input type="password" name= "password" id= "password" required></br>
</div>
<div id="test2" class="divs">
<label>Name </label>
<input type="text" name= "name" id= "name" required>
<label>User name </label>
<input type="text" name= "username" id= "username" required>
<label>Password <em>*</em></label>
<input type="password" name= "password" id= "password" required>
<input type="text" name= "username" id= "username" required>
<label>Adress<em>*</em></label>
<input type="text" name= "adress" id= "adress" required>
<label>Client name</label>
<?php
$sql="select ClientName from claims_follow_up.Client where id
!='10001' order by ClientName asc ";
$req=mysqli_query($dbc,$sql) or die("Erreur d'execution");
?>
<select name="ClientName" id="ClientName"
onchange="
var maVal = document.getElementById('ClientName').value;
if (maVal == 'Create new client')
{
window.open('newClientCreate.php', 'blank', 'scrollbars=yes,
resizable=no, top=50, left=155, width=1200, height=700');
};activer()" required disabled="true" onkeypress="activerSubmit()">
<option value="">select client </option>
<?php
while($d=mysqli_fetch_array($req))
{
echo'<option
value="'.$d['ClientName'].'">'.$d['ClientName'].'</option>';
}
mysqli_free_result($req);
?>
<option value="Create new client" style="color:blue;
font-weight:bold">create new client</option>
</select>
</div>
As you've discovered, elements in a html page should never have the same id and different input elements in a html form should not have the same name.
Assuming you want to stay within the world of vanilla javascript and don't want to use a javascript framework (e.g. angular, ember) you could accomplish this by setting the inner html of elements. This way the "hidden" html isn't present in the html markup.
Something like...
<script>
function hide () {
console.log("whatever")
}
function visibilite1(_this) {
var formgroup1 = '<div id="test1" class="divs"><label>Name </label><input type="text" name= "name" id= "name" required> </br><label>User name </label><input type="text" name= "username" id= "username" required></br><label >Password <em>*</em></label><input type="password" name= "password" id= "password" required></br></div>'
var formgroup2 = '<div id="test2" class="divs"><label>Name </label><input type="text" name= "name" id= "name" required><label>User name </label><input type="text" name= "username" id= "username" required><label>Password <em>*</em></label><input type="password" name= "password" id= "password" required><input type="text" name= "username" id= "username" required><label>Adress<em>*</em></label><input type="text" name= "adress" id= "adress" required></div>'
var formtestElement = document.getElementById('formtest');
if (_this.value == "test1") {
formtestElement.innerHTML = formgroup1
} else if (_this.value == "test2") {
formtestElement.innerHTML = formgroup2
};
}
</script>
<select name="role" id="role"
onchange="visibilite1(this);hide()" >
<option value='test1'>Year1</option>
<option value='test2'>Year2</option>
</select>
<div id="formtest">
<div id="test1" class="divs">
<label>Name </label>
<input type="text" name="name" id="name" required> </br>
<label>User name </label>
<input type="text" name="username" id="username" required></br>
<label>Password <em>*</em></label>
<input type="password" name="password" id="password" required></br>
</div>
</div>
Update: Edited to show the test1 form by default.
Another approach is to clone elements and on show/hide putting the right one in the form.In the window onload event I set the select to the desired index and I clone and save the elements, removing from the form the elements hidden. on change I remove the visible element and add the selected one.
var divsCloned = [];
function visibilite1(_this) {
if (divsCloned.length == 0) {
return;
}
var currDiv = document.getElementsByTagName('div')[0];
_this.parentNode.removeChild(currDiv);
_this.parentNode.insertBefore(divsCloned[_this.selectedIndex], _this.nextSibling);
}
window.onload = function() {
var divs = document.getElementsByTagName('div');
for (var no = 0; no < divs.length; no++) {
divsCloned.push(divs[no].cloneNode(true));
if (no != 0 && divs[no].parentNode) {
divs[no].parentNode.removeChild(divs[no]);
}
}
}
<form>
<select name="role" id="role"
onchange="visibilite1(this);">
<option value='test1'>Year1</option>
<option value='test2'>Year2</option>
</select>
<div id="test1" class="divs">
<label>Name </label>
<input type="text" name="name" id="name" required> </br>
<label>User name </label>
<input type="text" name="username" id="username" required></br>
<label>Password <em>*</em></label>
<input type="password" name="password" id="password" required></br>
</div>
<div id="test2" class="divs">
<label>Name </label>
<input type="text" name="name" id="name" required>
<label>User name </label>
<input type="text" name="username" id="username" required>
<label>Password <em>*</em></label>
<input type="password" name="password" id="password" required>
<input type="text" name="username" id="username" required>
<label>Adress<em>*</em></label>
<input type="text" name="adress" id="adress" required>
</div>
<input id="submit" type="submit" value="Submit">
</form>
1st thing don't put same id for 2 components, even if its in different divs...
2nd to achieve ur result, when ever u hide the div, disable the input fields corresponding to it and re-enble it when u need
Immediate reaction is that IDs in the document must be unique! - form element names can be the same, but that implies that they are part of a group (ie: within option buttons collection where there's only one possible selection).
Best to keep them all unique, else you need to refer specifically to formName plus elementName.
Whenever you hide a div, set all of the inputs inside of it as disabled. When an input is disabled, the required attribute is ignored, and disabled inputs don't get submitted with the form, so you won't have the name collisions on the back-end.
var inputs = divs[no].getElementsByTagName('input');
for (var x = 0, len = inputs.length; x < len; x++) {
inputs[x].disabled = true;
}
Obviously, when you unhide a div, you'll need to go through and re-enable all of the inputs within that div, as well.
Update: Here's an example using your given code, as requested. First, the JS:
function visibilite1(_this) {
var inputs;
var divToShow;
var id = _this.value;
var divs = document.getElementsByTagName('div');
for(var no=0;no<divs.length;no++) {
if (divs[no].className=='divs') {
divs[no].style.display = "none";
inputs = divs[no].getElementByTagName('input');
for (var x = 0, len = inputs.lenght; x < len; x++) {
inputs[x].disabled = true;
}
}
}
divToShow = document.getElementById(id);
divToShow.style.display = "block";
inputs = divToShow.getElementByTagName('input');
for (var x = 0, len = inputs.lenght; x < len; x++) {
inputs[x].disabled = false;
}
}
And the HTML (reduced a little, but enough to see what it should look like):
<select name="role" id="role" onchange="visibilite1(this);hide()" >
<option value='test1'>Year1</option>
<option value='test2'>Year2</option>
</select>
<div id="test1" class="divs">
<label>Name </label>
<input type="text" name= "name" required> </br>
<label>User name </label>
<input type="text" name= "username" required></br>
<label >Password <em>*</em></label>
<input type="password" name= "password" required></br>
</div>
<div id="test2" class="divs">
<label>Name </label>
<input type="text" name= "name" required>
<label>User name </label>
<input type="text" name= "username" required>
<label>Password <em>*</em></label>
<input type="password" name= "password" required>
<input type="text" name= "username" required>
<label>Adress<em>*</em></label>
<input type="text" name= "adress" required>
</div>
Related
I have a form created using HTML and I have a submit button.
I am trying to have the submit button disabled if the fields are not filled out.
However, now even if the fields are filled out the button stays disabled.
const subButton = document.querySelector('.sbutton')
const inputTexts = document.querySelector('.input')
subButton.disabled = true
function clickedButton() {
if (document.querySelector('.input').value === "") {
subButton.disabled = true
} else {
subButton.disabled = false
}
}
<div class="form">
<section>
<form action=[link] method="POST">
<fieldset>
<legend>Your Contact Info!</legend>
<label class="firstname" for="firstname">First Name</label>
<input class="input" type="text" id="firstname" name="name" placeholder="Your first name" required>
<label class="lastname" for="lastname">Last Name</label>
<input type="text" id="lastname" name="lname" placeholder="Your last name">
<label class="email" for="email">E-mail</label>
<input class="input" type="email" id="email" name="email" placeholder="Your e-mail" required>
<label class="comments" for="comments">Additional Comments</label>
<textarea class="input" placeholder="Anything else we should know!" id="comments" name="comments" required></textarea>
<label class='input' for="timeofday">When is the best time of day to contact you?</label>
<select id="timeofday" name="timeofday">
<option value='Morning'>Morning</option>
<option selected value="afternoon">Afternoon</option>
<option value="evening">Evening</option>
</select>
</fieldset>
<button class="sbutton" type="submit">Submit</button>
The issue is, that you never call the function clickedButton(). You need an eventListener that listens for change events within the inputs and then calls that function:
const INPUTS = document.querySelectorAll('input');
INPUTS.forEach(el =>
el.addEventListener('change', clickedButton)
)
const subButton = document.querySelector('.sbutton')
const inputTexts = document.querySelector('.input')
const INPUTS = document.querySelectorAll('input');
subButton.disabled = true
INPUTS.forEach(el =>
el.addEventListener('change', clickedButton)
)
function clickedButton() {
if (document.querySelector('.input').value === "") {
subButton.disabled = true
} else {
subButton.disabled = false
}
}
<div class="form">
<section>
<form action=[link] method="POST">
<fieldset>
<legend>Your Contact Info!</legend>
<label class="firstname" for="firstname">First Name</label>
<input class="input" type="text" id="firstname" name="name" placeholder="Your first name" required>
<label class="lastname" for="lastname">Last Name</label>
<input type="text" id="lastname" name="lname" placeholder="Your last name">
<label class="email" for="email">E-mail</label>
<input class="input" type="email" id="email" name="email" placeholder="Your e-mail" required>
<label class="comments" for="comments">Additional Comments</label>
<textarea class="input" placeholder="Anything else we should know!" id="comments" name="comments" required></textarea>
<label class='input' for="timeofday">When is the best time of day to contact you?</label>
<select id="timeofday" name="timeofday">
<option value='Morning'>Morning</option>
<option selected value="afternoon">Afternoon</option>
<option value="evening">Evening</option>
</select>
</fieldset>
<button class="sbutton" type="submit">Submit</button>
Note, that you check only the first input. querySelector returns only 1 element (the first).
Nothing on the page is calling clickedButton()
Attach an EventListener for changes on the form that calls this function.
var form = document.querySelector('form');
form.addEventListener('change', clickedButton);
Also when you are using querySelector you will only get the first element in the form which is a <input .... If you want to check for all you should use querySelectorAll.
But that function would return an array so then you need to check if all of them have text.
In that case you could do it like this.
function validateForm() {
// Get all elements
const elements = document.querySelectorAll("input");
// Filter out elements that have no value, if there is more then 1 set disabled to true, else it is false
const disabled = elements.filter((el) => el.value === "").length > 0 ? true : false;
subButton.disabled = disabled
}
And if you are going with this way you need to call this function instead of the other one like this:
var form = document.querySelector('form');
form.addEventListener('change', validateForm);
The code
<body>
<script>
function addInput() {
var container = document.getElementById("container");
var element = document.createElement("input");
element.setAttribute("list", "browsers");
container.appendChild(element);
var container = document.getElementById("container");
var element = document.createElement("input");
element.setAttribute("list", "op");
container.appendChild(element);
}
</script>
<!-- List -->
<form action="mailto:test#gmail.com" method="post" enctype="text/plain">
<fieldset>
<legend>Info:</legend>
<label for="fname">first name:</label>
<input type="text" id="fname" name="fname"><br>
<label for="lname">last name:</label>
<input type="text" id="lname" name="lname"><br>
<label for="date">date:</label>
<input type="date" id="date" name="date"><br>
<input type="radio" id="hkp" name="send" value="HKP">
<label for="hkp">HKP</label><br>
<input type="radio" id="patienten" name="send" value="Pat">
<label for="patienten">Pat</label><br>
<div id="container">
<label for="browser">Product:</label>
<input list="browsers" name="Product" id="browser">
<datalist id="browsers">
<option value=" x">
<option value=" y">
<option value=" z">
<option value=" a">
<option value=" b">
<option value=" c">
</datalist>
<label for="op">OP:</label>
<input list="op" name="op" id="op"><br>
</div>
<input type="button" value="+ Product" onclick="addInput()">
</fieldset>
<input type="submit" value="Senden">
<input type="reset" value="Reset">
</form>
Here's the problem, once I fill all the stuff and click on the button + Product it does add the lists of the "browsers" and the "op" but it isn't shown in the email once I click submit is there a way to fix than? I also need help with adding the text in front of the copied lists I only copy the lists but not the label at least I don't know how.
Submitting your form with a standard submit button will not work in this case. The submit button does not take into account the form fields that are created after page load.
You'll have to write a submit handler that serializes your data and create a mailto link on the fly:
function formSubmit(e) {
e.preventDefault();
const formData = new FormData(e.target);
var mail = document.createElement("a");
mail.href = "mailto:test#gmail.com";
mail.body = // get elements from formData;
mail.click();
}
const form = document.getElementById('form');
form.addEventListener('submit', formSubmit);
Don't forget to add id="form" to the form.
I have the following if that, so far, the only thing it does is to not let it trigger the form ajax submission if any input is blank. Being empty is one of the conditions but besides that, I'd also like it to prevent the form from being sent if a required filling pattern for each field is not respected. I've tried some things but they didn't work, so I guess I'm probably making mistakes regarding the synthax or other details. What would be the best way to do it?
(function($){
$('#enquiry').submit( function(event){
event.preventDefault();
var fname = $.trim($('.fname').val());
var lname = $.trim($('.lname').val());
var email = $.trim($('.email').val());
var subject = $.trim($('.subject').val());
var message = $.trim($('.message').val());
if (fname === '' || lname === '' || email === '' || subject === '' || message === ''){
alert('trigger error message')
}
else{
alert('ajax call sending the data')
}
Here's the form code, in case it's relevant:
<form id="enquiry" method="post" onsubmit="return false">
<div class="form">
<input class="input fname" placeholder="a" name="fname" type="text" autocomplete='off' pattern="[a-zA-Z]{1,36}" required></input>
<label for="namef" class="">Your name</label>
</div>
<div class="form">
<input class="input lname" placeholder="a" name="lname" type="text" autocomplete='off' pattern="[a-zA-Z]{1,36}" required></input>
<label for="surname" class="">Your surname</label>
</div>
<div class="form">
<input class="input email" placeholder="a" name="email" type="text" autocomplete='off' pattern="[^#\s]+#[^#\s]+\.[^#\s]+" required></input>
<label for="email" class="">Your email</label>
</div>
<div class="form custom-select">
<select class="input subject" name="subject" autocomplete='off' required>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</select>
</div>
<div class="form2">
<textarea class="input message" placeholder="a" name="message" autocomplete='off' pattern="[0-9a-zA-Z- ]" required></textarea>
<label for="tellme" class="">Tell me something</label>
</div>
<div class="contactbutton">
<button type="submit" class="button" role="button"><span>SUBMIT</span></button>
</div>
</form>
I have this javascript function that work properly it allows me to display a hide fields depending the option selected in role select field. the select field in var formgroup2 variable after the adress field has an onchange event that should open a modal window when create new office is selected. This part is not working when i add it to the function but out of the function it works.
function hide () {
console.log("whatever")
}
function visibilite1(_this) {
var formgroup1 = '<div id="test1" class="divs"><label>Name </label> <input type="text" name= "name" id= "name" required> </br><label>User name </label><input type="text" name= "username" id= "username" required></br><label >Password <em>*</em></label><input type="password" name= "password" id= "password" required></br></div>'
var formgroup2 = '<div id="test2" class="divs"><label>Name </label<input type="text" name= "name" id= "name" required> </br><label>User name </label><input type="text" name= "username" id= "username" required> </br><label>Password <em>*</em></label><input type="password" name= "password" id= "password" required> </br> <label>Adress<em>* </em></label><input type="text" name= "adress" id= "adress" required></br> <select name="office" id="office" onchange="goToPage()" required> <option value="">select office </option> <?php while($d=mysqli_fetch_array($req)) {echo"<option value=".$d['OfficeName'].">".$d['OfficeName']."</option>"; }mysqli_free_result($req); ?><option value="Create new office" style="color:blue; font-weight:bold">create new office</option></select>
</div>'
var formtestElement = document.getElementById('formtest');
if (_this.value == "test1") {
formtestElement.innerHTML = formgroup1
} else if (_this.value == "test2") {
formtestElement.innerHTML = formgroup2
};
}
<select name="role" id="role"onchange="visibilite1(this);hide()" >
<option value='test1'>Year1</option>
<option value='test2'>Year2</option>
</select>
<div id="formtest">
<div id="test1" class="divs">
<label>Name </label>
<input type="text" name="name" id="name" required> </br>
<label>User name </label>
<input type="text" name="username" id="username" required></br>
<label>Password <em>*</em></label>
<input type="password" name="password" id="password" required></br>
<select name="office"
id="office"
onchange="var maVal =
document.getElementById(" office ").value; if (maVal =="Create new office ")
{window.open("newOfficeCreate.php ", "blank ", "scrollbars=yes, resizable=no, top=50, left=155, width=1200, height=700 ");"}
required>
You never close the onchange attribute.
I think. It's really hard to tell. Trying to inline stuff like that is just horrible; write a function and either reference it if you feel you must use attributes, or attach it later.
I am trying to validate a form. I'm doing this by creating a JS code that ensures all text fields have atleast a character in it and if not the submit button is disabled. However, when i run this code my submit button becomes active after filling out only one field.
Also if you find any bugs etc please point them out, cheers.
This is my HTML
<form name = "form" onsubmit="validate()">
<h3>Please complete the form below. Mandatory fields marked with *</h3>
<fieldset>
<h4>Personal Details</h4>
<p>
<label for="fname">*First Name</label> <input type="text" name="fname" id="fname" placeholder="First Name" onKeyup="validate()" class = "form" >
</p>
<p>
<label for="lname">*Last Name</label> <input type="text" name="lname" id="lname" placeholder="Last Name" onKeyup="validate()" class = "form" />
</p>
<p>
<label for="Etype">Gender</label>
<select class = "form" id="gender" name="gender"><option value="">Select...</option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</p>
<p>
<label for="age">*Age</label>
<select class = "form" id="age" name="age"><option value="">Select...</option>
<option value="youngest">3-7</option>
<option value="young">7-12</option>
<option value="teen">12-16</option>
<option value="young-adult">16-18</option>
<option value="adult">18+</option>
</select>
</p>
<p>
<label for="s_add">*Street Address</label> <input type="text" name="s_add" id="s_add" placeholder="Insert Street Address" onKeyup="validate()" class = "form" />
</p>
<p>
<label for="s_sub">*Suburb</label> <input type="text" name="s_sub" id="s_sub" placeholder="Suburb" onKeyup="validate()" class = "form"/>
</p>
<p>
<label for="state">*State</label> <input type="text" name="state" id="state" onKeyup="validate()" class = "form" />
</p>
<p>
<label for="pcode">*Postcode</label> <input type="text" name="pcode" id="pcode" onKeyup="validate()" class = "form" />
</p>
<p>
<label for="phone">*Phone</label> <input type="text" name="phone" id="phone" placeholder="Mobile or Home" onKeyup="validate()" class = "form"/>
</p>
<p>
<label for="email">*Email</label> <input type="text" name="email" id="email" placeholder="Email Address" onKeyup="validate()" class = "form"/>
</p>
</fieldset>
<fieldset>
<h4>Emergency Contact</h4>
<p> please select someone within a close vicinity of 'Clowning Around'. </p>
<p>
<label for="fname">*First Name</label> <input type="text" name="fname" id="fname" onKeyup="validate()" placeholder="First Name" class = "form" />
</p>
<br>
<p>
<label for="lname">*Last Name</label> <input type="text" name="lname" id="lname" placeholder="Last Name" onKeyup="validate()" class = "form" />
</p>
<br>
<p>
<label for="s_add"> *Street Address</label> <input type="text" name="s_add" id="s_add" placeholder="Insert Street Address" onKeyup="validate()" class = "form" />
</p>
<br>
<p>
<label for="Mnum"> *Mobile Number</label> <input type="text" name="Mnum" id="Mnum" placeholder="Mobile Number" class = "form" />
</p>
<br>
<p>
<label for="Relationship"> *Relationship</label> <input placeholder="E.g Parent" class = "form"/>
</p>
<br>
<p>
<input id="SubmitButton" type="submit" disabled="disabled" value="Submit" />
</fieldset>
<fieldset>
<h4> Type of Enrollment </h4>
<label for="Etype">*What would you like to enrol in?</label>
<select class = "form" id="Etype" name="Etype"><option value="">Select...</option>
<option value="Camp">Camp</option>
<option value="Class">Class</option>
</select>
</p>
</form>
</body>
</fieldset>
as you can see in my code ive added onKeyup="validate()" in the inputs.
This is my JS
window.onload = function() {
console.log("The window has finished loading");
var SubmitButton = document.getElementById("SubmitButton");
SubmitButton.addEventListener('click', function() {
console.log("The submit button has been clicked");}, false);
var fname = document.getElementById("fname");
fname.addEventListener('keyup', function() {
console.log((fname).value);}, false);
var lname = document.getElementById("lname");
lname.addEventListener('keyup', function() {
console.log((lname).value);
validate();}, false);
}
function validate()
{
var x = document.forms["form"].elements;
var xbutton = true;
for (var i = 0; i < xbutton.length; i++) {
if (x[i].value.length == 0) xbutton = false;
}
if (xbutton) {
document.getElementById('SubmitButton').disabled = !xbutton;
}
}
I've added the first function just in case its related.
Edit:
I've fixed var i = 0; i < xbutton.length; i++
to x.length
Now when i run the code i get an Uncaught TypeError: Cannot read property 'length' of undefined
for line if (x[i].value.length == 0) xbutton = false;
any ideas?
The for loop isn't right, you refer to xbutton.length but it should be x.length because x is the list of elements and xbutton is a boolean:
for (var i = 0; i < x.length; i++) {
Also, you're duplicating the event handlers by using both the inline onkeyup and addEventListener. Use one or the other.
Finally, in the onsubmit handler, you need to return false in order to prevent the form from submitting, if the validation fails.
The new error occurs because you have fieldset elements included in the form.elements list, so you're trying to get the value of a fieldset which doesn't exist. To resolve that, add a condition to check that the element is an input[type=text]:
for (var i = 0; i < x.length; i++) {
if(x[i].tagName == 'INPUT' && x[i].type == 'text'){
if (x[i].value.length == 0) xbutton = false;
}
}