Skip to content

February 10, 2012

1

Deal with contacts cross-platform (part 2)

by nady

Welcome! This is the second part on a tutorial that shows you how to use mobile phone contact lists with PhoneGap. You can find the first part of this tutorial at Deal with contacts cross-platform (part 1).

We will cover with this tutorial:

  • the use of jQuery Mobile form elements
  • how to add, edit and delete a contact from the device

Final result:

use mobile phone contact lists with phonegap

Download Sources

Before we get into functionality, let’s make a view for our individual contacts using form elements from jQuery Mobile framework.
In index.html add an id="home" to the page and an Add button to the header.

[html]
<div data-role="page" id="home">
<div data-role="header" data-position="fixed">
<h1>DigitalNoiz</h1>
<a href="#contact" data-icon="plus" data-transition="slideup" class="ui-btn-right">Add</a>
</div>
<div data-role="content">
<h2>Contacts List</h2>
<ul id="allContacts" data-role="listview" data-filter="true" data-inset="true"></ul>
</div>
</div>
[/html]

Now add a second page with id="contact" and buttons Save and Delete into header.
To be able to see the changes in the contact page, open js/script.js and add into onDeviceReady function $.mobile.changePage( $('#contact') );

[html]
<div data-role="page" id="contact">
<div data-role="header" data-position="fixed">
<a href="#" id="save" data-icon="check">Save</a>
<h1>Contact</h1>
<a href="#" id="delete" data-icon="delete">Delete</a>
</div>
<div data-role="content">
<form id="formContact" action="#" method="post">

</form>
</div>
</div>
[/html]

All forms should have a <form> tag with an action and an method attribute.
When the action attribute is pointing to an php file on the server, the obtained data will be brought into DOM with AJAX. All the form elements must be paired with a meaningful label to make them more accessible.

[html]
<label for="givenName">First Name:</label>
<input type="text" name="givenName" id="givenName" placeholder="First Name" />
[/html]

To hide the label and adjust the layout accordingly use a field container with class="ui-hide-label"

[html]
<div data-role="fieldcontain" class="ui-hide-label">
<label for="givenName">First Name:</label>
<input type="text" name="givenName" id="givenName" placeholder="First Name" />
</div>
[/html]

Let’s add some more fields that we’ll use to describe the contact using the appropriate input type.

[html]
<div data-role="fieldcontain" class="ui-hide-label">
<label for="familyName">Last Name:</label>
<input type="text" name="familyName" id="familyName" placeholder="Last Name" />
</div>
<div data-role="fieldcontain" class="ui-hide-label">
<label for="phone">Phone:</label>
<input type="tel" name="phone" id="phone" placeholder="Phone" />
</div>
<div data-role="fieldcontain" class="ui-hide-label">
<label for="email">Email:</label>
<input type="email" name="email" id="email" placeholder="Email" />
</div>
[/html]

To illustrate more features of the form elements we add some more fields that will not be saved into the device database, you can store this information into your own database if you want.
Vertically grouped radio buttons, use a fieldset with data-role="controlgroup" to group them.

[html]
<p>This information won’t be saved into device:</p>
<!– radio buttons –>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Gender:</legend>
<input type="radio" name="gender" id="male" value="male" />
<label for="male">Male</label>

<input type="radio" name="gender" id="female" value="female" />
<label for="female">Female</label>
</fieldset>
</div>
[/html]

Radio buttons can also be grouped horizontal by using data-type="horizontal".

[html]
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>Loves animals:</legend>
<input type="radio" name="animals" id="la_yes" value="yes" />
<label for="la_yes">Yes</label>

<input type="radio" name="animals" id="la_no" value="no" />
<label for="la_no">No</label>
</fieldset>
</div>
[/html]

The same applies for checkbox buttons.

[html]
<!– checkboxes –>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Qualities:</legend>
<input type="checkbox" name="sincerity" id="sincerity" value="sincerity" />
<label for="sincerity">Sincerity</label>

<input type="checkbox" name="honest" id="honest" value="honest" />
<label for="honest">Honest</label>

<input type="checkbox" name="altruism" id="altruism" value="altruism" />
<label for="altruism">Altruism</label>

<input type="checkbox" name="empaty" id="empaty" value="empaty" />
<label for="empaty">Empaty</label>
</fieldset>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal">
<legend>Has a:</legend>
<input type="checkbox" name="has_home" id="has_home" value="home" />
<label for="has_home">Home</label>

<input type="checkbox" name="has_car" id="has_car" value="car" />
<label for="has_car">Car</label>

<input type="checkbox" name="has_job" id="has_job" value="job" />
<label for="has_job">Job</label>
</fieldset>
</div>
[/html]

A common UI element that is used on mobile devices is a flip toggle switch that is used to switch between values like on/off, yes/no or true/false . Use a <select> tag with attribute data-role="slider" and two options.

[html]
<!– flip toggle switch –>
<div data-role="fieldcontain">
<label for="flip">Keep in touch:</label>
<select name="flip" id="flip" data-role="slider">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
[/html]

Select menus use a custom styled select button and by default it uses the native OS menu to make a selection. If you don’t want to use the native interface, but use the custom select menu from jQuery Mobile instead, add attribute data-native-menu="false". To be able to select multiple values at once add attribute multiple.

[html]
<!– select menu –>
<div data-role="fieldcontain">
<label for="custom_select">Select Group:</label>
<select name="custom_select" id="custom_select" data-native-menu="false" multiple>
<option value="friend">Friend</option>
<option value="relative">Relative</option>
<option value="colleague">Colleague</option>
<option value="enemy">Enemy</option>
</select>
</div>
[/html]

It’s time to make this form work.
Open css/style.css and hide the delete button.

[css]
#delete{
display:none;
}
[/css]

Open js/script.js and remove $.mobile.changePage( $('#contact') ); from onDeviceReady function to load the home page first
When a list item is clicked retrieve the corresponding information and populate the form fields with it.

[js]
// Phonegap is loaded and can be used
function onDeviceReady(){
getContacts();
//$.mobile.changePage( $(‘#contact’) );

// get contact details
$(‘#home li a’).live(‘click’,function(){
var name = $(this).text();
getContact(name);
});
}

/* get a contact */
function getContact(name){
var optFilter = new ContactFindOptions();
optFilter.filter = $.trim(name); // remove unwanted spaces
fields = ["name", "phoneNumbers", "emails"];
console.log(optFilter.filter);
// get contact
navigator.contacts.find(fields, function(contacts){// get contact success
if( contacts.length != 0 ){
var contact = contacts[0];
if( contact.name.givenName ) var givenName = contact.name.givenName;
if( contact.name.familyName ) var familyName = contact.name.familyName;
if( contact.phoneNumbers) var phone = contact.phoneNumbers[0].value;
if( contact.emails ) var email = contact.emails[0].value;
// fill form fields
if( givenName ) $(‘#givenName’).val(givenName);
if( familyName ) $(‘#familyName’).val(familyName);
if( phone ) $(‘#phone’).val(phone);
if( email ) $(‘#email’).val(email);

$(‘#delete’).show();
$.mobile.changePage( $(‘#contact’) ); // show contact page
globalContact = contact;
} else navigator.notification.alert(‘no contact returned’);
}, function(contactError){// get contact error
navigator.notification.alert(‘get contact error’);
}, optFilter);
}
[/js]

We need a global variable to hold the current Contact object, add var globalContact = null; at the beginning of the script.
Create saveContact function to save or update a Contact object .

[js]
// save the global contact
function saveContact(){
if( globalContact ){
globalContact.save(function(contact){ // on save success
getContacts();
$.mobile.changePage( $(‘#home’) ); // return to home page
$(‘#formContact’)[0].reset(); // reset form fields
$(‘#delete’).hide();
globalContact = null;
}, function(contactError){ // on save error
navigator.notification.alert(‘error: ‘+contactError.code);
});
}
}
[/js]

Contact methods:

save – saves a new contact into the device database or updates a contact if a contact with the same id already exists
remove – removes the contact from the device database
clone – returns a new Contact object that is a copy of the calling object with the id set to null

Create deleteContact function to delete an existing contact.

[js]
/* delete a contact */
function deleteContact(){
if( globalContact ){
globalContact.remove(function(contact){ // on remove success
getContacts();
$.mobile.changePage( $(‘#home’) ); // return to home page
$(‘#formContact’)[0].reset(); // reset form fields
$(‘#delete’).hide();
globalContact = null;
}, function(contactError){ // on remove error
navigator.notification.alert(‘error: ‘+contactError.code);
});
}
}
[/js]

When the Delete button is clicked run function deleteContact(), add the following code into onDeviceReady.

[js]
$(‘#delete’).click(function(){
deleteContact();
});
[/js]

To add a new contact get the values from the form fields, the First Name, Last Name, Phone and Email, use navigator.contacts.create() to create a new Contact object, populate it with the values, assign the new contact to globalContact variable and saveContact().

[js]
/* add new contact */
function addContact(){
var givenName = $(‘#givenName’).val();
var familyName = $(‘#familyName’).val();
var phone = $(‘#phone’).val();
var email = $(‘#email’).val();

var newContact = navigator.contacts.create();
// add name
newContact.name = new ContactName();
if( givenName ) newContact.name.givenName = givenName;
if( familyName ) newContact.name.familyName = familyName;
// add phone number
if( phone ) {
newContact.phoneNumbers = new Array();
newContact.phoneNumbers.push( new ContactField(‘mobile’, phone, true) );
}
// add email
if( email ) {
newContact.emails = new Array();
newContact.emails.push( new ContactField(‘home’, email, true) );
}

// save contact on device
globalContact = newContact;
saveContact();
}
[/js]

To edit an existing contact get the values from the form field and overwrite them with the values from globalContact, where global contact should be the contact you are viewing, then saveContact() to update the existing contact information.

[js]
/* edit a contact */
function editContact(){
if( globalContact ){
var givenName = $(‘#givenName’).val();
var familyName = $(‘#familyName’).val();
var phone = $(‘#phone’).val();
var email = $(‘#email’).val();

if( givenName ) globalContact.name.givenName = givenName;
if( familyName ) globalContact.name.familyName = familyName;
// add phone number
if( phone ) {
globalContact.phoneNumbers = new Array();
globalContact.phoneNumbers.push( new ContactField(‘mobile’, phone, true) );
}
// add email
if( email ) {
globalContact.emails = new Array();
globalContact.emails.push( new ContactField(‘home’, email, true) );
}
}
saveContact();
}
[/js]

When the save button is clicked, in order to know if it should add a new contact or it should update an existing one, test if the delete button is visible. The delete button is visible only after getContact function runs.

[js]
$(‘#save’).click(function(){
if( $(‘#delete’).is(‘:visible’) ){ // edit
editContact();
} else addContact(); // add
});
[/js]

Now this mini mobile application is complete. The topic was on how to use mobile phone contact lists with phonegap.

Accessing contacts can help you to create rich mobile apps that integrate your contacts with social networking features or apps that uses your phone book list to implement messaging features. The possibility are up to your imagination. Hope you can benefit from this tutorial on how to use mobile phone contact lists with phonegap!

Read more from Mobile
1 Comment Post a comment
  1. Aakash
    May 13 2012

    Hi,

    I used the code source but the contacts are not listed in the app. can u help pls.

    Regards,
    Aakash

    Reply

Leave a Reply

required
required

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments