HTML - Create multiple forms out of one form template - javascript

I currently have multiple forms that are similar but have small changes. First, the user choses the form from a drop-down menu and then the form is shown below.
My forms looks like this.
Form 1
Customer Name
Phone Number
Address
Form 2
Customer Name
Is married?
Form 3
Customer Name
Social Security Number
Address
My code looks something like this.
<select onchange="changeOptions(this)">
<option value="" selected="selected"></option>
<option value="form1">f1</option>
<option value="form2">f2</option>
<option value="form3">f3</option>
</select>
<form class="className" name="form1" id="form1" style="display:none">
---form---
<form class="className" name="form2" id="form2" style="display:none">
---form---
<form class="className" name="form3" id="form3" style="display:none">
---form---
<script>
function changeOptions(selectEl) {
let selectedValue = selectEl.options[selectEl.selectedIndex].value;
let subForms = document.getElementsByClassName('className')
for (let i = 0; i < subForms.length; i += 1) {
if (selectedValue === subForms[i].name) {
subForms[i].setAttribute('style', 'display:block')
} else {
subForms[i].setAttribute('style', 'display:none')
}
}
}
</script>
Is there any way to create a 'main' form that has all the form elements and then specify which element to use in each form? The method I'm using right now works fine but there is too much repeated code and probably won't scale correctly if I try to make a change in one of the elements (since I would have to change each one of them and it will be easy to make mistakes)

You don't need three different forms, just have one form with all of the fields set as hidden. Then give each field a class matching which form that field should be shown. Then simply show the matching fields based on the selected value.
select_form = document.querySelector(".select_form");
fields = document.querySelectorAll(".field");
select_form.addEventListener("change", function() {
fields.forEach(function(el) {
el.style.display = "none";
});
show = document.querySelectorAll("." + this.value);
show.forEach(function(el) {
el.style.display = "block";
});
});
.field {
display: none;
}
<select class="select_form">
<option value="" selected="selected"></option>
<option value="form1">f1</option>
<option value="form2">f2</option>
<option value="form3">f3</option>
</select>
<form>
<div class="field form1 form2">ONLY form1 and 2</div>
<div class="field form3">ONLY form3</div>
</form>

Related

Getting selected datalist option value, and innerHTML, without using jQuery

I have a situation where I want to let a user decide titles of books that I have on my db, using an input with a datalist (generated by php), after the user picked a title, he would click a submit button and the form would send the title in another file.
Everything worked fine but I didn't realized that I needed to send the ID of the book that the user selected, because there can be more than one book with the same title.
What I would like to have is the option of the datalist, that no longer has the title of the book inside its "value" attribute, but I want that title inside its innerHTML, so that the title gets displayed, while having the ID inside the "value" attribute. My problem is that if I do that, when the user clicks on the datalist option, the ID gets inside the text input, so the user may not know what book he choose.
summing up: I would like to have the datalist that displays the title, when an option is chosen, that title gets displayed in the text input, when I submit, the Id of the book gets sent in "FindBook.php" inside $_POST.
isIn() checks if the title is inside the array of titles, I would need to change that so that it can check if the ID is inside the array of IDs.
<form onsubmit="alert(document.getElementById('number').value);" action="FindBook.php" target="_blank" method="POST">
<input id="number" list="BooksById">
<input type="submit" value="Find">
</form>
<datalist id="BooksById">
<option value="1">Title1</option>
<option value="2">Title2</option>
<option value="3">Title3</option>
<option value="4">Title4</option>
</datalist>
<br>
<form onsubmit="alert(document.getElementById('string').value);" action="FindBook.php" target="_blank" method="POST">
<input id="string" list="booksByTitle">
<input type="submit" value="Find">
</form>
<datalist id="booksByTitle">
<option value="Title1"></option>
<option value="Title2"></option>
<option value="Title3"></option>
<option value="Title4"></option>
</datalist>
Since I don't understand jQuery I would really prefer a solution that doesn't imply that.
I think that in your case you must use a <select> tag instead of a <datalist> because you do not want the end user to enter new names (or yes?). However you can work with the data attributes like in the code below:
HTML:
<input list="titles" id="title-input" oninput="getBookId()">
<datalist id="titles">
<option data-value="5" value="A book name">
</datalist>
JavaScript:
function getBookId() {
var selectedTitle = document.getElementById("title-input").value;
var value2send = document.querySelector(`#titles option[value='${selectedTitle}']`).dataset.value; // Here now you have the book title id.
console.log("getBookId ~ value2send", value2send)
}
I hope it works for you.
Assuming you can provide distinct title values for each datalist option...
Add a dataset attribute, such as data-id, to your datalist option elements, containing the corresponding id, and add a hidden type input to your form. Then use the onsubmit event handler function to get the selected datalist option's dataset id value and assign it to the value of the hidden input:
function findBook(form) {
form.bookid.value = document.querySelector(`datalist option[value="${form.booktitle.value}"]`).dataset.id;
console.log(form.bookid.value);
return false;
}
<form onsubmit="return findBook(this)">
<input type="hidden" name="bookid">
<input name="booktitle" list="BooksById">
<input type="submit" value="Find">
</form>
<datalist id="BooksById">
<option data-id="1" value="Title1">
<option data-id="2" value="Title2">
<option data-id="3" value="Title3">
<option data-id="4" value="Title4">
</datalist>
Upon form submission, your PHP file will have the variables $_POST['bookid'] and $_POST['booktitle'] available.
Thanks for your suggestions. I prefer to use a datalist, instead of a select tag, because it looks more like a dropdown menu that works like a button. Using datalist allows me to find a book by a random word inside the title of it, while the select only finds the first word of an entry. I can also distinguish different books with the same name by another attribute that states if it's available or if it's taken.
I asked for no JQuery, i appreciate your help but I really don't understand them, even if it's cleaner to use them I would like a solution that doesn't use them.
I ended up using the solution CBroe suggested:
document.getElementById("bookTitle").addEventListener('input', function (evt) {
let data = this.value.split('');
document.getElementById("bookId").value = "";
if(isIn(data,'books')){
document.getElementById("bookId").value = data[0];
document.getElementById("bookTitle").value = data[1];
}
});
function checkForm(id, value, list){
if(isIn([document.getElementById(id).value,document.getElementById(value).value],list)){
alert("Book found");
return true;
}else{
alert("not found")
return false;
}
}
function isIn(value, list) {
switch (list) {
case 'books':
//this was generated by php in my code
if (value[0] == 1 && value[1] == "Title1"){
return true;
}
if (value[0] == 2 && value[1] == "Title2"){
return true;
}
return false;
break;
//I've cut out other cases
}
}
<form onsubmit="checkForm('bookId','bookTitle','books')" action="FindBook.php" target="_blank" method="POST">
<input id="bookTitle" list="booksByTitle" autocomplete="off">
<label>id:</label>
<input id="bookId" <!--type="hidden"-->
<input type="submit" value="Find">
</form>
<datalist id="booksByTitle">
<!-- value was generated by php in my code-->
<option value="1Title1">Title1</option>
<option value="2Title2">Title2</option>
</datalist>

Why The Validation is not working for the provided html/ js code

I want the to get the required in the html page if none is selected.
function validation() {
var country = getElementById("country");
if (country.value = "") {
documnet.getElementById("countryy").innerHTML = "Required";
return false;
} else
return true;
}
<form onsubmit="return validation();">
<select id="country"><span id="countryy"></span>
</select><br>
<input type="submit" name="Submit" value="Submit">
</form>
Why The Validation is not working for the provided html/ js code. I want the to get the required in the html page if none is selected. I am new to js learning.
Several issues
Spelling mistake in the document.getElementById
missing document on the other document.getElementById
No preventDefault which will submit the form if any JS errors
= is assignment - you need == or === to compare
span needs to be outside the select
You did not use value="Default" in the "NONE" options
It is not recommended to have inline event handlers. Here is a better version
Note I added a class to toggle the required in case the user changes the select to conform
window.addEventListener("load", function() {
const errorSpan = document.getElementById("countryy"); // cache the elements
const country = document.getElementById("country");
document.getElementById("myForm").addEventListener("submit", function(e) {
const val = country.value; // get the value
if (val === "") {
e.preventDefault(); // stop submit
}
errorSpan.classList.toggle("hide",val); // hide if value
})
country.addEventListener("change",function() { // if user changes the select
errorSpan.classList.toggle("hide",this.val); // hide if value
})
})
.hide { display : none; }
<form id="myForm">
<select id="country">
<option value="">NONE</option>
<option value="ABDUL">ABDUL</option>
<option value="SULE">SULE</option>
</select> <span id="countryy" class="hide">Required</span><br>
<input type="submit" name="Submit" value="Submit">
</form>
HOWEVER you could remove all the script and just add required attribute to the select and keep the empty default
<form id="myForm">
<select id="country" required>
<option value="">NONE</option>
<option value="ABDUL">ABDUL</option>
<option value="SULE">SULE</option>
</select><span id="countryy"></span><br>
<input type="submit" name="Submit" value="Submit">
</form>
Use required attribute in the select tag. It will considered in html 5 validation.
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_select_required

If a user selects a option from the select box, hidden div should appear

so I am trying to display a div if user select a specific option value from a select drop down list. for example, if the user selects "trade" in the select box then the div with the company name should come up while the div containing the "first name and last name" should disappear. and If the user selects the "customer" in the select box then the the opposite should happen. Here is my code
Javascript
var custDetails = document.getElementById('retCustDetails');
var tradeDetails = document.getElementById('tradeCustDetails');
var SelectMenu = document.getElementById('makeBooking');
if (makeBooking.value == trd) {
document.getElementById('tradeDetails').style.display = 'block';
document.getElementById('custDetails').style.display = 'none';
}
else {
document.getElementById('custDetails').style.display = 'block';
}
HTML
<section id="makeBooking">
<h2>Make booking</h2>
Your details
Customer Type:
<select name="customerType">
<option value="">Customer Type?</option>
<option value="ret">Customer</option>
<option value="trd">Trade</option>
</select>
<div id="retCustDetails" class="custDetails">
Forename <input type="text" name="forename">
Surname <input type="text" name="surname">
</div>
<div id="tradeCustDetails" class="custDetails" style="visibility:hidden">
Company Name <input type="text" name="companyName">
</div>
You should be using an if / else if to handle the different values that the user could select - this also allows you to hide all the divs by default, if no valid selection is picked
You can use .addEventListener('change', function ()) on your Select element to call a function every time the value is updated, and then you can use this.value inside the function to access the selected element's value
Also, be sure that you're wrapping strings with ' or " - You were using makeBooking.value == trd, which is checking for a variable called trd, not the String 'trd' as you were aiming for
Finally, You could hide your divs by default using CSS, so that only the correct div is showing when selected
.custDetails {
display: none;
}
var custDetails = document.getElementById('retCustDetails');
var tradeDetails = document.getElementById('tradeCustDetails');
var SelectMenu = document.getElementById('makeBooking');
document.querySelector('select[name="customerType"]').addEventListener('change', function() {
if (this.value == 'trd') {
custDetails.style.display = 'none';
tradeDetails.style.display = 'block';
} else if (this.value == 'ret') {
custDetails.style.display = 'block';
tradeDetails.style.display = 'none';
} else {
custDetails.style.display = 'none';
tradeDetails.style.display = 'none';
}
});
.custDetails {
display: none;
}
<section id="makeBooking">
<h2>Make booking</h2>
Your details Customer Type:
<select name="customerType">
<option value="">Customer Type?</option>
<option value="ret">Customer</option>
<option value="trd">Trade</option>
</select>
<div id="retCustDetails" class="custDetails">
Forename <input type="text" name="forename"> Surname <input type="text" name="surname">
</div>
<div id="tradeCustDetails" class="custDetails">
Company Name <input type="text" name="companyName">
</div>
First, you had different names in your JavaScript than you had as ids in your HTML. You were also trying to work with the section element instead of the select element.
After that, you need to set up an event handling function to handle when the select gets changed.
Also, instead of working with inline styles. It's much simpler to set up a CSS class and then just add or remove it.
Finally, don't use an HTML heading element (h1...h6) because of the formatting applied to it. Formatting is done with CSS. Choose the right heading because it makes sense. You can't have the first heading in a section be an h2 because and h2 is for a subsection of an h1. The first heading in any section should always be h1.
See comments inline:
var custDetails = document.getElementById('retCustDetails');
var tradeDetails = document.getElementById('tradeCustDetails');
// You must get a reference to the <select> element
var selectMenu = document.getElementById('customerType');
// Then, you must configure a JavaScript function to run as a "callback"
// to a specific event that the <select> element could trigger:
selectMenu.addEventListener("change", function(){
// The value of the select will be a string, so you must wrap it in quotes
if (selectMenu.value == "trd") {
// Now, just add or remove the pre-made CSS class as needed.
tradeDetails.classList.remove("hidden");
custDetails.classList.add("hidden");
} else {
tradeDetails.classList.add("hidden")
custDetails.classList.remove("hidden");
}
});
.hidden { display:none; }
<section id="makeBooking">
<h1>Make booking</h1>
Your details<br>
Customer Type:
<select name="customerType" id="customerType">
<option value="">Customer Type?</option>
<option value="ret">Customer</option>
<option value="trd">Trade</option>
</select>
<div id="retCustDetails" class="custDetails hidden">
Forename <input type="text" name="forename">
Surname <input type="text" name="surname">
</div>
<div id="tradeCustDetails" class="custDetails hidden">
Company Name <input type="text" name="companyName">
</div>
</section>

jQuery - How to evaluate two select option values for an if/else statement?

I have a continue button with the class "options-btn" on a page (it's a multi-step booking process), with two select fields on the page. One of these dropdown select fields needs to have a value selected by the user before they can click the submit button on the page while also disabling the click event?
Each dropdown field has the default select option 0, with the other choice of "1". How can I write a function to basically say "If neither one of these options has a value of 1 selected - alert message "please select an option" and disable the button.
The two ID's associated with these select fields are:
#extra_units_7 & #extra_units_4
This is what I wrote so far, but it's not working:
jQuery(document).ready(function($) {
$(".options-btn").click(function() {
if ( $('#extra_units_7').val() === 0 || $('#extra_units_4').val() === 0 )
alert("Please select an option");
return false;
} else {
$('.options-btn').trigger('click');
}
});
I re-factored your HTML in order to enable you to feedback to the End User without being obtrusive with alert() boxes.
<!-- Use ID to attach to in JS -->
<form id="form_units" action="#" method="post">
<div>
<!-- Labels, because... well, labels. -->
<label for="extra_units_4">extra_units_4</label>
<!-- Use data-attr to identify which elements should be validated and how. This future proofs your code, and it's a good pattern to follow. -->
<select id="extra_units_4" data-validate="notempty">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<!-- Hidden element to provide feedback as it's better UX -->
<div class="fielderror">Please make a selection</div>
</div>
<div>
<label for="extra_units_7">extra_units_7</label>
<select id="extra_units_7" data-validate="notempty">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<div class="fielderror">Please make a selection</div>
</div>
<!-- Included an input[type="text"] for fun, and because future proofing is good -->
<div>
<label for="extra_units_8">extra_units_8</label>
<input type="text" id="extra_units_8" data-validate="notempty" />
<div class="fielderror">Please make a selection</div>
</div>
<!-- There appeared to be no reason not to use an input[type="submit"] in your code. Not doing so adds a tiny amount of complexity - so I slimmed the example down. Re-factor yourself for if <button> is a requirement. -->
<input type="submit" class="options-btn" value="Submit" />
</form>
Now we have a simple JS which will capture all <input>s with data-validate="notempty".
// Make sure you're specific with your selector for your form
$('#form_units').on('submit',function(e) {
// Hide all .fielderror elements within the context of 'this' form.
// This means that the next time we submit error messages are reset
$('.fielderror', this).hide();
// Select for all 'not empty' validations
$('[data-validate="notempty"]').each(function (index, item) {
// Check if it's an input[type="text"] - future proofing your "not empty" requirements. Expand on this idea for "radio" and "checkbox" inputs if and when required.
if ($(item).attr('type') === 'text') {
// Text is empty if the length is less than one char
if ($(item).val().length < 1) {
// We've found one that is invalid so stop the from from sending
e.preventDefault();
// Show the .fielderror text that is associated with the input being validated
$(item).siblings('.fielderror').show();
}
} else {
// Selects are empty if val() is less than 1. Be warned, this is dependant on having numerical values - and assumes that zero means no answer.
if ($(item).val() < 1) {
// We've found one that is invalid so stop the from from sending
e.preventDefault();
// Show the .fielderror text that is associated with the input being validated
$(item).siblings('.fielderror').show();
}
}
})
});
Lastly, add a little CSS to hide the error messages and style them when they become shown.
.fielderror { display: none; color: red;}
jsFiddle of working example with update to HTML structure and text input - https://jsfiddle.net/likestothink/xLLvzps2/9/
jQuery(document).ready(function($) {
$(".options-btn").click(function(){
if ( $('#extra_units_7').val() === 0 && $('#extra_units_4').val() === 0 )
alert("Please select an option");
return false;
}
return true;
});
)}
You should use && instead of ||. You don't need to trigger click event again.
1st: There is an error for }); at the end of your code
2nd: use == instead of ===
3rd: no need to use $('.options-btn').trigger('click');
try this .. if you have submit button without form
jQuery(document).ready(function($) {
$(".options-btn").on('click',function() {
if( $('#extra_units_4').val() == 0 ){
alert("Please select an option in extra_units_4");
//return false;
}else if($('#extra_units_7').val() == 0 ){
alert("Please select an option in extra_units_7");
//$('.options-btn').trigger('click');
}else{
alert('extra_units_4 value = '+$('#extra_units_4').val());
alert('extra_units_7 value = '+$('#extra_units_7').val());
}
});
});
Working Demo
or this .. if you have a submit button for a form (you need to use e.preventDefault(); and window.location.href )
jQuery(document).ready(function($) {
$(".options-btn").on('click',function(e) {
e.preventDefault();
if( $('#extra_units_4').val() == 0 ){
alert("Please select an option in extra_units_4");
//return false;
}else if($('#extra_units_7').val() == 0 ){
alert("Please select an option in extra_units_7");
//$('.options-btn').trigger('click');
}else{
alert('extra_units_4 value = '+$('#extra_units_4').val());
alert('extra_units_7 value = '+$('#extra_units_7').val());
// window.location.href = "type_url_here" // change type_url_here with url you need or with the form action attribute
}
});
});
Working Demo
you want to check id the condition is respected at every change of the select an basically disable / enable the button, the code was pretty much ok but you had to perform the check at the change event. I've extracted the check function in an external one just to help redability (you missed a { indenting too much the code) and i've introduced a class on the select to perform the check better, you can use the ID's if you like.
<select class="input-select" id="extra_units_4">
<option value="0">Volvo</option>
<option value="1">Saab</option>
</select>
<select class="input-select" id="extra_units_7">
<option value="0">Volvo</option>
<option value="1">Saab</option>
</select>
<button class="options-btn" disabled="disabled">Submit</button>
<script>
jQuery(document).ready(function() {
$(".input-select").on( "change", checkSelect);
});
function checkSelect() {
if ( $('#extra_units_7').val() == '0' && $('#extra_units_4').val() == '0' ) {
$(".options-btn").attr("disabled","disabled");
alert("Please select an option");
}
else {
$(".options-btn").removeAttr('disabled'); }
}
</script>
The if contition is an AND because you are checking that both the values are 0 and the check must be performed on string because the select value is not an integer.
Here's an alternative approach, in case you plan to keep adding selects which are mutually exclusive but required (you would need to add the required-select to all of them):
});
jQuery(document).ready(function($) {
var hasSelected = function() {
return $('.required-select option:not([value="0"]):selected').length;
};
$('.required-select').change(function() {
$('.options-btn').prop('disabled', !hasSelected());
});
$('form').submit(function(e) {
if (!hasSelected()) {
alert("Please select an option");
e.preventDefault();
} else {
alert('submitted');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" onsubmit="return false;">
<select id="extra_units_7" class="required-select">
<option value="0">Select an option</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
<select id="extra_units_4" class="required-select">
<option value="0">Select an option</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
<hr>
<button type="submit" class="options-btn" disabled="disabled">Submit</button>
</form>
I think it's overkill to validate on submit when the button is disabled, and it's not intuitive to allow submit, alert error and then disable the button. I'd take one of the two approaches in the code above (I prefer specifying in writing that the selects are required and not enabling the submit until they are selected).

How to make the chosen value of select list visible

How I can make the selected choice still visible until I re-choose another one?The list may contain more than 10 options
=====
<form method="get" action="Chairman.php" >
<select name="courses" id="courses" class="styled-select" >
<option value="courses"><--Courses--></option>
<option value="PHYS220">Physics for Engineers</option>
<option value="MATH210">Calculus II</option>
<option value="MATH225">Linear Algebra with Applications</option>
</select>
<input type="submit" value="Search Instructor"
onClick="checkDropdown()"></input>
<div id="error" style="color:red"></div>
=====
Also when I am trying to validate the select list,The error is displayed and then quickly it disappears
<script>
function checkDropdown () {
var courses = document.getElementById('courses');
if(courses.value==="courses") {
document.getElementById('error').innerHTML="PLEASE selecttt";
return false;
}
}
</script>
The select is reset and the error disappears because the form is still posted. The value that you return from the function doesn't stop the submission.
You should use the onsubmit event on the form instead of onclick on the button. Use return in the event code to convey the value from the function back to the event:
<form method="get" action="Chairman.php" onsubmit="return checkDropdown()">

Categories

Resources