2012-11-28 130 views
8

我正在研究Node.js中的一個非常基本的註冊表單(使用Express),並且我試圖找到提供基本表單驗證的最簡單方法。我已經使用了「Express-Validator」,這似乎做得很好。但是,我的目標是簡單地顯示所需的任何驗證消息,並使保留由用戶單獨輸入的值。Node.js(Express)表格提交清除

看來,請求信息沒有回到res.render,我認爲這是有道理的。但是,我已經在無處不在,我無法找到任何參考資料來討論如何在顯示錯誤消息後填充表單字段。

下面是說明我的做法一個小片段:

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

這就是人們說「網絡無國籍」時的意思。您需要在每次請求後手動重新填充您的值。 –

+1

是的,我意識到它需要服務器端的干預來傳回值,但我希望express有一些東西(或中間件插件)可以爲我們做到這一點。我只需轉到AJAX表單提交路線。無論如何,它會產生更好的用戶體驗。 – creativename

回答

10

不幸的是,你必須手動重新填充表單。如果您遇到任何頁面錯誤,您會將表單值傳回給視圖。

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

而在你看來,你會做一個簡單的檢查,看看他們是否有任何錯誤並相應地重新填充。您將不得不跟蹤每個表單字段產生的錯誤。

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

另一種流行的方法是通過ajax發送表單到服務器,並進行所有驗證。如果出現錯誤,輸入的表單數據將保留,您將顯示錯誤,否則在成功登錄後重定向。以下是如何使用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。根據應用程序的複雜性,通過Ajax提交表單並通過JSON返回錯誤消息可能相對容易(並且使用JavaScript相應地更新頁面)。 –

+0

謝謝,我認爲那就是我必須去的方式。我只是做AJAX調用表單提交併從那裏去。我認爲做完整帖子可能「容易」,但這是假設快遞可以以某種方式幫助回傳輸入值。我想這就是我從.NET獲得的東西! – creativename

-1

上register.html化妝檢查http://www.quietless.com/kitchen/building-a-login-system-in-node-js-and-mongodb/

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); 
     }); 

可能存在錯誤,如:無法在這種情況下POST/

教程的作者在上述用途鏈接lib $ .ajaxForm

您還可以使用https://github.com/felixge/node-formidable

或$( '#myForm的')。提交()替換爲$( '#提交-A-鏈接')。點擊()

5

有一個簡單的方法是使用的是

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

您可以使用req.body

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

而且我不知道你正在使用的模板語言,但你可以做這樣的事情..

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

然後這會返回良好的輸入,如果正常或錯誤的輸入,如果它需要糾正。

+0

謝謝,我認爲這實際上是使用expressValidator生成的「pageErrors」的正確方法。我應該結合使用AJAX驗證,然後在禁用JavaScript的情況下使用它作爲回退。 – creativename

0

爲所有的輸入變量,例如

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 
} 

,然後將該變量傳遞給視圖

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

那麼在你看來

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

你可以得到這完成使用connect-flash

下面是在不同文件中的代碼片段,以便在使用護照進行註冊時驗證失敗時,將用戶輸入的值返回到表單中。此下面命令

運行以新的包添加到的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()); 

配置/ passport.js(請專注形態數據加載到閃光燈)

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); 
      }); 
    }); 
})); 

路由/ index.js(請集中加載回可變閃光燈形式數據)

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

視圖/ signup.hbs(請專注值輸入元件)

<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> 

希望這有助於。

0

如果您使用jade並從npm中構建Validator,最好的部分是您可以在jade中使用if語句,然後您只需檢查是否有錯誤,然後再用res.render發送對象。看到這個

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

而且在玉石這樣做

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

所以如果有錯誤值將設置爲變量,將呈現名字的時候,我們發回

我想你也可以在Angular2/Angular.js中完成