Phone Numbers in Rails/MySQL

Is there any easy way to make a fancy looking form to take phone
numbers. Something that looks like this:

[ ] - [ ] - [ ] ext: [ ]

Then when you submit it it’s combined into one string in the database.

Optimally it would auto-switch from field-to-field after you fill each
field.

Has anyone seen anything like this in Rails?

Thanks,

Adam

On 4/20/06, Adam B. [email protected] wrote:

Is there any easy way to make a fancy looking form to take phone
numbers. Something that looks like this:

[ ] - [ ] - [ ] ext: [ ]

Then when you submit it it’s combined into one string in the database.

Optimally it would auto-switch from field-to-field after you fill each
field.

The better way of doing this is to have a single flat field in your
view,
then before it gets saved to the database, you strip the punctuation out
of
the number and verifies the required number of digits(for a single
country
site). Then, when you pull the number out of the db, you can add the
punctuation that you want.

No, I don’t know how to do the code for this atm, but that is the
general
idea.

Has anyone seen anything like this in Rails?

to me, it has nothing to do with the rails

you should create a javascript that observes fields, does not allow
anything
apart from number, jumps from one field to another and, upon submissing,
concatenates all number and save it into hidden field. This field then
can
be easily read by rails as regular param

Greetings Adam.

The multiple field solution can be painful for data entry, so I opt’d
for 2 fields - phone and extension. The following solution also
doesn’t force your users to format phone numbers in any special
manner. The normalization of the phones will also permit nice output
(for internalization) if required.

note this solution works for north american phone numbers (7 and 10
digit phone numbers).

The phone number is stored as a mysql bigint (which really speeds up
queries).

Then in your model,

To validate,

def validate
if errors.on(“phone”).nil?
validate_phone = self.phone_before_type_cast.gsub!(/[^0-9]/,"")
if !validate_phone.nil? and validate_phone.length != 7 and
validate_phone.length != 10
errors.add(“phone”, “number is not correct. Either a 7 or
10 digit phone # must be specified.”)
end
end

…and then these two methods will format the data after you retrieve
(after_find), and then strip away all non numerics (’(’, ‘)’, ‘-’,
etc) before saving.

protected
def after_find
self.phone = “#{self.phone_before_type_cast[0…2]}-#
{self.phone_before_type_cast[3…6]}” if !self.phone.nil? and
self.phone_before_type_cast.length == 7
self.phone = “(#{self.phone_before_type_cast[0…2]}) #
{self.phone_before_type_cast[3…5]}-#{self.phone_before_type_cast
[6…9]}” if !self.phone.nil? and self.phone_before_type_cast.length
== 10
end

def before_save
self.phone_before_type_cast.gsub!(/[^0-9]/,"") if !self.phone.nil?
end

hope this helps out. This technique can really help get clean data
into your model, without javascript complexities, and simplifies the
data entry, and normalizes the data such that outputting is simpler.

Jodi

Thanks Jodi, that helps a lot.

-Adam

The better way of doing this is to have a single flat field in your
view,
then before it gets saved to the database, you strip the punctuation out
of
the number and verifies the required number of digits(for a single
country
site). Then, when you pull the number out of the db, you can add the
punctuation that you want.

No, I don’t know how to do the code for this atm, but that is the
general
idea.

Has anyone seen anything like this in Rails?

Well, that would be a better way to do it for the programmer, but not
for the user. As a user it’s much more convenient to not have to wonder
whether you need to type "-"s or puts parens around the area code.

If we had to deal with international numbers you’re definitely right,
but this is purely a localized website.

-Adam

Rails Enthusiasts,

On Fri, Apr 21, 2006 at 06:34:03AM +0200, Adam B. wrote:

Well, that would be a better way to do it for the programmer, but not
for the user. As a user it’s much more convenient to not have to wonder
whether you need to type "-"s or puts parens around the area code.

Well, to make it easy for both the programmer and the user how about
masked
input fields? A while back I asked if Rails included such
functionality.
After getting no responses at all I searched the net for some JavaScript
functions that did what I was after. I include those scripts in my
standard
layout and added a couple of two line helper functions to my
helpers/application_helper.rb file and now masked input is as simple as:

<%= masked_text_field ‘user’, ‘phone’, ‘(###)###-####’ %>

or

<%= masked_auto_tab_text_field ‘user’, ‘phone’, ‘(###)###-####’ %>

The second variety jumps to the next field after the last digit of the
phone
number is entered. As the user types the phone number the punctuation
is
filled in automatically. Actually, I prefer using similar masked fields
for
date and time entry instead of select boxes.

For those interested my helper functions look something like:

def masked_text_field(object, method, mask, options = {})
options[“onKeyDown”] = “return dFilter(event.keyCode, this, '” +
mask + “');”
text_field(object, method, options)
end

def masked_auto_tab_text_field(object, method, mask, options = {})
options[“onKeyUp”] = "return autoTab(this, " +
mask.length.to_s + “, event);”
masked_text_field(object, method, mask, options)
end

The dFilter and autoTab scripts have a couple of quirks that I’m not
completely
happy with. I’m continuing to search for alternatives. Or, I might
just have
to brush up on my JavaScript and enhance the above scripts. With masked
input
and auto tab fields being so useful one would think such functionality
would be
included with Rails.

Kevin
http://www.RawFedDogs.net
http://www.WacoAgilityGroup.org
Bruceville, TX

Kevin,

This is probably a dumb question, but how do I get the dFilter and
autoTab scripts installed to use?

Thanks,

Adam

Nevermind. That was a really dumb question. :slight_smile:

However, it’s not currently working. :slight_smile: I get the automatic parens and
dashes, but there’s only one text field, and it tabs to the next field
(e-mail address) when I’ve typed 10 numbers.

Thanks Kevin! I realized right before I had to leave that it wasn’t
supposed to work the way I thought it did. :slight_smile:

-Adam

This is fantastic. You should submit this to http://script.aculo.us/ so
that it
would be included in Rails. Seriously, this is great stuff.

Brian

Adam,

On Fri, Apr 21, 2006 at 11:40:00PM +0200, Adam B. wrote:

Nevermind. That was a really dumb question. :slight_smile:

Actually I’ve often heard that the only dumb questions are the ones not
asked. I neglected to post links to the scripts because, as I said,
they
have a few quirks that I’m not completely happy with. In fact, I’ve
already
had to apply a couple of patches that I found in a JavaScript forum to
the
dFilter script. With the original script when one enters numbers via
the
numeric keypad they show up as letters instead of numbers. The first
patch
corrects that problem. The other patch keeps the mask characters from
showing up until one types past the spot where the mask characters
should
be. I’m not completely happy with that patch. I think the mask
charcters
should be showing up one keystroke sooner than they are. If you would
like
to try the script with the patches I mentioned above applied you can get
the
patched version at:

http://www.RawFedDogs.net/MaskAutoTab.tgz

I put both the dFilter and autoTab scripts in the archive, although I
haven’t
made any changes to the autoTab script.

However, it’s not currently working. :slight_smile:

Are you sure?

I get the automatic parens and dashes, but there’s only one text field,
and it tabs to the next field (e-mail address) when I’ve typed 10 numbers.

It sounds like it’s working to me. That’s exactly what it’s supposed to
do.
The masked input script doesn’t create separate entry fields for the
various
parts of a phone number, date, etc. All parts of the phone number,
date, etc.,
are entered into one field and the script fills in the mask characters
in the
appropriate spots. For example, for a date entry field one could use:

<%= masked_auto_tab_text_field ‘event’, ‘start_date’, ‘##/##/####’ %>

That would create one field. A user could enter:

04212006

and it would appear in the field as:

04/21/2006

The user didn’t have to type the slashes, only the numbers.

If you want to have separate fields you could use the autoTab script by
itself. Perhaps a helper similar to:

def auto_tab_text_field(object, method, length, options = {})
options[“onKeyUp”] = "return autoTab(this, " +
length.to_s + “, event);”
options[“size”] = length.to_s
text_field(object, method, options)
end

then in your template(using a phone number as an example):

Phone Number: (<%= auto_tab_text_field ‘phone’, ‘area_code’, 3 -%>
)<%= auto_tab_text_field ‘phone’, ‘exchange’, 3 -%>
-<%= auto_tab_text_field ‘phone’, ‘number’, 4 %>

might achieve what you’re looking for. Of course, as others have said,
you
would then have to piece the phone number together from the three form
fields. Personally I prefer using a single field. That’s one of the
things
I’m really beginning to appreciate about Rails. It’s so easy to add
form
helpers and make forms work just the way I want them to work, while
keeping
my templates neat and tidy.

Kevin
http://www.RawFedDogs.net
http://www.WacoAgilityGroup.org
Bruceville, TX