Git Product home page Git Product logo

forms's Introduction

Forms Version Badge

Build Status dependency status dev dependency status License Downloads

npm badge

Constructing a good form by hand is a lot of work. Popular frameworks like Ruby on Rails and Django contain code to make this process less painful. This module is an attempt to provide the same sort of helpers for node.js.

$ npm install forms

Contribute

This code is still in its infancy, and I'd really appreciate any contributions, bug reports, or advice. Especially on the following key areas:

  • Creating sensible default rendering functions that generate flexible, accessible markup. This is an early priority because without being confident that the standard markup won't change under their feet, developers will not be able to adopt the module for any sort of production use.
  • Exploring write-once validation that works on the client and the server. There are some unique advantages to using the same language at both ends, let's try and make the most of it!
  • Ensuring it's easy to use with existing node web frameworks. Ideally this module would integrate well with projects using any of the popular frameworks.

Example

Creating an example registration form:

var forms = require('forms');
var fields = forms.fields;
var validators = forms.validators;

var reg_form = forms.create({
    username: fields.string({ required: true }),
    password: fields.password({ required: validators.required('You definitely want a password') }),
    confirm:  fields.password({
        required: validators.required('don\'t you know your own password?'),
        validators: [validators.matchField('password')]
    }),
    email: fields.email()
});

Rendering a HTML representation of the form:

reg_form.toHTML();

Would produce:

<div class="field required">
    <label for="id_username">Username</label>
    <input type="text" name="username" id="id_username" value="test" />
</div>
<div class="field required">
    <label for="id_password">Password</label>
    <input type="password" name="password" id="id_password" value="test" />
</div>
<div class="field required">
    <label for="id_confirm">Confirm</label>
    <input type="password" name="confirm" id="id_confirm" value="test" />
</div>
<div class="field">
    <label for="id_email">Email</label>
    <input type="text" name="email" id="id_email" />
</div>

You'll notice you have to provide your own form tags and submit button, its more flexible this way ;)

Handling a request:

function myView(req, res) {
    reg_form.handle(req, {
        success: function (form) {
            // there is a request and the form is valid
            // form.data contains the submitted data
        },
        error: function (form) {
            // the data in the request didn't validate,
            // calling form.toHTML() again will render the error messages
        },
        empty: function (form) {
            // there was no form data in the request
        }
    });
}

That's it! For more detailed / working examples look in the example folder. An example server using the form above can be run by doing:

$ node example/simple.js

Bootstrap compatible output

For integrating with Twitter bootstrap 3 (horizontal form), this is what you need to do:

var widgets = require('forms').widgets;

var my_form = forms.create({
    title: fields.string({
        required: true,
        widget: widgets.text({ classes: ['input-with-feedback'] }),
        errorAfterField: true,
        cssClasses: {
            label: ['control-label col col-lg-3']
        }
    }),
    description: fields.string({
        errorAfterField: true,
        widget: widgets.text({ classes: ['input-with-feedback'] }),
        cssClasses: {
            label: ['control-label col col-lg-3']
        }
    })
});

var bootstrapField = function (name, object) {
    if (!Array.isArray(object.widget.classes)) { object.widget.classes = []; }
    if (object.widget.classes.indexOf('form-control') === -1) {
        object.widget.classes.push('form-control');
    }

    var label = object.labelHTML(name);
    var error = object.error ? '<div class="alert alert-error help-block">' + object.error + '</div>' : '';

    var validationclass = object.value && !object.error ? 'has-success' : '';
    validationclass = object.error ? 'has-error' : validationclass;

    var widget = object.widget.toHTML(name, object);
    return '<div class="form-group ' + validationclass + '">' + label + widget + error + '</div>';
};

And while rendering it:

reg_form.toHTML(bootstrapField);

Available types

A list of the fields, widgets, validators and renderers available as part of the forms module. Each of these components can be switched with customised components following the same API.

Fields

  • string
  • number
  • boolean
  • array
  • password
  • email
  • tel
  • url
  • date

Widgets

  • text
  • email
  • number
  • password
  • hidden
  • color
  • tel
  • date
  • datetimeLocal
  • checkbox
  • select
  • textarea
  • multipleCheckbox
  • multipleRadio
  • multipleSelect
  • label

Validators

  • matchField
  • matchValue
  • required
  • requiresFieldIfEmpty
  • min
  • max
  • range
  • minlength
  • maxlength
  • rangelength
  • regexp
  • color
  • email
  • url
  • date
  • datetimeLocal
  • alphanumeric
  • digits
  • integer

Renderers

  • div
  • p
  • li
  • table

API

A more detailed look at the methods and attributes available. Most of these you will not need to use directly.

forms.create(fields)

Converts a form definition (an object literal containing field objects) into a form object.

forms.create(fields, options)

Forms can be created with an optional "options" object as well.

Supported options:

  • validatePastFirstError: true, otherwise assumes false
    • If false, the first validation error will halt form validation.
    • If true, all fields will be validated.

Form object

Attributes

  • fields - Object literal containing the field objects passed to the create function

form.handle(req, callbacks)

Inspects a request or object literal and binds any data to the correct fields.

form.bind(data)

Binds data to correct fields, returning a new bound form object.

form.toHTML(iterator)

Runs toHTML on each field returning the result. If an iterator is specified, it is called for each field with the field name and object as its arguments, the iterator's results are concatenated to create the HTML output, allowing for highly customised markup.

Bound Form object

Contains the same methods as the unbound form, plus:

Attributes

  • data - Object containing all the parsed data keyed by field name
  • fields - Object literal containing the field objects passed to the create function

form.validate(callback)

Calls validate on each field in the bound form and returns the resulting form object to the callback.

form.isValid()

Checks all fields for an error attribute. Returns false if any exist, otherwise returns true.

form.toHTML(iterator)

Runs toHTML on each field returning the result. If an iterator is specified, it is called for each field with the field name and object as its arguments, the iterator's results are concatenated to create the HTML output, allowing for highly customised markup.

Field object

Attributes

  • label - Optional label text which overrides the default
  • required - Boolean describing whether the field is mandatory
  • validators - An array of functions which validate the field data
  • widget - A widget object to use when rendering the field
  • id - An optional id to override the default
  • choices - A list of options, used for multiple choice fields (see the field.choices section below)
  • cssClasses - A list of CSS classes for label and field wrapper
  • hideError - if true, errors won't be rendered automatically
  • labelAfterField - if true, the label text will be displayed after the field, rather than before
  • errorAfterField - if true, the error message will be displayed after the field, rather than before
  • fieldsetClasses - for widgets with a fieldset (multipleRadio and multipleCheckbox), set classes for the fieldset
  • legendClasses - for widgets with a fieldset (multipleRadio and multipleCheckbox), set classes for the fieldset's legend

field.choices

The choices property is used for radio, checkbox, and select fields. Two formats are supported and in case of select fields the format can be nested once to support option groups.

The first format is based on objects and is easy to write. Object keys are treated as values and object values are treated as labels. If the value is another object and nesting is supported by the widget the key will be used as label and the value as nested list.

The second format is array-based and therefore ordered (object keys are unordered by definition). The array should contain arrays with two values the first being the value and the second being the label. If the label is an array and nesting is supported by the widget the value will be used as label and the label as nested list.

Both formats are demonstrated below:

// objects
{
    'val-1': 'text-1',
    'val-2': 'text-2',
    'text-3': {
        'nested-val-1': 'nested-text-1',
        'nested-val-2': 'nested-text-2',
        'nested-val-3': 'nested-text-3'
    }
}

// arrays
[
    ['val-1', 'text-1'],
    ['val-2', 'text-2'],
    ['text-3', [
        ['nested-val-1', 'nested-text-1'],
        ['nested-val-2', 'nested-text-2'],
        ['nested-val-3', 'nested-text-3'],
    ]]
]

field.parse(rawdata)

Coerces the raw data from the request into the correct format for the field, returning the result, e.g. '123' becomes 123 for the number field.

field.bind(rawdata)

Returns a new bound field object. Calls parse on the data and stores in the bound field's data attribute, stores the raw value in the value attribute.

field.errorHTML()

Returns a string containing a HTML element containing the fields error message, or an empty string if there is no error associated with the field.

field.labelText(name)

Returns a string containing the label text from field.label, or defaults to using the field name with underscores replaced with spaces and the first letter capitalised.

field.labelHTML(name, id)

Returns a string containing a label element with the correct 'for' attribute containing the text from field.labelText(name).

field.classes()

Returns an array of default CSS classes considering the field's attributes, e.g. ['field', 'required', 'error'] for a required field with an error message.

field.toHTML(name, iterator)

Calls the iterator with the name and field object as arguments. Defaults to using forms.render.div as the iterator, which returns a HTML representation of the field label, error message and widget wrapped in a div.

Bound Field object

same as field object, but with a few extensions

Attributes

  • value - The raw value from the request data
  • data - The request data coerced to the correct format for this field
  • error - An error message if the field fails validation

validate(callback)

Checks if the field is required and whether it is empty. Then runs the validator functions in order until one fails or they all pass. If a validator fails, the resulting message is stored in the field's error attribute.

Widget object

Attributes

  • classes - Custom classes to add to the rendered widget
  • labelClasses - Custom classes to add to the choices label when applicable (multipleRadio and multipleCheckbox)
  • type - A string representing the widget type, e.g. 'text' or 'checkbox'

toHTML(name, field)

Returns a string containing a HTML representation of the widget for the given field.

Validator

A function that accepts a bound form, bound field and a callback as arguments. It should apply a test to the field to assert its validity. Once processing has completed it must call the callback with no arguments if the field is valid or with an error message if the field is invalid.

Renderer

A function which accepts a name and field as arguments and returns a string containing a HTML representation of the field.

forms's People

Contributors

amritb avatar artnez avatar blakmatrix avatar caulagi avatar deedubs avatar flaise avatar fzembow avatar grippy avatar hurrymaplelad avatar ivanquirino avatar jedp avatar kmohrf avatar lab43 avatar labs-scnm avatar ljharb avatar luddep avatar lukeburns avatar mauhib avatar mrdnk avatar nicksellen avatar piotrkowalczuk avatar pstadler avatar richardngn avatar richbs avatar simshaun avatar tbirkenstock avatar tellnes avatar thusoy avatar timjrobinson avatar voxpelli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

forms's Issues

Default widget attributes

forms.create({
    username: forms.fields.string({
      required: true
    })
});

does not result in <input required="true"> in the HTML. While this can be achieved by setting the widget manually after the fact, it seems counter intuitive to me that passing options to the widget requires an extra step.

Changing 17, 98, 119 of lib/fields.js from forms.widgets.___() to forms.widgets.___(opt) provides what is, in my opinion, more intuitive default behavior.

This also requires String(opt[k]).replace(...) in widgets.js:31, to convert "true" and similar into strings.

Object #<Object> has no method 'toHTML'

I get this error when I try and use toHTML() on the form I created.

var create_form = forms.create({
title: fields.string({required: true}),
price: fields.number({required: true}),
desc: fields.string({
required: true,
widget: {
type: 'textarea'
}
})
});

console.log('create_form :: '+ create_form.toHTML());

__proto__ !== instanceof http.IncomingMessage

I'm creating a "class that inherits" from the express.request, and has almost the same methods and attributes, but when you do a request instanceof http.IncomingMessage it's false of course, and I can't use it in form.handle. couldn't the check inside handle happen without trying to guess the instance of the request? like:

    // instead of 
    } else if (obj instanceof http.IncomingMessage) {
    // use
    } else if ((typeof obj.body !== 'undefined' || typeof obj.url !== 'undefined') && typeof obj.method !== 'undefined') {

all tests are passing OK: 570 assertions (1433ms) and this makes the code work with any HTTP request mock, without the actual manual instantiating of IncomingMessage. since it's the body, url and method members of the request that is important, that should suffice.

Test multipart POST requests

I can't figure out how to create a fake request object to pass to form.handle in order to test this functionality, introduced in e0ac2f0.

The gap was discovered thanks to #48.

Implement an easy way to translate a text within a node.

Default widgets should have a function that translate text. This function would be specified in some sort of configuration.

As of now, I have to "reimplement" all the widgets (copy paste them) just to surround a text with my function to translate it.

Exemple:
In the multipleSelect widget I have to surround 'f.choices[k]' width my function which gives 'i18next.t(f.choices[k])'

tel input?

Very useful option for iphone keyboards

Support initial data

When editing a database object, I want to fill the form with the object's current values, to be edited. Doesn't seem to be supported currently.

Divide form output into parts

I have a very large form, and it should be outputed using jQuery tabs. So I need to divide it into chunks, and output each chunk in a specific place. I've created three form objects and have rendered html for each of them, but in this case I need to perform three validations for each form object.

Validation issue

Hi,

First off, big thank you for this very useful, easy to understand library, especially for a node.js newbie like me.

I'm creating my own validator to make a field required based on a condition tied to another field.

Unfortunately, the validation doesn't happen since the field is empty. So I'd suggest to change the code to NOT bypass the validation if the field is empty yet has entries under 'validators.'

Example:

     b.validate = function (form, callback) {

        var check_validators = function() {
            async.forEachSeries(b.validators || [], function (v, callback) {
                if (!b.error) {
                    v(form, b, function (v_err) {
                        b.error = v_err ? v_err.toString() : null;
                        callback(null);
                    });
                } else {
                    callback(null);
                }
            }, function (err) {
                callback(err, b);
            });
        }

        if (raw_data === '' || raw_data === null || typeof raw_data === 'undefined') {
            // don't validate empty fields, but check if required
            if (b.required) { b.error = 'This field is required.'; }
            else check_validators();
            process.nextTick(function () { callback(null, b); });
        } else {
            check_validators();
        }
    };

Help text?

I've had a good look through the code and can't find anything representing help style text? Text that would go directly beneath a field to explain the content in the field for example.

Is this something you're interested in?

The message 'This field is required.' is hardcoded

So, the message for required fields is hardcoded. I suggest to add extra option for fields requiredMessage (or something like this) to setting it. It's simply to implemet by changing this line this way:

if (b.required) { b.error = 'This field is required.'; }

to

if (b.required) { b.error = b.requiredMessage || 'This field is required.'; }

File input?

I know that someone filed an issue about this (#44) Has it been merged? Any news on this? Thanks

How to reset form values after submitted

I'm playing with this plugin in my first node/express app, thanks for putting it out there!

Question: I have a form that submits back to the same URL (handled for both GET and POST). When it fails validation, I want it to re-render the form with the submitted values, and that works well. But when it succeeds, and writes the submitted values, I want to show the form again, but this time empty, to add another entry. How would I do this?

Thanks

Allow custom attributes to be passed to widgets

Would be useful if the built in widgets allowed custom attributes to be configured.

Maybe something like the classes option

{
    classes: ['my_class', 'another_class']
  , attributes: { readonly: 'readonly' }
}

multiple forms on a single page

If you create multiple bound forms on a single page by creating an array of forms and iterating over it calling toHTML() on each. Each form is rendered with the data from the final form in the array.

The problem appears to be in the rendering process, rather than the binding process. if you dump the form objects after binding each one, you can see that the the correct data is bound to each.

Cannot(?) validate that either field A or field B be filled.

Validation logic for requiring one of either fields to be filled, but not requiring both necessarily has to be done outside of the form definition.

While not a big deal, since it feels like the purpose of validators is to save the programmer to add extra validation logic outside from form creation, it would be nice to have the possibility to define a validator that gets executed when field.data is empty and the field is not required.

File field

Hello

I was asking myself how to add the file field (to upload an image) and then save the name in the DB ?
Is their a widget or a right way to do it ?

For the moment my code looks like this (it works, but lacks of the support of file field)

forms = require "forms"
fields = forms.fields
validators = forms.validators
widgets = forms.widgets

workForm = forms.create(
  title: fields.string(required: true)
  format: fields.string(required: true)
  technique: fields.string(required: true)
  sold: fields.string(
    required: false
    widget: widgets.checkbox()
  )
)

WorkForm = exports.WorkForm = workForm

Array input name

In my models I have: customer: {
name: String,
phone: String,
contact: String,
email: {
type: String,
index: { unique: false},
validate: /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/,
},

nI can@t defin a field like this:
...
title: fields.string({required: true}),
customer: {
email: fields.email(),
name: fields.string(),
}

I got error.. how can i fix it?

Validate client side on loss of focus

Hey there! Glad to find another fan of Django's form model. I see sharing validation on the client is a stated goal. Any progress? Thoughts on a direction? The biggest wins for me would be validating fields client side on loss of focus to display errors immediately, and tying in the forms isValid state to enable and disable form submission.

I'm happy to code up some directions to see how they feel.

Form-wide validation

It seems like the validators can only apply to particular fields, and while each validator has access to the whole form, it would be useful to have form-wide validation for more complex rules. For instance, I have a form that requires exactly one out of a list of fields to be filled and the rest empty. Having something like a second argument to forms.create where such a validator could be specified would be really helpful. Just a function(form, callback) would be fine. What do you think?

client-side use

Hi!

Wouldn't you take care of making the code usable at client-side? The require()ment of 'http' et al. is of pure node concern (and can be opted); and 'async' is feasible only in validation routines (afaics). These two stops so far the subj.

TIA for feedback,
--Vladimir

i18n

Add i18n support

Different form for each user?

Hi,

I'd like to create a slightly different form for each user. Something like:
var userHomeForm = forms.create({
email : fields.email({
label : i18n.__('Email'),
value : user.email,
}),
});
It has the user's email pre-filled. If I put the form in global level, other users can see the user's email.
So I thought about creating the form in each request of the page, and save it in the user's session. something like:
req.session.userHomeForm = userHomeForm;

However, when I retrieve the form for processing:
var userHomeForm = req.session.userHomeForm;
userHomeForm.handle(req, {
success : function (form)

The handle is not found. It seems all the field values are preserved in the session, but not the functions like handle, bind, toHTML etc.

Something I do wrong here? Or is it a bug?

Thanks.

`test-form.js` - `handle ServerRequest POST` fails on node v0.10.0

The test handle ServerRequest POST in test-form.js fails on node v0.10.0 with the following error:

TypeError: Cannot read property 'readable' of undefined
    at IncomingMessage._read (http.js:345:19)
    at IncomingMessage.Readable.read (_stream_readable.js:293:10)
    at IncomingMessage.read (http.js:337:15)
    at IncomingMessage.<anonymous> (_stream_readable.js:698:45)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at emitDataEvents (_stream_readable.js:724:10)
    at IncomingMessage.Readable.on (_stream_readable.js:656:5)
    at Object.f.handle (/Users/christian/code/forms/lib/forms.js:63:29)
    at Object.exports.handle ServerRequest POST (/Users/christian/code/forms/test/test-form.js:276:7)
    at Object.<anonymous> (/Users/christian/code/forms/node_modules/nodeunit/lib/core.js:235:16)

The problem seems to be that http.IncomingMessage requires a socket as the first parameter.

NPM package 2 years old

Thank you for your module - it's fantastic; however the tag that you uploaded to NPM is 2 years old.

Do you plan on updating the npm repository?

Form method POST dont work (using express)

Hi, I use node.js with express (expressjs.com). When I tried your forms module it worked great if I used GET as form method. But when I tried to use POST instead it did not work.
I looked at your code an come to the conclusion that somewher inside this if-statement things did not work out:
else if(obj.method === 'POST'){
var buffer = '';
obj.addListener('data', function(chunk){
buffer += chunk;
});
obj.addListener('end', function(){
f.handle(querystring.parse(buffer), callbacks);
});
}

I got stuck there so it will not run my success, error or empty code.

But I think I have solved the issue by changing the if-statement to:
else if(obj.method === 'POST'){
f.handle(obj.body, callbacks);
/*
var buffer = '';
obj.addListener('data', function(chunk){
buffer += chunk;
});
obj.addListener('end', function(){
f.handle(querystring.parse(buffer), callbacks);
});
*/
}

Do you know if this change is bad in any way?

Add a way to dynamically set a hidden field's value

Is it possible to set the value of a widget? I tried several variations on the following:

forms.create({
    _csrf: forms.widgets.hidden({ value: 'a csrf token' })
}).toHTML()

I assume that I'm doing it wrong, so I asked a question on SO showing my other attempts. @ljharb mentioned in #70 that this should be simple, but I'm not feeling too bright right now. I tried using fields.string({ type: hidden, value: 'a csrf token' }), but that's not right either.

example/simple.js doesn't work

node example/simple.js doesn't work as specified in README and I get this error -

➜ forms git:(master) ✗ node example/simple.js

node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: require.paths is removed. Use node_modules folders, or the NODE_PATH environment variable instead.
at Function. (module.js:378:11)
at Object. (/tmp/forms/example/simple.js:3:8)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Array.0 (module.js:479:10)
at EventEmitter._tickCallback (node.js:192:40)
➜ forms git:(master) ✗

However, it works with the following changes -

➜ forms git:(master) ✗ diff example/simple.js example/simple.js.1
3,4c3,4
< require.paths.push(__dirname + '/../lib');

< require.paths.push(__dirname + '/../deps');

//require.paths.push(__dirname + '/../lib');
//require.paths.push(__dirname + '/../deps');
10c10

< forms = require('forms'),

forms = require('../lib/forms'),

➜ forms git:(master) ✗ node example/simple.js.1
The "sys" module is now called "util". It should have a similar interface.
Server running at http://127.0.0.1:8080/

I am using node 0.6.15. Is this a bug?

Escaping quotes in value attribute of inputs

Attribute values with quotes in them (such as JSON) cause the outputted html to be invalid. For example, the following will output invalid html:

var forms = require('forms');
var fields = forms.fields;
var widgets = forms.widgets;

var form = forms.create({
  data: fields.string({required: true, widget: widgets.hidden()})
});

form.bind({data: '{"hello": "world"}'}).toHTML();

I believe this is due to /lib/widgets.js:28, but the surrounding code would suggest that the value attribute is specifically left unescaped as the others are subjected to .replace(/"/g, '&quot;'). Is this intentional?

Individual field rendering?

I would like to add extra markup and other changes to certain fields in my templates. How can I individually render the fields of a form in my template? Thanks

// Something like this
{% for field in formObj.fields %}
{% if field.widget.type === 'email' %}
... do something else
{% endif %}
{% endfor %}

Cannot handle request method: PUT

Hi,

thanks for form.js, but used with connects methodOverride I get problems with PUT.

It will ignore PUT and throw an error.

regards,
Nox

Make it easier to individually output the fields.

This is currently somewhat tedious. Not only there no way to call simply call "form.FOOFIELD.toHTML()" and have it print the html in a template, when writing the field html tags manually, you would want to persist the user's input in case of an error, so you would need to do something like this:

<input type="question" value="<%= form.data.question %>">

This will cause problems in some template languages however (like EJS) when the form is unbound, and therefore form.data does not exist. I suggest that the data dictionary should exist anyway, and contain empty strings, or null/undefined values.

On a somewhat related note, the "empty" callback currently is only called if no request object is passed; the example in the readme makes it sound like it is supposed to be called if the given request object contains no data. I understand the latter might be hard to determine due to GET and POST (a user might have a page with a querystring and a form that POSTs), but depending on how the design is supposed to work, I suggest that the example in the readme be updated to something like:

 if (QuestionForm.handle(req.method == 'POST' ? req : undefined, {
    empty: function() {  ... }
 }):

As the empty example currently stands, a user is likely to find that empty is not called the way he expects to.

Password field shouldn't set the value attribute

When .toHTML() is called on a form that includes a password widget, it creates a tag like <input type="password" value="my secret password">. I think it would be more prudent to not output the value for password widgets.

Custom template for form rendering

Hello,

I am looking for a clean way to customize template for input rendered. Have you an idea?

Thanks by the way for your librairie.

Form state is shared between different requests

Using: NodeJS 0.4.12, Express: 2.4.7

//controller.js, imported into app.js

var forms = require('../lib/forms'),
    fields = forms.fields,
    validators = forms.validators;

var signupForm = forms.create({

    first_name: fields.string({ required: true }),
    last_name: fields.string({ required: true }),
    email: fields.email({ required: true }),
    password: fields.password({ required: true }),
    password_confirm: fields.password({
        required: true,
        validators: validators.matchField('password')
    })

});

module.exports = function(app) {

    app.get('/signup', function(req, res, next) {
        res.render('signup', {
            signupForm: form.toHTML()
        });
    });

    app.post('/signup', function(req, res, next) {
        signupForm.handle(req.body, {
            success: function(form) {
                res.redirect('/app');
            },
            other: function(form) {
                res.render('signup', {
                    form: form.toHTML()
                });
            }
        });
    });
};

I've been seeing some strange behaviour, here's the steps to reproduce:

  1. Create form
  2. Open one browser and fill in the form, so it fails validation.
  3. Open a different browser, visit the '/signup' route and the form will be pre populated, showing data that the other browser (user) entered. Potentially displaying sensitive user info to another user.

Seems like the original signupForm object is being modified when bound to a request's form data?

Bump npm version?

I'm trying to use this and want type="tel" and type="email". Both are in master but there hasn't been a version bump on npm in a months. I totally understand if there's other work to be done before next release, so I may just use GH as the package source (I've had issues with that in the past so I try to avoid it). Thanks!

Adding div tag to form

This is my first dig at node js forms.
I am trying to look up tables in database and make a form for each table and i am able to generate the form but I am unable to add div's to separate the different tables.

I have the right break point to get to the point of adding div's but I am unable to understand how to add this.

Here is the snippet ..

var forms = require('forms');
var myFields = forms.fields, myValidators = forms.validators, myWidgets = forms.widgets, myRenderers = forms.render;

                                    if (typeof Table.table_name != 'undefined' && typeof Table.DATA_TYPE != 'undefined'){
                                            var type, renderer;
                                            if (Table.DATA_TYPE.match(/char/)){
                                                    type = myFields.string({required: true});
                                            }else if(Table.DATA_TYPE.match(/text/)){
                                                    type = myFields.string({ widget: myWidgets.textarea({rows: 6})});
                                            }else if(Table.DATA_TYPE.match(/int/)){
                                                    type = myFields.number({required: true});
                                            }
                                            //response.write('Type ' + type );

                                            if (profileTables.getIndex(Table.table_name) == -1 ){
                                                    profileTables.push(Table.table_name);
                                                    /* I DONT KNOW HOW TO ADD <DIV> TAG HERE */
                                                    var divtag='({<div id=' + Table.table_name + '>})';
                                                    var rend=myFields.string(divtag);
                                                    renderer = myRenderers.div(Table.table_name,rend);
                                                    response.write('RENDERER ' + renderer.toHTML);
                                                    jsonObject[renderer];
                                            }
                                            var column = Table.column_name;
                                            jsonObject[column]=type;

                      }

Appreciate any help on this.

  • Shekar

I am able to generate the form details

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.