4

I have a field called phone number which has values such as 0833888999 that I want to format as following 0833 888 999.

The answer that Rachana offered blew is true for few countries but not all countries.

Therefore, I am using this Google library to format contact numbers from different countries; however, the problem is that after persisting the contact numbers in database I can not search for them on database, for example the library would format contact numbers of different countries in different format, for example add space or "-" between them that makes hibernate unable to find them.

+18182223333 >>> +1 818-222-3333
+441135558888 >>> +44 113 555 8888

Hibernate

 .add(Restrictions.ilike("user.phone","+18182223333"); 
Community
  • 1
  • 1
Jack
  • 6,430
  • 27
  • 80
  • 151
  • Why do you think that users will like to see phones as formatted numbers, grouped by comma? – Roman C Jul 04 '14 at 07:24
  • @RomanC then do not want to see them with comma! they want to see them in groups. – Jack Jul 07 '14 at 00:41
  • What type is your phone number? Don't store formatted numbers. – Aleksandr M Jul 07 '14 at 07:54
  • @AleksandrM its type is phone number, I thought another option is to use the javascript code of the same library to format the values but if I show a list of these phone numbers it would take ages to do so. – Jack Jul 07 '14 at 11:48
  • @AleksandrM Sorry for the typo its type is String. – Jack Jul 08 '14 at 00:53

3 Answers3

3

Try this

<s:property value="getText('{0,number,0### ### ###}',{phone})"/>

Where,phone=0833888999

Hope this will help you also see Using Struts2 Tags to Formatting Numbers

you will get clear idea about number formatting

Community
  • 1
  • 1
rachana
  • 3,344
  • 7
  • 30
  • 49
2

I think you should keep the raw phone number (e.g. 0833888999) in the database and it's the View responsibility to format it accordingly.

You can have a separate table "country_phone_format" holding a country_id and a phone_format and you could fetch the phone_format as a @ManyToOne entity so that you have both the raw data and the format to properly display it into the View.

The PhoneFormat could be easily cached with the second level cache, as they should be rarely modified.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • the problem is that I should find a way to find the patterns of all international numbers around the world; however, in my case, I could delegate the task to Google. – Jack Jul 08 '14 at 05:57
  • 1
    Yes but once you found the pattern you could save it to DB, so the next time you won't have to access any external service, since you can rely on your own DB. – Vlad Mihalcea Jul 08 '14 at 06:02
  • I see, then how to find out what the pattern is, from the raw number and the formatted number? Moreover, in that case I do not need to keep the patterns in DB, I can pass all the numbers to Google to get them formatted; rather than keeping the patterns in DB and format them on my server. The problem of this approach is that if it is going to show a long list of results it affects the performance of the system, ex. list of 1000 users of the system along with their phone numbers. – Jack Jul 08 '14 at 06:46
  • 1
    Having the patterns in the db will guarantee a steady performance. Relying on google services incur a lot of networking overhead. And some services have a daily quota and too many requests might get you a ban. – Vlad Mihalcea Jul 08 '14 at 06:49
  • actually, it is not sending the requests to google server, I can use its library on my server. – Jack Jul 08 '14 at 06:52
  • Since the pattern is in db, you only need to store the raw number and the pattern reference (a FK) and that's it. When fetching your entity you join the pattern entity too to have both raw and pattern. Then a domain logic entity method will return the String value of the formatted phone number. – Vlad Mihalcea Jul 08 '14 at 06:52
  • I got you but imagine 1000 users are retrieved and the server needs to format them all. Even using the cached patterns it takes CPU time and memory to do the formattation. – Jack Jul 08 '14 at 06:54
  • 1
    Yes indeed. But you can configure the second level cache such a way that you never have to hit the DB for getting the patterns. Once everything is in memory, it's pretty fast. It's the DB and external services that will dictate your app performance and scalability. Formatting thousand of patterns is faster than retrieving a single entity from DB. You can test it out ;) – Vlad Mihalcea Jul 08 '14 at 07:02
2

Just as Vlad mentions, you should keep the raw phone number (e.g. 0833888999) in the database (or save it with the country and area code if you prefer) and leave th responsibility to format it accordingly to the View.

You can use Type Conversion to convert to/from the format you desire - and take advantage of the google library you mention. Something like the following can get you started (abbreviated just to get the gist of it):

public class MyConverter extends StrutsTypeConverter {
   public Object convertFromString(Map context, String[] values, Class toClass) {
      String phoneNr = values[0]
      MyPhoneObject phone = googleLibrary.doYourMagic(phoneNr);
      return phone;
   }

   public String convertToString(Map context, Object o) {
      googleLibrary.parseString( ((MyPhoneObject)o).rawPhoneNr() );
   }
}

Don't forget to register the converter in xwork-conversion.properties

my.PhoneObject=path.to.MyConverter
mmalmeida
  • 1,037
  • 9
  • 27