jQuery

jQuery To Do List App w/ SDK

We've provided an example app running on DreamFactory for the backend using only jQuery and Twitter Bootstrap, along with our JavaScript SDK for authenticating and making CRUD calls to the database. The app of choice here is the infamous to do list. To try it out for yourself, just sign up for a free DreamFactory account. You can add items to the list, toggle their completion status, and delete items from the list. Here's what the app looks like in action.

jQuery Todo App

It utilizes the DreamFactory REST API to communicate with the backend (your DreamFactory Services Platform or “DSP” for short). 

If you are brand new to DreamFactory we have screencasts explaining how to get started with DreamFactory and build an app from scratch.

We also have to do list apps for other popular frameworks - AngularJS and Sencha Touch.

Be sure to check out the sections at the end of this article. They show how to access our Live API Docs and how enabling CORS on your DSP allows you to run from your local machine or a service like Plunker.

Running and Exploring the App

This section shows you how to run the app and understand how it's put together. To skip straight to the code walkthrough click here.

We're assuming that you have access to the admin console for your DSP. If you don’t have a DreamFactory account, sign up here. Once you’ve signed up, go to https://<your-dsp-name>.cloud.dreamfactory.com and you can log in to the admin console. From the Applications tab look for an app named To Do List jQuery.

jQuery ToDo Image 01

This app came preinstalled on your DSP. If it was deleted or is missing for some reason you can import it by clicking the Import New App button in the upper right, selecting the To Do List jQuery app from the list, and clicking the Import button.

jQuery ToDo Image 02

Then go back to the Applications tab and it will be in the list. Click the preview button next to To Do List jQuery.  You should see the app running on the right side of the admin console. Try adding a few items to the list. You can click the item name to toggle the completion, or click the minus to delete.

jQuery ToDo Image 03

Click the file manager icon to view the source code for this app. These files are hosted on your DSP and can be edited live by clicking the pencil icon. You can drag and drop files from your desktop to the file manager, or upload zip files. We'll show you later how to run from files on your local machine for development and testing purposes.

jQuery ToDo Image 04

 

Code Walkthrough

This app consists of three files plus the SDK.

index.html - loads jQuery and Twitter Bootstrap and has a table to hold the list. It has an input field and add button for adding items to the list.

app.js - functions for creating, retrieving, updating, and deleting list items and building the list.

style.css - simple styling

The complete source code for this app is available on GitHub at https://github.com/dreamfactorysoftware/app-todo-jquery.  You can go there to clone this repo to your local machine.

In the SDK /lib directory there is a file sdk_init.c. This is where you specify the name of your app and the DSP your app is talking to. For hosted apps that use the DSP for app file storage you could set dsp_url to use location.protocol and location.host and it would always init the SDK to use the "current" DSP. If not a hosted app then dsp_url should be set to the DSP you want to use for that app.

When the SDK has been initialized the 'apiReady' event is triggered. At that point the app is ready to make API calls. The first thing we should do is check for a valid session and, if none exists, try to log in. The doLoginDialog() and login() methods take care of this.

$(window).on("apiReady", function () {

    checkSession();
});

// session

function checkSession() {

    $("#loading").show();
    // check for existing session, relevant when code is hosted on the dsp
    window.df.apis.user.getSession({"body": {}}, function (response) {
        $("#loading").hide();
        // existing session found, assign session token
        // to be used for the session duration
        var session = new ApiKeyAuthorization(
            "X-Dreamfactory-Session-Token",
            response.session_id,
            'header');
        window.authorizations.add("X-DreamFactory-Session-Token", session);
        runApp();
    }, function (response) {
        $("#loading").hide();
        // no valid session, try to log in
        doLogInDialog();
    });
}

After a session has been established we call runApp() which is the main entry point into the app. The function getRecords() uses the SDK to retrieve all records from the database table named todo. You could easily use NoSQL storage such as MongoDB by adding it as a new service on your DSP, then changing df.apis.db to df.apis.mongodb in each SDK call.

function runApp() {

    // your app starts here
    getRecords();
}

function getRecords() {

    window.df.apis.db.getRecords({"table_name":"todo"},
    function (response) {
        buildItemList(response);
    }, crudError
    );
}

On success, an array of records is returned such as

{
   "record":[
      {
         "id":"35",
         "name":"item 1",
         "complete":false
      },
      {
         "id":"36",
         "name":"item 2",
         "complete":true
      },
      {
         "id":"38",
         "name":"item 3",
         "complete":false
      }
   ]
}

buildItemList() uses this array to populate a table inside the list-container div. Column 1 of the table is for the delete icon. Column two is for the item name. The id of each item is stored in data-id and used when the item is updated or deleted. Note the onclick handlers being set up for the update and delete ui elements. This is where the completion is toggled.

function buildItemList(json) {

    var html = '';
    if (json.record) {
        json.record.forEach(function (entry) {
            var name = entry.name;
            var id = entry.id;
            html += '';
            html += '';
            if (entry.complete === true) {
                html += '' + name + '';
            } else {
                html += '' + name + '';
            }
            html += '';
        });
    }
    $('table').html(html);
    $('#list-container .item').click(function (e) {
        var id = $(this).data('id');
        var complete = $(this).hasClass('strike');
        updateRecord(id, !complete);
    });
    $('#list-container i').click(function (e) {
        var id = $(this).data('id');
        deleteRecord(id);
    });
}

When you enter a new item and click the Add Item button, the function createRecord() is called. It grabs the item name from the input field and, if not empty, calls the SDK createRecords() method. The POST data is passed in as the "body" field and is an array of JS objects. In this case there's only one element in the array. Since it's a new item we will set the complete field to false. On success the input field is cleared and the list is rebuilt. To keep things as simple as possible we are calling getRecords() to retrieve and rebuild the entire list rather than updating the DOM with only the items that changed.

function createRecord() {

    var name = $('#itemname').val();
    if (name === '') return;
    var item = {"record":[
        {"name":name, "complete":false}
    ]};
    df.apis.db.createRecords({"table_name":"todo", "body":item},
    function (response) {
        $('#itemname').val('');
        getRecords();
    }, crudError
    );
}

You can click an item in the list to toggle its completion status. Each time you do this the function updateRecord() will be called. It calls the SDK method mergeRecords() with body containing an array of records to be updated. The database id must be included for each record being updated.

function updateRecord(id, complete) {

    var item = {"record":[
        {"id":id, "complete":complete}
    ]};
    df.apis.db.mergeRecords({"table_name":"todo", "body":item},
    function (response) {
        getRecords();
    }, crudError
    );
}

You can click the minus button next to an item to delete it from the list. Each time you do this the function deleteRecord() will be called. It calls the SDK method deleteRecords() with the ids field containing a comma-delimited list of ids to delete.

function deleteRecord(id) {

    df.apis.db.deleteRecords({"table_name":"todo", "ids":id},
    function (response) {
        getRecords();
    }, crudError
    );
}

 

REST API Live Docs

To learn and experiment with the REST API you can access the Live API Documentation from your DSP's admin console.

jQuery ToDo Image 05

Running Locally

For development and testing purposes it is often helpful to have the code on your local machine and still make the same API calls to your DSP.  In this case you can turn on CORS to prevent the browser from enforcing the same-origin policy.  Go to the System Config screen in your DSP admin console and add * as the Host for CORS Access.

jQuery ToDo Image 06

You may want to enable guest users and assign them a role that gives them access to your app.  A guest user can make API calls without being logged in, with access limited by the assigned guest role.  After making these changes on the System Config screen you can access your DSP directly from your local machine.  Just change the URL in sdk_init.js to point to your DSP such as https://dsp-foo.cloud.dreamfactory.com.  Then open your local index.html in your browser.

Conclusion

That about covers the specifics of this app. If you have any questions or comments please contact us at support@dreamfactory.com. Your feedback is important to us!