jQuery find all elements with same name start as selector - javascript

I am building the form which has SELECT and few inputs. The part of it looks like this (only for Monday example, there will be 7 days..):
<div class="row">
<div class="col-md-3">
<div class="form-group mb-md">
<input type="text" name="1[day]" class="form-control text-bold" value="Monday" readonly>
</div>
</div>
<div class="col-md-1">
<div class="form-group">
<select class="form-control input-md mb-md" name="1[open]">
<option value="1" selected>Open</option>
<option value="0">Closed</option>
</select>
</div>
</div>
<!-- Working Hours -->
<div class="col-md-2">
<div class="form-group">
<input type="text" class="form-control time" name="1[start]" value="08:00">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input type="text" class="form-control time" name="1[end]" value="22:00">
</div>
</div>
<!-- Booking Hours -->
<div class="col-md-2">
<div class="form-group">
<input type="text" class="form-control time" name="1[from]" value="08:00">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input type="text" class="form-control time" name="1[to]" value="22:00">
</div>
</div>
</div>
I want to make time fields with same name start as SELECT field name start react to SELECT change. If value is 0 then all fields with same name start get attribute disabled.
So far i made this function, however i don't know hot to determine changed field name and correspondingly take actions against other fields.
$("select[name$='[open]']").change(function() {
if ($(this).val() == 0) {
// Should disable all input fields with same name as SELECT
} else if ($(this).val() == 1) {
// Should enable all input fields with same name as SELECT
}
});

Not sure if this is what you are attempting to achieve.
Please try below code.
$("select[name$='[open]']").change(function() {
var num = $(this).attr("name").replace("[open]",'');
var elems = $( "input[name^='"+num+"']");
if ($(this).val() == 0) {
// Should disable all input fields with same name as SELECT
elems.prop('disabled',true);
} else if ($(this).val() == 1) {
// Should enable all input fields with same name as SELECT
elems.prop('disabled',false);
}
});
Check the working fiddle here.

Related

How can I check if the type DATE is filled?

I have some questions.
I need to do an appointment form, where I have a bunch of text fields, for the name, email, a DATE field and two dropdown menus. At the end of the form, I have a submit button, but I want it to work only if all of the fields above are filled and if the fields are not filled i have an alert message. I did the verification for the name and email to see if the textboxes are empty or not, but I can't do it for the dropdown menus and the date. The date should be picked by the customer and if it's not picked from the menu I have the placeholder "DD.MM/YYYY".
For the dropdown menus I also have placeholders, and I wanna check if the customer has picked one of the options, how can I check if the value of it is the placeholder name that i set?
This is the code to check if the name and email fields are filled and it works. But I can't find any code to work to check if date is empty or the dropdown menus option is the same placeholder.
<script language="JavaScript1.1" type="text/javascript">
function popupok() {
ok = false;
test1=false;
const textbox1 = document.getElementById("name");
const textbox2 = document.getElementById("email");
if(textbox1.value.length && textbox2.value.length > 0)
{
ok=true;
}
if(ok==true)
{
alert("appointment has been scheduled!")
}
else
{
alert("please fill the required fields!")
}
}
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<div class="well-block">
<div class="well-title">
<h2>Programeaza-te acum!</h2>
</div>
<form required>
<!-- Form start -->
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label" for="name">Nume</label>
<input id="name" name="name" type="text" placeholder="Nume complet" class="form-control input-md"required>
</div>
</div>
<!-- Text input-->
<div class="col-md-6">
<div class="form-group">
<label class="control-label" for="email">Email</label>
<input id="email" name="email" type="text" placeholder="E-Mail" class="form-control input-md" required>
</div>
</div>
<!-- Text input-->
<div class="col-md-6">
<div class="form-group">
<label class="control-label" for="date">Data programarii</label>
<br/>
<input type="date" id="date" name="date" required>
</div>
</div>
<!-- Select Basic -->
<div class="col-md-6">
<div class="form-group">
<label class="control-label" for="time">Ora programarii</label>
<select id="time" name="time" class="form-control" required>
<option value="8:00">8:00</option>
<option value="9:00">9:00</option>
<option value="10:00">10:00</option>
<option value="11:00">11:00</option>
<option value="12:00">12:00</option>
<option value="13:00">13:00</option>
<option value="14:00">14:00</option>
<option value="15:00">15:00</option>
<option value="16:00">16:00</option>
<option value="17:00">17:00</option>
<option value="18:00">18:00</option>
<option value="19:00">19:00</option></option>
</select>
</div>
</div>
<!-- Select Basic -->
<div class="col-md-12">
<div class="form-group">
<label class="control-label" for="appointmentfor">Serviciul dorit</label>
<select id="appointmentfor" name="appointmentfor" class="form-control" required>
<option value="Service#1">Coafor</option>
<option value="Service#2">Cosmetica</option>
<option value="Service#3">Manichiura</option>
</select>
</div>
</div>
<!-- Button -->
<div class="col-md-12">
<br/>
<div class="form-group">
<button id="singlebutton" name="singlebutton" type="submit" onclick="popupok()">Rezerva locul!</button>
</div>
</div>
</div>
</form>```
You can -- the date seems to be an empty string, so you can simply do:
if (date) {
// date isn't an empty string, null, or undefined.
}
const input = document.getElementById("input");
console.log(`${input.value} (has value: ${!!input.value})`)
input.addEventListener("change", () => {
console.log(`${input.value} (has value: ${!!input.value})`)
})
<input type="date" id="input">
use:
const DROPDOWN = document.querySelector('.dropdown');
if(DROPDOWN.value === '') {
// do something if empty
}
if(DROPDOWN.value === 'option value') {
// do something
}
//every option has a value. in html you should specify it in tag by value = 'something';
to check if dropdown is chosen or not. although I don't know what kind of dropdown it is.
for date just do the same thing but like
if(DATE.innerHTML === "DD.MM/YYYY") { //your placeholder
// do something
}
or
if(DATE.value === "DD.MM/YYYY") { //your placeholder
// do something
}
if the user hasn't changed the date it would be same as your placeholder.
You have already used the "required" attribute in your fields which is a HTML5 attribute that forces the form not to be submitted if the field is empty, so you dont need additional JS code.
In case of select dropdowns you are missing an empty entry. Just add a first option in the dropdown with empty value and it will work. Do it like this:
<select name='myselect' id='myselect' required>
<option value=''>Please select</option>
<option value='1'>First option</option>
<option value='2'>Second option</option>
</select>
Its important to have the first option with an empty value. The first option always gets selected by default and the empty value there will trigger the validation.

Submitting form set all null inputs and their associated hidden input fields to disabled

I have a form with multiple input fields where users may choose to enter a value or not. Next to each input field is a hidden input field that will send a specific id unique to the previous input field. On form submission, all blank input fields are disabled. This I got to work using this code.
function disableEmptyInputs(form) {
var controls = form.elements;
for (var i = 0, iLen = controls.length; i < iLen; i++) {
controls[i].disabled = controls[i].value == '';
}
}
I now want to also disable the hidden inputs if their primary visible input field is null
<div class="col-md-4">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input name="Pay" placeholder="Amount for A" class="form-control" type="text" />
<input type="hidden" name="PayId" value="A" />
</div>
</div>
<div class="col-md-4">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input name="Pay" placeholder="Amount for B" class="form-control" type="text" />
<input type="hidden" name="PayId" value="B" />
</div>
</div>
Any help will be really appreciated. The form submits to a c# backend where I am able to filter out all blanks If I allowed all blanks to be submitted but I felt if I could filter all blanks by making them disabled at the client side in addition to server side that will be better.
You can use .each loop to iterate through your form elements and then compare if the value of input is "" simply disable that input and also the input next to it using .next().
Demo Code :
$("form").on("submit", function() {
//loop through input(exclude hidden input)..select..etc
$("form").find("input:not(:hidden),select").each(function() {
//if the value is empty
if ($(this).val() == "") {
$(this).prop("disabled", true) //disable
$(this).next().prop("disabled", true) //also next field (hidden) disable
}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="col-md-4">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input name="Pay" placeholder="Amount for A" class="form-control" type="text" value="abc" />
<input type="hidden" name="PayId" value="A" />
</div>
</div>
<div class="col-md-4">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input name="Pay" placeholder="Amount for B" class="form-control" type="text" />
<input type="hidden" name="PayId" value="B" />
</div>
</div>
<button>Click me ..</button>
</form>

Dynamically add/remove forms groups and give unique id and names for each inputs

I am working on a complex CMS kind of thing. Basically what I want is to create more form inputs on click of a button and even remove them by another button. The script is already working, but each input has the same name. I want to write a php script to submit the data in a database. So i want all of them to have unique name and id.
I have the following JS/jQuery/HTML:
$(document).ready(function() {
//group add limit
var maxGroup = 7;
//add more fields group
$(".addMore").click(function() {
if ($('body').find('.fieldGroup').length < maxGroup) {
var fieldHTML = '<div class="row fieldGroup">' + $(".fieldGroupCopy").html() + '</div>';
$('body').find('.fieldGroup:last').after(fieldHTML);
} else {
alert('Maximum ' + maxGroup + ' groups are allowed.');
}
});
//remove fields group
$("body").on("click", ".remove", function() {
$(this).parents(".fieldGroup").remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<div class="row fieldGroup">
<div class="col-md-3">
<div class="form-group">
<label for="productId">ID :</label>
<input type="text" name="productId[]" class="form-control" id="productId[]"> </div>
</div>
<div class="col-md-5">
<div class="form-group">
<label for="productName">Name :</label>
<input type="text" name="productId[]" class="form-control" id="productName[]">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="price">Price :</label>
<input type="number" name="price[]" id="price[]" class="form-control">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="commission">Commission :</label>
<input type="number" name="commission[]" id="commission[]" class="form-control">
</div>
</div>
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span> Add
</div>
<div class="row fieldGroupCopy" style="display: none;">
<div class="col-md-3">
<div class="form-group">
<label for="productId">ID :</label>
<input type="text" name="productId[]" class="form-control" id="productId[]"> </div>
</div>
<div class="col-md-5">
<div class="form-group">
<label for="productName">Name :</label>
<input type="text" name="productId[]" class="form-control" id="productName[]">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="price">Price :</label>
<input type="number" name="price[]" id="price[]" class="form-control">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="commission">Commission :</label>
<input type="number" name="commission[]" id="commission[]" class="form-control">
</div>
</div>
<span class="glyphicon glyphicon glyphicon-remove" aria-hidden="true"></span> Remove
</div>
</section>
Everything works as desired except the name and id arrays dont work.
I want the name be like productId1, productId2, productId3 and so on.
Similarly, I want the name be like price1, price2 etc.
Same is the case for commission and name.
I want the output to have unique id and names so that I can write php script easily to submit the form.
When I click on the add button, a new form group is created but it has the same id and name as the previous one. I want an array in place of those square brackets[]
Need to follow two steps:
1) You just have to maintain counter in input type hidden and increment it on each click.
and give id to particular Div.
var cnt=0;
$(".addMore").click(function() {
if ($('body').find('.fieldGroup').length < maxGroup) {
var fieldHTML = '<div class="row fieldGroup" id="dynamicfrom+ cnt>' + $(".fieldGroupCopy").html() + '</div>';
$('body').find('.fieldGroup:last').after(fieldHTML);
cnt++;
} else {
alert('Maximum ' + maxGroup + ' groups are allowed.');
}
});
2) after adding new form group , loop throu all input of form and change it's name by counter id.
$('#divformgroup(Counter) input').each(function () {
//Here change name of input.
$('input').attr('name', 'yourNewname');
});
you can follow this links:
enter link description here
enter link description here

Javascript disable/enable input field based on selection other field

I tried to follow answer here to do this in my code: How do I disable input field when certain select list value is picked but not working for me.
I have an HTML select field id 'TfL' with Yes/No answer, and next field 'TfLroad' is an input field. I want 'TfLroad' to load as disabled by default, then if 'TfL' changes from No to Yes, then 'TfLroad' should be enabled.
Whole page code below, JS at top of file, these two fields next to bottom, tx any suggestions!:
{% extends "base.jinja2" %}
{% block content %}
<script>
// value 0 for No answer to TfL road 1 for, in which case disabled, on change should
// enable TfLroad element by setting disabled = false, but not working yet!
document.getElementById("TfLroad").onload = function () {
document.getElementById("TfLroad").disabled = true;
}
document.getElementById('TfL').onchange = function () {
if(this.value = '0') {
document.getElementById("TfLroad").disabled = true;
}
else {
document.getElementById("TfLroad").disabled = false;
}
}
</script>
<h2 style="text-align:center">Add A 'Dummy' Street</h2>
<p>You can create a Dummy street here, which you will be able to search for in this application. This is to
demonstrate how a real Create & Update Process could work for this application, without corrupting the original
data. Dummy streets are indicated in search results.</p>
<form class="form-horizontal" action = "" method="post">
<fieldset>
<div class="form-group">
<div class="col-lg-6">
<label for="stname" class="control-label">Street Name</label>
<input class="form-control" id="stname" name="stname" pattern="^\S.{3,98}\S$"
title="Sorry, you must type from 5 to 100 characters, and no space at beginning or end."
placeholder="Full Street Name" required>
<!-- required attribute needed because empty string bypasses the pattern regex. -->
<span class="help-block">NB: No naughty word streets please, these will be deleted by admin!</span>
</div>
<!-- CR, CL, PR, 25, 16, 19, BE, KN, SC, TH, WA, WH -->
<div class="col-lg-3">
<label for="distr" class="control-label">Postal District</label>
<select class="form-control" id="distr" name="distr">
<option>Croydon (CR0, CR2, CR7 or CR9)</option>
<option>Coulsdon CR5</option>
<option>Purley CR8</option>
<option>London SE25</option>
<option>London SW16</option>
<option>Kenley CR8</option>
<option>South Croydon CR2</option>
<option>Thornton Heath CR7</option>
<option>Warlingham CR6</option>
<option>Whyteleafe CR3</option>
<option>Beckenham BR3</option>
</select>
<span class="help-block">NB: Original data uses postal district only, hence problem with several postcodes for Croydon.</span>
</div>
<div class="col-lg-3">
<label for="maint" class="control-label">Who looks after this street?</label>
<select class="form-control" id="maint" name="maint">
<option>Croydon Borough</option>
<option>Transport for London</option>
<option>Private Road</option>
</select>
</div>
</div>
<div class="form-group">
<h4 class="centre">Street Number Limits for this Street Section<br/><small>Please leave as None if all properties in this section have names</small></h4>
</div>
<div class="form-group">
<div class="col-lg-3">
<label for="onb" class="control-label">Odd Numbers From</label>
<input class="form-control" id="onb" name="onb" value="None" pattern="^\d*[13579]$|(None)" title="Odd Numbers only please with no spaces, or None">
<span class="help-block">e.g. '1' or '111'</span>
</div>
<div class="col-lg-3">
<label for="one" class="control-label">Odd Numbers To</label>
<input class="form-control" id="one" name="one" value="None" pattern="^\d*[13579]$|(None)" title="Odd Numbers only please with no spaces, or None">
<span class="help-block">e.g. '31' or '217'</span>
</div>
<div class="col-lg-3">
<label for="enb" class="control-label">Even Numbers From</label>
<input class="form-control" id="enb" name="enb" value="None" pattern="^\d*[02468]$|(None)" title="Even Numbers only please with no spaces, or None">
<span class="help-block">e.g. '2' or '110'</span>
</div>
<div class="col-lg-3">
<label for="ene" class="control-label">Even Numbers To</label>
<input class="form-control" id="ene" name="ene" value="None" pattern="^\d*[02468]$|^(None)$" title="Even Numbers only please with no spaces, or None">
<span class="help-block">e.g. '32' or '216'</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-4">
<label for="rdclass" class="control-label">Road Class</label>
<select class="form-control" id="rdclass" name="rdclass">
<option>Unclassified</option>
<option>A Road</option>
<option>B Road</option>
<option>C Road</option>
</select>
<span class="help-block">Leave as Unclassified if in any doubt.</span>
</div>
<div class="col-lg-4">
<label for="length" class="control-label">Length of this Street Section (whole no. metres)</label>
<input class="form-control" id="length" name="length" value= 0 pattern="^[1-9][0-9]*$" title="Whole number of metres please, no spaces!" required>
</div>
<div class="col-lg-4">
<!-- JS here to put in A B C / disable depending on what selected in rdclass box -->
<label for="rdnum" class="control-label">Road Number</label>
<input class="form-control" id="rdnum" name="rdnum" pattern="^[ABC][1-9][0-9]*$|^(None)$" title="Must be None, or A, B or C followed by a whole number for the road class, no spaces!" value="None" required>
<span class="help-block">Only for A/B/C roads e.g. 'A232', 'C3241'</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-3">
<label class="control-label left">Does one end of this street adjoin a TfL maintained street?</label>
<select class="form-control" id="TfL">
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div class="col-lg-4">
<!-- JS not working yet to disable only if no selected in rdclass box -->
<label class="control-label"><br/> Road Number of Adjoining TfL Road?</label>
<input class="form-control" pattern="^[ABC][1-9][0-9]*$|^(None)$"
title="Must be None, or A, B or C followed by a whole number, no spaces!" value="None" id="TfLroad" required>
<span class="help-block">E.g. 'A232', 'B2441'</span>
</div>
</div>
<div class="form-group">
<div class="centre">
<button type="reset" class="btn btn-default">Reset Form</button>
<button type="submit" class="btn btn-primary">Create Street</button>
</div>
</div>
</fieldset>
</form>
{% endblock %}
Instead of setting disabled through javascript you could add the disabled to the HTML input element:
<input class="form-control" disabled="disabled" .... />
Then in your javascript:
document.getElementById('TfL').onchange = function ()
{
if (this.value == '0')
{
document.getElementById("TfLroad").disabled = true;
}
else
{
document.getElementById("TfLroad").disabled = false;
}
}
There are several problems in the HTML/script you provided.
The <script> content is executing before the form fields exist (onload code isn't implemented the way you've done it.)
You haven't picked a default value for TfL
You haven't disabled TfLroad by default
You've got a typo in a comparison.
Fixing in order:
move the <script> to the bottom of the page and remove the onload function.
assuming you want No selected by default:
<select class="form-control" id="TfL">
<option value="0" selected>No</option>
<option value="1">Yes</option>
</select>
Add disabled attribute
<input class="form-control" pattern="^[ABC][1-9][0-9]*$|^(None)$" disabled
title="Must be None, or A, B or C followed by a whole number, no spaces!" value="None" id="TfLroad" required>
usie = instead of == (or ===):
if(this.value = '0') {
Should be
if(this.value === '0') {
(You could also rewrite the onchange handler):
document.getElementById('TfL').onchange = function () {
document.getElementById("TfLroad").disabled = (this.value === '0');
}
disabled is a Boolean attribute. You don't disable an element by setting its attribute to disabled=false. The browser checks if your element HAS a disabled property and doesn't care if its disabled=true, disabled=false, disabled=elephant. In order to "enable" your element you must completely remove the disabled attribute.
This should work:
document.getElementById('TfL').onchange = function () {
if(this.value == '0') {
document.getElementById("TfLroad").disabled = "elephant";
}
else {
document.getElementById("TfLroad").removeAttr("disabled");
}
}
Also when comparing two values use == and not =.
So the problem is load event does not work on all elements, it only supports the below HTML tags.
<body>, <frame>, <frameset>, <iframe>, <img>, <input type="image">,
<link>, <script> and <style>
Refer here to know more.
Also I have changed the logic for applying the initial disabled condition, please check it!
As an alternative you can watch for document.ready instead and then apply this change. Refer the below snippet.
var select = document.getElementById('TfL'), input = document.getElementById("TfLroad");
document.addEventListener("DOMContentLoaded", function(event) {
if (select.value === '0') {
input.disabled = true;
} else {
input.disabled = false;
}
});
select.onchange = function() {
if (this.value === '0') {
input.disabled = true;
} else {
input.disabled = false;
}
}
<h2 style="text-align:center">Add A 'Dummy' Street</h2>
<p>You can create a Dummy street here, which you will be able to search for in this application. This is to demonstrate how a real Create & Update Process could work for this application, without corrupting the original data. Dummy streets are indicated
in search results.</p>
<form class="form-horizontal" action="" method="post">
<fieldset>
<div class="form-group">
<div class="col-lg-6">
<label for="stname" class="control-label">Street Name</label>
<input class="form-control" id="stname" name="stname" pattern="^\S.{3,98}\S$" title="Sorry, you must type from 5 to 100 characters, and no space at beginning or end." placeholder="Full Street Name" required>
<!-- required attribute needed because empty string bypasses the pattern regex. -->
<span class="help-block">NB: No naughty word streets please, these will be deleted by admin!</span>
</div>
<!-- CR, CL, PR, 25, 16, 19, BE, KN, SC, TH, WA, WH -->
<div class="col-lg-3">
<label for="distr" class="control-label">Postal District</label>
<select class="form-control" id="distr" name="distr">
<option>Croydon (CR0, CR2, CR7 or CR9)</option>
<option>Coulsdon CR5</option>
<option>Purley CR8</option>
<option>London SE25</option>
<option>London SW16</option>
<option>Kenley CR8</option>
<option>South Croydon CR2</option>
<option>Thornton Heath CR7</option>
<option>Warlingham CR6</option>
<option>Whyteleafe CR3</option>
<option>Beckenham BR3</option>
</select>
<span class="help-block">NB: Original data uses postal district only, hence problem with several postcodes for Croydon.</span>
</div>
<div class="col-lg-3">
<label for="maint" class="control-label">Who looks after this street?</label>
<select class="form-control" id="maint" name="maint">
<option>Croydon Borough</option>
<option>Transport for London</option>
<option>Private Road</option>
</select>
</div>
</div>
<div class="form-group">
<h4 class="centre">Street Number Limits for this Street Section<br/><small>Please leave as None if all properties in this section have names</small></h4>
</div>
<div class="form-group">
<div class="col-lg-3">
<label for="onb" class="control-label">Odd Numbers From</label>
<input class="form-control" id="onb" name="onb" value="None" pattern="^\d*[13579]$|(None)" title="Odd Numbers only please with no spaces, or None">
<span class="help-block">e.g. '1' or '111'</span>
</div>
<div class="col-lg-3">
<label for="one" class="control-label">Odd Numbers To</label>
<input class="form-control" id="one" name="one" value="None" pattern="^\d*[13579]$|(None)" title="Odd Numbers only please with no spaces, or None">
<span class="help-block">e.g. '31' or '217'</span>
</div>
<div class="col-lg-3">
<label for="enb" class="control-label">Even Numbers From</label>
<input class="form-control" id="enb" name="enb" value="None" pattern="^\d*[02468]$|(None)" title="Even Numbers only please with no spaces, or None">
<span class="help-block">e.g. '2' or '110'</span>
</div>
<div class="col-lg-3">
<label for="ene" class="control-label">Even Numbers To</label>
<input class="form-control" id="ene" name="ene" value="None" pattern="^\d*[02468]$|^(None)$" title="Even Numbers only please with no spaces, or None">
<span class="help-block">e.g. '32' or '216'</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-4">
<label for="rdclass" class="control-label">Road Class</label>
<select class="form-control" id="rdclass" name="rdclass">
<option>Unclassified</option>
<option>A Road</option>
<option>B Road</option>
<option>C Road</option>
</select>
<span class="help-block">Leave as Unclassified if in any doubt.</span>
</div>
<div class="col-lg-4">
<label for="length" class="control-label">Length of this Street Section (whole no. metres)</label>
<input class="form-control" id="length" name="length" value=0 pattern="^[1-9][0-9]*$" title="Whole number of metres please, no spaces!" required>
</div>
<div class="col-lg-4">
<!-- JS here to put in A B C / disable depending on what selected in rdclass box -->
<label for="rdnum" class="control-label">Road Number</label>
<input class="form-control" id="rdnum" name="rdnum" pattern="^[ABC][1-9][0-9]*$|^(None)$" title="Must be None, or A, B or C followed by a whole number for the road class, no spaces!" value="None" required>
<span class="help-block">Only for A/B/C roads e.g. 'A232', 'C3241'</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-3">
<label class="control-label left">Does one end of this street adjoin a TfL maintained street?</label>
<select class="form-control" id="TfL">
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div class="col-lg-4">
<!-- JS not working yet to disable only if no selected in rdclass box -->
<label class="control-label"><br/> Road Number of Adjoining TfL Road?</label>
<input class="form-control" pattern="^[ABC][1-9][0-9]*$|^(None)$" title="Must be None, or A, B or C followed by a whole number, no spaces!" value="None" id="TfLroad" required>
<span class="help-block">E.g. 'A232', 'B2441'</span>
</div>
</div>
<div class="form-group">
<div class="centre">
<button type="reset" class="btn btn-default">Reset Form</button>
<button type="submit" class="btn btn-primary">Create Street</button>
</div>
</div>
</fieldset>
</form>

Dynamically add and remove form fields to be validated by Parsley.js

Here is my fiddle: My Fiddle (updated)
In my form (ID: #form), inputs fields are shown or hidden based on the selected option of a select input.
Each Input and its labels a wrapped in a div, which is hidden or shown based on the selected option. The attribute data-children of the select contains the information (in JSON Format) which inputs are to be shown when a certain option is selected.
I use the data-parsley-excluded attribute to remove the fields not visible from the parsley validation (Parsley Documentation).
Before I execute the parsley method $('#form').destroy();, at the end $('#form').parsley();
My HTML:
<div class="container">
<div class="row">
<div class="col-sm-offset-2 col-sm-8">
<form id="form" method="post" accept-charset="UTF-8" class="form-horizontal" data-parsley-validate="">
<div class="form-group">
<label class="control-label" for="question_01" style="">Question 1</label>
<select class="form-control" name="question_01" id="question_01" required data-children="{"option_01":["input_01","input_02","input_03","input_04","input_05","input_06"],"option_02":["input_01","input_06","input_07","input_08","input_09","input_10"],"option_03":["input_02","input_04","input_05","input_07","input_09","input_10","input_11"]}">
<option value="" selected>Bitte auswählen</option>
<option value="option_01">Option 01</option>
<option value="option_02">Option 02</option>
<option value="option_03">Option 03</option>
</select>
</div>
<div id="div_input_01" class="form-group input-div hidden">
<label for="input_01" style="">Input 01</label>
<input type="text" class="form-control" name="input_01" id="input_01" required>
</div>
<div id="div_input_02" class="form-group input-div hidden">
<label for="input_02" style="">Input 02</label>
<input type="text" class="form-control" name="input_02" id="input_02" required>
</div>
<div id="div_input_03" class="form-group input-div hidden">
<label for="input_03" style="">Input 03</label>
<input type="text" class="form-control" name="input_03" id="input_03" required>
</div>
<div id="div_input_04" class="form-group input-div hidden">
<label for="input_04" style="">Input 04</label>
<input type="text" class="form-control" name="input_04" id="input_04" required>
</div>
<div id="div_input_05" class="form-group input-div hidden">
<label for="input_05" style="">Input 05</label>
<input type="text" class="form-control" name="input_05" id="input_05" required>
</div>
<div id="div_input_06" class="form-group input-div hidden">
<label for="input_06" style="">Input 06</label>
<input type="text" class="form-control" name="input_06" id="input_06" required>
</div>
<div id="div_input_07" class="form-group input-div hidden">
<label for="input_07" style="">Input 07</label>
<input type="text" class="form-control" name="input_07" id="input_07" required>
</div>
<div id="div_input_08" class="form-group input-div hidden">
<label for="input_08" style="">Input 08</label>
<input type="text" class="form-control" name="input_08" id="input_08" required>
</div>
<div id="div_input_09" class="form-group input-div hidden">
<label for="input_09" style="">Input 09</label>
<input type="text" class="form-control" name="input_09" id="input_09" required>
</div>
<div id="div_input_10" class="form-group input-div hidden">
<label for="input_10" style="">Input 10</label>
<input type="text" class="form-control" name="input_10" id="input_10" required>
</div>
<div id="div_input_11" class="form-group input-div hidden">
<label for="input_11" style="">Input 11</label>
<input type="text" class="form-control" name="input_11" id="input_11" required>
</div>
<button type="button" class="btn btn-info btn-block btn-submit-settings">Submit</button>
</form>
</div>
</div>
</div>
My Javascript:
$(document).ready(function() {
$('.btn-submit-settings').on('click', function(e) {
window.Parsley.on('field:error', function()
{
console.log('Validation failed for: ', this.$element);
});
$('#form').submit();
});
$('#form select').change(function() {
var $this = $(this);
if ($this.data('children')) {
$('#form').parsley().destroy();
// Hide all child elements
$.each($this.data('children'), function(value_id, input_id_array) {
$.each(input_id_array, function(key, input_id) {
if ($('#div_' + input_id).length ) {
$('#' + input_id).val(null);
if (!$('#div_' + input_id).hasClass('hidden')) {
$('#div_' + input_id).addClass('hidden');
}
}
});
});
// show the child elements of the selected option
if ($this.data('children')[$this.val()]) {
$.each($this.data('children')[$this.val()], function(key, input_id) {
if ($('#div_' + input_id).length )
{
if ($('#div_' + input_id).hasClass('hidden'))
{
$('#div_' + input_id).removeClass('hidden');
}
}
});
}
// For all inputs inside hidden div set attribute "data-parsley-excluded" = true
$('#form div.input-div.hidden').find(':input').each(function() {
var attr_data_parsley_excluded = $(this).attr('data-parsley-excluded');
if (typeof attr_data_parsley_excluded === typeof undefined || attr_data_parsley_excluded === false) {
$(this).attr('data-parsley-excluded', 'true');
}
});
// For all inputs inside not hidden div remove attribute "data-parsley-excluded"
$('#form div.input-div:not(.hidden)').find(':input').each(function() {
console.log(this.id);
$(this).removeAttr('data-parsley-excluded');
});
$('#form').find(':input').each(function() {
// Log shows that attribute is set right, seems to be ignored by parsley
console.log('ID: ' + this.id + ' TYPE: ' + $(this).prop('nodeName') + ': excluded=' + $(this).attr('data-parsley-excluded'));
});
$('#form').parsley();
$('#form').parsley().refresh();
}
});
});
I can't get it to work, even though the attributes seem to be set the right way.
The fields once hidden, stay out of the validation.
I guess you should add the attribute data-parsley-required="false" to exclude hidden fields from validation.
I mean, try to change
<input type="text" class="form-control" name="input_01" id="input_01" required>
to this
<input type="text" class="form-control" name="input_01" id="input_01" data-parsley-required="false">
and just change the attribute value if you want to validate it or not
This is more of a personal opinion than a factual answer, but I think you are attempting to solve the problem incorrectly. If I were doing this, I would create 2 parsley groups "shouldValidate" and "shouldNotValidate", and add your fields accordingly based on whether they are displayed or not. Then when you call validate, pass the group name "shouldValidate", and only that set of elements will be validated.
You probably need to call refresh on your parsley form after you modify excluded.

Categories

Resources