3.14.2012

Nomination mobile - part 3


This post its a part of a series about creating an app with node.js and express for Facebook... this time for mobile browsers

Part 1
Part 2

Version en espaƱol


Desktop version:


Part 10

*NOTE: jqm = jquery mobile

This time we will see how to create a new nomination, how to see the details of one and how to add friends

Lets start updating the "dashboardm.jade"

#newn(data-role="page")
    div(data-role="header", data-theme="e")
        h1 New nomination
    //header

    div(data-role="header", data-theme="e")
        #errornf
        form#newf.ui-body.ui-body-a.ui-corner-all
            fieldset
                div(data-role="fieldcontain")
                    label(for="name") Name:
                    input#name(type="text", cols="40", rows="8", name="name")
                    label(for="date") End Date:
                    input#date(type="date", cols="40", rows="8", name="date")
                    button#newnfs(data-theme="b") Submit
    //content

    div(data-role="footer")
        a( href="#", data-rel="back", data-icon="back") Back
    //footer

///page new nomination
#addf(data-role="page")
    div(data-role="header", data-theme="e")
        h1 Add friends
    //header

    div(data-role="header", data-theme="d")
        div(data-role="fieldcontain")
            fieldset#lof(data-role="controlgroup")
    //content

    div.ui-bar(data-role="footer", data-theme="b", data-position="fixed")
        a#bina(href="#", data-icon="back") Back
        a.add(href="#", data-role="button", data-theme="b") Add

///page add friends
#details(data-role="page")

    div(data-role="header", data-theme="b")
        a#cancel(href="#", data-icon="delete") Cancel
        h1 Details
        a#end(href="#", data-icon="check") End
    ///header

    div(data-role="content")
        #attd
        .name
        .endD
        ul.users(data-role="listview")
            li(data-role="list-divider") Swipe to Vote/Delete
    ///content

    .ui-bar(data-role="footer", data-theme="b", data-position="fixed")
        div(data-role="controlgroup", data-type="horizontal")
            a(href="#", data-rel="back", data-icon="back") Back
            a#adduser(href="#", data-icon="plus") Add
            a(href="#", data-icon="refresh") Refresh
            a#remove(href="#", data-icon="minus") Remove Me
    ///footer

///page details

We are adding 3 pages, one for each thing all inside the same html

In new form we add a form where we ask for the name and the end date

In add friends, we show the list of friends so the user can select and add to the nomination

And last its the details page, this template will serve for all the types of nominations, we will show some buttons depending on the type but this will be done via jquery

Good, lets update the script in "mscript.js"

First lets add our function to load the friends

function loadUsers(next){
    $.getJSON(next || 'http://nomination.cloudno.de/friends', function(data) {
    if (data.data.length > 0){
        var list = $('#lof');
     $.each(data.data, function(key, value){
      list.append('<input type="checkbox" name="'+value.name+'" id="'+value.id+'" />');
      list.append('<label for="'+value.id+'">'+value.name+'</label>');
     });
     $('#lof').trigger( 'updatelayout' );
     loadUsers(data.paging.next);
 }else{
     return;
 }
    }).error(function() { showMsg('dashboard.error', 'dashboard.error_friends'); });
}

In this case we are loading the list of friends from facebook and adding it to the list to use it later, this list will be loaded as soon as the user land on the page, for that lets call the function when jqm create the page:

$('#dashboard-mine').live('pagecreate', function(){    
    loadNominations('mine');
    loadUsers(null);
});

We have our friends loaded, lets create a new nomination, remember that we put a button in all the pages to create one, lets give that button some functionality in "mscript" we add:

$('.create').live('click', function(){
    $.mobile.changePage( "#newn", { transition: "pop"} );
});

With this we tell jqm that at clicking this btn we will go to the new nomination page

In that page, lets wait for the user input and handle the submit button

$('#newnfs').live('click', function(ev){
    ev.preventDefault();
    $.mobile.showPageLoadingMsg();
    var name = $('#name').val();
    var date = $('#date').val();
    if (name!=='' && date !==''){
 $('#errornf').html('');
 $.post("http://nomination.cloudno.de/nominations/create", { name: name, datep: date },
     function(data) {
            var list = $('#mine');
            list.append('<li id="' + 
                data._id + '" type="mine"><a class="details" href="#">' + 
                data.name + '</a></li>');
            list.listview('refresh');
            $.mobile.hidePageLoadingMsg();
            $.mobile.changePage( "#dashboard-mine" );
            return false;
        }
 ).error(function() {
     $.mobile.hidePageLoadingMsg();
     $('#errornf').html('Error saving the nomination, try again later');
     return false;
 });
 return false;
    }else{
 $('#errornf').html('Name and date required');
 $.mobile.hidePageLoadingMsg();
 return false;
    }
});

First we show the msg that we are working, we retrieve the data from the form, we do a simple check and post it, show a message if any error, if the post goes without errors lets add the nomination to the mine list, then refresh the list so all the elements gets the styles, close the loading message and return to mine list

We have a new nomination, lets see the details, for this lets add to our lists that functionality, all the elements in the lists have the class "details" so lets use that

$('.details').live('click', function(){
    $.mobile.showPageLoadingMsg();
 var li = $(this).parents('li');
 var id = li.attr('id');
 var type = li.attr('type');
 $('#details').find('#attd').attr('past',$.mobile.activePage.attr('id'));
 showNomination(id, type, false);
 $.mobile.changePage($("#details"));
});

First take the data to know which nomination is selected, add some data to details page and then load the nomination with the "showNomination" function, after that lets change the page to details

"showNomination" functions its like this:

//cargar la nominacion y llenar details
function showNomination(id, type, refresh){
    $.mobile.showPageLoadingMsg();
    $.getJSON('http://nomination.cloudno.de/nominations/'+id, function(data) {
        if (!data){
            //alert('Du! nominacion ya no existe o termino :(');
            showMsg('dashboard.warning', 'dashboard.warning_erased');
        }
        var details = $('#details');
        details.find('#attd').attr('nid',id);
        details.find('#attd').attr('type',type);
        details.find('.name').html(data.name);
        var daten = new Date();
        daten.setISO8601(data.endDate);
        details.find('.endD').html( daten.getDate()+'/'+(daten.getMonth()+1)+'/'+daten.getUTCFullYear());
        var ntype = type;
        if (ntype === 'appear'){
            $('#end').hide();
            $('#cancel').hide();
            $('#remove').show();
        }else if (type === 'mine'){
            $('#end').show();
            $('#cancel').show();
            $('#remove').hide();
        }else{
            $('#end').hide();
            $('#cancel').hide();
            $('#remove').hide();
        }
        var usersl = details.find('.users');
        usersl.html('');
        var userl = data.users.length;
        usersl.hide();
        usersl.append('<li data-role="list-divider">Swipe to Vote/Delete</li>');
        for (var i=0; i<userl;i++){
      usersl.append('<li id="'+data.users[i]._id+'" type="'+type+'">'+
    '<img src="https://graph.facebook.com/'+data.users[i]._id+'/picture"/>'+
                data.users[i].name+
                '<span class="ui-li-count count">'+data.users[i].votes+'</span></li>');
        }
        usersl.listview('refresh');
        usersl.show();
        $.mobile.hidePageLoadingMsg();
    }).error(function() {
        $.mobile.hidePageLoadingMsg();
        showMsg('dashboard.error', 'dashboard.error_showing'); 
    });
}

We bring the data for the selected nomination and we fill out the details page, depending on the type of the nomination is the buttons we show, we add the list of friends already nominated and we refresh the list, if any error we show the message to the user, in this function we also use a function to parse the date from Facebook called "setISO8601"

Date.prototype.setISO8601 = function (string) {
    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
    var d = string.match(new RegExp(regexp));

    var offset = 0;
    var date = new Date(d[1], 0, 1);

    if (d[3]) { date.setMonth(d[3] - 1); }
    if (d[5]) { date.setDate(d[5]); }
    if (d[7]) { date.setHours(d[7]); }
    if (d[8]) { date.setMinutes(d[8]); }
    if (d[10]) { date.setSeconds(d[10]); }
    if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
    if (d[14]) {
        offset = (Number(d[16]) * 60) + Number(d[17]);
        offset *= ((d[15] == '-') ? 1 : -1);
    }

    offset -= date.getTimezoneOffset();
    var time = (Number(date) + (offset * 60 * 1000));
    this.setTime(Number(time));
};

Ok, we have the nomination, now lets add friends:

$('#adduser').live('click', function(){
    $.mobile.changePage( "#addf",
    {
     transition: "pop",
     reverse: false,
     changeHash: false
 });
});

When the user click on add user we change to the list of friends page, in tis page we show all the friends and an add button

$('.add').live('click', function(){
    $.mobile.showPageLoadingMsg();
    var users = [];
    var userp;
    $('#lof').find(':checked').each(function(){
        users.push({
            "_id" : $(this).attr('id'),
            "name" : $(this).attr('name'),
            "votes" : 0
        });
    });
    var ul = users.length;
    if (ul > 0 && ul <= 1){
        userp = users[0];
    }else{
     userp = users;
    }
    var details = $('#details');
    var nid = details.find('#attd').attr('nid');
    var type = details.find('#attd').attr('type');
    $.post("http://nomination.cloudno.de/nominations/adduser", { id: nid, users: userp },
 function(data) {
     if (data){
            $.each(users,function(key, value){
                var usersl = details.find('.users');
                usersl.append('<li id="'+value._id+'" type="'+type+'">'+
                    '<img src="https://graph.facebook.com/'+value._id+'/picture"/>'+
                    value.name+
                    '<span class="ui-li-count count">0</span></li>');
                usersl.listview('refresh');
            });
            $.mobile.changePage( "#details" );
     }else{
      $.mobile.changePage( "#details" );
      showMsg('dashboard.error', 'dashboard.error_adduser');
     }
     $.mobile.hidePageLoadingMsg();
 }).error(function() { 
        $.mobile.hidePageLoadingMsg(); 
        showMsg('dashboard.error', 'dashboard.error_adduser'); 
    });
});

We got the list of selected users, we add them to the nomination and if everything its ok we add the to the list to the page to later return to the details page

Great, we are set now, next time we will see how to add/erase users in a nomination and how to invite more friends to play

Fork the code

[https://github.com/nodejs-mexico/nomi-nation](https://github.com/nodejs-mexico/nomi-nation)

Greetings

No comments:

Post a Comment