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'); }); }
$('#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