I am trying to show input elements in a form with HTML select options. There are three options (DVD, book, and furniture) and each option has its product description input field (such as weight, height, size (MB) and length).
These inputs should be hidden and only show when the select option is changed. I want to use a for loop and not if or else conditionals.
The hidden input fields do not hide and show as expected using the select button. I am still learning, any tips will be helpful.
var display = {
1: [],
2: ["book"],
3: ["dvd"],
4: ["Furniture"],
}
function selectChanged() {
var sel = document.getElementById("productType");
for (var i = 1; i < 4; i++) {
document.getElementById("product" + i).classList.add("hidden");
}
display[sel.value].forEach(function(i) {
document.getElementById("product" + i).classList.remove("hidden");
});
}
<style>
.product{
border: 1px solid #333;
padding: 5px;
width: 20%;
margin: 25px 20px;
}
.info{
text-align: center;
}
.bottom-line{
box-sizing: border-box;
border-top: 1px solid;
margin: 0 34px;
}
form{
padding: 30px;
display: flex;
flex-direction: column;
}
.input-form{
width: 100%;
}
.data-input input{
width: 20%;
padding: 12px 20px;
margin: 8px 0px;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.switcher{
width: 25%;
margin: 25px;
display: inline-block;
display: flex;
justify-content: center;
}
.input-group{
margin: 20px;
display: flex;
justify-content: center;
}
.same-line{
margin: 0;
width: 25%;
}
.furniture{
width: 50%;
display: none;
}
.furniture input{
width: 20%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.describe{
margin-top: 25px;
}
.hidden{
display: none;
}
</style>
<section class="add_products">
<form class="input-form" action="" id="product_form">
<div class="data-input">
<label for="sku">SKU#:</label>
<input type="text" id="sku" name="sku">
</div>
<div class="data-input">
<label for="name">NAME:</label>
<input type="text" id="name" name="name">
</div>
<div class="data-input">
<label for="price">PRICE ($):</label>
<input type="number" id="price" name="price">
</div>
<div class="input-group switcher">
<label for="productType">Type Switcher:</label>
<select class="list_products" id="productType" name="TypeSwitcher" onchange="selectChanged()">
<option value="1">DVD</option>
<option value="2">Book</option>
<option value="3">furniture</option>
</select>
</div>
<div class="data-input product hidden">
<label for="size">Size (MB):</label>
<input type="number" class="hidden" id="size" name="price">
<p class="describe">Please provide size in (MB)</p>
</div>
<div class="furniture product hidden">
<label for="height">Height (CM):</label>
<input type="number" id="height" name="price">
</div>
<div class="furniture product hidden">
<label for="width">Width (CM):</label>
<input type="number" id="width" name="price">
</div>
<div class="furniture product hidden">
<label for="length">Length (CM):</label>
<input type="number" id="length" name="price">
<p class="describe">Please provide measurements in (CM)</p>
</div>
<div class="data-input product hidden">
<label for="weight">Weight (KG):</label>
<input type="number" id="weight" name="price">
<p class="describe">Please provide weight in KG</p>
</div>
My approach:
Put the input fields into their own divs
Give them ids that correspond to the selection options.
Use Javascript to check the selected value that you declared against the current display value of those ids and make the switch as necessary.
It's a bit different from what you were using but it works. Let me know what you think.
function selectChanged() {
var sel = document.getElementById("productType");
let dvd = document.getElementById("dvd");
let book = document.getElementById("book");
let furniture = document.getElementById("furniture");
for (var i = 1; i < 4; i++) {
dvd.style.display = sel.value == "1" ? "block" : "none";
book.style.display = sel.value == "2" ? "block" : "none";
furniture.style.display = sel.value == "3" ? "block" : "none";
}
}
.product {
border: 1px solid #333;
padding: 5px;
width: 20%;
margin: 25px 20px;
}
.info {
text-align: center;
}
.bottom-line {
box-sizing: border-box;
border-top: 1px solid;
margin: 0 34px;
}
form {
padding: 30px;
display: flex;
flex-direction: column;
}
.input-form {
width: 100%;
}
.data-input input {
width: 20%;
padding: 12px 20px;
margin: 8px 0px;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.switcher {
width: 25%;
margin: 25px;
display: inline-block;
display: flex;
justify-content: center;
}
.input-group {
margin: 20px;
display: flex;
justify-content: center;
}
.same-line {
margin: 0;
width: 25%;
}
.furniture {
width: 50%;
display: block;
}
.furniture input {
width: 20%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.describe {
margin-top: 25px;
}
#dvd {
display: none;
}
#book {
display: none;
}
#furniture {
display: none;
}
<section class="add_products">
<form class="input-form" action="" id="product_form">
<div class="data-input">
<label for="sku">SKU#:</label>
<input type="text" id="sku" name="sku">
</div>
<div class="data-input">
<label for="name">NAME:</label>
<input type="text" id="name" name="name">
</div>
<div class="data-input">
<label for="price">PRICE ($):</label>
<input type="number" id="price" name="price">
</div>
<div class="input-group switcher">
<label for="productType">Type Switcher:</label>
<select class="list_products" id="productType" name="TypeSwitcher" onchange="selectChanged()">
<option value="">Please Select</option>
<option value="1">DVD</option>
<option value="2">Book</option>
<option value="3">Furniture</option>
</select>
</div>
<div id="dvd">
<div class="data-input product">
<label for="size">Size (MB):</label>
<input type="number" id="size" name="price">
<p class="describe">Please provide size in (MB)</p>
</div>
</div>
<div id="book">
<div class="furniture product">
<label for="height">Height (CM):</label>
<input type="number" id="height" name="price">
</div>
<div class="furniture product">
<label for="width">Width (CM):</label>
<input type="number" id="width" name="price">
</div>
</div>
<div id="furniture">
<div class="furniture product">
<label for="length">Length (CM):</label>
<input type="number" id="length" name="price">
<p class="describe">Please provide measurements in (CM)</p>
</div>
<div class="data-input product">
<label for="weight">Weight (KG):</label>
<input type="number" id="weight" name="price">
<p class="describe">Please provide weight in KG</p>
</div>
</div>
</form>
</section>
Related
So I am trying to do this thing where a legend tag shows when the input box is being clicked. The idea is there is that the input box is inside a fieldset and the legend as a hidden class first. If the input box is on focus or clicked, the hidden class will be removed and it will show like this
I also added a part wherein if was left blank the legend tag will disappear by re-adding the removed
hidden class. However, it also leaves awkward whitespace in a place where it is formerly was like this
Did I do something wrong? Is there something I must do first?
The code is here:
$(function() {
$(".next").click(function() {
var div = $(this).closest('.wrapper');
var next = $(this).closest('.wrapper').next();
div.addClass('hidden');
next.removeClass('hidden');
})
})
$(function() {
$('input').click(function() {
$('input').each(function(index) {
const legend = $(this).closest('fieldset').children('legend');
if (($(this).val() == "" || $(this).val() == " ") && $(this).is(":focus") == false) {
if (legend.hasClass('hidden') == false) {
legend.addClass('hidden');
$(this).css("margin-top", "10px");
}
} else {
legend.removeClass('hidden');
$(this).css("margin-top", "-150%");
}
})
})
})
#import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
#import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght#700&display=swap');
html {
font-family: "Poppins", sans-serif;
margin: 0px;
padding: 0px;
background: #EDE9E8;
}
.cover {
width: 100%;
height: 100%;
position: absolute;
}
form {
/*border: 3px solid red;/**/
width: 57%;
height: 100%;
margin: 0 auto;
}
.child {
width: 50%;
}
.wrapper {
background: white;
width: 95%;
height: 65%;
padding: 3%;
margin-top: 8%;
border-radius: 50px;
display: flex;
}
.border_none {
border: none;
}
.border_black {
border: 2px solid black;
}
.with_image {
text-align: center;
margin-top: 15%;
}
.with_image img {
width: 40%;
}
.input_box {
height: 40px;
width: 70%;
}
.wrapper h1 {
margin-top: 10%;
}
.wrapper label {
font-size: 150%;
}
legend {
font-size: 12px;
/*border: 2px solid black;/**/
}
.wrapper fieldset input[type="text"],
.wrapper fieldset input[type="email"],
.wrapper input[type="password"],
input[type="number"] {
width: 100 %;
height: 100 %;
margin - top: 10 px;
border: none;
/**/
}
.wrapper fieldset input[type="text"]: focus,
.wrapper input[type="email"]: focus,
.wrapper input[type="password"]: focus,
input[type="number"]: focus {
outline: none;
}
.child fieldset {
overflow: hidden;
border - radius: 20 px;
}
.wrapper select {
margin - left: 14 %;
height: 40 px;
}
.wrapper.next {
background: #2c54db;
width: 15%;
height: 8%;
border: white;
color: white;
float: right;
border-radius: 40px;
font-weight: bold;
}
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cover">
<form method="post" action="">
<fieldset class="wrapper border_none">
<div class="child">
<h1>Identity</h1>
<fieldset class="input_box" class="input_outer">
<legend class="input_tag hidden">First Name</legend>
<input class="input_inner" type="text" name="fname" placeholder="First Name">
</fieldset><br>
<fieldset class="input_box" class="input_outer">
<legend class="input_tag hidden">Last Name</legend>
<input class="input_inner" type="text" name="lname" placeholder="Last Name">
</fieldset><br>
<label>Civil Status</label>
<select name="civil_status" id="cv_stat">
<option value="Single">Single</option>
<option value="Married">Married</option>
<option value="Widowed">Widowed</option>
<option value="Annulled">Anulled</option>
</select><br><br>
<fieldset class="input_box" class="input_outer">
<legend class="input_tag hidden">Email</legend><input type="email" name="email" placeholder="Email">
</fieldset>
<button type="button" class="next">
Next
</button>
</div>
<div class="child with_image">
<img src="../images/registration/user_folder_125px.png">
</div>
</fieldset>
<fieldset class="wrapper hidden">
<div class="child">
<h1>Password</h1>
<fieldset class="input_box" class="input_outer">
<legend class="input_tag hidden">Password</legend>
<input type="password" name="password" placeholder="Password">
</fieldset>
<br>
<fieldset class="input_box" class="input_outer">
<legend class="input_tag hidden">Confirm Password</legend>
<input type="password" name="cpassword" placeholder="Confirm Password">
</fieldset>
<button type="button" class="next">
Next
</button>
</div>
</div>
<div class="child">
</fieldset>
</form>
</div>
Thank you in advance!
The current problem I am having is that when an input is selected, all the div elements are permanently changed to red. I only want the selected input's div to become red. Also, if another input is selected I want the previous input to return to its original color.
This is what I have so far,
CodePen: https://codepen.io/martinlutherwinn/pen/jOEVmGj
function chgCol() {
var input =[];
var input = document.getElementsByClassName("Amt_Int");
var div =[];
var div = document.getElementsByClassName("Amt_Lal");
for(i=0; i < input.length; i++){
for(i=0; i < div.length; i++){
if(input[i].checked = true){
div[i].style.color = "red";
div[i].style.borderColor= "red";
} else{
div[i].style.color = "blue";
div[i].style.borderColor= "blue";
}
}
}
}
.DoF_Amt, .Pel_Info,.Pat_Info{
background-color: white;
margin-left: 20%;
margin-right: 20%;
color:blue;
margin-bottom: 5%;
padding: 5%
}
.Amt_Cor{
display:flex;
flex-wrap: wrap;
align-items:center;
justify-content: center;
}
.Amt_Lal{
display:flex;
justify-content:center;
align-items: center;
border: .3vmin solid rgba(0,0,255,1);
border-radius: 50%;
vertical-align: middle;
padding: 2%;
height: 10vmin;
width: 10vmin;
font-size: 4vmin;
margin: 2%;
}
.Amt_Int{
position: absolute;
clip: rect(0,0,0,0);
border: 0;
}
<form class="DoF_Amt">
<h2>Donation Amount</h2>
<div class="Amt_Cor">
<div class="Amt_Lal">
<label>
<input class="Amt_Int" type="radio" name="amount" value="one" />$1
</label>
</div>
<div class="Amt_Lal" onclick="chgCol()">
<label>
<input
class="Amt_Int"
type="radio"
name="amount"
value="twentyfive"
/>$25
</label>
</div>
<div class="Amt_Lal" onclick="chgCol()">
<label>
<input class="Amt_Int" type="radio" name="amount" value="fifty" />$50
</label>
</div>
<div class="Amt_Lal" onclick="chgCol()">
<label>
<input
class="Amt_Int"
type="radio"
name="amount"
value="seventhyfive"
/>$75
</label>
</div>
<div class="Amt_Lal" onclick="chgCol()">
<label>
<input
class="Amt_Int"
type="radio"
name="amount"
value="Custom"
/>Custom
</label>
</div>
</div>
<script src="/JavaScript/selectedInput.js"></script>
<button type="button">Donate with PayPal</button>
<button type="button">Donate with a Card</button>
</form>
Pass the event-target along to your click-handler by changing onclick="chgCol()" to onclick="chgCol({ target })". Then you can react more dynamically.
An even better solution would be to delegate the event to the parent-element (<div class="Amt_Cor">). An example follows:
const [clickTarget] = document.getElementsByClassName('Amt_Cor');
clickTarget.onclick = ({ target }) => {
if (!target.classList.contains('Amt_Lal')) return;
const currentlyHighlighted = document.querySelector('.highlight');
if (currentlyHighlighted) currentlyHighlighted.classList.remove('highlight');
target.classList.add('highlight');
target.firstElementChild.checked = true;
console.log(document.querySelector('[name="amount"]:checked').value);
};
.DoF_Amt, .Pel_Info,.Pat_Info{
background-color: white;
margin-left: 20%;
margin-right: 20%;
color:blue;
margin-bottom: 5%;
padding: 5%
}
.Amt_Cor{
display:flex;
flex-wrap: wrap;
align-items:center;
justify-content: center;
}
.Amt_Lal{
display:flex;
justify-content:center;
align-items: center;
border: .3vmin solid rgba(0,0,255,1);
border-radius: 50%;
vertical-align: middle;
padding: 2%;
height: 10vmin;
width: 10vmin;
font-size: 4vmin;
margin: 2%;
}
.Amt_Lal::after {
content: "";
position: absolute;
width: 15vmin;
height: 15vmin;
border-radius: 50%;
}
.Amt_Int {
position: absolute;
clip: rect(0,0,0,0);
border: 0;
}
.highlight {
border-color: red;
color: red;
}
<div class="Amt_Cor">
<label class="Amt_Lal">
<input class="Amt_Int" type="radio" name="amount" value="one">$1
</label>
<label class="Amt_Lal">
<input class="Amt_Int" type="radio" name="amount" value="twentyfive">$25
</label>
<label class="Amt_Lal">
<input class="Amt_Int" type="radio" name="amount" value="fifty">$50
</label>
<label class="Amt_Lal">
<input class="Amt_Int" type="radio" name="amount" value="seventhyfive">$75
</label>
<label class="Amt_Lal">
<input class="Amt_Int" type="radio" name="amount" value="Custom">Custom
</label>
</div>
You could do this with Pure CSS if you restructured your DOM a little and used the labels as the bubbles instead of their parent divs. You can take advantage of the :checked selector alongside the + (adjacent sibling) selectors.
Here's my take:
/* The important stuff: */
label {
border: .1rem solid rgba(0, 0, 255, 1);
color: rgba(0, 0, 255, 1);
}
input:checked+label {
border: .1rem solid rgba(255, 0, 0, 1);
color: rgba(255, 0, 0, 1);
}
/* The rest: */
form {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
label {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
vertical-align: middle;
height: 3rem;
width: 3rem;
font-size: 1rem;
padding: 0.5rem;
margin: 0.5rem;
}
input {
position: absolute;
clip: rect(0, 0, 0, 0);
border: 0;
}
<form>
<div>
<input id="option1" type="radio" name="amount" value="1">
<label for="option1">$1</label>
</div>
<div>
<input id="option2" type="radio" name="amount" value="5">
<label for="option2">$5</label>
</div>
<div>
<input id="option3" type="radio" name="amount" value="25">
<label for="option3">$25</label>
</div>
<div>
<input id="option4" type="radio" name="amount" value="50">
<label for="option4">$50</label>
</div>
</form>
When the user checks multiple checkboxes, form fields should appear according to the checkboxes, example: if flight checkbox had full name last name, when user checked both hotel and flight the full name and last name should be there and other fields should be hidden.
I have tried a toggle method which hides when I check, but I can not select multiple fields and get the common fields together and hide others. also my checkboxes should be aligned horizontally. I should css but it's not working
function toggle(object) {
var input;
var value = object.getAttribute("value");
switch (value) {
case "flight":
input = "input1";
break;
case "hotel":
input = "input2";
break;
case "travel":
input = "input3";
break;
}
var elements = document.getElementsByClassName(input);
for (var i = 0; i < elements.length; i++) {
if (elements[i].style.display == "block") {
elements[i].style.display = "none";
} else {
elements[i].style.display = "block";
}
}
document.getElementsByTagName("button")[0].style.display = "block";
}
.form-style-1 {
max-width: 600px;
padding: 15px 25px;
background: #f4f7f8;
margin: 15px auto;
padding: 20px;
background: #f4f7f8;
border-radius: 18px;
font-family: Calibri, sans-serif;
}
.form-style-1 fieldset {
border-radius: none;
background-color: #f2f2f2;
padding: 20px;
border: 1px solid lightgray;
width: 550px;
margin: auto;
}
.form-style-1 lable {
width: 180px;
float: left;
padding-top: 50px;
}
.form-control {
width: 550px;
padding: 15px 30px;
margin: 8px 0;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
display: inline;
}
output {
height: 30px;
display: block;
padding-top: 20px;
}
.btn {
width: 100%;
background-color: #4CAF50;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn:hover {
background-color: #45a049;
}
.form-style-1 input[type="text"],
.form-style-1 input[type="date"],
.form-style-1 input[type="datetime"],
.form-style-1 input[type="email"],
.form-style-1 input[type="number"],
.form-style-1 input[type="search"],
.form-style-1 input[type="time"],
.form-style-1 input[type="url"],
.form-style-1 input[type="tel"],
.form-style-1 textarea,
.form-style-1 select {
font-family: Calibri, sans-serif;
background: rgba(255, 0, 0, 0.2);
border: none;
border-radius: 3px;
font-size: 15px;
margin: 0;
outline: 0;
padding: 10px;
width: 50%;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
background-color: #e8eeef;
color: #000000;
-webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.03) inset;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.03) inset;
margin-bottom: 10px;
}
.form-style-1 input[type="text"]:focus,
.form-style-1 input[type="date"]:focus,
.form-style-1 input[type="datetime"]:focus,
.form-style-1 input[type="email"]:focus,
.form-style-1 input[type="number"]:focus,
.form-style-1 input[type="search"]:focus,
.form-style-1 input[type="time"]:focus,
.form-style-1 input[type="url"]:focus,
.form-style-1 input[type="tel"],
.form-style-1 textarea:focus,
.form-style-1 input {}
}
.form-style-1 select {
-webkit-appearance: menulist-button;
height: 15px;
color: #000000;
text-shadow: 0 1px 0 rgba(0, 0, 0);
background: #d2d9dd;
}
.form-style-1 number {
background: #1abc9c;
color: #000000;
height: 10px;
width: 10px;
display: inline-block;
font-size: 0.8em;
margin-right: 4px;
line-height: 10px;
text-align: center;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
border-radius: 15px 15px 15px 0px;
}
.form-style-1 input[type="submit"],
.form-style-1 input[type="button"] {
position: relative;
display: block;
padding: 15px 29px 15px 29px;
color: #FFF;
margin: 0 auto;
background: #1abc9c;
font-size: 15px;
text-align: center;
line-height: 10%;
font-style: normal;
width: 30%;
border: 1px solid #16a085;
border-width: 1px 1px 3px;
margin-top: 1px;
margin-bottom: 5px;
}
.form-style-1 input[type="submit"]:hover,
.form-style-1 input[type="button"]:hover {
background: #109177;
}
#travel-form label,
textarea {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
width: 80%;
padding-bottom: 0.1rem;
}
#travel-form input,
select {
margin-left: 1rem;
}
textarea {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
width: 250%;
padding-bottom: 0.1rem;
}
.common {
margin-bottom: 8px;
}
input[type="text"] {
display: none;
}
button {
display: none;
}
input[type="checkbox"] {
display: inline;
width: 12px;
height: 12px;
padding: 5px;
}
<body>
<div class="form-style-1">
<form action="mailto: ?subject=Travel Pre-approval Form " method="post" enctype="text/plain" id="travel-form" onsubmit="test1()">
<fieldset>
<input type="checkbox" onclick="toggle(this)" id="flight" value="flight"><label for="flight">Flight</label>
<input type="checkbox" onclick="toggle(this)" id="hotel" value="hotel"><label for="hotel">Hotel</label>
<input type="checkbox" onclick="toggle(this)" id="travel" value="travel"><label for="travel">Travel</label>
<label>Full Name: <input type="text" class="input1 common " id="name" placeholder="Full Name as per Passport"></label><br>
<label>Date of travel: <input type="date" class="input1 common " name="num1" id="date of travel"></label>
<label>Date of arrival: <input type="date" class="input1 common" name="num2"></label>
<label>Origin Location: <select name="opt2" id="cost" onchange="calculateTotal()">
<option value="select">select</option>
<option value="Dubai, United Arab Emirates (DXB-Dubai Intl.)">Dubai, United Arab Emirates (DXB-Dubai Intl.)</option>
</select></label>
<label>Destination Location: <select name="op1" id="locations" onchange="calculateTotal()">
<option value="none">none</option>
<option value="Aberdeen, Scotland, UK (ABZ)">Aberdeen, Scotland, UK (ABZ)</option>
</select></label>
<label>Mobile Number(Roaming) <input type="tel" id="phone"></label><br>
<br>
<label>Company Email Address <input type="email" id="email" placeholder="email address"></label><br>
<br>
<label>Passport Number <input type="text" id="passnum" size="5" name="passportnumber"></label>
<br>
<br>
<label>Passport Expiry Date <input type="date" id="passexdate" size="4" name="passportexdate"></label> <br>
<br>
<label>Visa Required <select type="checkbox" name="visarequired">
<option value="Yes">Yes</option>
<option value="No">No</option>
<option value="Don't Know">Don't Know</option>
</select></label>
<br>
<br>
<label>Visa Expiry Date <input type="date" id="visaexdate" name="visa"> </label>
<br>
<br>
<label>Purpose of Travel <input type="text" rows="6" cols="50" name="purpose Of Travel" form="usrform" placeholder="Purpose Of Travel">
</label> <br>
<label>Address Of Place Of Visitrows <input type="text" rows="6" cols="50" name="address" form="usrform" placeholder="Address of the place of Vist">
</label> <br>
<br>
<label>Billable Cost Centre <input type="text" id="billablecostcentre"></label>
<br>
<br>
<label>Billable project code <br> (Select "N/A" otherwise) <input type="text"></label>
<br>
<br>
<textarea rows="4" cols="150" name="comment" form="usrform" placeholder="Comments">
</textarea>
<label>Do you need Ground Transfer <select type="checkbox" namegroundtransfer>
<option>Yes</option>
<option>No</option>
</select></label>
<br>
<div id="totalCost">Total Cost </div><br>
<br>
<br>
<input type="submit" value="Submit">
</fieldset>
</form>
</div>
Check out the following code, it's a bit shortened and generalized CSS only approach of your form, that allows you to toggle form fields conditionally with checkboxes:
.form__field {
display: block;
}
[class*="--checkbox"] {
display: inline-block;
}
[data-conditional] {
display: none;
}
#flight:checked ~ [data-conditional*="flight"] {
display: block;
}
#hotel:checked ~ [data-conditional*="hotel"] {
display: block;
}
#travel:checked ~ [data-conditional*="travel"] {
display: block;
}
<form action="mailto:?subject=Travel Pre-approval Form " method="POST" enctype="text/plain" id="travel-form" onsubmit="test1()">
<input class="form__input form__input--checkbox" type="checkbox" id="flight" />
<label class="form__field form__field--checkbox" for="flight">
<span class="form__label">Flight</span>
</label>
<input class="form__input form__input--checkbox" type="checkbox" id="hotel" />
<label class="form__field form__field--checkbox" for="hotel">
<span class="form__label">Hotel</span>
</label>
<input class="form__input form__input--checkbox" type="checkbox" id="travel" />
<label class="form__field form__field--checkbox" for="travel">
<span class="form__label">Travel</span>
</label>
<label class="form__field form__field--text" data-conditional="flight hotel">
<span class="form__label">Full Name:</span>
<input class="form__input" type="text" placeholder="Full Name as per Passport" />
</label>
<label class="form__field form__field--date" data-conditional="flight hotel">
<span class="form__label">Date of travel:</span>
<input class="form__input" type="date" />
</label>
<label class="form__field form__field--date" data-conditional="flight hotel">
<span class="form__label">Date of arrival:</span>
<input class="form__input" type="date" />
</label>
<label class="form__field form__field--text" data-conditional="flight">
<span class="form__label">For Flight only:</span>
<input class="form__input form__input--text" type="text" />
</label>
<label class="form__field form__field--text" data-conditional="hotel">
<span class="form__label">For Hotel only:</span>
<input class="form__input form__input--text" type="text" />
</label>
<label class="form__field form__field--text" data-conditional="travel">
<span class="form__label">For Travel only:</span>
<input class="form__input form__input--text" type="text" />
</label>
<div class="form__field form__field--submit">
<button type="submit">Submit</button>
</div>
</form>
also my checkboxes should be aligned horizontally
this should be satisfied as well by the above snippet
We basically use checkboxes to toggle form fields based on the data-conditional attribute (you can call it whatever you like) that contains some value(s) we control to show/hide the form fields. The relatively simple secret-sauce part here is the general next sibling selector combined with HTML markup that allows us to use it properly.
I added some more fields that only show up for a single checkbox at the end of the form, to illustrate how the conditional filter works.
I not able to validate a multiple step form - I want a validation for each field instead of now it validates sets of fields
My code
function show_next(id, nextid, bar) {
var ele = document.getElementById(id).getElementsByTagName("input");
var error = 0;
for (var i = 0; i < ele.length; i++) {
if (ele[i].type == "text" && ele[i].value == "") {
error++;
}
}
if (error == 0) {
document.getElementById("account_details").style.display = "none";
document.getElementById("user_details").style.display = "none";
document.getElementById("qualification").style.display = "none";
$("#" + nextid).fadeIn();
document.getElementById(bar).style.backgroundColor = "#38610B";
} else {
alert("Fill All The details");
}
}
function show_prev(previd, bar) {
document.getElementById("account_details").style.display = "none";
document.getElementById("user_details").style.display = "none";
document.getElementById("qualification").style.display = "none";
$("#" + previd).fadeIn();
document.getElementById(bar).style.backgroundColor = "#D8D8D8";
}
body {
margin: 0 auto;
padding: 0;
text-align: center;
background-color: #D8D8D8;
}
#wrapper {
width: 995px;
padding: 0px;
margin: 0px auto;
font-family: helvetica;
position: relative;
}
#wrapper .baricon {
display: inline-block;
border-radius: 100%;
padding: 12px;
background-color: #38610B;
color: white;
}
#wrapper .progress_bar {
width: 200px;
height: 5px;
border-radius: 20px;
background-color: #D8D8D8;
display: inline-block;
}
#wrapper form div {
margin-left: 340px;
padding: 10px;
box-sizing: border-box;
width: 300px;
margin-top: 50px;
background-color: #585858;
}
#wrapper form div p {
color: #F2F2F2;
margin: 0px;
margin-top: 10px;
font-weight: bold;
}
#wrapper form div .form_head {
font-size: 22px;
font-weight: bold;
margin-bottom: 30px;
}
#wrapper form div input[type="text"] {
width: 200px;
height: 40px;
padding: 5px;
border-radius: 5px;
border: none;
margin-top: 10px;
}
#wrapper form div input[type="button"],
input[type="submit"] {
width: 80px;
height: 40px;
border-radius: 5px;
border: 2px solid white;
background: none;
color: white;
margin: 5px;
margin-top: 10px;
}
#user_details,
#qualification {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="wrapper">
<br>
<span class='baricon'>1</span>
<span id="bar1" class='progress_bar'></span>
<span class='baricon'>2</span>
<span id="bar2" class='progress_bar'></span>
<span class='baricon'>3</span>
<form method="post" action="">
<div id="account_details">
<p class='form_head'>Account Details</p>
<p>Email Address</p>
<input type="text" placeholder='Email Address'>
<p>Password</p>
<input type="text" placeholder='Password'>
<br>
<input type="button" value="Next" onclick="show_next('account_details','user_details','bar1');">
</div>
<div id="user_details">
<p class='form_head'>User Details</p>
<p>First Name</p>
<input type="text" placeholder='First Name'>
<p>Last Name</p>
<input type="text" placeholder='Last Name'>
<p>Gender</p>
<input type="text" placeholder='Gender'>
<br>
<input type="button" value="Previous" onclick="show_prev('account_details','bar1');">
<input type="button" value="Next" onclick="show_next('user_details','qualification','bar2');">
</div>
<div id="qualification">
<p class='form_head'>Qualification</p>
<p>Qualification</p>
<input type="text" placeholder='Qualification'>
<p>Hobbies</p>
<input type="text" placeholder='Hobbies'>
<br>
<input type="button" value="Previous" onclick="show_prev('user_details','bar2');">
<input type="Submit" value="Submit">
</div>
</form>
</div>
Here is a version that will not go to the next page if there are errors
Let me know what you think
I added two validations. You can change the rest. The code is vastly simplified
function isEmail(str) { // simple email validation
return /(.+)#(.+){2,}\.(.+){2,}/.test($.trim(str));
}
function isEmpty(str) { // test for empty string
return $.trim(str) === "";
}
function validate($div) { // validates any div - will not let you leave the div if error
var $fields = $div.find("input"), hasError = false;
$fields.each(function() {
$(this).removeClass("error")
hasError = this.name=="pword" && isEmpty(this.value);
if (hasError) {
$("#pword").addClass("error").focus();
return false;
}
hasError = this.name=="email" && (isEmpty(this.value) || !isEmail(this.value));
if (hasError) {
$("#email").addClass("error").focus();
return false;
}
hasError = isEmpty(this.value); // the rest of the fields
if (hasError) {
$(this).addClass("error").focus();
return false;
}
})
return hasError?false:true;
}
$(function() {
// validate all divs on submit, but actually only necessary to validate thediv the submit is on
$("#myForm").on("submit",function(e) {
$(".page").each(function() {
if (!validate($(this))) {
e.preventDefault(); // stop submission
return false;
}
});
});
$(".nav").on("click", function() {
var $parent = $(this).closest("div");
var $nextDiv = $(this).hasClass("next") ? $parent.next() : $parent.prev();
if (validate($parent)) { // is the div this button is on valid?
$parent.fadeOut(function() { // fade it out and fade the next one in
if ($nextDiv.length) {
$nextDiv.fadeIn()
for (var i=$(".page").length;i> $nextDiv.index(); i--) {
$("#bar" + i).css({"background-color": "#D8D8D8"}); // we are going backwards
}
$("#bar" + $nextDiv.index()).css({"background-color": "#38610B"});
}
});
}
});
});
body {
margin: 0 auto;
padding: 0;
text-align: center;
background-color: #D8D8D8;
}
#wrapper {
width: 995px;
padding: 0px;
margin: 0px auto;
font-family: helvetica;
position: relative;
}
#wrapper .baricon {
display: inline-block;
border-radius: 100%;
padding: 12px;
background-color: #38610B;
color: white;
}
#wrapper .progress_bar {
width: 200px;
height: 5px;
border-radius: 20px;
background-color: #D8D8D8;
display: inline-block;
}
#wrapper form div {
margin-left: 340px;
padding: 10px;
box-sizing: border-box;
width: 300px;
margin-top: 50px;
background-color: #585858;
}
#wrapper form div p {
color: #F2F2F2;
margin: 0px;
margin-top: 10px;
font-weight: bold;
}
#wrapper form div .form_head {
font-size: 22px;
font-weight: bold;
margin-bottom: 30px;
}
#wrapper form div input[type="text"] {
width: 200px;
height: 40px;
padding: 5px;
border-radius: 5px;
border: none;
margin-top: 10px;
}
#wrapper form div input[type="button"],
input[type="submit"] {
width: 80px;
height: 40px;
border-radius: 5px;
border: 2px solid white;
background: none;
color: white;
margin: 5px;
margin-top: 10px;
}
#user_details,
#qualification {
display: none;
}
.error { background-color:pink !important}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="wrapper">
<br>
<span class='baricon'>1</span>
<span id="bar1" class='progress_bar'> </span>
<span class='baricon'>2</span>
<span id="bar2" class='progress_bar'> </span>
<span class='baricon'>3</span>
<form method="post" action="" id="myForm">
<div id="account_details" class="page">
<p class='form_head'>Account Details</p>
<p>Email Address</p>
<input type="text" name="email" id="email" placeholder='Email Address'>
<p>Password</p>
<input type="text" name="pword" id="pword" placeholder='Password'>
<br>
<input type="button" value="Next" class="nav next" />
</div>
<div id="user_details" class="page">
<p class='form_head'>User Details</p>
<p>First Name</p>
<input type="text" name="fname" id="fname" placeholder='First Name'>
<p>Last Name</p>
<input type="text" name="lname" is="lname" placeholder='Last Name'>
<p>Gender</p>
<input type="text" name="gender" id="gender" placeholder='Gender'>
<br>
<input type="button" value="Prev" class="nav prev" />
<input type="button" value="Next" class="nav next" />
</div>
<div id="qualification" class="page">
<p class='form_head'>Qualification</p>
<p>Qualification</p>
<input type="text" placeholder='Qualification'>
<p>Hobbies</p>
<input type="text" placeholder='Hobbies'>
<br>
<input type="button" value="Prev" class="nav prev" />
<input type="Submit" value="Submit">
</div>
</form>
</div>
I am using the same form on two different pages. On the first one every div is tidy in the desired position. On the second page, there is a select that only appears after a change (jquery trigger), which causes the div below it to appear first on the right but after the trigger it moves on the left. I'd like the div which contains radio buttons to be on the left side at all times, just like it is on the first page. The part that I'd like to fix is #center-add-new-event-form .container-field input[type=radio].
This is the css.
#center-add-new-event-form,
#center-add-new-event-form * {
box-sizing: border-box;
}
#center-add-new-event-form {
padding: 20px 10px 0px;
}
#center-add-new-event-form .container-field {
width: 50%;
float: left;
padding: 0 10px;
margin-bottom: 20px;
vertical-align: top;
}
#center-add-new-event-form .container-field label {
display: block;
font-weight: 600;
margin-bottom: 5px;
}
#center-add-new-event-form .container-field input[type=text],
#center-add-new-event-form .container-field select {
height: 34px;
border: 1px solid #ddd;
padding: 0 7px;
display: block;
width: 100%;
}
#center-add-new-event-form .container-field input[type=radio]
{
height: 34px;
border: 1px solid #ddd;
padding: 0 7px;
display: block;
width: 100%;
}
#center-add-new-event-form .center-error-message {
font-size: 0.9em;
color: darkred;
display: block;
margin-left: 1px;
}
.center-event-actions {
border-top: 1px solid #ddd;
padding: 20px 20px 15px;
text-align: right;
}
.clearfix:before,.clearfix:after {
display: table;
content: " ";
}
.clearfix:after {
clear: both;
}
#media screen and (max-width: 767px) {
#center-add-new-event-form .container-field {
float: none;
width: 100%;
}
}
<form id="center-add-new-event-form" class="clearfix">
<div class="container-field" style="width: 100%">
<label></label>
<div id="center-request-details">
</div>
</div>
<div class="container-field">
<label for="teaching-requests"></label>
<select id="input-teaching-requests" name="teaching-requests" class="create-request-event ui-widget-content ui-corner-all">
<option value=""></option>
<option value=""></option>
</select>
<span class="center-error-message"></span>
</div>
<div class="container-field">
<label for="request-date"></label>
<input type="text" name='request-date' class="create-request-event event-datepicker ui-widget-content ui-corner-all">
<span class="center-error-message"></span>
</div>
</div>
<div class="container-field">
<label for="teaching-start-time"></label>
<input type="text" name="teaching-start-time" class="create-request-event event-timepicker text ui-widget-content ui-corner-all">
<span class="center-error-message"></span>
</div>
<span class="clearfix"></span>
<div class="container-field">
<label for="teaching-end-time"></label>
<input type="text" name="teaching-end-time" class="create-request-event event-timepicker text ui-widget-content ui-corner-all">
<span class="center-error-message"></span>
</div>
<div class="container-field">
<label for="teaching-teacher"></label>
<div id='contanier-teacher-selection'>
</div>
<span class="center-error-message"></span>
</div>
<div class="container-field pull-left" align="left">
<label for="recursive-events" align="left">
<input type="radio" align="left" name="recursive" value="daily"/>Daily
<input type="radio" align="left" name="recursive" value="weekly"/>Weekly
<input type="radio" align="left" name="recursive" value="monthly"/>Monthly
</label>
</div>
<span class="center-error-message"></span>
</form>
<div class="center-event-actions">
<button id="cancel-add-new-event" class='button' data-izimodal-close="" data-izimodal-transitionout="bounceOutDown"></button>
<button id="add-new-event" class='button button-primary'></button>
</div>
Before
After
It looks like it is caused by container-field <= width: 50% and float
so when this div appears it appears next to last one
the solution add
<span class="clearfix"></span>
before the the element with radio buttons
This might work:
#center-add-new-event-form .container-field input[type=radio]:before
{
height: 34px;
border: 1px solid #ddd;
padding: 0 7px;
display: block;
width: 100%;
}
#center-add-new-event-form .container-field input[type=radio]:after
{
height: 34px;
border: 1px solid #ddd;
padding: 0 7px;
display: block;
width: 100%;
float: right;
}