2.20.2012

Nomination part 10 - last touches


Version en espaƱol


This post is part of the series about creating an app with node.js, express for Facebook



Lets put a beta version now, lets integrate a search, a way to invite friends to the app, a logo and lets fix some of the reported bugs, lets go with parts:


1. Lets put a validation so users can only vote once a day, for this lets change how we add the voters, this part was made by Github alejandromg that holds the blog, nodehispano, but what he did overall its when we add a voter, we add an object with the facebook id as the object identifier and inside this the date of the last time the user voted, also i update the validation to search where the user has voted. thanks Alejandro


2. Lets add searching, for this we are going to add a little input text in our header as a form, with jquery we are going to bind to the submit event and with some ajax do the searching and on return show the list of nominations with those terms:

First lets update our "dashboard.jade" in the header part:

form#sf(action="#")
            input.search(type="text", placeholder="Search")


and this at the end to show the results

#dialog-sr(title="#{t('dashboard.search_results')}")
    form
        fieldset#sr


then lets add this to "dashboard.js" to add the route

    /**
     * buscar nominaciones
     */
    app.post('/nominations/search', checkUser, function(req, res){
        var term = req.param('term');
        nominator.findNominationByName( term, function(err, data){
            if (err) { log.debug('error getting nominations:' + err); res.json(null); return; }
            res.json(data);
        });
    });


Then update uur controller to add seaches in the db:

/**
 * find nominations by term
 * @term nomination name or term
 * @callback function
 *
 */
NOMINATOR.findNominationByName = function(term, callback){
    //TODO: scape this
    var myregex = RegExp(term);
    Nomination.find({name: myregex},['name', 'id'], callback);
};


Finally put our jquery part in "script.js":

$('#sf').submit(function(){
        var searchTerm = $('#sf').find('.search').val();
        if (searchTerm){
            $('.loading').show();
            //console.log(searchTerm);
            $.post("/nominations/search", { term: searchTerm },
                function(data) {
                    if (data){
                        var datal = data.length;
                        if (datal <1 ){
                            showMsg('dashboard.warning', 'dashboard.notfound');
                            $('.loading').hide();
                            return;
                        }
                        var dialog = $( '#dialog-sr' );
                        var fs = dialog.find('#sr');
                        fs.html('');
                        for (var i=0;i<datal;i++){
                            fs.append('<input type="radio" name="sr" value="'+data[i]._id+'"> '+data[i].name+'<br>');
                        }
                        dialog.dialog('open');
                    }else{
                        showMsg('dashboard.error', 'dashboard.error_searching');
                    }
                    $('.loading').hide();
                }
            ).error(function() { $('.loading').hide(); showMsg('dashboard.error', 'dashboard.error_searching'); });
        }
        return false;
    });

3. We need the users invite other people without nominating them so lets put a link to do that, after search text box lets put a link, catch the "click" event with jquery and show the list of friends to invite and from node write in the wall of the invited user(s)

In the hader of "Dashboard.jade"

div
            a.invite(href="#") Invite


at the end:

#dialog-invite(title="#{t('dashboard.invite_friends')}")
    form#filterformi(action="#")
        input#filterinputi(type="text")
    br
    form
        fieldset
            ol#selectablei


Lets add the route to the "dashboard.js"

/**
     * Invitar amigos
     */
    app.post('/invite', checkUser, function(req, res){
        var usersl = req.param('users');
        var userl = 0;
        var onerror;
        if (usersl instanceof Array){
            userl = usersl.length;
            onerror = function (error) {
                        if (error) { log.debug('error posting on voted user'); return; }
                    };
            for (var i=0;i<userl;i++){
                fb.apiCall(
                    'POST',
                    '/'+usersl[i]._id+'/feed',
                    {
                        access_token: req.session.user.access_token,
                        message: app._locals.t('dashboard.invited'),
                        name: app._locals.t('dashboard.nominate'),
                        link: url
                    },
                    onerror
                );
            }
        }else{
            onerror = function (error) {
                    if (error) { log.debug('error posting on voted user'); return; }
                };
            fb.apiCall(
                'POST',
                '/'+usersl._id+'/feed',
                {
                        access_token: req.session.user.access_token,
                        message: app._locals.t('dashboard.invited'),
                        name: app._locals.t('dashboard.nominate'),
                        link: url
                },
                onerror
            );
        }
        res.json(true);
    });


And our jquery code:

//creamos el dialog de agregar usuarios
    $( "#dialog-invite" ).dialog({
        autoOpen: false,
        height: 300,
  width: 450,
  modal: true,
  buttons: {
   "Invite friend(s)": function() {
                $('.loading').show();
                var dialog = $(this);
                var users = [];
                var userp;
                $('#selectablei').find('.ui-selected').each(function(key, value){
                    users.push({
                        "_id" : $(value).attr('id'),
                        "name" : $(value).text()
                    });
                });
                var ul = users.length;
                if (ul > 0 && ul <= 1){
                    userp = users[0];
                }else{
                    userp = users;
                }
                $.post("/invite", { users: userp },
                    function(data) {
                        if (data){
                            showMsg('dashboard.warning', 'dashboard.invited');
                            dialog.dialog( "close" );
                        }else{
                            dialog.dialog( "close" );
                            showMsg('dashboard.error', 'dashboard.warning_invited');
                        }
                        $('.loading').hide();
                    }
                ).error(function() { $('.loading').hide(); showMsg('dashboard.warning', 'dashboard.warning_invited'); });
   },
   Cancel: function() {
    $( this ).dialog( "close" );
   }
  },
  close: function() {
   //TODO:
  }
 });

$('.invite').click(function(){
        $( "#dialog-invite" ).dialog( "open" );
    });



4. Update our translation strings in all the folders

5. Update some styles

6. Alejandromg found an error at the moment of finishing a nomination when no users were added, the app hang, we just add an "if" to check the list of users if none we just cancel the nomination

7. See my very amateur gimp logo, its like a small diploma showing that you can win something... options are welcome
8. Add a wiki in github with a smal tutorial to use the app (in spanish only for now, translators are welcome)

9. Update the facebook page, put the logo and some info

10. Close github issues and

11. We have a beta :), lets make noise in facebook and with the friends, hopefully they will enjoy the app as well i did creating it


YAY!!!, we have our app working with node.js, express and some other modules

We have still some bugs so you are welcome to help

If you have ideas for enhancements send them, we will try to add them

Next post we will try to do the mobile version

Use and promote the app.

Fork the code in github:


Greetings 

No comments:

Post a Comment