I recently came across a situation where I was working on a huge form with atleast 60 fields and I wanted that form to only submit if all fields were filled and if not, I wanted to show a custom message (Sweetalert) for every field not filled.
For example, If first name was left empty, show the message "Please enter your first name", If country of residence was not selected, show them the message that "Please select your country of residence" so on and so forth.
While I was writing tons of if and else statements to match every field using document.getElementById(), this thought of not doing things right came into my mind. I tried searching the web for this but was unable to find a suitable way of doing such things. Can anyone suggest me a better way rather then writing if else statements of 100 lines ?
By adding a specific class to your form controls you'd be able to retrieve them and iterate through them in order to check which ones are not filled.
Let's say this is your form:
<form id="myForm" name="myForm" novalidate>
<div>
<label for="control_1">Label_1:</label>
<input type="text" id="control_1" name="control_1" class="control" />
</div>
<div>
<label for="control_2">Label_2:</label>
<input type="text" id="control_2" name="control_2" class="control" />
</div>
<div>
<label for="control_3">Label_3:</label>
<input type="text" id="control_3" name="control_3" class="control" />
</div>
<div>
<label for="control_4">Label_4:</label>
<select id="control_4" name="control_4" class="control">
<option value="option_1">Option 1</option>
<option value="option_2">Option 2</option>
<option value="option_3">Option 3</option>
</select>
</div>
<div>
<input type="submit" value="Submit!" />
</div>
</form>
Then you can use the .control class to retrieve all controls and check them:
function onSubmit(e) {
e.preventDefault();
const controls = document
.getElementById("myForm")
.querySelectorAll(".control");
controls.forEach(control => {
if (!isControlFilled(control)) {
console.log(control.id);
// Do whatever you want with control's id
}
});
}
// This is just for illustrative purposes
// Should be adapted to cover all control types
function isControlFilled(control) {
return control.value ? true : false;
}
Related
I have a situation where I want to let a user decide titles of books that I have on my db, using an input with a datalist (generated by php), after the user picked a title, he would click a submit button and the form would send the title in another file.
Everything worked fine but I didn't realized that I needed to send the ID of the book that the user selected, because there can be more than one book with the same title.
What I would like to have is the option of the datalist, that no longer has the title of the book inside its "value" attribute, but I want that title inside its innerHTML, so that the title gets displayed, while having the ID inside the "value" attribute. My problem is that if I do that, when the user clicks on the datalist option, the ID gets inside the text input, so the user may not know what book he choose.
summing up: I would like to have the datalist that displays the title, when an option is chosen, that title gets displayed in the text input, when I submit, the Id of the book gets sent in "FindBook.php" inside $_POST.
isIn() checks if the title is inside the array of titles, I would need to change that so that it can check if the ID is inside the array of IDs.
<form onsubmit="alert(document.getElementById('number').value);" action="FindBook.php" target="_blank" method="POST">
<input id="number" list="BooksById">
<input type="submit" value="Find">
</form>
<datalist id="BooksById">
<option value="1">Title1</option>
<option value="2">Title2</option>
<option value="3">Title3</option>
<option value="4">Title4</option>
</datalist>
<br>
<form onsubmit="alert(document.getElementById('string').value);" action="FindBook.php" target="_blank" method="POST">
<input id="string" list="booksByTitle">
<input type="submit" value="Find">
</form>
<datalist id="booksByTitle">
<option value="Title1"></option>
<option value="Title2"></option>
<option value="Title3"></option>
<option value="Title4"></option>
</datalist>
Since I don't understand jQuery I would really prefer a solution that doesn't imply that.
I think that in your case you must use a <select> tag instead of a <datalist> because you do not want the end user to enter new names (or yes?). However you can work with the data attributes like in the code below:
HTML:
<input list="titles" id="title-input" oninput="getBookId()">
<datalist id="titles">
<option data-value="5" value="A book name">
</datalist>
JavaScript:
function getBookId() {
var selectedTitle = document.getElementById("title-input").value;
var value2send = document.querySelector(`#titles option[value='${selectedTitle}']`).dataset.value; // Here now you have the book title id.
console.log("getBookId ~ value2send", value2send)
}
I hope it works for you.
Assuming you can provide distinct title values for each datalist option...
Add a dataset attribute, such as data-id, to your datalist option elements, containing the corresponding id, and add a hidden type input to your form. Then use the onsubmit event handler function to get the selected datalist option's dataset id value and assign it to the value of the hidden input:
function findBook(form) {
form.bookid.value = document.querySelector(`datalist option[value="${form.booktitle.value}"]`).dataset.id;
console.log(form.bookid.value);
return false;
}
<form onsubmit="return findBook(this)">
<input type="hidden" name="bookid">
<input name="booktitle" list="BooksById">
<input type="submit" value="Find">
</form>
<datalist id="BooksById">
<option data-id="1" value="Title1">
<option data-id="2" value="Title2">
<option data-id="3" value="Title3">
<option data-id="4" value="Title4">
</datalist>
Upon form submission, your PHP file will have the variables $_POST['bookid'] and $_POST['booktitle'] available.
Thanks for your suggestions. I prefer to use a datalist, instead of a select tag, because it looks more like a dropdown menu that works like a button. Using datalist allows me to find a book by a random word inside the title of it, while the select only finds the first word of an entry. I can also distinguish different books with the same name by another attribute that states if it's available or if it's taken.
I asked for no JQuery, i appreciate your help but I really don't understand them, even if it's cleaner to use them I would like a solution that doesn't use them.
I ended up using the solution CBroe suggested:
document.getElementById("bookTitle").addEventListener('input', function (evt) {
let data = this.value.split('');
document.getElementById("bookId").value = "";
if(isIn(data,'books')){
document.getElementById("bookId").value = data[0];
document.getElementById("bookTitle").value = data[1];
}
});
function checkForm(id, value, list){
if(isIn([document.getElementById(id).value,document.getElementById(value).value],list)){
alert("Book found");
return true;
}else{
alert("not found")
return false;
}
}
function isIn(value, list) {
switch (list) {
case 'books':
//this was generated by php in my code
if (value[0] == 1 && value[1] == "Title1"){
return true;
}
if (value[0] == 2 && value[1] == "Title2"){
return true;
}
return false;
break;
//I've cut out other cases
}
}
<form onsubmit="checkForm('bookId','bookTitle','books')" action="FindBook.php" target="_blank" method="POST">
<input id="bookTitle" list="booksByTitle" autocomplete="off">
<label>id:</label>
<input id="bookId" <!--type="hidden"-->
<input type="submit" value="Find">
</form>
<datalist id="booksByTitle">
<!-- value was generated by php in my code-->
<option value="1Title1">Title1</option>
<option value="2Title2">Title2</option>
</datalist>
I've tried, I've researched, and I still can't figure out how to validate this form using jQuery. I've even tried to check out the jQuery API and I had no luck with it. This shouldn't be as hard as it seems. There are a few id's that i'm not using yet because I want to get what I have so far working before I continue. The best I could find for validating emails is just straight up JavaScript. Here's my code.
$(document).ready(function(){
$("#sendForm").click(function(){
var validForm=true; //set valid flag to true, assume form is valid
//validate customer name field. Field is required
if($("#custName").val()) {
$("#custNameError").html(""); //field value is good, remove any error messages
} else {
$("#custNameError").html("Please enter your name.");
validForm = false;
}
//validate customer phone number. Field is required, must be numeric, must be 10 characters
var inPhone = $("#custPhone").val(); //get the input value of the Phone field
$("#custPhoneError").html(""); //set error message back to empty, assume field is valid
if(!inPhone) {
$("#custPhoneError").html("Please enter your phone number.");
validForm = false;
} else {
//if( !$.isNumeric(inPhone) || Math.round(inPhone) != inPhone ) //if the value is NOT numerice OR not an integer. Rounding technique
if( !$.isNumeric(inPhone) || (inPhone % 1 != 0) ) //if the value is NOT numerice OR not an integer. Modulus technique
{
$("#custPhoneError").html("Phone number must be a number.");
validForm = false;
} else {
if(inPhone.length != 10) {
$("#custPhoneError").html("Phone number must have 10 numbers");
validForm = false;
}
}
}
//ALL VALIDATIONS ARE COMPLETE. If all of the fields are valid we can submit the form. Otherwise display the errors
if(validForm) {
//all values are valid, form is good, submit the form
alert("Valid form will be submitted");
//$("#applicationForm").submit(); //SUBMIT the form to the server
} else {
//form has at least one invalid field
//display form and associated error messages
alert("Invalid form. Display form and error messages");
}
}); //end sendform.click
}); //end .ready
function isEmail(email) {
var regex = /^([a-zA-Z0-9_.+-])+\#(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
}
label {
width:150px;
display:inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2></h2>
<h3>Form Validation Project - Complaint Form</h3>
<form id="form1" name="form1" method="post" action="">
<p>Please enter the following information in order to process your concerns.</p>
<p>
<label for="custName">Name:</label>
<input type="text" name="custName" id="custName" />
<span id="custNameError" class="errorMsg"></span>
</p>
<p>
<label for="custPhone">Phone Number: </label>
<input type="text" name="custPhone" id="custPhone" />
<span id="custPhoneError" class="errorMsg"></span>
</p>
<p>
<label for = "email">Email:</label>
<input type = "text" name = "emailAdd" id = "emailAdd" />
<span id = "emailError" class = "emailError"></span>
</p>
<p>Please Select Product Group:</p>
<p>
<label>
<input type="radio" name="custProducts" value="books" id="custProducts_0" />
Books
</label>
<br />
<label>
<input type="radio" name="custProducts" value="movies" id="custProducts_1" />
Movies
</label>
<br />
<label>
<input type="radio" name="custProducts" value="electronics" id="custProducts_2" />
Consumer Electronics
</label>
<br />
<label>
<input type="radio" name="custProducts" value="computer" id="custProducts_3" />
Computer
</label>
<br />
</p>
<p>Description of problem: (Limit 200 characters)</p>
<p>
<label for="custComplaint"></label>
<textarea name="custComplaint" id="custComplaint" cols="45" rows="5"></textarea>
</p>
<p>
<input type="submit" name="button" id="button" value="File Complaint" />
<input type="reset" name="button2" id="button2" value="Reset" />
</p>
</form>
<p> </p>
$("#button").click(function(e){
e.preventDefault(); // you need to stop the initial event to have a chance to validate
var validForm=true;
// etc...
You can use jquery.validate.js to validate your forms , it will overcome all your manual efforts to create the validation rules also it is providing the various predefined rules like required,email, minlength and maxlength, etc. So, it will be easier for you to achieve what you need very easily.
https://jqueryvalidation.org/
I have a simple jquery form validation and submission package - see if that's of any help - it's easy to install and you can customise quite a few things: https://github.com/sebastiansulinski/ssd-form
Just to get you started, your submit control in the html has id "button", so you should use $('#button').click, not $('#sendForm').click.
Also, if you want to stay on the page (like to do validations, show errors, etc), you have to prevent the form from submitting automatically when the button is clicked. There are lots of ways to do this, but the easiest way is to just change your button type from submit to button. Ie, replace this:
<input type="submit" name="button" id="button" value="File Complaint" />
with this:
<input type="button" name="button" id="button" value="File Complaint" />
------
That should get you started, at least your code will run, you can use console.log to debug, etc. Good luck.
UPDATE
I should add that if you take my advice, the form will never submit on it's own - that is good if some validation fails and you want to stay on the page and give some error feedback to the user.
When you do want the form to submit, you have to make it happen yourself. Again, there are lots of ways to do this, but the simplest one is probably:
$('#form1').submit();
I need to validate filled inputs and on submit if all inputs are valid show load animation till next page will shown. I can check for validation one by one, but do not know how to collect them all in one. Maybe there are more simple way to check inputs validation? Also I did all validations inside inputs in code below.
Here is my inputs type which i need to validate and on success show load animation until page refresh to another page:
<form action="" method="POST" enctype="multipart/form-data" name="formz" >
<div>
<label>Name: </label>
<input type="text" onkeydown="return keyDown.call(this,event)" onchange="value = value.replace(/^\s+/,'')" pattern=".{3,20}" name="name" required>
</div>
<div>
<label>Surname: </label>
<input type="text" onkeydown="return keyDown.call(this,event)" onchange="value = value.replace(/^\s+/,'')" pattern=".{3,20}" name="surname" required>
</div>
<div>
<label>Unic Number: </label>
<input type="text" onkeydown="return keyDown.call(this,event)" onchange="value = value.replace(/^\s+/,'')" pattern=".{7,7}" maxlength='7' name="unicnumb" required />
</div>
<div>
<label>Select:</label>
<select name="select" id="select" required>
<OPTION VALUE="0" selected disabled >Select</OPTION>
<OPTION VALUE="1">Select1</OPTION>
<OPTION VALUE="2">Select2</OPTION>
</select>
</div>
<div>
<label>phone: </label>
<input type="text" name="phone" id="phone" placeholder="+XXX(XX) XXX-XX-XX" required>
</div>
<div>
<label for="epoct">E-mail</label>
<input type="email" pattern="[a-zA-Z0-9.-_]{1,}#[a-zA-Z.-]{2,}[.]{1}[a-zA-Z]{2,}" class="form-control input-sm" name="epoct" id="epoct" required>
</div>
<button type="submit" name="button" id="button">Done</button>
</form>
This is the outline for how I've handled successive form validation with jQuery:
$(document).ready(function() {
$( "#button" ).submit(function( event ) {
if ( /* validation fails for first form element */ ) {
// stop form submission
event.preventDefault();
// display an error message
$( "#firstFormFieldId" ).append("<span>Incorrect entry</span>");
// break out of function to ensure validation continues if and only if this condition is met
return false;
}
if ( /* validation fails for second form element */ ) {
// stop form submission
event.preventDefault();
// display an error message
$( "#secondFormFieldId" ).append("<span>Incorrect entry</span>");
// break out of function to ensure validation continues if and only if this condition is met
return false;
}
if ( /* validation fails for third form element */ ) {
// stop form submission
event.preventDefault();
// display an error message
$( "#thirdFormFieldId" ).append("<span>Incorrect entry</span>");
// break out of function to ensure validation continues if and only if this condition is met
return false;
}
// ... repeat for as many form fields that need validation
// if all validation criteria are met, you can deploy loading animation here :)
/* loading animation goes here */
});
});
You can probably already imagine some variations to this template. For instance, rather than appending the <span>s, you could add empty <span>s intended to contain the error messages to your HTML. If an error message needs to be displayed, you then use jQuery to add the text of the error message to the corresponding <span>. The actual implementation will depend on you, but this style has worked well for me.
In this question I would like to display some HTML text depending on a which combination of options is selected in a form. In this example for instance, I want to display some text if spelling is selected as a subcategory and 'greater-depth' (equivalent to an 'A' grade) is selected as the performance grade. I've developed this in Rails form_for but have shown the form as rendered in the browser.
<form class="new_english_grade" id="new_english_grade" action="/english_grades" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="VTtOS/86shuyQPW6/HfaduffmQiVXLiJb06IQp7+56LM8cD8KRnD3qLGbQBit4OuAIc92MYbFpPObR6ePYmY1g==" />
<div class="field">
<label for="english_grade_subcategory">Subcategory</label>
<select name="english_grade[subcategory]" id="english_grade_subcategory"><option value="Spelling">Spelling</option>
<option value="Reading">Reading</option>
<option value="Writing">Writing</option></select>
</div>
<div class="field">
<label for="english_grade_performance_grade">Performance grade</label>
<select name="english_grade[performance_grade]" id="english_grade_performance_grade"><option value="Not-started">Not-started</option>
<option value="Working-towards">Working-towards</option>
<option value="Working-at">Working-at</option>
<option value="Greater-depth">Greater-depth</option></select>
</div>
</form>
The text I'd like to display for instance is like:
<div id = "spelling_greater_depth">
This text is displayed only if 'spelling' and 'greater-depth' are selected in options
</div>
I have initially set my CSS to be:
#spelling_greater_depth
{
display: none;
}
My JavaScript is not really working yet so I have not included it but I was trying to implement it using this:
I think this might be enough to get you started https://jsfiddle.net/sxh0n7d1/37/
However it is very difficult to answer the question, can you clarify your question or give feedback to this answer if it is close?
$('select[name="english_grade"]').change(function () {
$('#spelling_working_at').css("display","none");
console.log($(this).val());
var fieldToShow = $(this).val();
$("#" + fieldToShow).css("display","block");
});
Within my form, called frmClock, I have a div that is ultimately used as the basis for a jQuery UI modal dialog:
<div id="dialog-form-clockout" title="Associate Mileage Reimbursement" data-ok="<%=clkContinueClockOut%>" data-cancel="<%=clkCancel%>" data-errornum="Invalid number format. Valid number format is 999.9" data-errorzero="Please enter a value greater than zero. Otherwise, select No." data-errormaxchars="Please enter a numeric value less than 5 characters long." data-errornoradio="Please select Yes or No.">
<fieldset>
<div id="personalVehicle">
<label for="<%=TAConstants.FN_ASM_RESPONSE%>">Did you use your personal vehicle for business travel during this shift?</label>
<br>
<input type="radio" name="<%=TAConstants.FN_ASM_RESPONSE%>" id="personalvehicle" class="text ui-widget-content ui-corner-all" value="Y"/>Yes
<input type="radio" name="<%=TAConstants.FN_ASM_RESPONSE%>" id="personalvehicle" class="text ui-widget-content ui-corner-all" value="N"/>No
<br>
</div>
<div id="questionsY" class="hidden">
<div class="modalDialogQuestions">
<label for="<%=TAConstants.FN_BANK_ROUND_TRIPS%>" class="modalDialogQuestionsLbl">Enter number of round-trips to the bank.</label>
<select name="<%=TAConstants.FN_BANK_ROUND_TRIPS%>" class="modalDialogAnswers" id="roundtrips">
<option selected value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div class="modalDialogQuestions">
<label for="<%=TAConstants.FN_OTHER_MILES%>" class="modalDialogQuestionsLbl">Enter number of miles for business related travel other than the bank.</label>
<input class="positive modalDialogAnswers" type="number" name="<%=TAConstants.FN_OTHER_MILES%>" id="mileage" value="0.0" maxlength=5/>
</div>
</div>
</fieldset>
<div class="ui-state-error hidden" style="height:auto;"><span class="ui-icon ui-icon-alert" style="display:inline; margin-right:.25em; float:left;"/></span><p class="validateTips" style="display:inline; border:0px;"></p></div>
</div>
</form>
So ultimately once we fill out this jQuery modal dialog form, I use the same javascript we used to use prior to this enhancement for form submission (plus alerts to tell me this data is in the document element).
alert(document.getElementById('personalvehicle').value);
alert(document.getElementById('roundtrips').value);
alert(document.getElementById('mileage').value);
submitForm();
...
/**
* This function disallows the form to be submitted twice.
*/
function submitForm () {
if (!hasBeenSubmitted) {
hasBeenSubmitted = true;
document.frmClock.submit();
}
The alerts display the same text the user inputs, but doesn't seem to be sent with the rest of the form data that we've received in the past without the jQuery modal dialog form. I've been determining this from our processor .java file, with the following code that doesn't seem to set the vars, as it doesn't pass null checks:
if (req.getParameter(FN_ASM_RESPONSE)!=null){
Character asmResponse = (req.getParameter(FN_ASM_RESPONSE)).charAt(0);
}
if (req.getParameter(FN_BANK_ROUND_TRIPS)!=null){
Integer bankRoundTrips = Integer.parseInt(req.getParameter(FN_BANK_ROUND_TRIPS));
}
if (req.getParameter(FN_OTHER_MILES)!=null){
Float otherMiles = Float.parseFloat(req.getParameter(FN_OTHER_MILES));
}
The most I've heard is to make sure my inputs have the name attribute. These name attributes seem to be set though, view source shows them as personalvehicle, roundtrips, and mileage, which were set from the following constants .java file:
public static final String FN_ASM_RESPONSE = "personalvehicle";
public static final String FN_BANK_ROUND_TRIPS = "roundtrips";
public static final String FN_OTHER_MILES = "mileage";
Does anyone have any ideas as to what I ought to look into or try? Breakpoints on the getParameter() methods to check if null show it hits these points, but doesn't hit what is contained because the parameters are null.
The problem is that jQuery UI moves the dialog containing your input field out of the form.
You can change your dialog loading function to add a function that runs when the dialog is created and move it back to your form.
$('#myDialog').dialog({ create: function () { $(this).parent().appendTo('form') } });