ZnetDK 4 Mobile

Tutorial

Learning how to add a contact list to your web application

What you will develop...

You will learn in the first part of this tutorial, how to display within a PHP view, a list of contacts stored in a MySQL database.

Then, at the end of the second part of the tutorial, you'll be able to add new contacts to the list and edit existing ones.

Prerequisite...

Before starting this tutorial, be sure to get the ZnetDK for Mobile Starter Application installed and configured to access to a MySQL database.
Otherwise, go to the Get Started Page and follow the procedure indicated.

PART 1 - Displaying a contact list

In this chapter, you will add a new table contacts to the web application database and then a PHP view contactlist.php to the application.

This first part only requires knowledge in PHP and HTML.

Creating the SQL table

First, download the zdk4m-tuto-contacts.sql Tutorial SQL script from the Download page.

Next, log in to your phpMyAdmin tool with a user account allowed to create a new table and to insert rows into the web application datatable.
Finally, import the downloaded zdk4m_tuto_contacts.sql script into your web application database.

Once import terminated, you should see a new table named contacts containing 100 sample rows as shown on the picture beside.

ZnetDK for Mobile Tutorial - Loading contacts in MySQL

Adding the "My contacts" item to the navigation menu

To display the contactlist.php view, a new menu item named My contacts is added to the navigation menu by editing the INSTALL_DIR/applications/default/app/menu.php script.

Insert the line in yellow below just after the definition of the Home menu.

TUTORIAL: menu.php

\MenuManager::addMenuItem(NULL, 'home', 'Home', 'fa-home');

\MenuManager::addMenuItem(NULL, 'contactlist', 'My contacts', 'fa-address-card-o');

\MenuManager::addMenuItem(NULL, 'myview1', 'My first view', 'fa-hourglass-1');

Each call to the ZnetDK \MenuManager::addMenuItem() method adds a new item to the navigation menu and connect it to the view to display.

The parameters passed to the method are explained below:

  • NULL: this NULL value indicates that the item is to display as a root menu item.
  • 'contactlist': this is the name of the PHP view (without the .php extension) to display when the user clicks on the menu item.
  • 'My contacts': the label displayed for the menu item on the navigation menu.
  • 'fa-address-card-o': the name of the Font Awesome icon to display for the menu item on the navigation menu.

Now, reload the application into your web browser to display the My contacts menu item.

ZnetDK for Mobile Tutorial part 1 - My contacts menu

Creating the PHP view

To begin, add a new PHP script named contactlist.php into the INSTALL_DIR/applications/default/app/view/ folder of the Starter Application then copy and paste the following code.

TUTORIAL: contactlist.php

<?php
    $contactsDao = new SimpleDAO('contacts');
    $rowsFound = array();
    $rowCount = $contactsDao->getRows($rowsFound, 'name');
?>
<h3><?php echo "{$rowCount} contacts found:"; ?></h3>
<ul class="w3-ul w3-border">
<?php foreach ($rowsFound as $row) : ?>
    <li>
        <b><?php echo $row['name']; ?></b>
        <a class="w3-right" href="tel:<?php echo $row['phone']; ?>">
            <i class="w3-text-theme fa fa-phone-square fa-lg"></i> 
            <span style="font-family: monospace;"><?php echo $row['phone']; ?></span>
        </a>
    </li>
<?php endforeach; ?>
</ul>
ZnetDK for Mobile Tutorial part 1 - display of contacts

This code is a simple and usual way in PHP to display data rows in a HTML view.

The first 3 lines of code in the view are written in PHP. They consist in extracting the data rows from the contacts database table thanks to the ZnetDK SimpleDAO class.
The rows of contacts are assigned to the $rowsFound variable by the SimpleDao::getRows() method which further sorts the returned rows by name.

The next lines of PHP code iterate over the table rows (foreach loop) in order to display them within a HTML unordered list (ul HTML tag).

Only the values of the name and phone columns of the contacts table are displayed.

Finally, the w3-ul, w3-border, w3-center and w3-text-theme W3.CSS classes help to style a minimum the HTML list.

PART 2 - Adding and editing contacts

This chapter presents another solution to display the list of contacts, in particular based on AJAX requests, JavaScript code and the ZnetDK for Mobile framework.

This solution is particularly suitable for displaying a large number of data rows by loading them on demand using an infinite scroll mechanism.

At last, this second part shows how to add and edit contacts.

Adding a controller to the application

According to the MVC design pattern, we will add the contactctrl.php application controller to handle the AJAX requests sent by the view.

The contactctrl.php controller is a PHP script added to the INSTALL_DIR/applications/default/app/controller/ folder.
This script contains the definition of the PHP class ContactCtrl consisting of 3 methods, each one matching a specific controller action.

The 3 actions of the controller are:

  • action_all(): method called by the view to get the 20 next data rows to display.
  • action_detail(): called to retrieve the data of a given contact for editing purposes.
  • action_store(): action called to store a new contact or to update the data of an existing one.

These controller actions use the SimpleDao class again to manipulate the data in the contacts MySQL table.

Here is below the PHP code of the contactctrl.php script.

TUTORIAL: contactctrl.php

<?php
namespace app\controller;
class 
ContactCtrl extends \AppController {
    static protected function 
action_all() {
        
$response = new \Response();
        
$contacts = array();
        
$dao = new \SimpleDAO('contacts');
        
$response->total $dao->getRows($contacts'id');
        
$response->rows $contacts;
        return 
$response;
    }
    static protected function 
action_detail() {
        
$request = new \Request();
        
$dao = new \SimpleDAO('contacts');
        
$detail $dao->getById($request->id);
        
$response = new \Response();
        
$response->setResponse($detail === FALSE ? array() : $detail);
        return 
$response;
    } 
    static protected function 
action_store() {
        
$request = new \Request();
        
$formData $request->getValuesAsMap('id''name''birthdate',
                
'address''zip''city''country''phone''email');
        
$dao = new \SimpleDAO('contacts');
        
$contactId $dao->store($formData);
        
$response = new \Response();
        
$response->setSuccessMessage('Contact',
                
"Storage of the contact with ID={$contactId} succeeded.");
        return 
$response;
    }
}
?>

A controller action returns its response in JSON format thanks to a ZnetDK \Response object.

Each property set for the \Response object is automatically converted to a JSON property by the ZnetDK framework, before being returned to the AJAX caller.
The \Response::setResponse() method allows to assign multiple properties in only one instruction (for example all the properties of a given contact selected by ID into the action_detail() method).
The \Response::setSuccessMessage() method sets the message displayed by the web browser when a server-side action is fullfilled successfully.

The POST parameters of the AJAX request are read by the controller action by instantiating a ZnetDK \Request object.

A single value can be directly read by specifying the name of the relevant POST parameter (i.e. $request->id into the action_detail() method).
The ZnetDK \Request::getValuesAsMap() method helps to assign multiple POST parameters to an indexed array as illustrated by the action_save() method.

The view - Displaying contacts from AJAX request

In this chapter, we will replace the contactlist.php view code written in PART 1 of this tutorial, by new code based on the ZnetDK for Mobile framework.

This new version of the view has the advantage of only loading on demand a subset of contacts (infinite scroll), unlike the previous version that loaded all the contacts into the view at one time.

Here is the new code of the view.

TUTORIAL PART 2: contactlist.php

<ul id="contactlist" class="w3-ul w3-border w3-margin-top w3-hide"
    data-zdk-load="contactctrl:all">
    <li data-id="{{id}}">
        <a class="edit w3-xlarge"><i class="fa fa-edit fa-lg"></i></a>
        <b>{{name}}</b>
        <a class="w3-right" href="tel:{{phone}}">
            <i class="w3-text-theme fa fa-phone-square fa-lg"></i>
            <span style="font-family: monospace;">{{phone}}</span>
        </a>
    </li>
</ul>
<script>
    var myContactList = znetdkMobile.list.make('#contactlist', false, false);
</script>

As you can see, there is no PHP code in this new version of the view.

It means that the HTML list is no longer built by the Web server before being downloaded.

Indeed, the list is now generated in JavaScript on the client-side by the ZnetDK for Mobile znetdkMobile.list.make() method once the view is loaded, where the '#contactlist' parameter value is the selector of the HTML list in the DOM.
The rows are retrieved from the Web server through an AJAX call to the ContactCtrl:action_all() controller action implemented at the previous chapter.
This is the data-zdk-load="contactctrl:all" HTML attribute set to the <ul> element that connects the list to the remote PHP controller action.
The {{name}} and {{phone}} placeholders are used to display the name and the phone of each contact in the list.
The {{id}} placeholder set to the data-id attribute of the <ul> element will be required to edit a contact when clicking on the a.edit anchor element.
Only 20 rows are returned at the first AJAX call. The following 20 rows are returned on demand only when the list is scrolled down and so on until the end of the list is reached.
Finally, you will notice that the total number of contacts is automatically added to the right of the My contacts menu item.

ZnetDK for Mobile Tutorial part 2 - display of contacts

The view - Adding an input form for creating and editing contacts

Now, we will add to the contactlist.php view, the definition in HTML of the input form used for editing the information of an existing contact and for adding new contacts.

Here is the new code of the view including the input form implementation.

TUTORIAL PART 2: contactlist.php

<!-- LIST OF CONTACTS -->
<ul id="contactlist" class="w3-ul w3-border w3-margin-top w3-hide"
    data-zdk-load="contactctrl:all">
    <li data-id="{{id}}">
        <a class="edit w3-xlarge"><i class="fa fa-edit fa-lg"></i></a>
        <b>{{name}}</b>
        <a class="w3-right" href="tel:{{phone}}">
            <i class="w3-text-theme fa fa-phone-square fa-lg"></i>
            <span style="font-family: monospace;">{{phone}}</span>
        </a>
    </li>
</ul>
<!-- CONTACT INPUT FORM -->
<div id="contact-modal" class="w3-modal">
    <div class="w3-modal-content w3-card-4">
        <header class="w3-container w3-theme-d5">
            <span class="close w3-button w3-xlarge w3-hover-theme w3-display-topright">
                <i class="fa fa-times-circle fa-lg"></i>
            </span>
            <h4 class="title">Contact</h4>
        </header>
        <form class="w3-container w3-theme-light" data-zdk-load="contactctrl:detail"
                data-zdk-submit="contactctrl:store">
            <input type="hidden" name="id">
            <div class="w3-section">
                <label class="zdk-required"><b>Name</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="text" name="name" required>
                <label><b>Birthdate</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="date" name="birthdate">
                <label><b>Address</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="text" name="address">
                <label><b>ZIP</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="text" name="zip">
                <label><b>City</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="text" name="city">
                <label><b>Country</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="text" name="country">
                <label><b>Phone</b></label>
                <input class="w3-input w3-border w3-margin-bottom" type="text" name="phone">
                <label><b>Email</b></label>
                <input class="w3-input w3-border" type="email" name="email">
                <button class="w3-button w3-block w3-green w3-section w3-padding" type="submit">Save</button>
            </div>
        </form>
    </div>
</div>
<script>
    // The list of contacts is generated
    var myContactList = znetdkMobile.list.make('#contactlist', false, false);
    // The contact input form is linked to the list
    myContactList.setModal('#contact-modal', true, function(){ // NEW
        this.setTitle('New contact');
    }, function(formObject) { // EDIT
        var contactId = formObject.getInputValue('id');
        this.setTitle('Edit contact #' + contactId);
    });
</script>

If we look now at the HTML source code of the input form, we can notice that the <form> element is surrounded by a <div> element having the w3-modal CSS class.
Indeed, the form is displayed in a modal dialog as shown on the picture below.

On the other hand, you can see the data-zdk-load="contactctrl:detail" attribute of the form element that indicates to the ZnetDK framework, the controller action to call for getting the information of a given contact to edit.
According to the same principle, the data-zdk-submit="contactctrl:store" attribute indicates the controller action to call on form submit.

About the Javascript source code, a call to the setModal() method on the myContactList ZnetDK object specifies the modal dialog to display (matching the '#contact-modal' selector) when editing a contact and when adding a new contact.
Two callback methods are passed in parameters of the setModal() method to customize the title of the modal dialog when adding and editing a contact.

To see the new version of the view in action, click on the red Plus button (+ at the bottom right of the list) to display the new contact form. Once filled in, click on the Save button to store the new contact.
To modify an existing contact, click on the Edit icon () from the list, change data in the form and save by clicking on the Save button.

ZnetDK for Mobile Tutorial - Contact form

The view - Styling the contact list

Finally, we will display additional information for each contact in the list while ensuring their optimal readability regardless of the dimensions of the screen.

To do this, simply apply the W3.CSS responsive grid style classes for an adaptive display based on the size of the viewport.

See below the new HTML code of the list of contacts.

TUTORIAL PART 2: contactlist.php

<!-- LIST OF CONTACTS -->
<ul id="contactlist" class="w3-ul w3-hide"
    data-zdk-load="contactctrl:all">
    <li class="w3-border-theme" data-id="{{id}}">
        <div class="w3-row">
            <div class="w3-col" style="width: 60px;">
                <a class="edit w3-button w3-circle w3-ripple w3-xlarge w3-theme-action w3-hover-theme"><i class="fa fa-edit"></i></a>
            </div>
            <div class="w3-rest w3-row">
                <div class="w3-col s12 m5 l3 w3-padding-small">
                    <span class="w3-tag w3-theme-d1">{{id}}</span>
                    <span class="w3-text-theme w3-large"><strong>{{name}}</strong></span>
                </div>
                <div class="w3-col s12 m7 l3 w3-padding-small">
                    <i class="w3-text-theme fa fa-map-signs fa-lg"></i> <span>{{zip}} - {{city}}</span>                            
                </div>
                <div class="w3-col s12 m9 l4 w3-padding-small">
                    <a href="mailto:{{email}}">
                        <i class="w3-text-theme fa fa-envelope fa-lg"></i> <span>{{email}}</span>
                    </a>
                </div>
                <div class="w3-col s12 m3 l2 w3-padding-small">
                    <a href="tel:{{phone}}">
                        <i class="w3-text-theme fa fa-phone-square fa-lg"></i> <span>{{phone}}</span>
                    </a>
                </div>
            </div>
        </div>
    </li>
</ul>

As shown in the screen shot below, the contact list display automatically adjusts according to the screen orientation.

In portrait orientation, the name, address, email and phone number of the contact are stacked on top of each other.
The w3-col CSS class combined with the s12 CSS class indicates that the text should occupy the full width of the container on a small screen.
Indeed, the W3.CSS responsive grid is divided into 12 columns.

In landscape orientation that corresponds to a medium screen, the name and address are displayed on the same line according to a distribution of 5/12 (m5 CSS class for a width=41.66%) and 7/12 (m7 CSS class for a width=58.33%).
Concerning the email and the phone number, the m9 and m3 CSS classes respectively apply a display on 3 columns (width=25%) and 9 columns (width=75%) in the grid.

ZnetDK for Mobile Tutorial - Responsive Contact list

Going further

Downloading source code

The full source code presented in this tutorial can be downloaded as a zip archive named zdk4m-tuto-contacts.zip from the Download page.

If you have any question or comment about this tutorial, please post a message on the official ZnetDK Forum.

Reading more documentation

To learn more about formatting views with W3.CSS, I invite you to visit the W3.CSS Tutorial page.

For a full documentation of the ZnetDK Framework methods used in this tutorial, please visit the ZnetDK PHP API and ZnetDK JS API pages on this website.
If any documentation is missing, fill free to post a message on the official ZnetDK Forum.