2012-11-28 19 views
8

Sto lavorando su un modulo di registrazione di base in Node.js (con Express), e sto cercando di trovare il modo più semplice per fornire la convalida del modulo di base. Sono andato con "Express-Validator", che sembra fare un buon lavoro. Tuttavia, il mio obiettivo è semplicemente mostrare tutti i messaggi di convalida richiesti e per lasciare i valori immessi dall'utente solo.Node.js (Express) Modulo Cancella su invio

Sembra che le informazioni sulla richiesta non stiano rientrando nel res.render, il che credo abbia senso. Tuttavia, ho guardato ovunque mi viene in mente e non riesco a trovare alcun riferimento che discuti su come mantenere popolati i campi modulo dopo aver mostrato i messaggi di errore.

Qui di seguito è un piccolo frammento che descrive il mio approccio:

post: function(req, res){ 

      var userName = req.body.username; 
      var password = req.body.password; 

      //Validate input 
      req.assert("username", 'Invalid email address.').isEmail(); 
      req.assert("password", 'Password cannot be empty.').notEmpty(); 
      req.assert("passwordConfirm", 'Passwords entered do not match!').equals(password); 

      //Make sure we have no validation errors 
      var pageErrors = req.validationErrors(); 
      if(!pageErrors) 
      { 
       userModel.CreateUser(userName, password, function(err){ 
        if(err) 
        { 
         //there was a problem inserting new user... probably already exists 
         //will need to check the error to confirm 
         var dbErrorMessage = "Could not insert record into database!"; 
         if(err.code === 11000) 
         { 
          //this is a duplicate entry 
          dbErrorMessage = "A user with that email address already exists!"; 
         } 

         res.render('register.html', { pageErrors: [{msg: dbErrorMessage }]}); 
        } 
        else 
        { 
         res.render('register.html', { successMessage: successMessage }); 
        } 
       }); 
      } 
      else 
      { 
       res.render('register.html', { pageErrors: pageErrors }); 
      } 
+0

Questo è ciò che la gente intende quando dicono che "il web è senza stato". È necessario reinserire manualmente i valori dopo ogni richiesta. –

+1

Sì, ho capito che sarebbe stato necessario un intervento da parte del server per ritrasferire i valori, ma speravo che Express avesse qualcosa (o un componente aggiuntivo del middleware) che potesse farlo per noi. Mi limiterò a seguire il percorso di invio del modulo AJAX. Sarebbe comunque un'esperienza utente migliore. – creativename

risposta

10

Purtroppo, è necessario ripopolare il modulo manualmente. Se si verificano errori di pagina, si passeranno i valori del modulo alla vista.

 if(!pageErrors) 
     { 
      // ... 
     } 
     else 
     { 
      res.render('register.html', { 
       pageErrors: pageErrors, 
       userName: userName 
      }); 
     } 

E dal tuo punto di vista, dovresti fare un semplice controllo per vedere se ci sono errori e ripopolare di conseguenza. Dovresti tenere traccia di quali errori vengono prodotti per ogni campo modulo.

<% if (userNameError) { %> 
    <input type="text" name="userName" value="<%- userName %>" /> 
<% } else { %> 
    <input type="text" name="userName" /> 
<% } %> 

Un altro modo popolare è quello di inviare il modulo tramite la tecnologia AJAX per il server, e fare tutte le vostre convalide. Se si verifica un errore, i dati del modulo immessi rimangono e si visualizzerà l'errore, altrimenti il ​​reindirizzamento dopo il login riuscito. Di seguito è riportato un esempio di come inviare un modulo con javascript.

$("#login-button").live("submit", function (e) { 

    // this will prevent the form from being uploaded to the server the conventioanl way 
    e.preventDefault(); 

    // the form data 
    var data = $(this).serialize(); 

    // this logs the user in 
    $.ajax({ 
     type: 'POST', 
     url: BASE_URL + '/login', 
     data: data, 
     dataType: 'json', 
     success: function (data, status) { 
      // successful 
     }, 

    }); 

    // superfluous fallback 
    return false; 
}); 
+1

+1. A seconda della complessità dell'app, potrebbe essere relativamente semplice inviare il modulo tramite Ajax e restituire i messaggi di errore tramite JSON (e aggiornare la pagina di conseguenza con JavaScript). –

+0

Grazie, penso che sia proprio il modo in cui dovrò andare, allora. Farò semplicemente dei moduli come chiamate AJAX e andrò da lì.Ho pensato che potrebbe essere "più facile" fare post completi, ma ciò presupponeva che express potesse in qualche modo aiutare a restituire i valori di input. Immagino che sia quello che ottengo per venire da .NET! – creativename

-1

controllo http://www.quietless.com/kitchen/building-a-login-system-in-node-js-and-mongodb/

su register.html rendono questo

var data = {}; 
     data.user = $('#user-input').val(); 
     data.email = $('#email-input').val(); 
     data.pass = $('#pass-input').val(); 
    $.ajax({ url: '/signup' 
      , type: 'POST' 
      , data: JSON.stringify(data) 
      , contentType: 'application/json' 
      , dataType: 'html' 
     }) 
     .done(function(data) { 
      if (data == 'ok') { 
       $('#content').html('You are registered!'); 
      } 
      else $('#account-form-container').append('<br>error:' + data); 
     }); 

ci potrebbe essere errore come: Non puoi inviare/

in questo caso l'autore del tutorial su link qui sopra usi lib $ .ajaxForm

puoi anche usare https://github.com/felixge/node-formidable

o $ ('# myform'). Submit() sostituire a $ ('# submit-a-link'). Click()

5

C'è un modo semplice è che si sta utilizzando

app.use(express.bodyParser()) and app.use(expressValidator()); 

È possibile utilizzare req.body

res.render('register.html', { 
     pageErrors: pageErrors, 
     validated: req.body 
    }); 

E io non sono sicuro di quale linguaggio di template che si sta utilizzando, ma si potrebbe fare qualcosa di simile ..

<input type="text" name="userName" value="<%= pageErrors.userName.value || validated.userName %>" /> 

Questo restituisce l'input corretto se ok o l'input errato se è necessario correggerlo.

+0

Grazie, penso che questo sia in realtà il modo corretto di utilizzare il "pageErrors" che expressValidator genera. Dovrei fare una combinazione di convalida AJAX e quindi usarlo come fallback in caso di JavaScript disabilitato. – creativename

0

impostare una variabile per tutti gli input, ad esempio

var inputData = { 
    firstname : req.body.firstname, 
    lastname : req.body.lastname, 
    email : req.body.email, 
    username : req.body.username, 
    password : req.body.password, 
    password_confirmation : req.body.password_confirmation, 
    agreetoterms: req.body.agreetoterms 
} 

e quindi passare tale variabile alla vista

res.render('register.html', { pageErrors: [{msg: dbErrorMessage }], inputData: inputData }); 

quindi nella vista

value="<%= inputData.userName %>" 
3

È possibile ottenere questo fatto utilizzando connect-flash

Di seguito sono riportati i frammenti di codice in file diversi al fine di ottenere i valori immessi dall'utente di nuovo in forma quando le convalide falliscono durante l'iscrizione con il passaporto.

Esegui il sotto comando per aggiungere nuovo pacchetto in package.json

npm install connect-flash --save 

app.js

var flash = require('connect-flash'); 

app.use(flash()); // add this above passport initialize 
app.use(passport.initialize()); 
app.use(passport.session()); 

config/passport.js (Si prega di concentrarsi sulla forma caricamento dei dati in flash)

passport.use('local.signup', new LocalStrategy({ 
    usernameField: 'email', 
    passwordField: 'password', 
    passReqToCallback: true 
}, function (req, email, password, done) { 
    req.checkBody('first_name', 'Firstname is missing').notEmpty(); 
    req.checkBody('last_name', 'Lastname is missing').notEmpty(); 
    req.checkBody('email', 'Invalid email').notEmpty().isEmail(); 
    req.checkBody('password', 'Password is too short. Minimum size is 6.').notEmpty().isLength({min:6}); 
    req.checkBody('confirm_password', 'Password and confirm password didn\'t not match').equals(req.body.password); 
    var errors = req.validationErrors(); 
    if (errors) { 
      var messages = []; 
      errors.forEach(function(error) { 
       messages.push(error.msg); 
      }); 
      req.flash('formdata', req.body); // load form data into flash 
      return done(null, false, req.flash('error', messages)); 
    } 
    User.findOne({'email': email}, function (err, user) { 
      if (err) { 
        req.flash('formdata', req.body); // load form data into flash 
        return done(err); 
      } 
      if (user) { 
        req.flash('formdata', req.body); // load form data into flash 
        return done(null, false, {message: 'Email is already in use.'}); 
      } 
      var newUser = new User(); 
      newUser.first_name = req.body.first_name; 
      newUser.last_name = req.body.last_name; 
      newUser.email = email; 
      newUser.password = newUser.encryptPassword(password); 
      newUser.save(function(err, result) { 
       if (err) { 
         return done(err); 
       } 
       return done(null, newUser); 
      }); 
    }); 
})); 

percorsi/index.js (prego concentrarsi sui dati del modulo, flash ricaricato in una variabile)

router.get('/signup', function (req, res, next) { 
    var messages = req.flash('error'); 
    var formdata = req.flash('formdata'); // Get formdata back into a variable 
    res.render('user/signup', {csrfToken: req.csrfToken(), 
     messages: messages, // pass it here to access in view file 
     hasErrors: messages.length > 0, 
     formData: formdata[0] 
    }); 
}); 

router.post('/signup', passport.authenticate('local.signup', { 
     badRequestMessage: 'Please fill the form with all details', 
     failureRedirect: '/user/signup', 
     failureFlash: true 
    }), function (req, res, next) { 
     if (req.session.oldUrl) { 
      var oldUrl = req.session.oldUrl; 
      req.session.oldUrl = null; 
      res.redirect(oldUrl); 
     } else { 
      res.redirect('/user/profile'); 
     } 
}); 

viste/signup.hbs (favore concentrarsi sui valori negli elementi di input)

<form class="wow fadeInUp animated" data-wow-delay=".7s" action="/user/signup" method="post" > 
    <input type="text" placeholder="First Name" name="first_name" value="{{ formData.first_name }}"> 
    <input type="text" placeholder="Last Name" name="last_name" value="{{ formData.last_name }}"> 
    <input type="text" class="email" placeholder="Email Address" name="email" value="{{ formData.email }}"> 
    <input type="password" name="password" value="" class="lock" placeholder="Password"> 
    <input type="password" name="confirm_password" value="" class="lock" placeholder="Confirm Password"> 
    <input type="hidden" name="_csrf" value="{{ csrfToken }}"> 
    <input type="submit" name="Register" value="Register"></form> 

Spero che questo aiuti.

0

se si utilizza jade e form Validator da npm, la parte migliore è che è possibile un'istruzione if in jade e quindi è sufficiente verificare se l'errore con res.render viene inviato anche agli oggetti. Vedere questo

if(errors){ 
    res.render('register',{ 
     errors : errors, 
     name : name, 
     email : email, 
     username : username, 
     password : password, 
     password2 : password2 
    }); 

E in giada si esegue questa operazione

input.form-control(name='name',type='text',placeholder='Enter Name',value = (errors ? '#{name}':'')) 

quindi se c'è valore errori imposterà alla variabile di nome che sarà reso quando inviamo indietro

penso che si può anche essere fatto in Angular2/Angular.js