Phone Formatting

A while back, I posted a phone formatting method that was working quite well for me. It could be set as an onDataChange method for any phone field, and it would format the phone and put the data back in the right field.

Now it’s not working, and I can’t figure out why. At first, I thought there’d been a change in 2.1.2, but that’s seeming less and less likely.

From running debugger, it seems that the variable fldContents isn’t getting defined/populated. Can anyone else reproduce this? Better yet, does someone still have 2.1.1 that they can try this on, to confirm it’s not a version difference? The method doesn’t require any special field definitions, just an onDataChange trigger on any existing phone field (text).

// gather information about where the user is and what s/he entered 
var eleName = application.getMethodTriggerElementName(); 
var frmName = application.getMethodTriggerFormName(); 
var fldName = forms[frmName].elements[eleName].getDataProviderID(); 
var fldContents = forms[frmName].controller.getDataProviderValue(fldName); 
// exit if there's nothing in the field to format 
if (!utils.stringToNumber(fldContents) || utils.stringLeft(fldContents,1) == '+') 
{ 
   return; // *****This is where the method is currently exiting*****
} 
// Set initial variables. 
var entry = fldContents; 
var phone = '(###) ###-####'; 
// first fill in the format pattern 
while (utils.stringPatternCount(phone, '#')>0 && entry ) 
{ 
   if(utils.stringPatternCount('0123456789',utils.stringLeft(entry, 1))) 
   { 
      nextPosition = utils.stringPosition(phone, '#', 1, 1 ); 
      phone = utils.stringIndexReplace(phone, nextPosition , 1 , utils.stringLeft(entry, 1)); 
   } 
   entry = utils.stringRight(entry, entry.length - 1); 
} 
// if there's more, fill in initial letters beyond the format, such as 'ext' or 'x' 
if ( entry ) 
{ 
   if(utils.stringPatternCount('0123456789',utils.stringLeft(entry, 1))) 
   { 
      phone += ' x'; 
   } 
   else 
   { 
      phone += ' '; 
   } 
} 
while (entry && !utils.stringPatternCount('0123456789',utils.stringLeft(entry, 1))) 
{ 
   phone += utils.stringLeft(entry, 1); 
   entry = utils.stringRight(entry, entry.length - 1); 
} 
// if there's still more, enter remaining numbers 
if ( entry ) 
{ 
   phone += ' '; 
} 
while (entry) 
{ 
   if(utils.stringPatternCount('0123456789',utils.stringLeft(entry, 1))) 
   { 
      phone += utils.stringLeft(entry, 1); 
   } 
   entry = utils.stringRight(entry, entry.length - 1); 
} 
forms[frmName].foundset[fldName] = phone;

if you debug or application.output(…) your first 4 variables is only the last one empty? are the others correct?

That is correct. Only fldContents comes up “undefined”.

I’ve noticed that the eleName variable notes the field I’m tabbing TO, not tabbing FROM, but so far I’m assuming that that’s because events trigger a bit differently with debugger. To confirm that that’s not the issue at hand, I tried hard-coding eleName, but fldContents remained undefined.

btw: Just to confirm my sanity (to myself, if no one else), I double-checked: The version I currently have deployed at the client still works with EXACTLY this code (I copied it and pasted it to a post on this forum). When the user changes a phone number and tabs out, that phone is formatted. I have it working on three phone numbers each on two tabpanels.

Cain:
… I tried hard-coding eleName, but fldContents remained undefined…

so these return different values?
var test1 = forms.xxxx.controller.getDataProvider(‘yyyy’)
var test2 = forms.xxxx.yyyy

No. What I mean is, I tried changing to

var eleName = 'phone_2';

and also

var fldContents = forms[frmName].controller.getDataProviderValue('phone_2'); 

Niether results in a good fldContents.

Have you tried running the method yourself? Are you getting a fldContents result?

please test, with xxxx and yyyy filled in.
var test1 = forms.xxxx.controller.getDataProvider(‘yyyy’)
var test2 = forms.xxxx.yyyy

OK.

var test1 = forms.companiesRecDev.controller.getDataProviderValue('phone3'); 
var test2 = forms.companiesRecDev.phone3;

… where ‘phone3’ is a phone number field element name on the form ‘companiesRecDev’.

In debugger, both variables remain ‘undefined’.

Also tried:

var test0 = forms.companiesRecDev.elements.phone3.getDataProviderID();
var test1 = forms.companiesRecDev.controller.getDataProviderValue(test0); 
var test2 = forms.companiesRecDev.phone3;

… and got a data provider name for the phone3 element (test0 = companies_to_phones3.phone_number), but test1 and test2 still remain undefined.

Cain:
In debugger, both variables remain ‘undefined’.

That means that the dataprovider (for example a column name) with the name ‘phone3’ does not exist!

Jan, that’s absolutely correct. ‘phone3’ is an ELEMENT name. That’s why I tried the second set of code.

‘companies_to_phones3.phone_number’ IS a DataProvider name, as returned by Servoy as the variable test0.

Could you please tell me what results you get when you run this code? I was only hard coding to ensure that the problem was in getting the fourth variable, fldContents. I’ve confirmed that this is the variable that no longer returns a value, as it did (and still does) in a previous version of my solution.

I can’t get…

forms.companiesRecDev.controller.getDataProviderValue(xxxx)

… to return a value with a literal string OR a variable, whether the dataprovider is in the form or related.

I’m back to thinking that syntax has changed or something in the latest version…

yes this is a regression.

getDataproviderValue only works for just the record itself currently, i will fix this ASAP.

So you can’t get a related value at once currently like this:

controller.getDataproviderValue(“relation.column”);

but you have other options:

var x = controller.getDataProviderValue(‘relation’)[‘column’];
var y = foundset.getRecord(foundset.getSelectedIndex())[‘relation.column’]
var z = foundset[‘relation’][‘column’]

Thanks, Johan. I’ll just hold off having my client go to 2.1.2 for now.

There isn’t another way to capture the relation used by a field, is there? So I’d have to hard code the relation name portion of the alternatives you listed?

currently you have to use:

foundset.getRecord(foundset.getSelectedIndex())[‘relation.column’]

instead of controller.getDataproviderValue(‘relation.column’);

i already fixed this for the next release.

Excellent! That works perfectly!

For anyone using this phone formatting, the first section of the code is below (with the old code commented out).

// gather information about where the user is and what s/he entered 
var eleName = application.getMethodTriggerElementName(); 
var frmName = application.getMethodTriggerFormName(); 
var fldName = forms[frmName].elements[eleName].getDataProviderID(); 
var fldContents = forms[frmName].foundset.getRecord(forms[frmName].foundset.getSelectedIndex())[fldName];
// var fldContents = forms[frmName].controller.getDataProviderValue(fldName); 
// exit if there's nothing in the field to format