Contacts

The contacts plugin provides access to the device's contacts database in order to find and create contacts. In order to use the contacts plugin in our Apache Cordova project, we need to use the following cordova plugin add command:

> cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git

Demo

In order to access the contacts demo, you can click on the Contacts list item. You will be introduced to the Contacts page. You can search for contacts by typing in the search field (you have to type at least three characters), as shown in the following screenshot:

Demo

Searching for contacts

You can click on any of the filtered contacts, and you will be introduced to the Contact Details page in order to check the contact details, as shown in the following screenshot:

Demo

Viewing contact details

The HTML page

The following code snippet shows the "contacts" page:

<div data-role="page" id="contacts">
    <div data-role="header">
        <h1>Contacts</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <ul data-role="listview" id="contactList" data-filter="true" data-filter-placeholder="Enter 3+ chars to search ...">
        </ul>
    </div>
</div>

As shown in the preceding "contacts" page code snippet, it contains the following:

  • A page header that includes a back button.
  • Page content that includes a jQuery Mobile list view element ("contactList") that is defined by setting the data-role attribute to "listview". Setting the data-filter attribute to true tells jQuery Mobile to provide a search field for our list view. Finally, the placeholder attribute informs the user to enter at least three characters in order to search for contacts.

When the user clicks on any of the filtered contacts, the user will be introduced to the "contactDetails" page. The following code snippet shows the "contactDetails" page:

<div data-role="page" id="contactDetails">
    <div data-role="header">
        <h1>Contact Details</h1>
        <a href="#" data-role="button" data-rel="back" data-icon="back">Back</a>
    </div>
    <div data-role="content">
        <div id="contactInfo"></div>
    </div>
</div>

As shown in the preceding "contact details" page code snippet, it contains the following:

  • A page header that includes a back button
  • Page content that includes a "contactInfo" div to display information on contact details

View controller

The following code snippet shows the contacts page view controller JavaScript object that includes the event handlers of the page (contacts.js):

(function() {
    var contactsManager = ContactsManager.getInstance();

    $(document).on("pageinit", "#contacts", function(e) {
        e.preventDefault();

        $("#contactList").on("filterablebeforefilter", function (e, data) {
            e.preventDefault();
    
            var filterText = data.input.val();

            if (filterText && filterText.length > 2) {
                var callback = {};

                callback.onSuccess = function (contacts) {
                    updateContactsList(contacts);
                };

                callback.onError = function (error) {       
                    $("#contactList").empty();
                    $("<li>Error displaying contacts</li>").appendTo("#contactList");
                };        

                contactsManager.getAllContacts(callback, filterText);
            }
        });
    });    

    function updateContactsList(contacts) {
        $("#contactList").empty();

        if (jQuery.isEmptyObject(contacts)) {
            $("<li>No Contacts Available</li>").appendTo("#contactList");
        } else {
            var i;

            //Display the top 50 elements
            for (i = 0; i < contacts.length || i < 50; ++i) {
                if (contacts[i]) {
                    $("<li><a href='#contactDetails?contact=" + encodeURIComponent(JSON.stringify(contacts[i])) + "'>" + 
                            contacts[i].name.formatted + "</a></li>").appendTo("#contactList");
                }
            }
        }

        $("#contactList").listview('refresh'),        
    }    
})();

As highlighted in the preceding code snippet, the "pageinit" event handler registers the "filterablebeforefilter" event handler on the "contactList" list view in order to create our custom contacts filter. In the "filterablebeforefilter" event handler, the current filter text entered by the user is retrieved by calling data.input.val(). In order to minimize the search space, the filter text has to be at least three characters. If the filter text's length exceeds two characters, then a call to the contactsManager.getAllContacts(callback, filterText) method is performed in order to get all the contacts that match the entered filter text.

In order to call the contactsManager.getAllContacts(callback, filterText) method, we specified a callback object that contains two attributes: the onSuccess attribute (which represents a success callback) and the onError attribute (which represents a failure callback). The onSuccess callback receives the filtered contacts list and then calls the updateContactsList() method in order to update the current contacts list view with the new filtered contacts list. The onError callback just displays an error message to the user. The second parameter filterText represents the input filter text.

The updateContactsList(contacts) method clears the "contactList" list view, and if the contacts list (contacts) is not empty, contacts are appended to the "contactList" list view, and finally, the "contactList" list view is refreshed with new updates.

You might notice that every contact item in the list view is linked to the "contactDetails" page and passes the item's contact object as a parameter (after converting the contact object to an encoded JSON string).

Thanks to the jQuery Mobile page parameters plugin (which can be downloaded from https://github.com/jblas/jquery-mobile-plugins/tree/master/page-params) and its inclusion in the index.html file, we can pass parameters between pages easily using "#pageID?param1=value1&param2=value2 ...etc.

However, in our application, in the js/common.js file (which contains common utilities across all of the app pages and is included after the plugin, that is, the jqm.page.params.js file), we added a small utility over the plugin in order to retrieve page parameters at any event of the "to" page. In order to implement this, we create an event handler for the "pagebeforechange" event in order to get the passed parameter(s), as shown in the following code snippet:

$(document).bind("pagebeforechange", function(event, data) {
    $.mobile.pageData = (data && data.options && data.options.pageData) 
                      ? data.options.pageData : null;
});

By checking data.options.pageData, we can determine whether there are any passed parameters from the "from" page to the "to" page, thanks to the page parameters plugin. After getting the passed parameters, we set them in $.mobile.pageData, which can be accessible from any event in the "to" page. If there are no passed parameters, then $.mobile.pageData will be set to null.

The following code snippet shows contactDetails.js, which is the view controller of the "contactDetails" page:

(function() {    
    $(document).on("pageshow", "#contactDetails", function(e) {
        e.preventDefault();

        var contactDetailsParam = $.mobile.pageData.contact || null;
        var contactDetails = JSON.parse(decodeURIComponent(contactDetailsParam));        
        var i;
        var numbers = "";

        if (contactDetails.phoneNumbers) {
            for (i = 0; i < contactDetails.phoneNumbers.length; ++i) {
                numbers = "<a href='tel:" + contactDetails.phoneNumbers[i].value + "'>" +
                          contactDetails.phoneNumbers[i].value + "</a><br/>";
            }
        } else {
            numbers = "NA<br/>";
        }

        $("#contactInfo").html("<p>" +
                "Name: <strong>" + contactDetails.name.formatted + "</strong><br/><br/>" +
                "Phone(s): " + "<br/>" + 
                numbers +
                "</p>");
    });
})();

In the "pageshow" event handler of the "contactDetails" page, contactDetails is retrieved using $.mobile.pageData.contact and then decoded and parsed to be converted to a JavaScript object. Finally, the contact names and numbers are acquired from contactDetails using contactDetails.name.formatted and contactDetails.phoneNumbers and are displayed in the "contactInfo" div.

Tip

The jQuery Mobile "pageshow" event is triggered on the "to" page after the transition completes.

API

The following code snippet shows the contacts manager JavaScript object that wraps the Apache Cordova Contacts API (ContactsManager.js):

var ContactsManager = (function () {     
    var instance;

    function createObject() {
        return {
            getAllContacts: function (callback, filterText) {
                var options = new ContactFindOptions();

                options.filter = filterText || "";
                options.multiple = true;

                var fields = ["id", "name", "phoneNumbers"];

                navigator.contacts.find(callback.onSuccess, callback.onError, fields, options);
            }
        };
    };

    return {
        getInstance: function () {
            if (!instance) {
                instance = createObject();
            }

            return instance;
        }
    }; 
})();

As you can see, ContactsManager is a singleton object that has a single method as highlighted in the preceding code. The getAllContacts(callback, filterText) method uses the Cordova navigator.contacts.find() method to retrieve contacts.

The navigator.contacts.find(contactSuccess, contactError, contactFields, contactFindOptions) method has the following parameters:

  • contactSuccess: This callback will be called if the operation succeeds. It receives the retrieved contacts array as a parameter. In ContactsManager, contactSuccess is set to callback.onSuccess.
  • contactError: This callback will be called if the operation fails. In ContactsManager, contactError is set to callback.onError.
  • contactFields: This object specifies the fields of every contact object in the returned result of navigator.contacts.find(). In ContactsManager, we specified the ["id", "name", "phoneNumbers"] contact fields.
  • contactFindOptions: This is an optional parameter that is used to filter contacts.

The contactFindOptions parameter has the attributes shown in the following table:

Attribute name

Description

filter

This represents the search string used to filter contacts. In ContactsManager, the value is set to filterText.

multiple

This specifies whether the find operation returns multiple contacts. By default, it is false. In our ContactsManager, it is set to true.

We are now done with the Contacts functionality in the Cordova Exhibition app. However, before exploring the device's API functionality, note that the navigator.contacts.find() method's contactFields parameter can have one or more attribute(s) from the Contact object, whose attributes are specified in the following table:

Attribute name

Description

id

This represents a globally unique identifier for the contact. It is used in our contacts example.

displayName

This represents the name of this contact.

name

This represents a ContactName object that contains all the components of a name, which will be illustrated later. It is used in our contacts example.

nickname

This represents the contact's nickname.

phoneNumbers

This represents a ContactField array of all the contacts' phone numbers. It is used in our contacts example. The ContactField object will be illustrated later.

Emails

This represents a ContactField array of all the contacts' e-mail addresses.

addresses

This represents a ContactAddress array of all the contacts' addresses. It will be illustrated later.

ims

This represents a ContactField array of all the contacts' IM addresses.

organizations

This represents a ContactOrganization array of all the contacts' organizations. It will be illustrated later.

birthday

This represents the contact's birthday.

note

This represents a note about the contact.

photos

This represents a ContactField array of the contacts' photos.

categories

This represents a ContactField array of all the user-defined categories associated with the contact.

urls

This represents a ContactField array of web pages associated with the contact.

The ContactName object has the attributes shown in the following table:

Attribute name

Description

formatted

This represents the complete name of the contact.

familyName

This represents the contact's family name.

givenName

This represents the contact's given name.

middleName

This represents the contact's middle name.

honorificPrefix

This represents the contact's prefix (such as Mr or Mrs).

honorificSuffix

This represents the contact's suffix.

The ContactField object has the attributes shown in the following table:

Attribute name

Description

type

This represents a string that indicates what type of field it is.

value

This represents the value of the field, for example, a phone number.

pref

If this is set to true, it means that this ContactField object contains the user's preferred value.

The ContactAddress object has the attributes shown in the following table:

Attribute name

Description

type

This represents a string that indicates what type of field it is.

pref

If this is set to true, it means that this ContactAddress object contains the user's preferred value.

formatted

This represents the formatted full address for display.

streetAddress

This represents the full street address.

locality

This represents the city or locality.

region

This represents the state or region.

postalCode

This represents the zip code or postal code.

country

This represents the country name.

The ContactOrganization object has the attributes shown in the following table:

Attribute name

Description

type

This represents a string that indicates what type of field it is, for example, "home".

pref

If this is set to true, it means that this ContactOrganization contains the user's preferred value.

name

This represents the contact's organization name.

department

This represents the contact's department name inside the organization.

title

This represent the contact's title in the organization.

The navigator.contacts object has also the method shown in the following table:

Method name

Description

navigator.contacts.create(properties)

This is used to return a Contact object that you can use, for example, to save a contact in the device contacts database by calling the save() method of the Contact object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.66.94