Tutorial: Developing a PhoneGap Application


In this tutorial, you create a fully functional employee directory application with PhoneGap. You will learn:

  • How to use different local data storage strategies.
  • How to use several PhoneGap APIs such as Geolocation, Contacts, and Camera.
  • How to handle specific mobile problems such as touch events, scrolling, styling, page transitions, etc.
  • How to build an application using a single page architecture and HTML templates.
  • How to build (compile and package) an application for 6 platforms using PhoneGap Build.

To complete this tutorial, all you need is a code editor, a modern browser, and a connection to the Internet. A working knowledge of HTML and JavaScript is assumed, but you don’t need to be a JavaScript guru.

Setting Up

  1. Download the assets for the workshop here.
  2. Unzip the file anywhere on your file system.
  3. If your code editor allows you to “open a directory”, open the phonegap-workshop-master directory.
  4. Follow the instructions below.
Step-by-step solution files are also available here.

Part 1: Choosing a Local Storage Option


Step 1: Explore different persistence mechansisms

Open the following files in phonegap-workshop-master/js/storage, and explore the different persistence stores they define:

  1. memory-store.js (MemoryStore)
  2. ls-store.js (LocalStorageStore)
  3. websql-store.js (WebSqlStore)

Step 2: Test the application with different persistence mechanisms

To change the local persistence mechanism for the application:

  1. In index.html: add a script tag for the corresponding .js file: memory-store.js, ls-store.js, or websql-store.js.
  2. In js/main.js: Instantiate the specific store in the initialize() function of the app object: MemoryStore, LocalStorageStore, or WebSqlStore.
  3. To test the application, open index.html in your browser, or simply double-click index.html on your file system. Type a few characters in the search box to search employees by name. Clicking an employee link doesn’t produce any result at this time.


Part 2: Building with PhoneGap Build


  1. If you don’t already have one, create an account on http://build.phonegap.com.
  2. Click the “new app” button to create a new application on PhoneGap Build.
  3. Either point to a GitHub repository where you push your code for this workshop, or zip up your phonegap-workshop directory and upload it to PhoneGap Build.
  4. Click the Ready to build button.
    The iOS button will immediately turn red because the iOS build requires that you upload your Apple Developer certificate and an application provisioning profile. You can find more information here if you haven’t already signed up for the Apple Developer Program. If you don’t have an iOS device, or if you are not ready to upload your developer certificate, you can skip step 5 and keep running the application in the browser or a non iOS device.
  5. To upload your Apple developer certificate and your application provisioning profile:
    • Click the red iOS button.
    • Select “add a key” in the “No key selected” dropdown.
    • Provide a title for your developer certificate/provisioning profile combination (for example: EmployeeDirectory), select your developer certificate and provisioning profile, enter your developer certificate password, and click “submit key”.
    • Go back to the list of apps. Click the iOS button for your application again. Select your newly added key in the iOS dropdown. The iOS build will start automatically.
  6. When the build process completes, use a QR Code reader app to install the Employee Directory application on your device.

To fine tune your build preferences:

  1. In the phonegap-workshop directory, create a file namedconfig.xml file defined as follows (make the necessary adjustments for id, author, etc.):
    <?xml version="1.0" encoding="UTF-8"?>
    <widget xmlns       = "http://www.w3.org/ns/widgets"
            xmlns:gap   = "http://phonegap.com/ns/1.0"
            id          = "org.coenraets.employeedirectory"
            versionCode = "10"
            version     = "1.1.0">
    
        <name>Employee Directory</name>
    
        <description>
            A simple employee directory application
        </description>
    
        <author href="http://coenraets.org" email="ccoenraets@gmail.com">
            Christophe Coenraets
        </author>
    
        <feature name="http://api.phonegap.com/1.0/camera"/>
        <feature name="http://api.phonegap.com/1.0/contacts"/>
        <feature name="http://api.phonegap.com/1.0/file"/>
        <feature name="http://api.phonegap.com/1.0/geolocation"/>
        <feature name="http://api.phonegap.com/1.0/media"/>
        <feature name="http://api.phonegap.com/1.0/network"/>
        <feature name="http://api.phonegap.com/1.0/notification"/>
    
    </widget>
    
  2. If you used the GitHub approach, sync with GitHub and click the Update Code button in PhoneGap Build.
    If you used the zip file approach, zip up your phonegap-workshop directory and upload the new version to PhoneGap Build
There are many other parameters you can specify in config.xml to configure the build process. See the documentation for config.xml here.


Part 3: Using Native Notification


A default webview alert gives away the fact that your application is not native. In this section, we set up the basic infrastructure to display native alerts when the application is running on a device, and fall back to default browser alerts when running in the browser.

  1. In index.html, add the following script tag (as the first script tag at the bottom of the body):
    <script src="phonegap.js"></script>
    

    This instructs PhoneGap Build to inject a platform specific version of phonegap.js at build time. In other words, phonegaps.js doesn’t need to be (and shouldn’t be) present in your project folder.

  2. In main.js, define a function named showAlert() inside the app object. If navigator.notification is available, use its alert() function. Otherwise, use the default browser alert() function.
    showAlert: function (message, title) {
        if (navigator.notification) {
            navigator.notification.alert(message, null, title, 'OK');
        } else {
            alert(title ? (title + ": " + message) : message);
        }
    },
    
  3. Test the notification logic by displaying a message when the application store has been initialized: Pass an anonymous callback function as an argument to the constructor of the persistence store (the store will call this function after it has successfully initialized). In the anonymous function, invoke the showAlert() function.
    initialize: function() {
        var self = this;
        this.store = new MemoryStore(function() {
            self.showAlert('Store Initialized', 'Info');
        });
        $('.search-key').on('keyup', $.proxy(this.findByName, this));
    }
    
  4. Test the application: When you run the application in the browser, you should see a standard browser alert. When you run the application on your device, you should see a native alert.


Part 4: Setting Up a Single Page Application


A single page application is a web application that lives within a single HTML page. The “views” of the application are injected into- and removed from the DOM as needed as the user navigates through the app. A single page application architecture is particularly well suited for mobile apps:

  • The absence of continual page refreshes provides a more fluid / closer to native experience.
  • The UI is entirely created at the client-side with no dependency on a server to create the UI, making it an ideal architecture for applications that work offline.

In this section, we set up the basic infrastructure to turn Employee Directory into a single page application.

  1. In index.html: remove the HTML markup inside the body tag (with the exception of the script tags).
  2. In main.js, define a function named renderHomeView() inside the app object. Implement the function to programmatically add the Home View markup to the body element.
    renderHomeView: function() {
        var html =
                "<div class='header'><h1>Home</h1></div>" +
                "<div class='search-view'>" +
                "<input class='search-key'/>" +
                "<ul class='employee-list'></ul>" +
                "</div>"
        $('body').html(html);
        $('.search-key').on('keyup', $.proxy(this.findByName, this));
    },
    
  3. Modify the initialize() function of the app object. In the anonymous callback function of the store constructor, call the renderHomeView() function to programmatically display the Home View.
    initialize: function() {
        var self = this;
        this.store = new MemoryStore(function() {
            self.renderHomeView();
        });
    }
    


Part 5: Using Handlebar Templates


Writing HTML fragments in JavaScript and programmatically inserting them into the DOM is tedious. It makes your application harder to write and harder to maintain. HTML templates address this issue by decoupling the UI definition (HTML markup) from your code. There are a number of great HTML template solutions: Mustache.js, Handlebar.js, and Underscore.js to name a few.

In this section, we create two templates to streamline the code of the Employee Directory application. We use Handlebar.js but the smae result can be achieved using the other HTML template solutions.

Modify index.html as follows:

  1. Add a script tag to include the handlebar.js library:
    <script src="lib/handlebars.js"></script>
    
  2. Create an HTML template to render the Home View. Add this script tag as the first child of the body tag:
    <script id="home-tpl" type="text/x-handlebars-template">
        <div class='header'><h1>Home</h1></div>
        <div class='search-bar'><input class='search-key' type="text"/></div>
        <ul class='employee-list'></ul>
    </script>
    
  3. Create an HTML template to render the employee list items. Add this script tag immediately after the previous one:
    <script id="employee-li-tpl" type="text/x-handlebars-template">
        {{#.}}
        <li><a href="#employees/{{this.id}}">{{this.firstName}} {{this.lastName}}<br/>{{this.title}}</a></li>
        {{/.}}
    </script>
    

Modify main.js as follows:

  1. In the initialize() function of the app object, add the code to compile the two templates defined above:
    this.homeTpl = Handlebars.compile($("#home-tpl").html());
    this.employeeLiTpl = Handlebars.compile($("#employee-li-tpl").html());
    
  2. Modify renderHomeView() to use the homeTpl template instead of the inline HTML:
    renderHomeView: function() {
        $('body').html(this.homeTpl());
        $('.search-key').on('keyup', $.proxy(this.findByName, this));
    },
    
  3. Modify findByName() to use the employeeLiTpl template instead of the inline HTML:
    findByName: function() {
        var self = this;
        this.store.findByName($('.search-key').val(), function(employees) {
            $('.employee-list').html(self.employeeLiTpl(employees));
        });
    },
    
  4. Test the application.


Part 6: Creating a View Class


It’s time to provide our application with some structure. If we keep adding all the core functions of the application to the app object, it will very quickly grow out of control. In this section we create a HomeView object that encapsulates the logic to create and render the Home view.

Step 1: Create the HomeView Class

  1. Create a file called HomeView.js in the js directory, and define a HomeView class implemented as follows:
    var HomeView = function(store) {
    
    
    }
    
  2. Add the two templates as static members of HomeView.
    var HomeView = function(store) {
    
    
    }
    
    HomeView.template = Handlebars.compile($("#home-tpl").html());
    HomeView.liTemplate = Handlebars.compile($("#employee-li-tpl").html());
    
  3. Define an initialize() function inside the HomeView class. Define a div wrapper for the view. The div wrapper is used to attach the view-related events. Invoke the initialize() function inside the HomeView constructor function.
    var HomeView = function(store) {
    
        this.initialize = function() {
            // Define a div wrapper for the view. The div wrapper is used to attach events.
            this.el = $('<div/>');
            this.el.on('keyup', '.search-key', this.findByName);
        };
    
        this.initialize();
    
    }
    
    HomeView.template = Handlebars.compile($("#home-tpl").html());
    HomeView.liTemplate = Handlebars.compile($("#employee-li-tpl").html());
    
  4. Move the renderHomeView() function from the app object to the HomeView class. To keep the view reusable, attach the html to the div wrapper (this.el) instead of the document body. Because the function is now encapsulated in the HomeView class, you can also rename it from renderHomeView() to just render().
    this.render = function() {
        this.el.html(HomeView.template());
        return this;
    };
    
  5. Move the findByName() function from the app object to the HomeView class.
    this.findByName = function() {
        store.findByName($('.search-key').val(), function(employees) {
            $('.employee-list').html(HomeView.liTemplate(employees));
        });
    };
    

Step 2: Using the HomeView class

  1. In index.html, add a script tag to include HomeView.js (just before the script tag for main.js):
    <script src="js/HomeView.js"></script>
    
  2. Remove the renderHomeView() function from the app object.
  3. Remove the findByName() function from the app object.
  4. Modify the initialize function() to display the Home View using the HomeView class:
    initialize: function() {
        var self = this;
        this.store = new MemoryStore(function() {
            $('body').html(new HomeView(self.store).render().el);
        });
    }
    


Part 7: Adding Styles and Touch-Based Scrolling


Step 1: Style the Application

  1. Add the Source Sans Pro font definition to the head of index.html
    <script src="css/source-sans-pro.js"></script>
    

    Source Sans Pro is part of the free Adobe Edge Web Fonts.

  2. Add styles.css to the head of index.html
    <link href="css/styles.css" rel="stylesheet">
    
  3. In index.html, modify the home-tpl template: change the search-key input type from text to search.
  4. Test the application. Specifically, test the list behavior when the list is bigger than the browser window (or the screen)

Step 2: Native Scrolling Approach

  1. Modify the home-tpl template in index.html. Add a div wrapper with a scroll class around the ul element with a scroll:
    <script id="home-tpl" type="text/x-handlebars-template">
        <div class='header'><h1>Home</h1></div>
        <div class='search-bar'><input class='search-key' type="search"/></div>
        <div class="scroll"><ul class='employee-list'></ul></div>
    </script>
    
  2. Add the following class definition to css/styles.css:
    .scroll {
        overflow: auto;
        -webkit-overflow-scrolling: touch;
        position: absolute;
        top: 84px;
        bottom: 0px;
        left: 0px;
        right: 0px;
    }
    
If the platforms you target support touch-based scrolling of fixed regions, this approach is all you need (you can skip step 3 below). If not, you’ll need to implement a programmatic approach, typically with the help of a library such as iScroll.

Step 3: iScroll Approach

  1. Add a script tag to include the iscroll.js library:
    <script src="lib/iscroll.js"></script>
    
  2. In HomeView.js, modify the findByName() function: Instantiate an iScroll object to scroll the list of employees returned. If the iScroll object already exists (), simply refresh it to adapt it to the new size of the list.
    this.findByName = function() {
        store.findByName($('.search-key').val(), function(employees) {
            $('.employee-list').html(HomeView.liTemplate(employees));
            if (self.iscroll) {
                console.log('Refresh iScroll');
                self.iscroll.refresh();
            } else {
                console.log('New iScroll');
                self.iscroll = new iScroll($('.scroll', self.el)[0], {hScrollbar: false, vScrollbar: false });
            }
        });
    };
    
More information on iScroll is available here.


Part 8: Highlighting Tapped or Clicked UI Elements


  1. In styles.css, add a tappable-active class definition for tapped or clicked list item links. The class simply highlights the item with a blue background:
    li>a.tappable-active {
        color: #fff;
        background-color: #4286f5;
    }
    
  2. In main.js, define a registerEvents() function inside the app object. Add a the tappable_active class to the selected (tapped or clicked) list item:
    registerEvents: function() {
        var self = this;
        // Check of browser supports touch events...
        if (document.documentElement.hasOwnProperty('ontouchstart')) {
            // ... if yes: register touch event listener to change the "selected" state of the item
            $('body').on('touchstart', 'a', function(event) {
                $(event.target).addClass('tappable-active');
            });
            $('body').on('touchend', 'a', function(event) {
                $(event.target).removeClass('tappable-active');
            });
        } else {
            // ... if not: register mouse events instead
            $('body').on('mousedown', 'a', function(event) {
                $(event.target).addClass('tappable-active');
            });
            $('body').on('mouseup', 'a', function(event) {
                $(event.target).removeClass('tappable-active');
            });
        }
    },
    
  3. Invoke the registerEvents() function from within the app object’s initialize() function.
  4. Test the application.


Part 9: View Routing


In this section, we add an employee details view. Since the application now has more than one view, we also add a simple view routing mechanism that uses the hash tag to determine whether to display the home view or the details view for a specific employee.

Step 1: Create the employee template

Open index.html and add a template to render a detailed employee view:

<script id="employee-tpl" type="text/x-handlebars-template">
    <div class='header'><a href='#' class="button header-button header-button-left">Back</a><h1>Details</h1></div>
    <div class='details'>
        <img class='employee-image' src='img/{{firstName}}_{{lastName}}.jpg' />
        <h1>{{firstName}} {{lastName}}</h1>
        <h2>{{title}}</h2>
        <span class="location"></span>
        <ul>
            <li><a href="tel:{{officePhone}}">Call Office<br/>{{officePhone}}</a></li>
            <li><a href="tel:{{cellPhone}}">Call Cell<br/>{{cellPhone}}</a></li>
            <li><a href="sms:{{cellPhone}}">SMS<br/>{{cellPhone}}</a></li>
        </ul>
    </div>
</script>

Step 2: Create the EmployeeView class

  1. Create a file called EmployeeView.js in the js directory, and define an EmployeeView class implemented as follows:
    var EmployeeView = function() {
    
    
    }
    
  2. Add the template as a static member of EmployeeView.
    var EmployeeView = function() {
    
    
    }
    
    EmployeeView.template = Handlebars.compile($("#employee-tpl").html());
    
  3. Define an initialize() function inside the HomeView class. Define a div wrapper for the view. The div wrapper is used to attach the view related events. Invoke the initialize() function inside the HomeView constructor function.
    var EmployeeView = function(employee) {
    
        this.initialize = function() {
            this.el = $('<div/>');
        };
    
        this.initialize();
    
     }
    
    EmployeeView.template = Handlebars.compile($("#employee-tpl").html());
    
  4. Define a render() function implemented as follows:
    this.render = function() {
        this.el.html(EmployeeView.template(employee));
        return this;
    };
    
  5. In index.html, add a script tag to include EmployeeView.js (just before the script tag for main.js):
    <script src="js/EmployeeView.js"></script>
    

Step 3: Implement View Routing

  1. In the app’s initialize() function, define a regular expression that matches employee details urls.
    this.detailsURL = /^#employees\/(\d{1,})/;
    
  2. In the app’s registerEvents() function, add an event listener to listen to URL hash tag changes:
    $(window).on('hashchange', $.proxy(this.route, this));
    
  3. In the app object, define a route() function to route requests to the appropriate view:
    • If there is no hash tag in the URL: display the HomeView
    • If there is a has tag matching the pattern for an employee details URL: display an EmployeeView for the specified employee.
    route: function() {
        var hash = window.location.hash;
        if (!hash) {
            $('body').html(new HomeView(this.store).render().el);
            return;
        }
        var match = hash.match(app.detailsURL);
        if (match) {
            this.store.findById(Number(match[1]), function(employee) {
                $('body').html(new EmployeeView(employee).render().el);
            });
        }
    }
    
  4. Modify the initialize() function to call the route() function:
    initialize: function() {
        var self = this;
        this.detailsURL = /^#employees\/(\d{1,})/;
        this.registerEvents();
        this.store = new MemoryStore(function() {
            self.route();
        });
    }
    
  5. Test the application.


Part 10: Using the Location API


In this section, we add the ability to tag an employee with his/her location information. In this sample application, we display the raw information (longitude/latitude) in the employee view. In a real-life application, we would typically save the location in the database as part of the employee information and show it on a map.

The code below works when running the application as a PhoneGap app on your device. It should also work in Chrome on the desktop when the page is served with the http:// protocol, and in Firefox, regardless of the protocol (http:// or file://).
  1. In index.html, add the following list item to the employee-tpl template:
    <li><a href="#" class="add-location-btn">Add Location</a></li>
    
  2. In the initialize() function of EmployeeView, register an event listener for the click event of the Add Location list item:
    this.el.on('click', '.add-location-btn', this.addLocation);
    
  3. In EmployeeView, define the addLocation event handler as follows:
    this.addLocation = function(event) {
        event.preventDefault();
        console.log('addLocation');
        navigator.geolocation.getCurrentPosition(
            function(position) {
                $('.location', this.el).html(position.coords.latitude + ',' + position.coords.longitude);
            },
            function() {
                alert('Error getting location');
            });
        return false;
    };
    
  4. Test the Application


Part 11: Using the Contacts API


In this section, we use the PhoneGap Contacts API to provide the user with the ability to add an employee to the device’s contact list.

The code below only works when running the application on your device as a PhoneGap app. In other words, you can’t test it in a browser on the desktop.
  1. In index.html, add the following list item to the employee template:
    <li><a href="#" class="add-contact-btn">Add to Contacts</a></li>
    
  2. In the initialize() function of EmployeeView, register an event listener for the click event of the Add to Contacts list item:
    this.el.on('click', '.add-contact-btn', this.addToContacts);
    
  3. In EmployeeView, define the addToContacts event handler as follows:
    this.addToContacts = function(event) {
        event.preventDefault();
        console.log('addToContacts');
        if (!navigator.contacts) {
            app.showAlert("Contacts API not supported", "Error");
            return;
        }
        var contact = navigator.contacts.create();
        contact.name = {givenName: employee.firstName, familyName: employee.lastName};
        var phoneNumbers = [];
        phoneNumbers[0] = new ContactField('work', employee.officePhone, false);
        phoneNumbers[1] = new ContactField('mobile', employee.cellPhone, true); // preferred number
        contact.phoneNumbers = phoneNumbers;
        contact.save();
        return false;
    };
    
  4. Test the Application


Part 12: Using the Camera API


In this section, we use the PhoneGap Camera API to provide the user with the ability to take a picture of an employee, and use that picture as the employee’s picture in the application. We do not persist that picture in this sample application.

The code below only works when running the application on your device as a PhoneGap app. In other words, you can’t test it in a browser on the desktop.
  1. In index.html, add the following list item to the employee template:
    <li><a href="#" class="change-pic-btn">Change Picture</a></li>
    
  2. In the initialize() function of EmployeeView, register an event listener for the click event of the Change Picture list item:
    this.el.on('click', '.change-pic-btn', this.changePicture);
    
  3. In EmployeeView, define the changePicture event handler as follows:
    this.changePicture = function(event) {
        event.preventDefault();
        if (!navigator.camera) {
            app.showAlert("Camera API not supported", "Error");
            return;
        }
        var options =   {   quality: 50,
                            destinationType: Camera.DestinationType.DATA_URL,
                            sourceType: 1,      // 0:Photo Library, 1=Camera, 2=Saved Photo Album
                            encodingType: 0     // 0=JPG 1=PNG
                        };
    
        navigator.camera.getPicture(
            function(imageData) {
                $('.employee-image', this.el).attr('src', "data:image/jpeg;base64," + imageData);
            },
            function() {
                app.showAlert('Error taking picture', 'Error');
            },
            options);
    
        return false;
    };
    
  4. Test the Application


Part 13: Sliding Pages with CSS Transitions


  1. Add the following classes to styles.css:
    .page {
        position: absolute;
        width: 100%;
        height: 100%;
        -webkit-transform:translate3d(0,0,0);
    }
    
    .stage-center {
        top: 0;
        left: 0;
    }
    
    .stage-left {
        left: -100%;
    }
    
    .stage-right {
        left: 100%;
    }
    
    .transition {
        -moz-transition-duration: .375s;
        -webkit-transition-duration: .375s;
        -o-transition-duration: .375s;
    }
    
  2. Inside the app object, define a slidePage() function implemented as follows:
    slidePage: function(page) {
    
        var currentPageDest,
            self = this;
    
        // If there is no current page (app just started) -> No transition: Position new page in the view port
        if (!this.currentPage) {
            $(page.el).attr('class', 'page stage-center');
            $('body').append(page.el);
            this.currentPage = page;
            return;
        }
    
        // Cleaning up: remove old pages that were moved out of the viewport
        $('.stage-right, .stage-left').not('.homePage').remove();
    
        if (page === app.homePage) {
            // Always apply a Back transition (slide from left) when we go back to the search page
            $(page.el).attr('class', 'page stage-left');
            currentPageDest = "stage-right";
        } else {
            // Forward transition (slide from right)
            $(page.el).attr('class', 'page stage-right');
            currentPageDest = "stage-left";
        }
    
        $('body').append(page.el);
    
        // Wait until the new page has been added to the DOM...
        setTimeout(function() {
            // Slide out the current page: If new page slides from the right -> slide current page to the left, and vice versa
            $(self.currentPage.el).attr('class', 'page transition ' + currentPageDest);
            // Slide in the new page
            $(page.el).attr('class', 'page stage-center transition');
            self.currentPage = page;
        });
    
    },
    
  3. Modify the route() function as follows:
    route: function() {
        var self = this;
        var hash = window.location.hash;
        if (!hash) {
            if (this.homePage) {
                this.slidePage(this.homePage);
            } else {
                this.homePage = new HomeView(this.store).render();
                this.slidePage(this.homePage);
            }
            return;
        }
        var match = hash.match(this.detailsURL);
        if (match) {
            this.store.findById(Number(match[1]), function(employee) {
                self.slidePage(new EmployeeView(employee).render());
            });
        }
    },
    

143 Responses to Tutorial: Developing a PhoneGap Application

  1. Adrien Glitchbone November 27, 2012 at 7:30 pm #

    Awesome!

    • Gary Banzo June 24, 2013 at 1:59 am #

      Alternatives to Phonegap Build?

  2. ryo November 27, 2012 at 7:34 pm #

    very nice tutorial, very simple and clear. I am in the process of adding transition to my apps, and find part 8, part 13 is very useful.

    • ryo November 28, 2012 at 11:08 pm #

      In my case, css a:active would be better than part8 touchstart, touchend event hack on the mobile device. The later one will have a problem if you touch the button or anchor, and hold it, move to other place and release it. The css class “tappable-active” will not be removed.

  3. JCLang November 28, 2012 at 11:19 am #

    Hello Christophe.
    A great job you’re doing, thank you.
    We miss you in the Flex World :)

  4. csheets November 28, 2012 at 6:23 pm #

    excellent tutorial – best I have seen on creating a good phonegap application architecture

    I haven’t made it all the way through yet but I have found a couple of items that may be of use to others:

    1) Step #4 is missing ending “;” for html var declaration statement – this renders in Chrome desktop browser but not on Android

    2) Step #5.1 tag needs to be placed before the app.js tag (maybe obvious but..)

    also I should mention that I am using PhoneGap 2.2 in Eclipse development environment

    again thanks for the tutorial and architecture example!

  5. Dams640 December 4, 2012 at 12:43 pm #

    Thank you for this great job!

  6. Styxali December 4, 2012 at 9:08 pm #

    Very nice tutorial.. Thanks a lot (y)

  7. Anon December 4, 2012 at 10:38 pm #

    Thanks for the great tutorial! Question: After selecting an employee and “sliding” back to the homepage, the search box seems to be disabled. Anyone know why? Thanks.

  8. Sandro December 8, 2012 at 3:25 pm #

    I have the same issue. Anyone can help us? Thanks!

  9. Vladimir December 14, 2012 at 11:38 am #

    This is great tutorial, i had pleasure reading and following. There is some code which didn’t work for me, like calling methods within event handlers. So I had to wrap them within anonymous functions and also give them context. For example this event handler this.el.on(‘keyup’, ‘.search-key’, this.findByName); had to be written llike var that = this; this.el.on(‘keyup’, ‘.search-key’, function(){that.findByName();});

    My question is there a particular name for this pattern in JavaScript ? It reminds me some of BackboneJS structuring. Were you inspired by it?

    It would be also great to see some ajax layers and how would that fit into a whole thing.

    Awesome tutorial once again, thanks!

    • Jim O'Keefe February 4, 2013 at 5:28 pm #

      I had the same experience. Original code caused an error within jQuery. Vlad’s code worked.

    • Jim O'Keefe February 5, 2013 at 2:20 am #

      Similarly in step 11.2 this is what worked for me:

      this.el.on(‘click’, ‘.add-location-btn’, function(){that.addLocation(event);});

      notice in particular that the event needed to be passed along to the addLocation function.

      • Jim O'Keefe February 5, 2013 at 2:22 am #

        that should be section 10.2 – Using the Location API

    • Anna October 2, 2013 at 1:36 pm #

      Thanks for this fix!

  10. kozmicblues December 15, 2012 at 3:59 am #

    Great tutorials. I’ve learned a lot.
    How come in the websql-store.js you always drop the table and repopulate it? How come you don’t check the version first and not install it if there are no changes?

  11. phpyuz December 20, 2012 at 4:20 pm #

    Christophe, very nice tutorial. I have a question for you. ;)
    Windows Phone doesn’t support WebSQL. Can lawnchair be a valid alternative to store big size data? Please, advice.

  12. Isidro January 15, 2013 at 6:26 pm #

    Regarding to the search box disabled when going back to the home page, I solved it setting the id of the div element in HomeView.js to “homePage” and changing … not(‘.homePage’) … to … not(‘#homePage’) … in main.js.

    • andyg1 May 11, 2013 at 9:43 am #

      That’s a great shout.

    • Bleepy November 22, 2013 at 6:50 am #

      This didnt work for me :(

      • Bleepy November 22, 2013 at 6:53 am #

        Apologies, it did fix the problem.
        Now to find out why I can still scroll to the employee page from home.

  13. cirovladimir January 18, 2013 at 1:41 am #

    Thank you very much!

    Very good tutorial. Now I have an idea of phonegap to see if it fits my needs.

  14. Sam Hunting January 24, 2013 at 6:45 am #

    Thanks for the best tutorial on Cordova/PhoneGap I have seen.

    I’m having trouble with this function:

    this.store.findById(Number(match[1]), function(employee)

    In step 3.3.

    I’m using memoryStore, and when I trace the callback there the parameters seem to be right. I’m using Cordova 2.30.

    • MuddJeff February 8, 2013 at 9:42 pm #

      Check that you have the ‘employee’ in Part 9, step 2.
      var EmployeeView = function(employee) { … }

      It’s there in step 2.3, but not in step 2.1 – 2.2

      • David Horn March 28, 2014 at 8:32 pm #

        Brilliant – thanks for that … loads of head scratching, and I’d missed the (employee) out of the function. Cheers!

  15. 4Dev January 30, 2013 at 2:59 pm #

    Would just like to know if you are using jQuery? It looks like it in some examples code.

    • Steve September 22, 2013 at 1:27 am #

      Yup, jQuery is used.

  16. foobar January 30, 2013 at 5:05 pm #

    Hi,

    is it possible to customize the splash screen and use the builder to build everything? For example creating the resource folder and put it in there and then upload it to phonegap builder?

    Thanks in advance

    • Chris August 22, 2013 at 5:37 am #

      Check the config.xml for the phonegap application. You can customize the splash screen and app icons from there.

  17. Dong February 1, 2013 at 4:38 pm #

    “If you don’t have an iOS device, or if you are not ready to upload your developer certificate, you can skip step 5 and keep running the application in the browser or a non iOS device.”

    However, I can not figure out how to skip step 5(upload apple developer certificate). The whole process just stopped.

    ps: I’m using the sample code from this tutorial.

    Thanks!

    • Dong February 1, 2013 at 8:16 pm #

      resolved!
      It need about one hour to finish compiling and go to next step.

  18. selman February 9, 2013 at 8:34 pm #

    Thanks for this insightful tutorial!

    Just one question: How can i import and use this code in eclipse?

    thanks

  19. niki4810 February 9, 2013 at 9:02 pm #

    Hi Christophe,

    Thank you very much for posting this very well organized tutorial. This is by far the best working tutorial I have come across for native mobile app development.

    Regards

  20. Joe February 12, 2013 at 5:31 am #

    Wow, native development?? Hardly, this is web development without the benefit of serving UI remotely. Just because it compiles into an “app” doesn’t make it “native”. It’s still depends on a browser, inferior JS engines and JS APIs, and HTML code.

  21. A.Bruce February 13, 2013 at 6:44 am #

    Small typos: Part 9, Step 2, Para 3. HomeView should be EmployeeView, twice.

  22. Walter February 16, 2013 at 4:28 am #

    thanks¡¡¡¡¡¡ served me a lot to understand the framework

  23. Mario February 19, 2013 at 1:51 pm #

    Hi, thank you for writing this tutorial.
    The resulting app, after building it with PhoneGap Build, is really slow on my Nexus S. (No other apps are running in background)
    Is there an active debug flag or something else, that should be unset for production release?
    Or is this what we can expect, concerning performance?
    Thx

  24. kathir February 26, 2013 at 9:03 pm #

    Can we display images & details from json(other site) details,
    for example
    can display food item images, details from dynamic site(mysql)
    Any example there?

  25. Joseph Mainwaring February 28, 2013 at 1:06 am #

    Thank you for sharing so many excellent implementation tutorials! I figured I would have to go hunt for examples of these individually

  26. dcz.switcher March 2, 2013 at 10:10 pm #

    Thanks for this awesome tuto !

    if it can help : in HomeView.js, you must declare render() and findByName() functions BEFORE initialize() !
    if not, you must use the Vladimir hack

    • Steve September 21, 2013 at 11:46 pm #

      Thanks, that helped!

  27. dcz.switcher March 2, 2013 at 10:39 pm #

    … and if the search function not work after use back button, you can do that.

    in main.js, slidePage() function, add an ID to homePage then, test it after to not delete this view

    slidePage : function(page){
    var currentPageDest,
    self = this;

    if(!this.currentPage){
    $(page.el)
    .attr(‘class’, ‘page stage-center’)
    .attr(‘id’, ‘homePage’); // add ID !

    $(‘body’).append(page.el);
    this.currentPage = page;
    return;
    }

    $(‘.stage-right, .stage-left’).not(‘#homePage’).remove(); // exclusion of the home page with the ID !

    • Steve September 22, 2013 at 1:13 am #

      Thanks that was needed after adding the transitions

  28. Andres March 25, 2013 at 3:55 am #

    thanks a lot.
    now, i can start my final task from college.

  29. Magesh April 2, 2013 at 12:31 pm #

    Thanks for this good tutorial..

  30. Ryan LeTulle April 2, 2013 at 9:24 pm #

    Thank you! Awesomely done!

  31. Jeremy April 9, 2013 at 7:46 am #

    Hi,

    Great tips.

    I read here https://groups.google.com/forum/?fromgroups=#!searchin/phonegap/translate3d/phonegap/SlNAA9EOpxA/MAdTuFex4vMJ that ’3D CSS transforms don’t work on Android 2.x or Android 3.x at all.’!!

    So your part 13 is limited to Android 4, correct?

    Kind regards
    J

  32. Morgan April 10, 2013 at 11:02 pm #

    When following your tutorials, I get the following error:

    Uncaught SyntaxError: Unexpected token u Insertion.js:1
    (anonymous function) Insertion.js:1
    module.exports.send ripple.js:37
    module.exports.initialize ripple.js:38
    _baton.pass ripple.js:13
    _baton.pass ripple.js:13
    (anonymous function)

    This is when I have created my own files and using your solution files. I am viewing the code via the cordova/phonegap emulator with ripple in chrome.

    Any ideas?

    • Ben August 20, 2013 at 9:14 pm #

      Did you ever figure this out? I’m having the same issue

      • Egbert October 2, 2013 at 2:07 am #

        In ripple, try using another device then generic.
        I selected the Nexus 4 and boom, error is gone.
        It has to do with the User Agent being undefined. When choosing another device to emulate it is well filled.

  33. Mkhuda April 29, 2013 at 10:54 pm #

    Phonegap is easy to use and easy to rock. Thanks mr. Conraets for your great article !
    I was made app because your tutorial is help me so much. :D

  34. Sanket May 1, 2013 at 2:19 pm #

    Will it work for the latest version? If not do you have some tutorial for the latest version of Phonegap?

    • Sennin May 7, 2013 at 9:48 am #

      What I need to do, If I want those animations works smoothly? If I tap the back button or simply choose person from list, animation is pathetic, even on quadcore devices.

  35. professional phonegap developer May 16, 2013 at 7:59 am #

    Someone essentially help to make seriously posts I would state. This is the very first time I frequented your web page and thus far? I amazed with the research you made to create this particular publish amazing. Great job!

  36. penile extender May 19, 2013 at 9:30 am #

    I almost never leave remarks, however i did some searching and
    wound up here Tutorial: Developing a PhoneGap Application |
    Christophe Coenraets. And I actually do have a couple of questions for you
    if you tend not to mind. Could it be only me or does it seem like a few of these comments appear like written by brain dead individuals?
    :-P And, if you are writing at additional online social sites, I would
    like to follow everything new you have to post. Would you list of all of
    all your social pages like your twitter feed, Facebook page or linkedin profile?

  37. nuwancv May 21, 2013 at 10:14 am #

    A wonderful tutorial – I learned many things and this helped me covered lots of new areas with JS based development for mobile phone..

    Looking forward to see more from you. Wish you luck!

  38. Nicolas Rouyer May 23, 2013 at 2:59 am #

    Hi Christophe,

    Thanks a lot for this wonderful tutorial : it has been very helpful to me.
    I have a little question : what should I do when phonegap build tells me that “This app isn’t using the latest version of PhoneGap. We recommend upgrading to 2.7.0″ ? Should I download latest version of phonegap to package my app instead of doing it online ?

    Best regards,

    NR

  39. Christophe May 23, 2013 at 10:54 am #

    Hi, very nice tutorial, was a great help for me!
    I have one question, the transitions between pages does some weird shit.
    the moment I click a link, the transitions start, but the content of the first page suddenly jumps down
    the content fades away, but is suddenly 50-100pixels lower before leaving the screen
    transition left or right, it’s the same problem

    Any idea?

    • Christophe May 24, 2013 at 10:53 am #

      Nevermind, fixed it…
      Other question, anyone here who knows how to work with iScroll? The scrolling works but the content jumps back to the top as soon as I release my finger?

  40. cash June 1, 2013 at 3:36 am #

    This is a completely useless tutorial

    Getting this crappy technology to work with eclipse is impossible unless you just want to write “hello
    world” .

    Phonegap is a far greater problem and more of a hassle than actually learning android .

    Don’t waste your time with this joke of a “technology” .

    But wait ! They have a solution – give away your idea and thus create a thousand clone apps on Github and they will compile it for you.
    That’s sweet.

  41. Nym June 5, 2013 at 1:19 pm #

    Christophe, I am curious if there is some benefit to replacing all content within the body tag rather than say just the html inside a container div with main content, in turn keeping the header bar in place. Of course this would eliminate the use of the page slide effect as well but that’s not something I really need. A coworker of mine suggested that it may be a performance issue manipulating the DOM but if the entire HTML content of the body tag is being replaced, isn’t that DOM manipulation as well?

  42. gary June 13, 2013 at 3:29 pm #

    One thing that got me confused is that the chapter “Part 7: Adding Styles and Touch-Based Scrolling”
    didn’t really affect the way the page looked, until I replaced

    - $(‘body’).html(new HomeView(self.store).render().el);
    + $(‘body’).append(new HomeView(self.store).render().el);

    (this change is spelled out much later in the last chapter but was not given at part 7 where it changes the entire “look”)

    please address all the comments in this tutorial to make it awesomer :)

    some parts of the code could be cleaned up. e.g:

    if (this.homePage) {
    this.slidePage(this.homePage);
    } else {
    this.homePage = new HomeView(this.store).render();
    this.slidePage(this.homePage);
    }

    could be replaced by
    if (!this.homePage) {
    this.homePage = new HomeView(this.store).render();
    }
    this.slidePage(this.homePage);

  43. S Bradley June 27, 2013 at 11:55 am #

    Hi can someone help me understand the search capability of Employee Directory a bit better?

    We would like to use this in our organisation but need to be able to search by the person’s name, by Project (this could be the Department field) to see everyone working on a particular project and by location so we can limit search to only people in a particular office. Are you able to search that way with this app ? or does it only let you search by the person’s name?

    Thanks in advance for any info you can provide.

  44. Tim Waldie June 28, 2013 at 11:41 am #

    Excellent course! We would love to see this in our online computer training library. Can you have a look at my site to see examples of the other courses we offer and contact me if you are interested in producing a course for us?

    Best, Tim

  45. dvd rw June 29, 2013 at 3:39 am #

    I reckon something really interesting about your site so I bookmarked .

  46. dvd online June 29, 2013 at 3:41 am #

    You have mentioned very interesting points ! ps decent website . “I understand a fury in your words, But not the words.” by William Shakespeare.

  47. twilight dvd box June 29, 2013 at 3:42 am #

    I really like your writing style, wonderful information, thanks for posting :D. “Much unhappiness has come into the world because of bewilderment and things left unsaid.” by Feodor Mikhailovich Dostoyevsky.

  48. JasonMichael July 7, 2013 at 1:48 pm #

    I think this code provides an interesting start to a project, but unfortunately, I’m not sure if this is a nuance with jQuery or Firefox or both, but tracking the windows.location.hash and then setting windows.location with this code gave some results that took hours to troubleshoot – especially trying to develop this on a PC and then move the code over to Android – that might also have been an issue. I had to put in a “preventDefault()” to keep control of the mouse/click event in order to prevent a page loading issue. Also, I suspect since the code is using $.proxy, it continues to retain old values and never gets the new hash value after the event – so this required me to put the hash into a separate object, outside of the app object and using that for the regular expression match – otherwise there was no way I was ever going to have the employee details show up.

    The good thing about spending the time to fix this – I got a very close view of how it all works, and am confident I can use this as a start to a personal project. I think I like this better than the backbone.js example, because my particular project is very involved and I think I could develop using this example first, and then streamline it later – but this code still provides an efficient manner to display content in a fast way, and is flexible enough to play around with various features and possibly get a SQLite database working with it.

    Thanks.
    -Jason

  49. Rima July 12, 2013 at 4:22 pm #

    Great tutorial, I didn’t know where to start with phone Gap before

  50. Pratik Butani July 13, 2013 at 6:43 am #

    Really Nice Practice…. Awesome…. Thanks a lot

  51. Fred July 21, 2013 at 6:25 pm #

    Great tutorial, did try it and got most areas to work however some areas still don’t work and would be great if you could share your thoughts

    Using latest version of phonegap and eulators i can get the scrolling to wok on either IOS or Android as well as non of the api’s are working,do you know if this is because how phonegap have evolved or any other points would be great
    (you can find my source code at https://bitbucket.org/fwahlqvist/phonegaptutorial )

    Many thanks
    Fred

    • Yuraï July 24, 2013 at 2:35 pm #

      In ‘index.html’ you use ‘phonegap.js’! Why? Why not ‘cordova.js’!? Change it ;-) And try this app to run in web browser like Chrome and look to the Console.
      Rule #2: Keep your application “browser runnable” :-)

  52. Lee Wright July 23, 2013 at 4:54 am #

    I visited this blog it is nice and very informative for apps developers. Thanks for sharing this information

  53. Mark Galbreath July 23, 2013 at 9:33 am #

    I’ve never seen a tutorial for a GUI that didn’t include screenshots…what gives?

  54. Jerry July 28, 2013 at 10:36 pm #

    I am implementing the camera api feature. But How can I test my app? Do i need to install every SDK on my machine?

    I been following this url: http://docs.phonegap.com/en/edge/guide_platforms_index.md.html. Starting with Android but wow I can’t get it working.

  55. Rahul Bohra July 30, 2013 at 5:53 am #

    Is there any way can i add new employee into the application?
    very well drafted, please email me the adding employee process, need to learn more.

  56. jkf August 14, 2013 at 7:52 am #

    Thanks a lot for this great tutorial, keep it up!

    At the moment I’m working on a app that uses Handlebars templating.
    Right now I’m trying to include any of the popular touch-swipe libraries (swipe.js, photoSwipe.js, swipeshow.js) in one of my Handlebars templates.

    But I’m keep on getting the same error: ReferenceError: Swipe is not defined @ main.js:43

    I do check if my template is properly loaded, and print it’s html to check if it exists in the DOM, and everything seems in place.
    I’m aware that someone has manage to do this before: http://jsfiddle.net/nGULk/

    For the routing, I use your basic routing function where I check for hashchanges

    $(window).on(‘hashchange’, route);

    and then I initialize the swipe object after parsing the current page in the slidePage function:

    function route() {
    var hash = window.location.hash;
    if (hash ===’#story’) {
    slider.slidePage(new storyView(storyTpl).render().el);

    if ($(‘#mySwipe’).length) {
    console.log(‘slider is in the dom’);
    var html = document.getElementById(‘storyPage-tpl’).innerHTML;
    console.log(html);
    var elem = document.getElementById(‘mySwipe’);
    window.mySwipe = Swipe(elem, {
    continuous: false,
    });
    } else {
    console.log(“slider not loaded”);
    }
    }
    }());

    I have no idea, what the problem is, any help would be great!

  57. Saje Dennis August 26, 2013 at 8:14 am #

    I was really enjoyed with this post, I think it will be a great article and useful for Phone Application developers, thanks

  58. Yudiz Solution September 9, 2013 at 2:39 am #

    It is great tutorial on developing the PhoneGap. I have great experience in using Cross Mobile Platform App. AnyWay I am gonna follow this tutorial and develop a best of app.

  59. GS&F September 9, 2013 at 1:00 pm #

    Phonegap is truly awesome. We literally just discovered it 2 weeks ago and we’ve been working through some tutorial for it. When we came across this one I knew we had something good going. Thank you all for taking the time to be so thorough with this tut it’s been really helpful for us with our latest venture in mobile dev.

  60. Developers Code September 12, 2013 at 7:54 am #

    Awesome.. Well explained Tut

  61. web Page September 21, 2013 at 10:06 pm #

    I think the admin of this site is really working hard for his web site, because here every stuff is quality based material.

  62. Hao September 24, 2013 at 12:17 am #

    Thanks for the great tutorial.

    I enjoyed it a lot, and now have a bit confidence of building a hybrid app.

    Sadly, it seems the camera and contact api is broken on iOS 7…

    I have tried the master sample code, it doesn’t work as well…

  63. marijuana's effect on the brain September 25, 2013 at 4:00 am #

    You will realize initially when i first started off looking at this I did not suppose this was initially fairly likely that exactly what you covered on this website actually
    existed.

  64. erwin September 29, 2013 at 6:48 am #

    Thanks a lot !
    I went through all steps without any issue ! up-to-date : Sept 29 / 2013…
    I paused on Step 5, to learn a little bit more about Handlebars.js
    then I went back into the tuto process….

    I wish all tuto on the web to be so easy to follow on…
    If it’s not too uch to ask for , please do a tuto on OAuth2 authentification ! could not find a good one….

  65. Winston October 7, 2013 at 12:24 am #

    Great tutorial, thanks a lot!!
    I’ve been throgh 6-5 tutorials, this one is the best so far!

  66. Dirk October 8, 2013 at 5:19 am #

    Excellent tutorial Christophe! People are even redistributing it without giving appropriate credits: http://harishblog.wordpress.com/2013/09/15/tutorial-developing-a-phonegap-application/

  67. brian October 10, 2013 at 11:50 pm #

    I am receiving an error when loading your apps with jquery mobile “connection to server was unsuccessful” I am not sure if it is because the folder stucture is wrong or if is because of the xml file. It seems to load every once in a while but really slow. Please help me.

  68. Fahed October 22, 2013 at 10:54 am #

    Hi,

    Great content! Thanks !

    Just a little mistake on part 9 step 2, replace “Define an initialize() function inside the HomeView class” with: “Define an initialize() function inside the EmployeeView class”

    Told twice before me but still not corrected, a little reminder will not hurt…

    • Liz November 30, 2013 at 5:11 pm #

      +1 x million for your comment! That was driving my crazy trying to figure it out

  69. Sicelo October 26, 2013 at 2:13 am #

    My man you are a life saver

  70. Reefersleep October 28, 2013 at 11:07 am #

    I can’t get eclipse to import this project, neither by choosing the zip or the extracted files. :/

  71. Gurunathan October 30, 2013 at 10:52 am #

    Hi
    Each And every sample code good and easy thank you for this .

    i want to implement local storage and sqlite in wp7 using phonegap 2.9.0 plz provide me way to use it

  72. John November 3, 2013 at 7:44 pm #

    I found perfect site for creating apps…Yesterday I ended up on some site called apps-machine.com . I have to share it with you guys. I started creating my own app and after 15 minutes clicking on their control panel(no programming,just clicks) I made app in what user could make effects on their photos,paint photos,play music,play videos,have notepad,chat and stream music. They got literally 1000′s of features on their control panel :D I think this could be a gold mine :P :P And I read something that they have free app development and so on. Aaand you can change everything all the backgrounds,colors,tabs…and you instantly see it on that same page through their simulator..don’t know how they managed to do that but it is super handy…I am super excited at the moment..time to get some apps on apple and play store :D :D

  73. jejehan November 12, 2013 at 12:40 am #

    thanks for tutorial, but i have problem, if i click back button on employee-tpl , iscroll doesnt work.

  74. andres November 12, 2013 at 5:20 am #

    hello, as you do, that apple does not display the alert message requesting permission for location var/mobile/applications/xxxx

    regards;

  75. Jeremy November 16, 2013 at 1:40 pm #

    Hi,

    In your tutorial above, it’s possible to swipe right to see the adjacent div’s content.

    How can i prevent the user from manualls swiping left/right?

    Many thanks

    • Bleepy November 22, 2013 at 6:15 am #

      I’m having the exact same problem.

      I’ve tweaked the slide removal code as a temporary fix, its not nice bit will remove the slide after .375 seconds which is the time of the transition in this example.

      Look for:
      $(‘.stage-right, .stage-left’).not(‘.homePage’).remove();

      Replace with:
      setTimeout(function(){
      $(‘.stage-left, .stage-right’).remove();
      }, 375);

      Nasty I know, but it works for me.

      • Bleepy November 22, 2013 at 6:43 am #

        Unfortunately this does not solve the search bar issue mentioned previously in the moments.

  76. eddy December 4, 2013 at 1:31 am #

    thanks very much for this tutorial but I want to modify the code so that the back button will go back to the previous page instead of going back to the search page. any ideas how can i do that?

  77. Janet December 11, 2013 at 11:11 am #

    This tutorial doesn’t work on iOS 7!!!

    There is a redirect loop on install and the app never gets fully installed. This seems to be the case with all of the PhoneGap Build apps in iOS 7.

    Anyone found a fix yet?

    • GrandSteph December 30, 2013 at 9:31 am #

      Janet,
      I had what I believe was the same issue and solved it in 2 steps. First, the UDID app I used to retrieve the device’s unique ID doesn’t work in iOS7. You have to use itunes (connect the device to your computer, then select the device in itunes and click on serial#, it will reveal the UDID. Then copy and it will copy it to your clipboard).
      Second, I had to redo the provisionning profile to match the correct UDID of the device. It did the trick for me. Hope it helps.

  78. bigL December 13, 2013 at 3:48 pm #

    Tried it on Android and did not see the Source Sans Pro font display correctly even when using the ‘solutions’ files directly. The font, however, did display correctly in the desktop browser. What changes would need to be made to get the Source Sans Pro font to display correctly on Android?

  79. Rajasekhar December 16, 2013 at 3:34 am #

    I’m working on a Calender scheduler using dhtmlx in phonegap.I managed to get the events from my mysql database but unable to create new events because the double click event in a touch screen enable to zoom-in or zoom-out.
    Please help me in this.how to disable this zoom-in and zoom-out and enable create event.

  80. Russell January 5, 2014 at 4:45 pm #

    I was going to ask a question, but this looks like a one-way blog, since I see no answers at all from the author (the Christophe in the replies is not the author and it’s not clear that the user “Chris” that replies – only once – is the author. Could be anybody.).

  81. Bruno Soufo January 6, 2014 at 2:34 pm #

    Thanx! very great turorial

  82. Alwyn Bester January 10, 2014 at 5:26 am #

    Thanks for a great tutorial. Was a great help for a PhoneGap NOOB like myself.

  83. katie rose January 18, 2014 at 5:44 am #

    great stuff for beginners!!

  84. Kiran January 24, 2014 at 2:37 pm #

    Thanks…Nice Tutorial…helps a lot for beginners like me….appreciate your effort in putting this tutorial together….

  85. Jimmy February 14, 2014 at 9:33 am #

    Do you wanna develop your iPhone Apps? No problem, we are ready to help you because we have huge information about it. come check out our website, http://www.taoteapps.com, we have a lot information to help making your mobile deployment a success.

  86. Martin February 24, 2014 at 4:47 am #

    Hi,

    its somehow frustrating.

    i just zip the solutions (www15) and let it build on phonegap online.
    Then installed it on my device (nexus 5).

    After open the app, everything works (like search, and visiting the profile)
    except all plugins : (

    It says “Contact API is not supported” or
    “Camera API is not supported”.

    I didnt change anything… why doesnt it work :(
    It would be very kind, if someone can help.

    Kind regards.

  87. Orkun March 2, 2014 at 3:22 pm #

    Hi,
    I ve downloaded the workshop zip, phonegap-workshop-master,
    as it is, when i open the index.

    There s no data, just a textbox and Hello on the top.
    What am i missing here?
    Cheers. -Orkun

    • One March 14, 2014 at 7:58 am #

      Maybe the glasses?

  88. Al March 5, 2014 at 12:41 pm #

    Can anyone tell me how to adjust HomeView.js to show the list right away rather than after typing something in?

  89. Jawad March 14, 2014 at 4:24 pm #

    I just want to start work on Phonegap after reading this tutorial. Appreciated!

  90. Andy Wibbels March 23, 2014 at 10:17 pm #

    Ran into problems with Part 4 – this helped answer my question – http://stackoverflow.com/questions/19908770/handlebars-template-is-not-rendered

    Christophe, it’d also be helpful if you post the final finished code – so we can compare it to where we are in your tutorial.

    Thanks for sharing it!

  91. www.gamezebo.com April 15, 2014 at 9:47 am #

    obviously like your web-site however you need to test the spelling on quite a few of your posts.

    Several of them are rife with spelling issues and I find it very bothersome to
    inform the reality nevertheless I’ll certainly come again again.

  92. https://www.youtube.com/ April 15, 2014 at 11:29 pm #

    I’m not sure where you’re getting your information, but good topic.
    I needs to spend some time learning much more or understanding more.
    Thanks for great info I was looking for this info for my mission.

  93. Trevor Best April 16, 2014 at 11:50 am #

    At step 6 it no longer works, I get “Uncaught TypeError: undefined is not a function” in jquery-1.8.2.min.js

    • Trevor Best April 16, 2014 at 12:06 pm #

      Sorry, Part 6

      • Trevor Best April 17, 2014 at 8:37 am #

        OK found it, the render() function needs to go above initialize()

Trackbacks/Pingbacks

  1. New Tutorial: Developing and Architecting a PhoneGap Application | Christophe Coenraets - November 26, 2012

    [...] tutorial is available here. Follow ccoenraets !function(d,s,id){var [...]

  2. Rad tutorial on building a PhoneGap mobile application — Blurb ★ Herd - November 27, 2012

    [...] Tutorial: Developing a PhoneGap Application by Christophe Coenraets [...]

  3. Blue Ray Plus - Latest Technology News - February 5, 2013

    Christophe Coenraets | Tutorial: Developing a PhoneGap Application…

    Thank you for submitting this cool story – Trackback from Blue Ray Plus – Latest Technology News…

  4. Phonegap Tutorials « PHPsolutionBD - February 18, 2013

    [...] http://coenraets.org/blog/phonegap-tutorial/ Share this:TwitterFacebookLike this:LikeBe the first to like this. Bookmark the permalink. Leave a comment [...]

  5. Getting Started with PhoneGap and PhoneGap Build | SDK News - February 19, 2013

    [...] Coenraets has a beginner’s tutorial to help you develop your first PhoneGap [...]

  6. PhoneGap Q&A | Christophe Coenraets - February 28, 2013

    [...] PhoneGap Tutorial [...]

  7. Débuter avec PhoneGap « Guide du Dev - March 11, 2013

    [...] article est basé sur : coenraets.org « aide d’installation WAMP Les Alerts avec PhoneGap [...]

  8. Les Alerts avec PhoneGap « Guide du Dev - March 11, 2013

    [...] article est basé sur : coenraets.org « Débuter avec PhoneGap [PHP] zebra image, faire du cropping d’images [...]

  9. Tutorial – Créer une application mobile avec PhoneGap et SenchaTouch | Blog agence web open source - May 23, 2013

    [...] http://coenraets.org/blog/phonegap-tutorial/ [...]

  10. Créer une application iphone : Tutoriel avec PhoneGap et SenchaTouch | Blog agence web open source - May 23, 2013

    [...] http://coenraets.org/blog/phonegap-tutorial/ [...]

  11. Capturematic: Leveraging Mobile Templates in a Backbone.js App | Developer Force Blog - August 13, 2013

    [...] Looking at style.css for a moment, you can see how I’ve extended the Mobile Templates to add styling for an icon-panel class (copied from the template’s detail-view-action-panel class and modified from vertical to horizontal orientation), and sliding pages with CSS transitions, inspired by Christophe Coenraets’ PhoneGap Tutorial. [...]

  12. PhoneGap : transformer votre single-page Web en une application mobile native | La petite pause technique - September 24, 2013

    [...] Tutoriel de développement d’une application PhoneGap [...]

  13. Phonegap plugins Contact API not supported when running on device | QueryPost.com - September 29, 2013

    [...] run the PhoneGap tuto written by Christophe Coenraets ( http://coenraets.org/blog/phonegap-tutorial/ ) .. no problem , I tested then built for iOS via Adobe PhoneGap Build.. and run it on my iphone [...]

  14. Мобильная разработка | Дмитриев Сергей - September 30, 2013

    [...] http://coenraets.org/blog/phonegap-tutorial/ [...]

  15. iPhonegap: Developing a PhoneGap Application | Solution's point... - October 9, 2013

    [...] Reference : Here [...]

  16. Phonegap and the universe of frameworks? | Technology & Programming - November 10, 2013

    [...] final decision is based on “http://coenraets.org/blog/phonegap-tutorial/&#8220;. This is a Tutorial about developing a Phonegap Application. Christophe Coenraets is a [...]

  17. Handlebars Template is not rendered - QueryPost.com | QueryPost.com - November 11, 2013

    [...] Hey I am completly new to Handlebars.js and almost new to JavaScript itself. So I tried to go through the following tut: http://coenraets.org/blog/phonegap-tutorial/ [...]

  18. Three great phoneGap tutorials » VC-TEL Team Blog - December 12, 2013

    [...] Developing a PhoneGap Application http://coenraets.org/blog/phonegap-tutorial/ [...]

  19. File Upload and Download in Phonegap , Mobile Application Development | Techooks - January 1, 2014

    [...] Posts Related to Simple Phonegap Tutorials More Tutorials studied Phonegap Tutorials [...]

  20. WordPress and Phonegap for mobile app development | Coding Logbook - March 15, 2014

    […] Tutorial: Developing a PhoneGap Application […]

Leave a Reply