RSS Feed

Message App – Templates.

Posted on

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:

<div id="home" data-role="page">
<div data-role="header">
<center>
<h1>Messages</h1>
</center></div>
<!-- /header -->
<div data-role="content"></div>
<!-- /content -->
<div data-role="footer">
<div data-role="controlbar" data-style="tabbar">
<ul>
	<li><a href="javascript:composeSMS();" data-icon="ctrlbar-compose">Compose SMS</a></li>
	<li><a href="javascript:createTemplate();" data-icon="ctrlbar-chat">Templates</a></li>
	<li><a href="javascript:aboutApp();" data-icon="ctrlbar-info">About</a></li>
	<li><a href="javascript:exitApp();" data-icon="ctrlbar-close">Exit</a></li>
</ul>
</div>
<!-- /navbar --></div>
<!-- /footer --></div>

<!-- /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:

<div id="message_view" data-role="page">
<div data-role="header"></div>
<div id="content_sms" data-role="content">
 <input id="contact_number" type="hidden" />

 <input id="message_ready_to_sent" type="hidden" />
<div data-role="fieldcontain"><label for="sms_to_send">Message:</label>
 <input id="sms_to_send" type="text" maxlength="160" /></div>
</div>
<div data-role="footer" data-position="fixed">
<div data-role="controlbar" data-style="toolbar">
<ul>
	<li><a href="javascript:sendSMS();" data-icon="ctrlbar-share">Send</a></li>
	<li><a href="javascript:useTemplate();" data-icon="ctrlbar-chat">Template</a></li>
	<li><a id="add_contacts" style="visibility: hidden;" href="javascript:contactPopulate();" data-icon="ctrlbar-contacts">
 Add Contact</a></li>
</ul>
</div>
</div>
</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.

<div id="templates_page" data-role="page">
<div data-role="header">
<h1>Templates</h1>
</div>
<div data-role="content">
<ul id="templates_list" data-role="listview" data-autodividers="alpha">
	<li></li>
</ul>
</div>
<div data-role="footer" data-position="fixed">
<div data-role="controlbar" data-style="toolbar">
<ul>
	<li><a href="javascript:createTemplatePage();" data-icon="ctrlbar-create">Create Template</a></li>
</ul>
</div>
</div>
</div>

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

<div id="templates_create_page" data-role="page">
<div data-role="header">
<h1>New Template</h1>
</div>
<div data-role="content">

 <label for="template_title_txt">Title:</label>
 <input id="template_title_txt" type="text" />

 <label for="template_content_txt">Content:</label>
 <textarea id="template_content_txt" rows="20" cols="20"></textarea>

 <a id="templete_delete_btn" style="visibility: hidden;" href="javascript:deleteTemplate();" data-icon="ctrlbar-share">Delete template</a>

 <a id="templete_select_btn" style="visibility: hidden;" href="javascript:useTemplate();" data-icon="ctrlbar-share">Use this template</a></div>
<div data-role="footer" data-position="fixed">
<div data-role="controlbar" data-style="toolbar">
<ul>
	<li><a href="javascript:saveTemplate();" data-icon="ctrlbar-save">Save</a></li>
	<li><a href="javascript:cancelTemplate();" data-icon="ctrlbar-close">Cancel</a></li>
</ul>
</div>
</div>
</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:


var init = function () {
  templateToSendOrCreate = true;
  indexPeopleToSend = 0;
  peopleToSend = [];
  loadContacts();
  getSmsService();
}

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():

function templatePage(sendOrCreate)
{
  if(localStorage == null || typeof localStorage == "undefined")
  {
    alert('Templates not avaliable');
    return;
  }

  templateToSendOrCreate = sendOrCreate;
  $.mobile.changePage('#templates_page');
  loadTemplates();
}

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.

function loadTemplates()
{
  var element = "";
  var titleSafe;
  var funcToCall;
  $('#templates_list').html('');

  if(templateToSendOrCreate == false)
  {
    funcToCall = 'setTemplateForMessage';
  }
  else
  {
    funcToCall = 'editTemplate';
  }

  for(var key in localStorage){
    titleSafe = $('<div/>').text(key).html();
    element = '<li>'
    +'<a href="javascript:'+funcToCall+'(\''+$.trim(key.toString())+'\');">'+
    '<span >'+
    titleSafe+'</a></span></li>';

    $('#templates_list').append(element);
  }
}

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:

function saveTemplate()
{
  var title, content, id;

  id = $.trim($('#template_id').val());
  title = $.trim($('#template_title_txt').val());
  content = $.trim($('textarea#template_content_txt').val());

  if(title == null || title == "" || content == null ||
     content == "")
  {
    alert('Enter the template information');
    return;
  }

  if(id != title && id.length > 0) //updating
  {
    localStorage.removeItem(id);
    localStorage.setItem(title, content); //save on the disk
  } else { //new template
    localStorage.setItem(title, content); //save on the disk
  }

  cleanTemplateInput();
  history.go(-1); //back page
  loadTemplates();
}

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

function deleteTemplate()
{
  localStorage.removeItem(templateIdUpdate);
  cleanTemplateInput();
  history.go(-1); //back page
  loadTemplates();
}

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.

function setTemplateForMessage(id)
{
  var templateContent;

  if(typeof id == "undefined")
  {
    id = $('#template_id').val();
  }

  templateContent = $.trim(unescape(localStorage.getItem(id)));

  templateToSendOrCreate = true;
  $.mobile.changePage('#message_view');
  $('#add_contacts').css('visibility', 'visible');

  $('#sms_to_send').val(templateContent);

}

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.

function editTemplate(templateId)
{
  var content;
  $.mobile.changePage('#templates_create_page');
  $('#templete_delete_btn').css('visibility', 'visible');
  $('#templete_select_btn').css('visibility', 'visible');
  templateIdUpdate = templateId;

  content = localStorage.getItem(templateId);

  $('#template_id').val($('<div/>').text(templateId).html());
  $('#template_title_txt').val($('<div/>').text(templateId).html());
  $('textarea#template_content_txt').val(unescape(content));

}

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:

function parseContent(content, name)
{
  var contentToSend;

  contentToSend = content.replace(//ig, name);

  return contentToSend;
}

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:

function composeSMS(contactId){

  var contact,fistName,lastName;
  var names = "";

  $.mobile.changePage('#message_view');
  $('#message_thread').html('');
  $('#add_contacts').css('visibility', 'visible');

  if(contactId != null){
    contact = getContact(contactId);
    lastName = contact.name.lastName;
    firstName = contact.name.firstName;

  if (lastName == null){
    lastName = "";
  }

    peopleToSend.push([contactId,firstName + ' '+lastName]);

    for(var i = 0; i < peopleToSend.length; i++){
      names += peopleToSend[i][1]+',';
    }

    $('#contact_name').html('<h3>'+
    $('<div/>').text( names ).html()+
    '</h3>');
}else{
  $('#contact_name').html('Select a contact');
  }
}

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:

//Send the SMS to the recipients
function sendSMS(){
  var msg,content;
  var contact, contentToSend;
  var phoneNumber;

  if(peopleToSend.length == 0){
    alert('Add a receipient');
    return;
  }

  if(indexPeopleToSend >= peopleToSend.length){
    indexPeopleToSend = 0;
    peopleToSend = [];
    $("#sms_to_send").val('');
    return;
  }

  content = $('#sms_to_send').val();
  //contact = getContact($('#contact_number').val());
  contact = getContact(peopleToSend[indexPeopleToSend][0]);

  //This means we don't have the contact in the list.
  //We only have the phone number
  if(contact != null){
    phoneNumber = contact.phoneNumbers[0].number;
  } else {
    phoneNumber = peopleToSend[indexPeopleToSend][0];
  }

  contentToSend = parseContent(content, peopleToSend[indexPeopleToSend][1]);

  $('#message_ready_to_sent').val(contentToSend);

  msg = new tizen.Message("messaging.sms", {plainBody:contentToSend,to:[phoneNumber]});

  timeLastMsg = msg.timestamp.toLocaleDateString();

  smsService.sendMessage(msg, messageSent, onError);
}

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:

function messageSent(recipients) {

  $('#message_thread').append('<li>'+
  $('<div/>').text( $("#message_ready_to_sent").val() ).html()+
  '<span>'+
  timeLastMsg
  +'</span></li>');

  indexPeopleToSend++;
  sendSMS();
}

See? I update the indexPeopleToSend and call the sendSMS again.

Take a look at the App:

Well, this is all for now.

Don’t forget that you can check the code here: http://git.profusion.mobi/cgit.cgi/iscaro/FirstApp/

Advertisements

One response »

  1. Pingback: Message App – Templates

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: