Edit: this is not a duplicate, because I am using HTML5 validating and the required attribute, and when the input is hidden with the modal, the required attribute is removed from it. I only have it as required when the fixed-term radio button is clicked and during the time the modal is open. When submitting the form, it is not required anymore (although this might not be the right way to solve this).
/*Change expiration date input to required once the fixed term choice is
taken, change back when open-ended is chosen*/
function updateRequired() {
document.getElementById('expdate').required = true;
}
function updateNonRequiredCancel() {
document.getElementById('expdate').removeAttribute('required');
radiobtn = document.getElementById("openend");
radiobtn.checked = true;
}
function updateNonRequired() {
document.getElementById('expdate').removeAttribute('required');
}
My problem:
Seen some posts on this topic, but no solutions have worked yet. I have a form with many inputs I'm trying to validate. Currently I am stuck on validating an input inside a bootstrap modal, since it keeps giving me the error: "An invalid form control with name='expdate' is not focusable." when I try to submit the form. All other inputs validate fine outside the radio buttons and modal.
The modal is toggled when the radio button "fixed-term" is chosen and contains the input to choose an expiration date. I have some onclick functions in there for:
1) when open-ended is clicked, 'expdate' is no longer required
2) when fixed-date is chosen, 'expdate' is required
3) when cancel is clicked inside the modal, 'expdate' is no longer required and the radio button selection goes to open-ended automatically
4) when save changes is clicked I validate whether the 'expdate' field is empty or not.
These onclick functions work fine, for example I can't save changes inside the modal without
entering an expiration date. Only problem arises when trying to submit the whole form.
<fieldset>
<div class="form-check form-check-inline">
<input type="radio" required class="form-check-input" id="openend"
name="term" onClick="updateNonRequired();">
<label class="form-check-label" for="openend">
Open-ended
</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input"
onclick="updateRequired();" id="fixed-term" name="term" data-toggle="modal"
data-target="#dateModal">
<label class="form-check-label" for="fixed-term">
Fixed-term
</label>
<div class="modal fade" id="dateModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="end-date" id="end-date">Pick the end-date</h4>
</div>
<div class="modal-body">
<label for="expdate">
Enter a date of expiration:
</label>
<input type="date" oninvalid="InvalidTerm(this);" oninput="InvalidTerm(this);" id="expdate" class="form-control" name="expdate" min="2000-01-02" max="2020-01-01">
<br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="updateNonRequiredCancel();">Close</button>
<button type="button" class="btn btn-primary" onclick="ValidateModal();">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</fieldset>
And some Javascript I'm using to try and validate 'expdate' while the modal is open which is not working, except for checking if the field is empty (which sets var isFine to true and let's the save button hide the modal):
var isFine = false;
function InvalidTerm(datebox) {
var date = new Date(datebox.value);
if (!isNaN(date.getTime())) {
datebox.setCustomValidity('Required field!');
}
else if (datebox.validity.rangeOverflow || datebox.validity.rangeUnderflow){
numberbox.setCustomValidity('Date must be between today and 2020-01-
01');
}
else {
datebox.setCustomValidity('');
}
isFine=true;
return true;
}
function ValidateModal(){
if (isFine === true) {
//document.getElementById('expdate').removeAttribute('required'); //questionable
$('#dateModal').modal('hide');
}
else{
alert('no no');
}
}
Any help is appreciated!
Related
I am beginner webdeveloper;
I make my project in Html/Css/jQuery.
I have 5 checkboxes on the website. 3 of them have the checkboxRequired class. After clicking on each of the 5 checkboxes, I have to check if all 3 checkboxes with the checkboxRequired checkout are selected.
I try this solution:
$('input[type="checkbox"]').click(function(){
if($('input:checkbox.checkboxRequired').prop('checked')){
console.log("Checkbox is checked.");
}
else {
console.log("Checkbox is unchecked.");
}
});
but it's always show: Checkbox is unchecked.
How can I repair it?
Please help me.
You need to use the .is() method and the :checked selector.
On clicking of a checkbox - you iterate over the checkboxes with the required class (using the .each() method) and can test each to see if its checked or not.
Note the little ternary equation in there to demonstrate an alternative to the traditional if/ else block - but it does the same thing (the "?" line is equivalent to true and the ":" is equivalent to false / else....
EDIT - I have updated the function to match your needs. Basically you need to check if all the checkboxes are checked and if so - submit the form and if not - raise the error modal.
The following amended code should do that for you.
$('input[type="checkbox"]').click(function(){
let total = 0;
let checked = 0;
$('.checkboxRequired').each(function(index){
total += 1;
if( $(this).is(':checked') ) {checked +=1 }
})
total === checked
? ($('.orderForm').submit(), console.log('Form Submitted'))
: $('#errorModal').modal('show');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<label> <input type="checkbox" class="checkbox checkboxRequired"/> Checkbox 1</label><br/>
<label> <input type="checkbox" class="checkbox "/> Checkbox 2</label><br/>
<label> <input type="checkbox" class="checkbox checkboxRequired"/> Checkbox 3</label><br/>
<label> <input type="checkbox" class="checkbox checkboxRequired"/> Checkbox 4</label><br/>
<label> <input type="checkbox" class="checkbox "/> Checkbox 5</label>
<!-- form
<form class="orderForm" method="post"></form>
-->
<!-- Modal -->
<div id="errorModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-sm">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Error Modal Header</h4>
</div>
<div class="modal-body">
<p>There is a disturbance in the force..... not all required checkboxes are checked</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
You can check the checked status in the element itself. Like this:
$('input[type="checkbox"]').click(function(){
if($('input:checkbox.checkboxRequired')[0].checked){
console.log("Checkbox is checked.");
}
else {
console.log("Checkbox is unchecked.");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="checkboxRequired">
I would try to check if all 3 checkboxes with the .checkboxRequired are selected in this way:
$('input[type="checkbox"]').click(function(){
const checkboxes = $('.checkboxRequired:checked');
if (checkboxes.length === 3) {
console.log("All 3 required checkboxes are checked.");
} else {
console.log("Some required checkbox is unchecked.");
}
});
Demo - https://codepen.io/vyspiansky/pen/NWNrLXN
Because $('input:checkbox.checkboxRequired') is select all elements by that selector. But prop method works with first element only:
Get the value of a property for the first element in the set of matched elements or set one or more properties for every matched element.
Link to docs:
https://api.jquery.com/prop/
Depending on your needs, you can handle it in other ways:
Simplest way: you can use attribute required - see docs
If you need more custom way, you can do something like that:
var $form2 = $('form#action2')
$form2.submit(function(e){
var isAllReqChecked = true
$form2.find('input:checkbox.checkboxRequired')
.each(function propChecker(){
isAllReqChecked &= $(this).prop('checked')
})
alert(isAllReqChecked ? 'All required was checked!' : 'Not all required was checked')
e.preventDefault()
});
Check demo
I have this plunker to show my issue.
Once user clicks on "Open Modal" a modal opens up showing input fields. If user enters on all the 3 input fields, it should close the modal. This works fine.
Now, if user forgets to mention any one of the field, it gives a alert message showing us to enter values to the fields... After this message, the modal should remain open. in my case, it closes after showing the alert.
I tried to remove the hide function from here
ng-click="$hide();adduser()"
So instead of the above, i tried this
ng-click="adduser()"
This solves the problem. i.e. it gives an alert when one of the fields are missing. But the other issue comes up which was working in the first scenario.
after user enters all the 3 values and clicks 'add' the modal doesnt close. since i have removed hide() functionality from ng-click.
Can someone tell me how to get both the cases possible and working.
You can simply add validations to your form and then you can disable the button to prevent user click on button without fill all fields, like this:
ng-disabled="form.$invalid"
So you can have something like this in your modal:
<div class="modal ng-scope center am-fade-and-scale" tabindex="-1" role="dialog" aria-hidden="true" style="z-index: 1050; display: block;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" ng-show="title">
<button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" ng-bind-html="title"></h4></div>
<div class="modal-body">
<form novalidate name="form">
<div class="form-group">
Select Sedol:
<input name="select1" type="text" ng-model="selectedState" bs-options="state for state in states" placeholder="Enter state" ng-change="get_change(selectedState)" bs-typeahead required>
</div>
<div class="form-group">
RestrName:
<select name="select2" id="restrName" ng-model="selectedOption" ng-change="set_value(selectedOption)" required>
<option value="sedol">sedol</option>
<option value="cusip">cusip</option>
</select>
</div>
<div class="form-group">
RestrType:
<select name="select3" id="restrType" ng-model="selectedOption1" ng-change="set_value1(selectedOption1)" required>
<option value="NoBuy">NoBuy</option>
<option value="NoSell">NoSell</option>
<option value="NoHold">NoHold</option>
<option value="NoTrade">NoTrade</option>
<option value="NoincExp">NoincExp</option>
<option value="NoDecExp">NoDecExp</option>
<option value="NoHoldLong">NoHoldLong</option>
<option value="NoHoldShort">NoHoldShort</option>
<option value="NoCoverBuy">NoCoverBuy</option>
<option value="NoSellShort">NoSellShort</option>
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-disabled="form.$invalid" ng-click="$hide();adduser()">Add</button>
</div>
</div>
</div>
</div>
DEMO
Well, if you want to hide your modal, something has to trigger it. I'm not sure how to do it properly from your controller right now, you could use jquery to hide it from inside addUser() method.
A cleaner solution imo is to use https://angular-ui.github.io/bootstrap/#/modal
then you can programmatically close it (and more) in a nicer way.
You should be using your controller to manage the lifecycle of the modal. I have created a new plunker that shows you how to do this:
http://plnkr.co/edit/k0yDjAcUbRhUtm1vQ2Ck?p=preview
$scope.detailsModal = $modal({
scope: $scope,
title: 'Enter details',
html: true,
show: false,
templateUrl: 'modal/docs/modal.demo.tpl.html'
});
$scope.showModal = function() {
$scope.detailsModal.show();
}
$scope.adduser = function() {
if ($scope.selectedState && $scope.selectedOption && $scope.selectedOption1) {
$scope.detailsModal.hide();
}
else {
window.alert('please select all required fields');
}
}
I am new to js/jquery and I am hoping you might be able to help me out with a simple edit to my script. The basis of my script is that I have a set of radio buttons, if the user selects Yes - they're done. However, if they click No, a new input box will popup and ask for more information.
Unfortunately, I have been unable to find a way to make the popup input box be required for submission because it has issues when the user clicks Yes, still being required, but hidden.
Here is my code so far:
function ShowHide(){
if(document.getElementById('spellingN').checked){
document.getElementById("spellingT").style.display = "block";
} else {
document.getElementById("spellingT").style.display = "none";
}
}
<div class="col-md-4">
<div class="radio"><b><input id="spellingY" name="spelling" onchange="ShowHide()" required="" type="radio" value="yes" /> Yes</b></div>
<div class="radio"><b><label for="radios-1"><input id="spellingN" name="spelling" onchange="ShowHide()" required="" type="radio" value="no" /> No </label></b></div>
</div>
</div>
<div id="spellingT" style="display: none;">
<div class="form-group"><b><label class="col-md-4 control-label" for="Spelling-Correction"><b>Question 2a</b> Type the grammatically correct version of the term.</label> </b>
<div class="col-md-4"><b><input class="form-control input-md" id="Grammar-Correction" name="Grammar-Correction" placeholder="" required="" style="width: 100%;" type="text" /></b></div>
</div>
I hope you'll be able to make some sense of it and help me out. Thanks in advance!
You could add this check in your function:
if(document.getElementById('spellingT').style.display == "block"){
//your submission
}
// Element is hidden
if(document.getElementById('spellingT').offsetParent === null)
{
}
// Element is visible
else
{
}
For more details visit https://stackoverflow.com/a/21696585/2240375
At a user registration web form I validate via ajax whether a username already exists in DB. When a username already exists, the corresponding input-text will go .has-error class.
Edit
I changed the ng-class attribute to {'has-error':signup.userUnavaliable()} but even though that the input is not seemly getting such class, in other words the mail input text is not getting red.
I place the directive at the wrapper as this is how the Bootstrap docs tell it.
This is how my form looks like now:
<form class="form-inline" role="form">
<div class="form-group" ng-class="{'has-error':signup.userUnavaliable()}">
<input type="email" class="form-control input-lg" ng-model="signup.mail" placeholder="e-mail" ng-change="signup.userExists(signup.mail)">
</div>
<div class="form-group">
<input type="password" class="form-control input-lg" placeholder="Contraseña" ng-nodel="signup.password">
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="signup.role" value="admin"> Administrador
</label>
</div>
<button type="submit" class="btn btn-primary" ng-disabled="signup.unavaliable">Registrar</button>
</form>
And this is my Controller:
app.controller('SignUpController',function ($scope, $http) {
$scope.userUnavaliable = function() {
return $scope.unavaliable
}
$scope.print = function(msg) {
console.log(msg)
}
this.userExists = function(mail) {
if (mail) {
var who = $http.get("/existingUsers/"+mail)
who.success(function(data,status, headers, config) {
if (data.mail) {
$scope.unavaliable = true
console.log(data.mail + " ya existe en la DB")
}
else{
$scope.unavaliable = false
}
});
who.error(function(data, status, headers, config) {
alert("AJAX failed!");
})
}
}
})
Also, I'm trying to disable the button and it's not gettin such effect, so I think my controller has any issue.
As given in bootstrap validation states, if you want your label color to be changed according to the validation state of the input, you will have to apply ng-class on that.
Here is the sample code that I had written a little while. Please note that to take advantage of Angular JS validation states on form elements, you need to provide name to all input types.
This code would turn the input box plus label color red or green depending upon the validation state.
<div class="form-group"
ng-class="( newProfileForm.email.$dirty ? (newProfileForm.email.$valid ? 'has-success has-feedback' : 'has-error has-feedback' ) : ' ')"
>
<label class="col-sm-4 control-label">Email</label>
<div class="col-sm-6">
<input type="email" name="email" class="form-control" ng-model="user.mail" ng-required='true'>
<!-- Invalid Span -->
<span ng-if='newProfileForm.email.$invalid && newProfileForm.email.$dirty' class="glyphicon glyphicon-remove form-control-feedback"></span>
<!-- Valid Span -->
<span ng-if='newProfileForm.email.$valid' class="glyphicon glyphicon-ok form-control-feedback"></span>
<p ng-show="newProfileForm.email.$invalid && newProfileForm.email.$dirty" class="bg-danger pad">Please enter valid email.</p>
</div>
</div>
[EDIT] Explanation for name attribute.
Angular makes use of name attribute to determine the state of the input control. So, if you have a input control with name username. Even your form should have a name for angular validation states.
AngularJS would use the fallowing variables to check its validation state.
formname.username.$valid = if username is alright according to validation rules.
formname.username.$invalid = if username is invalid
formname.username.$dirty = if user has edited the input box
formname.username.$pristine = if user has not edited the input box.
Angular makes use of name attribute for validaiton.
And if you want your button to be disabled depending upon the availability of the user.
Use something like
<button class="btn btn-default" ng-disabled="unavaliable">Submit</button>
try
<div class="form-group" ng-class="{'has-error':signup.userUnavaliable()}">
I am new to Meteor and Javascript. I have slowly figured out how to set up a modal form that will show up when I click a button, and can capture my form data and have the form close when I click submit. Where I am stuck is that whenever I click the button to add more data, the previous values are still in the modal form. I have tried most of the other answer and examples I have found, but I can't seem to figure out what I need to do to make it clear the values. Any suggestions would be appreciated. Here is what I have currently:
Modal Template
<template name="addButton">
<div class="modal fade" id="addButton">
<form>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Add Button</h4>
</div>
<div class="modal-body">
<form role="form">
<div class="form-group">
<label for="buttonOrder">Button Order</label>
<input type="text" class="form-control" name="buttonOrder">
</div>
<div class="form-group">
<label for="buttonName">Button Name</label>
<input type="text" class="form-control" name="buttonName">
</div>
<div class="form-group">
<label for="buttonDescription">Button Description</label>
<input type="text" class="form-control" name="buttonDescription">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
<input type="submit" value="Submit" class="btn btn-primary"/>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</form>
</div>
</template>
Modal JS Helper
Template.addButton.events({
'submit form': function(e) {
e.preventDefault();
var button = {
buttonOrder: $(e.target).find('[name=buttonOrder]').val(),
buttonName: $(e.target).find('[name=buttonName]').val(),
buttonDescription: $(e.target).find('[name=buttonDescription]').val()
}
button._id = Buttons.insert(button);
$('#addButton').modal('hide');
$(this).removeData('#addButton.modal');
}
})
#Jeremy-s
I couldn't get your suggestion to work, although the Session key suggestion got me a solution that did for work with Bootstrap 2 but not with Bootstrap 3. I did finally get things working with Bootstrap 3, although I doubt it is the most elegant solution. I added ids to the elements and just set the value for each element to null like so:
$('#addButton').modal('hide')
$('#buttonOrder').val(null);
$('#buttonName').val(null);
$('#buttonDescription').val(null);
Now I just need to figure out why I can't get it to work with the Session key and Bootstrap 3.
One possible way to go is to use Meteor's findAll to find the inputs in the template, then iterate through them and set the value of each input to null. The findAll is a jquery selector but is limited here to the context of the template.
Template.addButton.events({
'submit form': function(e) {
e.preventDefault();
var button = {
buttonOrder: $(e.target).find('[name=buttonOrder]').val(),
buttonName: $(e.target).find('[name=buttonName]').val(),
buttonDescription: $(e.target).find('[name=buttonDescription]').val()
}
button._id = Buttons.insert(button);
_.each(
this.findAll("input"),
function(element){element.value = null}
);
$('#addButton').modal('hide');
}
})
Note also that instead of using jquery to show and hide the modal, Meteor's preferred approach would be to add and remove it completely from the DOM based on a reactive source like a Session key. I would look at Meteor's reactivity summary for additional guidance on how to do this.