Google Apps Script Form textValidationBuilder does not recognize regex pattern - regex

I am trying to create a Form with apps script and for some reason it will not allow the simplest phone number validation in a TextItem input field. I only need the user to enter their 10 digit number with no spaces, dashes, dots, with area code included. I know this isn't the technical "best" way to validate phone numbers but for our purposes it works. This is section of code I have to generate the field. (edited to make a more reproducible example)
function CreateForm() {
var form = FormApp.create('Test');
var tenantNum = form.addTextItem()
.setTitle("Tenant Phone #");
var phoneValid = FormApp.createTextValidation()
.setHelpText("Please enter valid phone number, 10-digits, no symbols or spaces.")
.requireTextMatchesPattern(/\d{10}/g)
.build();
tenantNum.setValidation(phoneValid);
console.log(form.getPublishedUrl())
}
I have also tried other things like:
(No capture group or global tag, both individually)
.requireTextMatchesPattern(/\d{10}/)
Entering the regex as a string literal.
.requireTextMatchesPattern("\d{10}")
Even dumdum stuff like.
.requireTextMatchesPattern(/[0-9]{10}/)
or
.requireTextMatchesPattern(/\d\d\d\d\d\d\d\d\d\d/)
Just to see if it works. I have also tried .requireTextContainsPattern() as well.
Whenever you enter in the form however i get this response:
Please enter valid phone number, 10-digits, no symbols or spaces.
My only thought is that there might be some confusion with whether or not the user is entering a string vs. number and this method only works on strings. But this validation
and regex work fine when you enter it into the form creation manually so I'm completely lost. Any help is appreciated!

Just a guess... Try this:
.requireTextMatchesPattern("\\d{10}")
Update
It works fine for me:
function CreateForm() {
var form = FormApp.create('Test');
var tenantNum = form.addTextItem()
.setTitle("Tenant Phone #");
var phoneValid = FormApp.createTextValidation()
.setHelpText("Please enter valid phone number, 10-digits, no symbols or spaces.")
.requireTextMatchesPattern("\\d{10}")
.build();
tenantNum.setValidation(phoneValid);
console.log(form.getPublishedUrl())
}
And the "not existed" method setHelpText() works fine as well, as you can tell from the screenshots.

Related

Flutter / Dart - Parsing a Textfield controller text for multiple matches of a RegExp's and calling a function each time it matches

I have a textfield controller which matches a RegExp whenever the user type it in. For example the typed in string may be "#jack and #jill went up the hill". The following code will match the taghandles and list them.
Firstly the TextField:
TextField(
controller: myController,
)
Which listens for each input into the text field and passes it to a function:
myController.addListener(_matchTextToRegexp);
The function then matches taghandles ie. '#jack' '#jill'
_matchTextToRegexp() {
String value = myController.text;
RegExp regExpTaghandle = RegExp(r"\B#+([\w]+)\b");
Iterable matches = regExpTaghandle.allMatches(value);
matches.forEach((match) {
tagHandle = value.substring(match.start, match.end);
_callToAction(tagHandle);
}
}
The issue is that i want to call a function _callToAction() and pass it the taghandle (for example it could pass the substring/taghandle to a typeahead suggestion dropdown menu as the user types it in - similar functionality to a tweet mention). This code works for one taghandle, but if the users continues inputting text (or adds multiple taghandles) into the form it will keep matching the first taghandle even though the user has typed passed the first taghandle.
So how do you distinguish between multiple taghandles as they are dynamically typed in?

case-insensitive regular expression in a Google form: is it allowed?

I am using GAS to set some restriction to the string i receive from a textItem added to a form
initialy i have wrote it like that:
var form = FormApp.getActiveForm();
var textItem = form.addTextItem().setTitle('put some integer
followed by A, B or C');
var textValidation = FormApp.createTextValidation()
.setHelpText('wrongPattern')
.requireTextContainsPattern(/(\d+)(a|b|c)/i)
.build();
textItem.setValidation(textValidation);
The idea was to get an integer followed by a,b or c and be case-insensitive.
It does not work and if i check the form editor i see that :look at the screenshot
just changing the pattern,I make it do the drill but with something I don't feel great about
.requireTextContainsPattern('(\\d+)(a|A|b|B|c|C)')
witch give in the form editor: this screenshot
My question is Why does it work ?
Witch rules to follow using:requireTextContainsPattern()?
how to do a case-insensitive pattern ?
Thank to Wiktor Stribiżew here is an other brick added to the questionement.
If i use
.requireTextContainsPattern('(?i)\\d+[abc]')
the editor accept the regular expression as correct,but when you try to submit the form, the answer is not submitted, the button 'SUBMIT' become grey and nothing happen.

Replace variable names with actual class Properties - Regex? (C#)

I need to send a custom email message to every User of a list ( List < User > ) I have. (I'm using C# .NET)
What I would need to do is to replace all the expressions (that start with "[?&=" have "variableName" in the middle and then ends with "]") with the actual User property value.
So for example if I have a text like this:
"Hello, [?&=Name]. A gift will be sent to [?&=Address], [?&=Zipcode], [?&=Country].
If [?&=Email] is not your email address, please contact us."
I would like to get this for the user:
"Hello, Mary. A gift will be sent to Boulevard Spain 918, 11300, Uruguay.
If marytech#gmail.com is not your email address, please contact us."
Is there a practical and clean way to do this with Regex?
This is a good place to apply regex.
The regular expression you want looks like this /\[\?&=(\w*)\]/ example
You will need to do a replace on the input string using a method that allows you to use a custom function for replacement values. Then inside that function use the first capture value as the Key so to say and pull the correct corresponding value.
Since you did not specify what language you are using I will be nice and give you an example in C# and JS that I made for my own projects just recently.
Pseudo-Code
Loop through matches
Key is in first capture group
Check if replacements dict/obj/db/... has value for the Key
if Yes, return Value
else return ""
C#
email = Regex.Replace(email, #"\[\?&=(\w*)\]",
match => //match contains a Key & Replacements dict has value for that key
match?.Groups[1].Value != null
&& replacements.ContainsKey(match.Groups[1].Value)
? replacements[match.Groups[1].Value]
: "");
JS
var content = text.replace(/\[\?&=(\w*)\]/g,
function (match, p1) {
return replacements[p1] || "";
});

Angular - force validation through ng-keydown is not working as expected

Please see this jsFiddle (Disclaimer - the ng-keydown function isn't calling but that is not the main issue in the fiddle)
I am trying to add validation for an input box so numbers (0-100) are allowed and nothing else through a regex I made. However it is not working as expected as when using this function:
$scope.validatebox = function (e) {
var element = e.target;
var element_val = $(element).val();
element_val = parseInt(element_val);
var reg = /^[1-9][0-9]?$|^100$/;
if (reg.test(element_val) === false) //validate
{
e.preventDefault();
return;
}
};
The e.preventDefault() acts funny and doesn't permit the user to enter any number if there is nothing in the input box.
How can I ammend my code to force proper validation on the user so he can only enter numbers 0-100.
AngularJS has support for custom validators, and actually already has some built in for number range. Instead of writing code to work on keydown, leverage Angular's custom validators.
For numbers in particular, you can use min and max, eg:
<input type="number" name="box1" ng-model="box1"
min="0" max="100"/>
You just need to put it in a form, and then you can display the error however you wish. Working Fiddle here: http://jsfiddle.net/js4tm3j7/1/
More info on number validators here: https://docs.angularjs.org/api/ng/input/input%5Bnumber%5D
Info on custom validators here: https://docs.angularjs.org/guide/forms
EDIT
If you want to force validation instead of just showing an error, take a look at parsers and formatters: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
There's an example here: filters on ng-model in an input

Finding the phone company of a cell phone number?

I have an application where people can give a phone number and it will send SMS texts to the phone number through EMail-SMS gateways. For this to work however, I need the phone company of the given number so that I send the email to the proper SMS gateway. I've seen some services that allow you to look up this information, but none of them in the form of a web service or database.
For instance, http://tnid.us provides such a service. Example output from my phone number:
Where do they get the "Current Telephone Company" information for each number. Is this freely available information? Is there a database or some sort of web service I can use to get that information for a given cell phone number?
What you need is called a HLR (Home Location Register) number lookup.
In their basic forms such APIs will expect a phone number in international format (example, +15121234567) and will return back their IMSI, which includes their MCC (gives you the country) and MNC (gives you the phone's carrier). The may even include the phone's current carrier (eg to tell if the phone is roaming). It may not work if the phone is currently out of range or turned off. In those cases, depending on the API provider, they may give you a cached result.
The site you mentioned seems to provide such functionality. A web search for "HLR lookup API" will give you plenty more results. I have personal experience with CLX's service and would recommend it.
This would be pretty code intensive, but something you could do right now, on your own, without APIs as long as the tnid.us site is around:
Why not have IE open in a hidden browser window with the URL of the phone number? It looks like the URL would take the format of http://tnid.us/search.php?q=########## where # represents a number. So you need a textbox, a label, and a button. I call the textbox "txtPhoneNumber", the label "lblCarrier", and the button would call the function I have below "OnClick".
The button function creates the IE instance using MSHtml.dll and SHDocVW.dll and does a page scrape of the HTML that is in your browser "object". You then parse it down. You have to first install the Interoperability Assemblies that came with Visual Studio 2005 (C:\Program Files\Common Files\Merge Modules\vs_piaredist.exe). Then:
1> Create a new web project in Visual Studio.NET.
2> Add a reference to SHDocVw.dll and Microsoft.mshtml.
3> In default.aspx.cs, add these lines at the top:
using mshtml;
using SHDocVw;
using System.Threading;
4> Add the following function :
protected void executeMSIE(Object sender, EventArgs e)
{
SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorerClass();
object o = System.Reflection.Missing.Value;
TextBox txtPhoneNumber = (TextBox)this.Page.FindControl("txtPhoneNumber");
object url = "http://tnid.us/search.php?q=" + txtPhoneNumber.Text);
StringBuilder sb = new StringBuilder();
if (ie != null) {
ie.Navigate2(ref url,ref o,ref o,ref o,ref o);
ie.Visible = false;
while(ie.Busy){Thread.Sleep(2);}
IHTMLDocument2 d = (IHTMLDocument2) ie.Document;
if (d != null) {
IHTMLElementCollection all = d.all;
string ourText = String.Empty;
foreach (object el in all)
{
//find the text by checking each (string)el.Text
if ((string)el.ToString().Contains("Current Phone Company"))
ourText = (string)el.ToString();
}
// or maybe do something like this instead of the loop above...
// HTMLInputElement searchText = (HTMLInputElement)d.all.item("p", 0);
int idx = 0;
// and do a foreach on searchText to find the right "<p>"...
foreach (string s in searchText) {
if (s.Contains("Current Phone Company") || s.Contains("Original Phone Company")) {
idx = s.IndexOf("<strong>") + 8;
ourText = s.Substring(idx);
idx = ourText.IndexOf('<');
ourText = ourText.Substring(0, idx);
}
}
// ... then decode "ourText"
string[] ourArray = ourText.Split(';');
foreach (string s in ourArray) {
char c = (char)s.Split('#')[1];
sb.Append(c.ToString());
}
// sb.ToString() is now your phone company carrier....
}
}
if (sb != null)
lblCarrier.Text = sb.ToString();
else
lblCarrier.Text = "No MSIE?";
}
For some reason I don't get the "Current Phone Company" when I just use the tnid.us site directly, though, only the Original. So you might want to have the code test what it's getting back, i.e.
bool currentCompanyFound = false;
if (s.Contains("Current Telephone Company")) { currentCompanyFound = true }
I have it checking for either one, above, so you get something back. What the code should do is to find the area of HTML between
<p class="lt">Current Telephone Company:<br /><strong>
and
</strong></p>
I have it looking for the index of
<strong>
and adding on the characters of that word to get to the starting position. I can't remember if you can use strings or only characters for .indexOf. But you get the point and you or someone else can probably find a way to get it working from there.
That text you get back is encoded with char codes, so you'd have to convert those. I gave you some code above that should assist in that... it's untested and completely from my head, but it should work or get you where you're going.
Did you look just slightly farther down on the tnid.us result page?
Need API access? Contact sales#tnID.us.
[Disclosure: I work for Twilio]
You can retrieve phone number information with Twilio Lookup.
If you are currently evaluating services and functionality for phone number lookup, I'd suggest giving Lookup a try via the quickstart.