You are viewing limited content. For full access, please sign in.

Question

Question

Phone number format using JS in Forms 11 update 3?

asked on February 1, 2023 Show version history

Normally I would use the following JS to format a phone number field:

$(document).ready(function () {
$.getScript('https://xxx.com/Forms/js/jquery.mask.min.js', function () {
$(".phone input").mask("(999)999-9999");
});
});

Forms 11 update 3 now allows JS, and I've reviewed the information about using JS in the new forms designer, but I'm not sure how I would need to modify the above JS to work with the new forms designer.

Any advice on how to do this?

Thanks.

 

0 0

Answer

SELECTED ANSWER
replied on February 2, 2023

jquery.mask.min.js can no longer be used as new form designer doesn't use JQuery.  You can write  your own phoneMask function similar as following and call it when need:

function phoneMask (phone) {
  return phone.replace(/\D/g, '')
    .replace(/^(\d)/, '($1')
    .replace(/^(\(\d{3})(\d)/, '$1) $2')
    .replace(/(\d{3})(\d{1,5})/, '$1-$2')
    .replace(/(-\d{4})\d+?$/, '$1');
}

LFForm.onFieldBlur(function(){ LFForm.setFieldValues({fieldId: 2}, phoneMask(LFForm.getFieldValues({fieldId: 2}))) }, {fieldId: 2})

You can also put some common used functions in a separate JS file and add the URL for the file in the external URL and call the functions from inline JavaScript.

Take the above one for example, you can put following pieces of code in the JS file and the URL to access the file is https://xxx.laserfiche.com/Forms/js/mask.js

function phoneMask (phone) {
  return phone.replace(/\D/g, '')
    .replace(/^(\d)/, '($1')
    .replace(/^(\(\d{3})(\d)/, '$1) $2')
    .replace(/(\d{3})(\d{1,5})/, '$1-$2')
    .replace(/(-\d{4})\d+?$/, '$1');
}

You add the URL in the external tab of JavaScript for the form

and call the function from Inline JavaScript with following piece of code:

LFForm.onFieldBlur(function(){ LFForm.setFieldValues({fieldId: 2}, phoneMask(LFForm.getFieldValues({fieldId: 2}))) }, {fieldId: 2})

 

5 0
replied on February 3, 2023

Wow!  Great solution!

0 0
replied on February 3, 2023 Show version history

That works really well.  Is there a way to reference a CSS class instead of a field ID?

 

Edit:  Is there anything special I need to do if the field is in a table?  It seems to work fine except in that situation.

 

0 0
replied on February 5, 2023

Hi Mike,

 

The built-in api provided in new form designer cannot accept the CSS class as parameter, so it can only be done with field ID, you may write your own code to realize it.

 

The setFieldValues and getFieldValues methods are both supported for fields in Collection/Table, in this post https://doc.laserfiche.com/laserfiche.documentation/11/administration/en-us/Default.htm#../Subsystems/Forms/Content/Javascript-and-CSS/JavaScript-in-the-Forms-Designer.htm%3FTocPath%3DForms%7CCreating%2520a%2520Form%7C_____9  it has some examples to illustrate, e.g.:

  1. For a repeatable field with 3 rows, where each row has a single line with fieldID: 10 and row values are: row 1, value "a"; row 2, value "b"; and row 3, value "c":
    • LFForm.getFieldValues({fieldId: 10}) will return ["a", "b", "c"].
    • LFForm.getFieldValues({fieldId: 10, index: 0) will return "a".
0 0
replied on February 6, 2023

I am uncertain how to proceed from here. The documentation suggests that the method is identical for a single field or a field in a table:

The following should work to set the values in each row of the table but it's not working:

LFForm.onFieldBlur(function()
 { LFForm.setFieldValues({fieldId: 76}, 
   phoneMask(LFForm.getFieldValues({fieldId: 76}))) }, {fieldId: 76})

 

This is something I will need to learn more about.

0 0
replied on February 6, 2023

The problem is, with a table, you are now passing an array of values into the phoneMask function:   phoneMask(LFForm.getFieldValues({fieldId: 76}))

So you need to either modify the function to handle an array.  Or you need to work through each value in the array and send each one to the function.

Here's what the latter will look like, taking the array of values and passing each one into the function: 

function phoneMask (phone) {
  return phone.replace(/\D/g, '')
    .replace(/^(\d)/, '($1')
    .replace(/^(\(\d{3})(\d)/, '$1) $2')
    .replace(/(\d{3})(\d{1,5})/, '$1-$2')
    .replace(/(-\d{4})\d+?$/, '$1');
}

LFForm.onFieldBlur(function(){ 
  var updatedValues = LFForm.getFieldValues({fieldId: 76});
  updatedValues.forEach(function(part, index) {
    this[index] = phoneMask(this[index]);
  }, updatedValues);
  LFForm.setFieldValues({fieldId: 76}, updatedValues );
  }, {fieldId: 76});

 

3 0
replied on February 6, 2023

Thanks Matthew, that was very helpful and it works like a charm.

 

1 0
replied on February 6, 2023

You're quite welcome.

0 0
replied on February 14, 2023 Show version history

You actually can use CSS class as parameter, we have updated the help document to include sample for findFieldsByClassName(className). 

3 0
replied on August 17, 2023

I tried using findFieldsByClassName and it's not working, does anyone see where I went wrong?

Also I was thinking that because the form in then end would have multiple fields with the same class name that maybe I should be trying to modify Matthew's code but I was not able to get that working either. 

 


function phoneMask (phone) {
  return phone.replace(/\D/g, '')
    .replace(/^(\d)/, '($1')
    .replace(/^(\(\d{3})(\d)/, '$1) $2')
    .replace(/(\d{3})(\d{1,5})/, '$1-$2')
    .replace(/(-\d{4})\d+?$/, '$1');
}



LFForm.onFieldBlur(function(){ LFForm.setFieldValues(LFForm.findFieldsByClassName('phoneMask'), phoneMask(LFForm.getFieldValues(LFForm.findFieldsByClassName('phoneMask')))) }, LFForm.findFieldsByClassName('phoneMask'))

 

0 0
replied on August 17, 2023

This:   LFForm.findFieldsByClassName('phoneMask')   is going to return an array of values - all of the objects that have the phoneMask class.

Therefore this:     LFForm.getFieldValues(LFForm.findFieldsByClassName('phoneMask'))     is also going to return an array of values - the list of values from that list of objects.

Then you are doing this:     phoneMask(LFForm.getFieldValues(LFForm.findFieldsByClassName('phoneMask')))     and you are passing that array of values into the phoneMask function - and that function is expecting a single value, not an array of values - so it breaks.

If you only have one field with the phoneMask class, then you could append [0] to the end of the findFieldsByClassName call to tell it just to return the first object that it finds:     LFForm.findFieldsByClassName('phoneMask')[0]

But if you have multiple fields with that class, your code is going to need some modification in order to loop through each field and pass its specific value into the phoneMask function.

1 0

Replies

replied on February 1, 2023

The Javascript functionality within the Modern Designer runs within a sandboxed iFrame so it is separate from the structure of the form itself.  The effect is that the code within the iFrame, that you are writing, cannot impact the form itself except by using the options included in the LFForm object.  They are basically separate windows.  Since this isn't something that appears to be included in the LFForm object, you won't be able to do it on the Modern designer.

My suggestion is to continue to use the Classic designer for forms where this is important, or check to see if using the Regular Expression option on the fields in the Modern designer will meet your needs.

1 0
replied on February 1, 2023

Hi Matthew; thanks for the feedback. 

I hope field masking is something that LF can implement in a future update.  RegEx is good for validation, but it's simply not a solution when we need a field to be masked.

Thanks,

Mike

 

 

4 0
replied on February 1, 2023

I agree!

2 0
You are not allowed to follow up in this post.

Sign in to reply to this post.