Maybe the subject line is incorrect, but here is my question:
I am trying to see if the user input is a valid email address, or if there is an input at all at the first place. if none of the above, then i want to loop the question requesting the answer again, until i get a valid answer(in this case, email address). Below is the code i have written, which was working until i added REGEX testing.
function emailPrompt() {
var ui = SpreadsheetApp.getUi();
var entry = ui.prompt("REQUIRED: Email Address", "Please type the email address you want the exported excel spreadsheet to be emailed to:"+"\n\n", ui.ButtonSet.OK);
var button = entry.getSelectedButton();
var response = entry.getResponseText();
var sum = 1;
for(var i=0;i<sum;i++){
var regex = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
var matchRegex = regex.test(response);
if(response == ""||response == " "|| response != matchRegex) {
if(!matchRegex) { ui.alert("Invalid Email Address")}
ui.prompt("REQUIRED: Email Address", "Please type the email address you want the exported excel spreadsheet to be emailed to:"+"\n\n", ui.ButtonSet.OK);
sum++;
} else {
sum--;
}
}
return response;
Logger.log(response);
}
Specifically, if the input is incorrect/invalid email address, i inserted another if statement to alert the user. I am positive i am messed the code somewhere in the REGEX matching/testing. Any help would be much appreciated. TIA
Your regex statement is ok. It tests and returns a boolean. Your first if statement is a little redundant. response == ""||response == " "|| response != matchRegex Most of these are already tested by the regex statement and the last one should never be false as you are comparing a string to a boolean.
EDIT: Additionally, the response variable is never update with the new prompt data (Code updated).
function emailPrompt() {
var ui = SpreadsheetApp.getUi();
var entry = ui.prompt("REQUIRED: Email Address", "Please type the email address you want the exported excel spreadsheet to be emailed to:"+"\n\n", ui.ButtonSet.OK);
var button = entry.getSelectedButton();
var response = entry.getResponseText();
var sum = 1;
for(var i=0;i<sum;i++){
var regex = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
var matchRegex = regex.test(response);
if(!matchRegex) {
ui.alert("Invalid Email Address");
//Ask for email again and set new response.
var responseItem = ui.prompt("REQUIRED: Email Address", "Please type the email address you want the exported excel spreadsheet to be emailed to:"+"\n\n", ui.ButtonSet.OK);
response = responseItem.getResponseText();
sum++;
}
//sum--; this isn't needed to stop the loop.
if(sum > 3) //You shouldn't go on forever... Stop after a few tries?
break;
}
Logger.log(response); //Moved above return so this code runs.
return response;
}
Related
I am working on a lab for school where we create a function that validates that the email textbox value is a valid email structure (xyx#xyz.xyz). I am having trouble figuring out how it will work I am typing it in VS code and I'm not really getting anywhere when I load the page on Live Server. I am very new to JS so I feel like I am not implementing my function properly. Also, I used a simple Regex email pattern but am curious about how I can validate it with just vanilla javascript. Any help will be greatly appreciated. Thank you!
function validate(){
var email = document.getElementById("email").value;
var error = "";
const emailPattern =/\S+#\S+\.\S+/;
if(email.value.match(emailPattern))
{
return true;
}
else if(email.value == ""){
error = "You entered a blank email address. \n";
alert(error);
return false;
}
else
{
error = "You have entered an invalid email address!";
alert(error);
return false;
}
Creating a good regex for email is quite difficult for a novice because the email specification is quite permissive you can have multiple dots before and after the # and that's beside various disallowed characters.
You can google for proper regexes for email if required.
But you have multiple problems with your function besides the regex.
First your function block is not closed, you need to add another curly bracket at the end.
Here because you use ".value" Property you get a string with the actual email entered in the input field.
var email = document.getElementById("email").value;
But here you try to use the "email" variable as if it is the reference to the input object when it is in reality a string and does not have the ".value" Property.
if(email.value.match(emailPattern))
You should drop the .value and just use
if(email.match(emailPattern))
you make the same mistake in other places were you use the email variable.
Here is the corrected code with a naive regex for email matching.
function validate(){
const email = document.getElementById("email").value;
let error = "";
const emailPattern =/\w+#\w+\.\w+/;
if(email.match(emailPattern)){
console.log(`Your email ${email} is marvelous`);
return true;
}
else if(email == ""){
error = "You entered a blank email address. \n";
alert(error);
return false;
}
else {
error = "You have entered an invalid email address!";
alert(error);
return false;
}
}
<input id="email" type="text" value="">
<button onclick="validate()">Validate</button>
I am currently having problems with displaying different span error messages for some of the same input texboxes based on if the user doesn't follow my validation rules. I really could use some suggestions of how I can make some of my if statements better to enforce my rules that I have setup. I am okay with how my if statement is validating the username and how if statement is validating the password, but I have been struggling to try to figure what is the best method for validating my repeatemail textbox and emailaddress textbox. Can someone help me? Thanks in advance! Here is my HTML, CSS, and JavaScript/JQuery code
$('#button2').on('click', function () {
var NewUsernameError = document.getElementById("New_Username_error");
var NewPasswordError = document.getElementById("New_Password_error");
var NewEmailAddressError = document.getElementById("New_Email_error");
// var NewRepeatEmailAddressError=document.getElementById("NewReenter_Email_error");
// How can I get my span id's to display one of two different error //messages based on my rules below? Right now it will only display first error //messages. Do I need to create two different span ids (except for the password // texbox) for each input textbox or is one span id fine how I currently have //it? Shouldn't I be able to display either message just using one span id?
if($(".newUsername").val().length < 6)
{
NewUsernameError.innerHTML= "The username must be at least 6 characters";
// NewUsernameError.innerHTML= "There is an already existing account with username";
}else
{
NewUsernameError2.innerHTML = '';
}
if($(".newPassword").val().length < 6) {
{
NewPasswordError.innerHTML= "The password must be at least 6 characters";
}else{
NewPasswordError.innerHTML = '';
}
if($(".newEmail")== "" && $(".newEmail") != /^[a-zA-Z0-9]#[a-zA-Z])+.[a-z])
{
NewEmailAddressError.innerHTML= "The email must not be left empty.";
NewEmailAddressError.innerHTML= "The email must contain # symbol in it.";
}else{
NewEmailAddressError.innerHTML= '';
}
if($(".repeatEmail").value != $(".newEmail").value && $(".repeatEmail") == ""){
NewRepeatEmailAddressError.innerHTML= "This repeat email doesn't equal to the first one entered.";
NewRepeatEmailAddressError.innerHTML= "This repeat email must not be blank.";
}else{
NewRepeatEmailAddressError.innerHTML= '';
}
.
Lots of problems here.
if($(".newEmail")== "" && $(".newEmail") != /^[a-zA-Z0-9]#[a-zA-Z])+.[a-z])
That tries to compare the <input> element instead of its contents.
if($(".repeatEmail").value != $(".newEmail").value && $(".repeatEmail") == ""){
That tries to compare undefined instead of the form element's contents. (jQuery doesn't use .value.)
Instead, you want .val():
if($(".newEmail").val() == "" && $(".newEmail").val() != /^[a-zA-Z0-9]#[a-zA-Z])+.[a-z])
...
if($(".repeatEmail").val() != $(".newEmail").val() && $(".repeatEmail").val() == ""){
A secondary problem is where you try to assign two error messages simultaneously:
NewRepeatEmailAddressError.innerHTML= "This repeat email doesn't equal to the first one entered.";
NewRepeatEmailAddressError.innerHTML= "This repeat email must not be blank.";
In these cases the second .innerHTML is going to immediately overwrite the first one, so the first error message will never be seen. Each of those errors needs to be in its own, separate if {} condition.
Third, this isn't how to do regex comparisons, that regex contains several syntax errors (no trailing slash, mismatched parens), and even if it worked it would disallow many valid email addresses:
$(".newEmail") != /^[a-zA-Z0-9]#[a-zA-Z])+.[a-z])
Better email address validation regexes can be found in e.g. this question, but even those can disallow some valid addresses. Keep things simple and test only for what the error message claims you're testing for, the presence of an # symbol:
/#/.test($('.newEmail').val())
Putting it all together
Cleaning your original function, converting all the vanilla js into jQuery (there's no real drawback to mixing them other than that it makes the code harder to read, but I figure if you've already got jQuery may as well use it), and rearranging some logic to simplify the code results in this:
var validate=function() {
// clear out the error display ahead of time:
var newUsernameError = $("#New_Username_error").html('');
var newPasswordError = $("#New_Password_error").html('');
var newEmailAddressError = $("#New_Email_error").html('');
var newRepeatEmailAddressError = $("#Repeat_Email_error").html('');
// just to make the later conditions easier to read, let's grab all the values into vars:
var newUsername = $('.newUsername').val();
var newPassword = $('.newPassword').val();
var newEmail = $('.newEmail').val();
var repeatEmail = $('.repeatEmail').val();
// presumably you'll want to prevent form submit if there are errors, so let's track that:
var errorsFound = false;
if (newUsername === "") {
errorsFound = true;
newUsernameError.html("The username must not be empty.");
} else if (newUsername.length < 6) {
errorsFound = true;
newUsernameError.html("The username must be at least 6 characters.");
}
if (newPassword.length < 6) {
errorsFound = true;
newPasswordError.html("The password must be at least 6 characters.");
}
if (newEmail === "") {
errorsFound = true;
newEmailAddressError.html("The email must not be left empty.");
} else if (!/#/.test(newEmail)) {
errorsFound = true;
newEmailAddressError.html("The email must contain an # symbol.");
}
if (repeatEmail !== newEmail) {
errorsFound = true;
newRepeatEmailAddressError.html("This repeat email doesn't equal to the first one entered.");
}
// No need to test for repeatEmail being empty, since that's already covered by the newEmail case above.
// OK, all conditions checked, now:
if (errorsFound) {
// prevent form submit. (If this is called in an onsubmit handler, just return false.)
} else {
// allow form submit.
}
console.log("Errors found: ", errorsFound);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
Username: <input class="newUsername">
<div id="New_Username_error"></div>
Password: <input class="newPassword">
<div id="New_Password_error"></div>
newEmail: <input class="newEmail">
<div id="New_Email_error"></div>
repeatEmail: <input class="repeatEmail">
<div id="Repeat_Email_error"></div>
</form>
<button onclick="validate()">Validate</button>
Keep one container for the errors you might expect to get on the input. I would do something like this to avoid all the else and else if's
$('#button2').on('click', function () {
// VALIDATE USERNAME
var newUserErrStr = '';
var newUsernameVal = $(".newUsername").val();
if(newUsernameVal.length < 6) newUserErrStr += "The username must be at least 6 characters";
document.getElementById("New_Username_error").innerHTML = newUserErrStr;
// VALIDATE PASSWORD
var newPasswordErrStr = '';
var newPasswordVal = $(".newPassword").val();
if(newPasswordVal.length < 6) newPasswordErrStr += "The password must be at least 6 characters";
document.getElementById("New_Password_error").innerHTML = newPasswordErrStr;
// VALIDATE EMAIL
var newEmailErrStr = '';
var newEmailVal = $(".newEmail").val();
if (newEmailVal === "") newEmailErrStr += "The email must not be left empty<br/>";
if (newEmailVal !== /^[a-zA-Z0-9]#[a-zA-Z])+.[a-z]/ ) newEmailErrStr += "The email must contain # symbol in it.";
document.getElementById("New_Email_error").innerHTML = newEmailErrStr;
});
I would like to ask series of questions to users in one function.
If I use prompt(), it is possible to ask all the questions in one function.
function question(){
var name = prompt("Enter your name");
var age = prompt("Enter your age");
}
But if I try to use input tag, this is impossible.
function question(){
document.write("Enter your name");
// you can't wait until the user responds. It will simply execute all the lines at once.
name = document.getElementById("input").value;
document.write("Enter your age");
age = document.getElementById("input").value;
}
If I do this, I can't use input tag to ask questions to users in one function. How can I wait until the user responds?
To chain prompts you can do something like:
const name = prompt("Enter your name");
if (!!name) {
const age = prompt("Enter your age");
if(!!age){
...
}
}
Or if you can use rxjs 5.5+ in your project you can use an observable to wait for the first prompt.
For example:
of(prompt("Enter your name"))
.pipe(first(), filter((name) => !!name))
.subscribe((name) => {
var age = prompt("Enter your age")
if(age) {
...
}
});
You can keep all your input boxes disabled except the first one. The second one can be enabled upon the user response to the first one. The line of inputs will go on like this.
Here is a little demonstration. Please note this is only a sample code which shows you the design pattern.
<input id="name"></input> <button onClick="getInput()">Ok</button>
<input id="address"></input> <button onClick="getInput()" disabled>Ok</button>
and in JS
var name, address;
functon getInput() {
name = document.getelementById("name").value;
address = document.getElementById("address").value;
if (address !== "")
document.getElementById("address").removeAttribute("disabled");
}
There are many advance methods than this is available in JS. But probably you should study this pattern first.
You cant take 2 different values from the same input in a function. You should create another input or some button to differentiate variables. For example:`
Enter your name
Enter your age
Save
var bSave = window.document.getElementById('bSave');
bSave.addEventListener("click", question);
var newName = window.document.getElementById('iName');
var newAge = window.document.getElementById('iAge');
function question() {
name=newName.value;
age=newAge.value;
}
</script>
`
document.write() is to writes HTML not for asking user input like prompt(). what you need is input validation before user submit the form like
function checkQuestion(){
if(document.getElementById("name").value == "")
alert('name empty');
if(document.getElementById("age").value == "");
alert('age empty');
}
I am using ServiceNow platform. I am writing a Catalog Client Script to validate form fields on a Catalog Item record producer.
I am stopping the submission of the form by using return false if validation does not pass inspection.
I have tested this by entering invalid data (group name with special characters or a group name that exists already) and it catches the issue and shows the error message. I can enter invalid data and submit multiple times and it works.
However, the issue:
The script seems to "stop" running after I first enter invalid data and submit, and then I correct the data press the submit button again. It just sits there and does nothing. I have to reload the form again which is not desirable.
What is going on with the control flow? How can I cleanly stop the form if the data is invalid, but then allow the user to correct the mistake and press the submit button again to proceed?
I can tell that the script doesn't run again because I have an alert box popping up that says "script run" every time the script runs. It just stops running at some point after submitting invalid data first and then entering some valid data and pressing submit.
function onSubmit() {
g_form.hideAllFieldMsgs('error');
alert("script run");
//Group Name contain letters numbers and dashes only
var group_name = g_form.getValue('u_group_name');
// Group name regular expression
var regGrpName = /^([A-Za-z0-9\-]+)$/;
// Check name against regular expression
if (regGrpName.test(group_name) == false) {
g_form.showFieldMsg('u_group_name', "Group Name must contain only letters, numbers or dashes. ", 'error');
//Do not submit
//g_form.submitted = false;
return false;
}
//Check if google group already exists
var rec = new GlideRecord('u_google_user_accounts');
rec.addQuery('u_account_email', new_group_email);
rec.query();
while (rec.next()) {
g_form.showFieldMsg('u_group_name',rec.u_account_email + " already exists as an account.",'error');
return false;
}
//Group Members Email List separated by commas
// Hide error message
//g_form.hideErrorBox('u_group_members');
var group_members = g_form.getValue('u_group_members');
// Comma separate list
var member_split = group_members.split(',');
// Loop over list of email addresses
for (var n = 0; n < member_split.length; n++) {
// Trim whitespace
var member_info = trim ? member_split[n].trim() : member_split[n];
// Email validation regular expression
var regEmail = /^\w+((-\w+)|(\.\w+))*\#[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
// Check each item against regular expression
if (member_info.search(regEmail) == false) {
g_form.showFieldMsg('u_group_members', "Group Members contains an invalid email address. " + member_info, 'error');
//Do not submit
//g_form.submitted = false;
return false;
} else if (member_info.search(validRegExp) == true) {
g_form.setValue('u_group_members', group_members);
}
}
return true;
}
I'm glad you found a solution above, but I wanted to leave a comment as well, to ask if you've tried a try{} catch{} block to handle invalid data?
I think I have solved the issue. I made a completely separate function that checks the validation. The onSubmit calls the validation function and checks the return value. If the return value is false then it stops the form. Otherwise it is submitted even after multiple attempts with invalid data. I think this will do the trick. Let me know if anyone can see any issues. Thanks for the help.
function onSubmit() {
var isValid = checkGoogleGroup();
if (isValid == false) {
g_form.submitted = false;
return false;
}
}
function checkGoogleGroup() {
g_form.hideAllFieldMsgs('error');
//Group Name contain letters numbers and dashes only
var group_name = g_form.getValue('u_group_name');
// Group name regular expression
var regGrpName = /^([A-Za-z0-9\-]+)$/;
// Check name against regular expression
validGroupName = regGrpName.test(group_name);
if (validGroupName == false) {
g_form.showFieldMsg('u_group_name', "Group Name must contain only letters, numbers or dashes. ", 'error');
//Do not submit
return false;
}
//Check if google group already exists
var rec = new GlideRecord('u_broad_user_accounts');
rec.addQuery('u_account_email', new_group_email);
rec.query();
while (rec.next()) {
g_form.showFieldMsg('u_group_name',rec.u_account_email + " already exists as an account.",'error');
return false;
}
//Group Members Email List separated by commas
var group_members = g_form.getValue('u_group_members');
// comma separate list
var member_split = group_members.split(',');
// loop over list of email addresses
for (var n = 0; n < member_split.length; n++) {
// trim whitespace
var member_info = trim ? member_split[n].trim() : member_split[n];
// validation regular expression
var validRegExp = /^\w+((-\w+)|(\.\w+))*\#[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
// check each item against regular expression
if (member_info.search(validRegExp) == -1) {
g_form.showFieldMsg('u_group_members', "Group Members contains an invalid email address. " + member_info, 'error');
return false;
}
}
}
This is what I'm using.
It's great. I only need to add function that checks if one of "cp", "bp", "hp" input area is entered or not. If not it should give an error that says "Please enter at least 1 phone number."
(cp = cell phone, bp = business phone, hp = home phone)
function checkPhones(){
var frm = document.forms["myform"];
var cell = frm.cp.val;
var bus = frm.bp.val;
var home = frm.hp.val;
if(ValidatePhone(cell) || ValidatePhone(bus) || ValidatePhone(home)){
return true;
}
return false;
}
function ValidatePhone(val){
//insert code to check phone meets your system requirements
//either length or pattern
//return true or false
}
frmvalidator.setAddnlValidationFunction("checkPhones");