I just started a new nodejs app, which will contain a notable amount of forms for creating and editing/updating database values. My question is: How can I repopulate form entries if the given data is invalid?
Example: Somebody tries to login. If the credentials are wrong I'm using something like the following to display the login page again:
res.render('sessions/new')
Thing is, the username is not populated with the request data. I was wondering how to accomplish this both easy and clean. Since there is no form_for
like in rails, I guess I have to implement that manually, right? My first approach was to bypass the request body/params as locals to the render
function and set the value within my jade template like so:
// In controller/route
res.render('sessions/new', req.body)
// In template
input(type='text', name='username', value=locals.username)
Is there a better or more unobtrusive solution? I mean the example above works and is pretty easy to implement, just wondering if I missed something. This is also interesting for stuff like adding an error class to invalid form fields. Couldn't really find anything on the web.
Thanks in advance!
I do it on client side with jQuery.
I use express-validator to generate an error map, this contains field name, original value, and an error message.
Then I just print that inside script tags on my layout template at the bottom of the page, and in jQuery I check if it's empty or not and loop through the error stack. Tagging the field as error and displaying original value and error message.
Here is express-validator code:
route:
req.assert('username', 'Enter username').notEmpty();
req.assert('password', 'Enter password').notEmpty();
res.locals.errors = req.validationErrors(true);
res.render('/login');
view:
<p>
<label>Username</label>
<input name="username" />
</p>
<script>var errors = <%= errors %>;</script>
Client side javascript (jQuery):
for ( var e in errors ) {
var $field = $('[name='+e+']'),
$el = $field.parents('p');
$el.addClass('err');
$el.append('<span class="msg">'+errors[e].msg+'</span>');
}
The alternative is to do a bunch of if/else and echo statements in your view which can get real ugly, real quick.