I am working on a web forms project. I have many phone number fields. I have added both a RequiredFieldValidator and a RegularExpressionValidator to each phone field as well as a PhoneNumberFormatter() javascript function to the oninput event for each asp:Textbox.
The main way to express my problem is that the RegualrExpressionValidator will still allow the asp:Button to submit the page even when there is an incomplete phone number in those boxes.
I have added a DoPost() function to the buttons OnClientClick event that cycles through all the validators and turns all the inputs red that have not met their validator's parameters. But still the RegularExpressionValidator is still allowing incomplete phone numbers to pass through when the button is pressed.
The only way that I have found to overcome this is by adding a function to agressively validate the phone length as needed, and use the setCustomValidity javascript function, which works to keep the page from submitting with incomplete numbers, but for some reason that undoes all the other boxes that I turned red for not passing their validation.
For some reason, if I click submit twice, THEN the boxes that are supposed to turn red will finally turn red. This was not a problem until I added the setCustomValidity to the phone inputs that were incomplete, otherwise the fields would turn red when expected on the first click, BUT incomplete partial phone numbers were passing through.
Basically, I want to know what I can do with basic validators and javascript to ensure the phone number is the length I need and wont interfere with the other function of turning the other required fields red when they need to.
Markup for phone input
<div class="form-group">
<label>School Contact Administrator Phone:</label>
<asp:TextBox runat="server" ID="MainContactPhone" CssClass="form-control" TextMode="Phone"
oninput="PhoneNumberFormatter(ContentPlaceHolder1_MainContactPhone); ReValidateText(ContentPlaceHolder1_MainContactPhone)"/>
<asp:RegularExpressionValidator ID="MainContactRegVal" runat="server" CssClass="text-danger"
ErrorMessage="Not a valid phone number" ControlToValidate="MainContactPhone"
ValidationExpression="^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$" />
<asp:RequiredFieldValidator runat="server" ValidationGroup="ValGro" ID="MainContactVal"
ControlToValidate="MainContactPhone" InitialValue=""
Text="Required Field" CssClass="text-danger" />
</div>
Markup for Submit Button
<asp:Button runat="server" ID="IntakeTypeSubmit" Text="Next"
OnClick="IntakeTypeSubmit_Click"
CssClass="btn btn-info" ValidationGroup="ValGro" OnClientClick="DoPostIntro()" />
JS for DoPostIntro()
function DoPostIntro() {
try {
//DoPost(); //I have tried changing the order of when I do the base DoPost()
var phone = document.getElementById('ContentPlaceHolder1_MainContactPhone');
var reqVal = document.getElementById('ContentPlaceHolder1_MainContactVal');
var regVal = document.getElementById('ContentPlaceHolder1_MainContactRegVal');
ValidatePhone(phone, reqVal, regVal);
DoPost();
} catch (Error) {
alert(Error);
}
}
JS for base DoPost()
function DoPost() {
try {
for (var i = 0; i < Page_Validators.length; i++) {
var val = Page_Validators[i];
var ctrl = document.getElementById(val.controltovalidate);
if (ctrl != null && ctrl.style != null) {
if (!val.isvalid) {
ctrl.style.backgroundColor = '#FFAAAA';
}
else {
ctrl.style.backgroundColor = '';
}
}
}
document.getElementById('Warning').style.visibility = 'visible';
} catch (Error) {
alert(Error);
}
}
JS for ValidatePhone
function ValidatePhone(input, reqVal, regVal) {
if (input.value == '' && (reqVal.enabled == true || reqVal.enabled === undefined)) {
input.style.backgroundColor = '#FFAAAA';
ValidatorEnable(reqVal, true);
reqVal.style.visibility = 'visible';
}
if (input.value.length < 14 && (regVal.enabled == true || regVal.enabled === undefined)) {
input.style.backgroundColor = '#FFAAAA';
ValidatorEnable(regVal, true);
input.setCustomValidity("Invalid Phone Number");
regVal.style.visibility = 'visible';
} else {
input.setCustomValidity("");
regVal.style.visibility = 'hidden';
}
}
C# that registers the DoPostIntro()
Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "val", "DoPostIntro();");
Related
I have a python flask webapp and JavaScript front-end. In my front end I am doing all form validations, before submitting it. One such validation is to check the value of a name input field against a list of names(array) I am passing to the template already on GET request. The code below works fine unless it's the last element in the array !!! Then it alerts properly, yet still submits the form. In other words - when rendering the page I am passing the list with all names existing in the database. Then if the same name is provided in the input field, I expect alert and stop execution. In my case, it works fine for all but the last element in the passed array. Then it alerts, yet still submits the form.
My HTML:
function submitServiceForm() {
if ($('#ingested_product_name').val() == '') {
alert("you must specify a product name");
return false;
} else if ($('#ingested_product_features').val() == '') {
alert("you must specify at least one feature");
return false;
} else if ($('#selected_quality_1').val() == null && !$('#no_qualities').is(':checked')) {
alert("you must select at least one Quality");
return false;
} else if ($('#selected_aspect_1').val() == null && !$('#no_qualities').is(':checked')) {
alert("you must select at least one Aspect");
return false;
} else if ($('#ingesting_service').val() == '') {
alert("you must select an ingesting service");
return false;
} else {
let no_qa_check = document.getElementById('no_qualities');
if (no_qa_check.checked) {
let allIngestInPlatform = {
{
allIngestInPlatform | safe
}
};
for (let i = 0; i < allIngestInPlatform.length; i++) {
if ($('#ingested_product_name').val() == allIngestInPlatform[i]['ingested']) {
alert("an Ingested Product with the same name already exists on that platform");
return false;
} else {
document.getElementById('ingested_product_form').submit();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-row">
<table class="table">
<tr>
<td>
<button type="button" onclick="return submitServiceForm();" class="btn btn-primary">Add Ingested Product</button>
</td>
</tr>
</table>
</div>
Returning false in a submit button click doesn't do anything. A submit button click has a default action of submitting the form. You would need to specifically return false in the onsubmit event instead:
<form .. onsubmit="return submitServiceForm();">
Nowadays people also often prefer to avoid inline Javascript, so with jQuery, that might look more like this:
// Use a more specific selector than this
$('form').on('submit', function(){
return submitServiceForm();
});
Alternatively if you'd like to keep it in onclick, you can use event.preventDefault() instead.
// use a more specific selector than .btn-primary
$('.btn-primary').click(function(e){
if(!submitServiceForm()){
e.preventDefault();
}
});
Change this line on your code
From
for (let i = 0; i < allIngestInPlatform.length; i++)
To
for (let i = 0; i <= allIngestInPlatform.length; i++)
I have two fields where the user can only write in one or the other, we validate the client side using the javascript below. The problem that I have is that the textboxes by default have a clear 'x' that when used doesn't trigger the javascript leaving one of the fields disabled.
How can I call the javascript function when the user clicks the clear 'x' of the textbox in order to get both fields enabled?
<asp:TextBox ID="txtFIELD1Val" runat="server" onKeyup="javascript:clearFields();" TabIndex="1" CssClass="cssTextbox"></asp:TextBox>
<asp:TextBox ID="txtFIELD2Val" runat="server" onKeyup="javascript:clearFields();" TabIndex="2" CssClass="cssTextbox"></asp:TextBox>
function clearFields() {
var txtFIELD1 = document.getElementById('<%= txtFIELD1Val.ClientID %>');
var txtFIELD2 = document.getElementById('<%= txtFIELD2Val.ClientID %>');
//Enable/Disable FIELD1 and FIELD2 fields based on text.
if (txtFIELD1.value == "" && txtFIELD2.value == "") {
txtFIELD1.disabled = false;
txtFIELD2.disabled = false;
}
else if (txtFIELD1.value == "" || txtFIELD2.value != "") {
txtFIELD1.disabled = true;
txtFIELD2.disabled = false;
}
else if (txtFIELD1.value != "" || txtFIELD2.value == "") {
txtFIELD1.disabled = false;
txtFIELD2.disabled = true;
}
}
Remove IE10's "clear field" X button on certain inputs?
See the second answer, seems to be the best approach to getting rid of the 'X' and the problems it's causing.
I'm building a multipage form and I have some unusual validation requirements. Here's what I'd like to do/what I have done so far.
What I Want to Do:
(1) As each form field is filled in, I want a function to run and check that the user-input has met certain conditions -- i.e. for first and last name, that there are no numbers and there is a space in between the names.
(2) Once each of the field are full and have passed as true, I want another function to run that re-enabled a previously disabled "Next" button that will move the user to the next page of the form.
What I Have Done
(1) Created a mini version of the form with two inputs:
One that takes a first name, a space and a last name
One that takes a phone number set up the following way xxx xxx xxx
(2) I've console.logged the results with pass/fail logic so I know when certain things are being input by the user, that the code is validating properly.
Where I am Stuck:
I do not know how to create the secondary code that will reenabled the previously disabled "next" button that will move the form to the next page.
What I would like to do is make it so when the "Next" button is reenabled, and clicked on, it's own onclick function hides the current page, looks for the next page in the sequence and changes its display:block and I believe I have that code worked out separately, but I don't know how to integrate it with my other needs.
function checkForm()
{
var firstName = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
function checkFirstName()
{
if(firstName == "" || !isNaN(firstName) || !firstName.match(/^[A-Za-z]*\s{1}[A-Za-z]*$/))
{
console.log("Put a first Name and Last Name");
}
else
{
console.log("Thank You");
}
};
checkFirstName();
function checkPhoneNumber()
{
if(!phone.match(/^[0-9]*\s{1}[0-9]*\s{1}[0-9]*$/))
{
console.log("Please Put in a proper phone number");
}
else
{
console.log("Thank you");
cansubmit = true;
}
};
checkPhoneNumber();
};
<form>
First Name: <input type="text" id="name" onblur="checkForm()" /><label id="nameErrorPrompt"></label>
<br />
Phone Number: <input type="text" id="phone" onblur="checkForm()" /><label></label>
<br />
<button id="myButton" disabled="disabled">Test Me</button>
</form>
See below code.
It might be more user-friendly to use on keyup rather than onblur, as most users I know will try and click the disabled button, rather than pressing tab or focusing on another element.
function checkForm() {
var firstName = document.getElementById("name").value;
var phone = document.getElementById("phone").value;
var phoneCanSubmit, nameCanSubmit = false;
function checkFirstName() {
if (firstName == "" || !isNaN(firstName) || !firstName.match(/^[A-Za-z]*\s{1}[A-Za-z]*$/)) {
nameCanSubmit = false;
console.log("Put a first Name and Last Name");
} else {
nameCanSubmit = true;
console.log("Thank You");
}
};
checkFirstName();
function checkPhoneNumber() {
if (!phone.match(/^[0-9]*\s{1}[0-9]*\s{1}[0-9]*$/)) {
phoneCanSubmit = false;
console.log("Please Put in a proper phone number");
} else {
phoneCanSubmit = true;
console.log("Thank you");
cansubmit = true;
}
};
checkPhoneNumber();
if (nameCanSubmit && phoneCanSubmit) {
document.getElementById("myButton").disabled = false;
} else {
document.getElementById("myButton").disabled = true;
}
};
<form>
First Name:
<input type="text" id="name" onblur="checkForm()" />
<label id="nameErrorPrompt"></label>
<br />Phone Number:
<input type="text" id="phone" onblur="checkForm()" />
<label></label>
<br />
<button id="myButton" disabled="disabled">Test Me</button>
</form>
The code below gives you what you want. I removed some extraneous checks to simplify the code and also moved the event handlers from he HTML to the JavaScript. I also pulled the field checks out of the larger checkForm function. This provides you the flexibility to use them one at at time if need be.
window.addEventListener('load', function(e) {
var nameInput = document.getElementById('name');
var phoneInput = document.getElementById('phone');
var myButton = document.getElementById('myButton');
myButton.addEventListener('click', function(e) {
e.preventDefault(); //Stop the page from refreshing
getNextPage('Next page shown!!');
}, false);
nameInput.addEventListener('blur', function(e) {
checkName(this.value);
}, false);
phoneInput.addEventListener('blur', function(e) {
//Uncomment below to make this responsible only for checking the phone input
//checkPhoneNumber(this.value);
/*You could do away with diasbling and check the form
on submit, but if you want to keep the disable logic
check the whole form on the blur of the last item*/
checkForm();
}, false);
}, false);
function getNextPage(foo) {
console.log('Callback fired: ', foo);
//Do something here
}
function checkPhoneNumber(phone) {
if(!phone.match(/^[0-9]*\s{1}[0-9]*\s{1}[0-9]*$/)) {
console.log("Please Put in a proper phone number");
return 0;
}
else {
console.log("Thank you name entered");
return 1;
}
};
//Removed a bit of over coding, no ned to check isNaN or empty string since using regex already
function checkName(firstAndLastName) {
if(!firstAndLastName.match(/^[A-Za-z]*\s{1}[A-Za-z]*$/)) {
console.log("Put a first Name and Last Name");
return 0;
}
else {
console.log("Thank You phone entered");
return 1;
}
};
function checkForm() {
var validCount = 0;
fieldCount = document.forms[0].elements.length - 1; //substract one for the submitbutton!
var phoneNum = document.getElementById('phone').value;
var name = document.getElementById('name').value;
var myButton = document.getElementById('myButton');
validCount += checkPhoneNumber(phoneNum);
validCount += checkName(name);
console.log(validCount + ' of ' + fieldCount + ' fields are valid');
if (validCount > 0 && validCount === fieldCount) {//Compare the inputs to the number of valid inputs
myButton.disabled = false;
}
else {
myButton.disabled = true;
}
}
HTML
<form>
First Name: <input type="text" id="name" /><label id="nameErrorPrompt"></label>
<br />
Phone Number: <input type="text" id="phone" /><label></label>
<br />
<button id="myButton" disabled="disabled">Test Me</button>
</form>
How about you start by making the onblur for each input return a boolean indicating if the field is valid.
Then setting a cansubmit variable (= checkName && checkPhone) in the checkForm function and only moving on after that - then you don't need to enable and disable the button.
If you really want the button to enable you can use the same pattern, but do
document.getElementById("myButton").disabled = !canSubmit;
and you will always want to call checkForm on field blur like you are now.
Also note you aren't scoping canSubmit locally right now.
In my application I have a textbox to search for items. In this textbox I want the user to have to enter at least 2 characters before searching. If there's less than 2 characters then I want to display a simple alert box telling the user to enter at least 2 characters. On my text box code looks like:
function checkSearchLen(obj, defaultEnterButton) {
if (obj.value == 'Search') obj.value = '';
if (obj.value.length < 2 && event.keyCode == 13) {
event.returnValue = false;
event.cancel = true;
alert('Please ENter at Least 2 Characters');
//return false;
obj.select();
obj.focus();
return false;
} else
doEnterKey(defaultEnterButton);
}
function doEnterKey(s) {
if (event.keyCode == 13) {
event.returnValue = false;
event.cancel = true;
document.getElementById(s).click();
}
}
<input class="searchtext" id="txtSearch" value="Search" onfocus="this.value = '';this.style.color='black';this.style.fontStyle='normal';" onkeydown="checkSearchLen(this,'MenuBar_imgSearchGo');" name="txtSearch" />
In my javascript the function on every keystroke from the user, it checks the keyCode being pressed looking for the 'Enter' input. If the user presses 'Enter' and the number of characters in the textbox is less than 2 then it should alert the user and return false. But regardless the form is still submitted when the user presses 'Enter'.I also noticed it doesn't hit the 'doEnterKey' function it just submits the form. Any help or suggestions is appreciated.
In Internet Explorer everything works as should, the javascript code stops wait for input from the user then continues, returning false. However in chrome the alert box is displayed it and it still submits the form, almost as if it's not returning the false back to the element.
Pass the event object in the call and on ENTER prevent event default.
I used the keypress event and tested on IE, FF and Chrome.
Now the alert message on form submit will not happen because the ENTER is prevented.
function checkSearchLen(event, obj, defaultEnterButton) {
event = event || window.event;
if (obj.value == 'Search') obj.value = '';
if (obj.value.length < 2 && event.keyCode == 13) {
alert('Please ENter at Least 2 Characters');
obj.select();
obj.focus();
event.preventDefault();
return false;
} else
doEnterKey(defaultEnterButton);
}
function doEnterKey(s) {
if (event.keyCode == 13) {
event.returnValue = false;
event.cancel = true;
document.getElementById(s).click();
}
}
<form action="http://www.google.com" onsubmit="alert('submit');">
<input class="searchtext" id="txtSearch" value="Search" onfocus="this.value = '';this.style.color='black';this.style.fontStyle='normal';" onkeypress="checkSearchLen(event, this,'MenuBar_imgSearchGo');" name="txtSearch" />
</form>
The best method to deal with this kind of problems is by using Jquery...just a few lines of Jquery code is capable of doing what you did in the entire program!
Another alternate answer is to do checking in form submit event and cancel that submit event based on invalid input. This will prevent page post back. Actually, this is the same approach that ASP.Net framework takes when a page has ASP.Net validators in it with client-side validation turned on.
Also, there is no need to cancel the event in doEnterKey, so I have commented two lines in that function.
The following code will work as I have tested on my side. There are two aspects to the logic being used:
A global variable stopSubmit decides if form submit event will be canceled or not. If this variable is true then form submit event will cancel.
The original form submit event code of the form is being pre-pended with our custom JavaScript that will return a false in case the form submit needs to be canceled. This is happening when body loads for the page i.e. body's onload event calls setFormSubmit to modify existing form submit code. If everything was valid, then original form submit code executes without issues and page posts back.
<body onload="setFormSubmit()">
<form id="form1" runat="server">
<asp:Label ID="label1" runat="server"></asp:Label>
<div>
First name:
<input type="text" name="FirstName" value="Mickey" /><br />
Last name:
<input type="text" name="LastName" value="Mouse" /><br />
<input type="submit" value="Submit" />
<input type="text" onkeydown="checkSearchLen(this,'MenuBar_imgSearchGo');" />
<input type="submit" value="Submit" id="MenuBar_imgSearchGo"/>
</div>
<script>
var stopSubmit = false;
function setFormSubmit() {
document.forms[0].setAttribute("onsubmit", " var stopPostback = StopPostback(); if(stopPostback === true) { return false; } " + (document.forms[0].onsubmit === null ? "" : document.forms[0].onsubmit));
}
function checkSearchLen(obj, defaultEnterButton) {
if (obj.value === 'Search') obj.value = '';
if (obj.value.length < 2 && event.keyCode == 13) {
event.returnValue = false;
event.cancel = true;
stopSubmit = true;
alert('Please ENter at Least 2 Characters');
obj.select();
obj.focus();
return false;
} else {
stopSubmit = false;
doEnterKey(defaultEnterButton);
}
}
function doEnterKey(s) {
if (event.keyCode == 13) {
//event.returnValue = false;
//event.cancel = true;
document.getElementById(s).click();
}
}
function StopPostback() {
if (stopSubmit === true) {
stopSubmit = false;
return true;
}
return false;
}
</script>
</form>
When I click the asp.net button as per the below code, it goes into my js file, and gets the function as I need, however if it fails validation it still goes through with the postback as if it were valid.
the asp.net button
<asp:Button ID="bttnSend" runat="server" OnClientClick="DoValidation()" Text="Send" CssClass="btn btn-primary margin30" />
the javascript
function DoValidation(parameter) {
console.log("validating");
var valid = true;
var emailTo = document.getElementById("txtEmailTo").value;
if (emailTo.length < 1) {
alert("Please select at least one recipient to send an email to");
valid = false;
}
console.log(valid);
if (valid == true) {
__doPostBack('bttnSend', parameter);
}
};
I would be grateful if someone could please tell me what i need to change and what to so that the validation doesnt allow the postback if it fails.
thanks
You need to prevent the default action of button when condition fails.
Modify your function to return true/false
function DoValidation(parameter) {
var valid = true;
var emailTo = document.getElementById("txtEmailTo").value;
if (emailTo.length < 1) {
alert("Please select at least one recipient to send an email to");
valid = false;
}
return valid;
};
The use the return value
<asp:Button ID="bttnSend" runat="server" OnClientClick="return DoValidation()" Text="Send" CssClass="btn btn-primary margin30" />