Home Message App – Templates

Message App – Templates

The following post was published at Iscaros Tizen Development Blog:
Hello everyone, today we will add a new feature in the message App. Now it will be possible to create template messages to send to your contacts.
Just as an example, imagine that you want to ask to Jim, Gary and Tom what are they doing. Usually you would create three different SMSs to send to them. But with this new feature you would create a template like this: “Hey, what are you doing tonight, <name> ?” and then  you add your friends and click send. The App will parse your message and send to each of your friends the following message:
Message to Jim – “Hey, what are you doing tonight, Jim?”
Message to Gary – “Hey, what are you doing tonight,  Gary?”
Message to Tom – “Hey, what are you doing tonight,  Tom?”
So let’s start!
 

  • HTML

As usual we will start with the HTML changes, because they are easier to understand.
In the main screen I added one button that will send you to the templates screen where you can manage your templates:
 

01 <div id="home" data-role="page">
02 <div data-role="header">
03 <center>
04 <h1>Messages</h1>
05 </center></div>
06 <!-- /header -->
07 <div data-role="content"></div>
08 <!-- /content -->
09 <div data-role="footer">
10 <div data-role="controlbar" data-style="tabbar">
11 <ul>
12     <li><a href="javascript:composeSMS();" data-icon="ctrlbar-compose">Compose SMS</a></li>
13     <li><a href="javascript:createTemplate();" data-icon="ctrlbar-chat">Templates</a></li>
14     <li><a href="javascript:aboutApp();" data-icon="ctrlbar-info">About</a></li>
15     <li><a href="javascript:exitApp();" data-icon="ctrlbar-close">Exit</a></li>
16 </ul>
17 </div>
18 <!-- /navbar --></div>
19 <!-- /footer --></div>
20
21 <!-- /page -->

 

The new link is at line 13.
In the message view I also added a link to the templates page, so I can add my templates to a SMS:

01 <div id="message_view" data-role="page">
02 <div data-role="header"></div>
03 <div id="content_sms" data-role="content">
04  <input id="contact_number" type="hidden" />
05
06  <input id="message_ready_to_sent" type="hidden" />
07 <div data-role="fieldcontain"><label for="sms_to_send">Message:</label>
08  <input id="sms_to_send" type="text" maxlength="160" /></div>
09 </div>
10 <div data-role="footer" data-position="fixed">
11 <div data-role="controlbar" data-style="toolbar">
12 <ul>
13     <li><a href="javascript:sendSMS();" data-icon="ctrlbar-share">Send</a></li>
14     <li><a href="javascript:useTemplate();" data-icon="ctrlbar-chat">Template</a></li>
15     <li><a id="add_contacts" style="visibility: hidden;" href="javascript:contactPopulate();"data-icon="ctrlbar-contacts">
16  Add Contact</a></li>
17 </ul>
18 </div>
19 </div>
20 </div>

 
The new link is at line 14.
Moving on to the template page. This is a simple page with a list to show all the templates and a button to create a new template.
 

01 <div id="templates_page" data-role="page">
02 <div data-role="header">
03 <h1>Templates</h1>
04 </div>
05 <div data-role="content">
06 <ul id="templates_list" data-role="listview" data-autodividers="alpha">
07     <li></li>
08 </ul>
09 </div>
10 <div data-role="footer" data-position="fixed">
11 <div data-role="controlbar" data-style="toolbar">
12 <ul>
13     <li><a href="javascript:createTemplatePage();" data-icon="ctrlbar-create">Create Template</a></li>
14 </ul>
15 </div>
16 </div>
17 </div>

 
And now the last page. Here we will create the template, save it, modify it, use it and delete it.
 

01 <div id="templates_create_page" data-role="page">
02 <div data-role="header">
03 <h1>New Template</h1>
04 </div>
05 <div data-role="content">
06
07  <label for="template_title_txt">Title:</label>
08  <input id="template_title_txt" type="text" />
09
10  <label for="template_content_txt">Content:</label>
11  <textarea id="template_content_txt" rows="20" cols="20"></textarea>
12
13  <a id="templete_delete_btn" style="visibility: hidden;" href="javascript:deleteTemplate();"data-icon="ctrlbar-share">Delete template</a>
14
15  <a id="templete_select_btn" style="visibility: hidden;" href="javascript:useTemplate();"data-icon="ctrlbar-share">Use this template</a></div>
16 <div data-role="footer" data-position="fixed">
17 <div data-role="controlbar" data-style="toolbar">
18 <ul>
19     <li><a href="javascript:saveTemplate();" data-icon="ctrlbar-save">Save</a></li>
20     <li><a href="javascript:cancelTemplate();" data-icon="ctrlbar-close">Cancel</a></li>
21 </ul>
22 </div>
23 </div>
24 </div>

 
And that’s all for the HTML.

  • Javascript

Because we are creating templates to send in the future we must store them somewhere. However we will not use the Tizen’s file system API to store the template. I will use a HTML5 Storage specification, basically it’s a persistent Hashmap. But if you want to read more about it, check here: http://www.w3.org/TR/webstorage/ And the reason that I’m not using the file system API it is because the HTML5 specification is much more suitable for our requirements.
To store values in the phone’s hard drive we will use localStorage.setItem(key, value), where key is going to be the template title and value the template’s content.
So let’s start.
Looking in the init function, we added some lines:
 

1 var init = function () {
2   templateToSendOrCreate = true;
3   indexPeopleToSend = 0;
4   peopleToSend = [];
5   loadContacts();
6   getSmsService();
7 }

 
The variable peopleToSend is an array that will store the contacts that we would like to send the SMS to, the indexPeopleToSend is the index of this array and templateToSendOrCreate is a flag that says if we are creating or sending a template.
In our home screen we have a button for the template page, this button will call the function createTemplate() and what createTemplate does is call the function templatePage with false as argument. So I will skip createTemplate and jump to templatePage():
 

01 function templatePage(sendOrCreate)
02 {
03   if(localStorage == null || typeof localStorage == "undefined")
04   {
05     alert('Templates not avaliable');
06     return;
07   }
08
09   templateToSendOrCreate = sendOrCreate;
10   $.mobile.changePage('#templates_page');
11   loadTemplates();
12 }

 
We first check if localStorage is available and of course it is, because Tizen has a recent WebKit implementation. However it’s a good practice to check if resources are available, then after this we call the function loadTemplates() to load the templates.
 

01 function loadTemplates()
02 {
03   var element = "";
04   var titleSafe;
05   var funcToCall;
06   $('#templates_list').html('');
07
08   if(templateToSendOrCreate == false)
09   {
10     funcToCall = 'setTemplateForMessage';
11   }
12   else
13   {
14     funcToCall = 'editTemplate';
15   }
16
17   for(var key in localStorage){
18     titleSafe = $('<div/>').text(key).html();
19     element = '<li>'
20     +'<a href="javascript:'+funcToCall+'(\''+$.trim(key.toString())+'\');">'+
21     '<span >'+
22     titleSafe+'</a></span></li>';
23
24     $('#templates_list').append(element);
25   }
26 }

 
Loading the templates is basically iterating over our localStorage variable and putting the key (the template title) in the list. But first we check from where we came from to know what function should I call if the user click on the item. If the user came from the compose SMS screen we will call setTemplateForMessage otherwise editTemplate.
Now let’s take a look in the function that actually saves our template:
 

01 function saveTemplate()
02 {
03   var title, content, id;
04
05   id = $.trim($('#template_id').val());
06   title = $.trim($('#template_title_txt').val());
07   content = $.trim($('textarea#template_content_txt').val());
08
09   if(title == null || title == "" || content == null ||
10      content == "")
11   {
12     alert('Enter the template information');
13     return;
14   }
15
16   if(id != title && id.length > 0) //updating
17   {
18     localStorage.removeItem(id);
19     localStorage.setItem(title, content); //save on the disk
20   else //new template
21     localStorage.setItem(title, content); //save on the disk
22   }
23
24   cleanTemplateInput();
25   history.go(-1); //back page
26   loadTemplates();
27 }

 
Before I save the template I make the check to see if the user is editing a template title. So I check the id with the possible new title if they are different it means the user changed the template’s title. Otherwise is a new template or the user is just editing the template’s content, so just save it.
Now to delete a template is even easier
 

1 function deleteTemplate()
2 {
3   localStorage.removeItem(templateIdUpdate);
4   cleanTemplateInput();
5   history.go(-1); //back page
6   loadTemplates();
7 }

 
Just retrieve the value from the tempalteIdUpdate variable and remove it.
Now I have two functions that their job are just put the template content in the screen to send the SMS or edit the template itself.
 

01 function setTemplateForMessage(id)
02 {
03   var templateContent;
04
05   if(typeof id == "undefined")
06   {
07     id = $('#template_id').val();
08   }
09
10   templateContent = $.trim(unescape(localStorage.getItem(id)));
11
12   templateToSendOrCreate = true;
13   $.mobile.changePage('#message_view');
14   $('#add_contacts').css('visibility''visible');
15
16   $('#sms_to_send').val(templateContent);
17
18 }

 
This function is called when the user wants to use the template in the SMS, so we just get its value and put in the message text box. And the last function is called when the user is going to edit a template.
 

01 function editTemplate(templateId)
02 {
03   var content;
04   $.mobile.changePage('#templates_create_page');
05   $('#templete_delete_btn').css('visibility''visible');
06   $('#templete_select_btn').css('visibility''visible');
07   templateIdUpdate = templateId;
08
09   content = localStorage.getItem(templateId);
10
11   $('#template_id').val($('<div/>').text(templateId).html());
12   $('#template_title_txt').val($('<div/>').text(templateId).html());
13   $('textarea#template_content_txt').val(unescape(content));
14
15 }

 
That’s all for template management.
Remenber that I said that the App would replace “<name>” with the contact name and send the SMS?
So to do this we use a very simple function:
 

1 function parseContent(content, name)
2 {
3   var contentToSend;
4
5   contentToSend = content.replace(//ig, name);
6
7   return contentToSend;
8 }

 
Also its possible to send SMSs to multiple contacts at once so I had to modify the functions composeSMS and sendSMS to support this. The changes are simple, lets start with composeSMS:
 

01 function composeSMS(contactId){
02
03   var contact,fistName,lastName;
04   var names = "";
05
06   $.mobile.changePage('#message_view');
07   $('#message_thread').html('');
08   $('#add_contacts').css('visibility''visible');
09
10   if(contactId != null){
11     contact = getContact(contactId);
12     lastName = contact.name.lastName;
13     firstName = contact.name.firstName;
14
15   if (lastName == null){
16     lastName = "";
17   }
18
19     peopleToSend.push([contactId,firstName + ' '+lastName]);
20
21     for(var i = 0; i < peopleToSend.length; i++){
22       names += peopleToSend[i][1]+',';
23     }
24
25     $('#contact_name').html('<h3>'+
26     $('<div/>').text( names ).html()+
27     '</h3>');
28 }else{
29   $('#contact_name').html('Select a contact');
30   }
31 }

 
What we modified here is the peopleToSend array, we are pushing the contactId and their names to be used in the sendSMS function. Doing this we are able to send SMS to as many contacts as we want !
Now our last function, sendSMS:
 

01 //Send the SMS to the recipients
02 function sendSMS(){
03   var msg,content;
04   var contact, contentToSend;
05   var phoneNumber;
06
07   if(peopleToSend.length == 0){
08     alert('Add a receipient');
09     return;
10   }
11
12   if(indexPeopleToSend >= peopleToSend.length){
13     indexPeopleToSend = 0;
14     peopleToSend = [];
15     $("#sms_to_send").val('');
16     return;
17   }
18
19   content = $('#sms_to_send').val();
20   //contact = getContact($('#contact_number').val());
21   contact = getContact(peopleToSend[indexPeopleToSend][0]);
22
23   //This means we don't have the contact in the list.
24   //We only have the phone number
25   if(contact != null){
26     phoneNumber = contact.phoneNumbers[0].number;
27   else {
28     phoneNumber = peopleToSend[indexPeopleToSend][0];
29   }
30
31   contentToSend = parseContent(content, peopleToSend[indexPeopleToSend][1]);
32
33   $('#message_ready_to_sent').val(contentToSend);
34
35   msg = new tizen.Message("messaging.sms", {plainBody:contentToSend,to:[phoneNumber]});
36
37   timeLastMsg = msg.timestamp.toLocaleDateString();
38
39   smsService.sendMessage(msg, messageSent, onError);
40 }

 
This part is interesting, because I had some problems when I tried to call smsService.sendMessage() over and over again inside a “for” loop. It seems it’s not safe to call this function until the callback was called.
So what I did is just call the function peopleToSend.length times. The messageSent callback is responsible to call the smsSend again and we use the variable indexPeopleToSend to control if we have to stop it or not. So let’s take a look the in the messageSent callback:
 

01 function messageSent(recipients) {
02
03   $('#message_thread').append('<li>'+
04   $('<div/>').text( $("#message_ready_to_sent").val() ).html()+
05   '<span>'+
06   timeLastMsg
07   +'</span></li>');
08
09   indexPeopleToSend++;
10   sendSMS();
11 }

 
See? I update the indexPeopleToSend and call the sendSMS again.
Take a look at the App:
 

 
Source Iscaro’s

About ReadWrite’s Editorial Process

The ReadWrite Editorial policy involves closely monitoring the tech industry for major developments, new product launches, AI breakthroughs, video game releases and other newsworthy events. Editors assign relevant stories to staff writers or freelance contributors with expertise in each particular topic area. Before publication, articles go through a rigorous round of editing for accuracy, clarity, and to ensure adherence to ReadWrite's style guidelines.

Get the biggest tech headlines of the day delivered to your inbox

    By signing up, you agree to our Terms and Privacy Policy. Unsubscribe anytime.

    Tech News

    Explore the latest in tech with our Tech News. We cut through the noise for concise, relevant updates, keeping you informed about the rapidly evolving tech landscape with curated content that separates signal from noise.

    In-Depth Tech Stories

    Explore tech impact in In-Depth Stories. Narrative data journalism offers comprehensive analyses, revealing stories behind data. Understand industry trends for a deeper perspective on tech's intricate relationships with society.

    Expert Reviews

    Empower decisions with Expert Reviews, merging industry expertise and insightful analysis. Delve into tech intricacies, get the best deals, and stay ahead with our trustworthy guide to navigating the ever-changing tech market.