From 5fcc78e5f3986e35fb54806161402e031ac6cac4 Mon Sep 17 00:00:00 2001 From: Luke Burns Date: Wed, 24 Jul 2013 01:01:51 -0400 Subject: [PATCH 1/9] objects field --- example/simple.js | 14 +++++++++++--- lib/fields.js | 4 +++- lib/forms.js | 17 ++++++++++------- package.json | 3 ++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/example/simple.js b/example/simple.js index f3b7f64..c3d6df3 100644 --- a/example/simple.js +++ b/example/simple.js @@ -25,14 +25,22 @@ var reg_form = forms.create({ required: true, validators: [validators.matchField('password')] }), - email: fields.email() + personal: fields.object({ + name: fields.string({required: true}), + email: fields.email({required: true}), + address: fields.object({ + address1: fields.string({required: true}), + address2: fields.string(), + city: fields.string({required: true}), + state: fields.string({required: true}), + zip: fields.number({required: true}) + }) + }) }); - http.createServer(function (req, res) { reg_form.handle(req, { success: function (form) { - var req_data = require('url').parse(req.url, 1).query; res.writeHead(200, {'Content-Type': 'text/html'}); res.write('

Success!

'); res.end('
' + util.inspect(form.data) + '
'); diff --git a/lib/fields.js b/lib/fields.js index 14858c6..5ac1f4c 100644 --- a/lib/fields.js +++ b/lib/fields.js @@ -85,7 +85,6 @@ exports.string = function (opt) { return f; }; - exports.number = function (opt) { if (!opt) { opt = {}; } var f = exports.string(opt); @@ -167,3 +166,6 @@ exports.date = function (opt) { return f; }; +exports.object = function (fields, opts) { + return forms.create(fields || {}); +}; \ No newline at end of file diff --git a/lib/forms.js b/lib/forms.js index 26017a5..add0bd9 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -3,7 +3,7 @@ var async = require('async'), http = require('http'), - querystring = require('querystring'), + querystring = require('qs'), parse = require('url').parse; @@ -23,13 +23,13 @@ exports.create = function (fields) { b.toHTML = f.toHTML; b.fields = {}; Object.keys(f.fields).forEach(function (k) { - b.fields[k] = f.fields[k].bind(data[k]); + b.fields[k] = (data[k])? f.fields[k].bind(data[k]): f.fields[k].bind(''); }); b.data = Object.keys(b.fields).reduce(function (a, k) { a[k] = b.fields[k].data; return a; }, {}); - b.validate = function (callback) { + b.validate = function (obj, callback) { async.forEach(Object.keys(b.fields), function (k, callback) { b.fields[k].validate(b, function (err, bound_field) { b.fields[k] = bound_field; @@ -52,7 +52,8 @@ exports.create = function (fields) { (callbacks.empty || callbacks.other)(f); } else if (obj instanceof http.IncomingMessage) { if (obj.method === 'GET') { - f.handle(parse(obj.url, 1).query, callbacks); + var qs = parse(obj.url).query; + f.handle(querystring.parse(qs), callbacks); } else if (obj.method === 'POST' || obj.method === 'PUT') { // If the app is using bodyDecoder for connect or express, // it has already put all the POST data into request.body. @@ -71,7 +72,7 @@ exports.create = function (fields) { throw new Error('Cannot handle request method: ' + obj.method); } } else if (typeof obj === 'object') { - f.bind(obj).validate(function (err, f) { + f.bind(obj).validate(null, function (err, f) { if (f.isValid()) { (callbacks.success || callbacks.other)(f); } else { @@ -82,10 +83,12 @@ exports.create = function (fields) { throw new Error('Cannot handle type: ' + typeof obj); } }, - toHTML: function (iterator) { + toHTML: function (name, iterator) { var form = this; + return Object.keys(form.fields).reduce(function (html, k) { - return html + form.fields[k].toHTML(k, iterator); + var kname = (name)? name+'['+k+']': k; + return html + form.fields[k].toHTML(kname, iterator); }, ''); } }; diff --git a/package.json b/package.json index 67731fc..3a03e80 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "test-browser": "./node_modules/.bin/browserify test-browser.js | ./node_modules/.bin/testling" }, "dependencies": { - "async": "~0.2.9" + "async": "~0.2.9", + "qs": "~0.6.5" }, "licenses": [ { From 19da5d6a2ba36b9ca05bc2d1245f2b0f9827578f Mon Sep 17 00:00:00 2001 From: Luke Burns Date: Sat, 27 Jul 2013 10:37:31 -0400 Subject: [PATCH 2/9] compatibility --- lib/forms.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/forms.js b/lib/forms.js index add0bd9..8e817c3 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -30,6 +30,10 @@ exports.create = function (fields) { return a; }, {}); b.validate = function (obj, callback) { + if(typeof obj == 'function') { + callback = obj; + } + async.forEach(Object.keys(b.fields), function (k, callback) { b.fields[k].validate(b, function (err, bound_field) { b.fields[k] = bound_field; @@ -72,7 +76,7 @@ exports.create = function (fields) { throw new Error('Cannot handle request method: ' + obj.method); } } else if (typeof obj === 'object') { - f.bind(obj).validate(null, function (err, f) { + f.bind(obj).validate(function (err, f) { if (f.isValid()) { (callbacks.success || callbacks.other)(f); } else { @@ -86,8 +90,12 @@ exports.create = function (fields) { toHTML: function (name, iterator) { var form = this; + if(typeof name == 'function') { + iterator = name; + } + return Object.keys(form.fields).reduce(function (html, k) { - var kname = (name)? name+'['+k+']': k; + var kname = (typeof name == 'string')? name+'['+k+']': k; return html + form.fields[k].toHTML(kname, iterator); }, ''); } From 28618eac7e8dfa31b68bce2b56901b51c6ac5eb0 Mon Sep 17 00:00:00 2001 From: Luke Burns Date: Sat, 27 Jul 2013 18:39:36 -0400 Subject: [PATCH 3/9] take object literals as nested fields --- example/simple.js | 22 +++++++++++----------- lib/forms.js | 4 ++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/example/simple.js b/example/simple.js index c3d6df3..cd63cb8 100644 --- a/example/simple.js +++ b/example/simple.js @@ -25,17 +25,17 @@ var reg_form = forms.create({ required: true, validators: [validators.matchField('password')] }), - personal: fields.object({ - name: fields.string({required: true}), - email: fields.email({required: true}), - address: fields.object({ - address1: fields.string({required: true}), - address2: fields.string(), - city: fields.string({required: true}), - state: fields.string({required: true}), - zip: fields.number({required: true}) - }) - }) + personal: { + name: fields.string({required: true, label: 'Name'}), + email: fields.email({required: true, label: 'Email'}), + address: { + address1: fields.string({required: true, label: 'Address 1'}), + address2: fields.string({label: 'Address 2'}), + city: fields.string({required: true, label: 'City'}), + state: fields.string({required: true, label: 'State'}), + zip: fields.number({required: true, label: 'ZIP'}) + } + } }); http.createServer(function (req, res) { diff --git a/lib/forms.js b/lib/forms.js index 8e817c3..dd835f0 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -14,6 +14,10 @@ exports.validators = require('./validators'); exports.create = function (fields) { Object.keys(fields).forEach(function (k) { + // if it's not a field object, create an object field. + if(typeof fields[k].toHTML !== 'function' && typeof fields[k] == 'object') { + fields[k] = exports.fields.object(fields[k]); + } fields[k].name = k; }); var f = { From 9aaf0b2bc8a3a7beaae5709a78569ab214b7512b Mon Sep 17 00:00:00 2001 From: Luke Burns Date: Sun, 25 Aug 2013 14:23:27 -0400 Subject: [PATCH 4/9] style corrections --- lib/fields.js | 2 +- lib/forms.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/fields.js b/lib/fields.js index 5ac1f4c..62fb425 100644 --- a/lib/fields.js +++ b/lib/fields.js @@ -168,4 +168,4 @@ exports.date = function (opt) { exports.object = function (fields, opts) { return forms.create(fields || {}); -}; \ No newline at end of file +}; diff --git a/lib/forms.js b/lib/forms.js index dd835f0..340be45 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -15,7 +15,7 @@ exports.validators = require('./validators'); exports.create = function (fields) { Object.keys(fields).forEach(function (k) { // if it's not a field object, create an object field. - if(typeof fields[k].toHTML !== 'function' && typeof fields[k] == 'object') { + if (typeof fields[k].toHTML !== 'function' && typeof fields[k] === 'object') { fields[k] = exports.fields.object(fields[k]); } fields[k].name = k; @@ -27,14 +27,14 @@ exports.create = function (fields) { b.toHTML = f.toHTML; b.fields = {}; Object.keys(f.fields).forEach(function (k) { - b.fields[k] = (data[k])? f.fields[k].bind(data[k]): f.fields[k].bind(''); + b.fields[k] = data[k] ? f.fields[k].bind(data[k]) : f.fields[k].bind(''); }); b.data = Object.keys(b.fields).reduce(function (a, k) { a[k] = b.fields[k].data; return a; }, {}); b.validate = function (obj, callback) { - if(typeof obj == 'function') { + if (typeof obj === 'function') { callback = obj; } @@ -94,12 +94,12 @@ exports.create = function (fields) { toHTML: function (name, iterator) { var form = this; - if(typeof name == 'function') { + if (typeof name === 'function') { iterator = name; } return Object.keys(form.fields).reduce(function (html, k) { - var kname = (typeof name == 'string')? name+'['+k+']': k; + var kname = typeof name === 'string' ? name+'['+k+']' : k; return html + form.fields[k].toHTML(kname, iterator); }, ''); } From e77f58d7599d520036aec369bd8a18b8a5e5b2a8 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 28 Jul 2013 11:48:54 -0700 Subject: [PATCH 5/9] Adding a nested example. --- example/complex.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/example/complex.js b/example/complex.js index 9b17f68..5c5d268 100644 --- a/example/complex.js +++ b/example/complex.js @@ -67,7 +67,12 @@ var form = forms.create({ notes: fields.string({ widget: widgets.textarea({rows: 6}) }), - spam_me: fields.boolean() + spam_me: fields.boolean(), + nested_1: { + nested_2: { + nested: fields.string() + } + } }); From 84dec9c8b2938e2f62af51bbff9ed844cb436200 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 28 Jul 2013 11:49:48 -0700 Subject: [PATCH 6/9] Adding a trailing newline. --- lib/fields.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/fields.js b/lib/fields.js index 0aba1a1..f45942e 100644 --- a/lib/fields.js +++ b/lib/fields.js @@ -172,3 +172,4 @@ exports.date = function (opt) { exports.object = function (fields, opts) { return forms.create(fields || {}); }; + From 6100e485bc874dbe91c86c290e2232590fa063cd Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 27 Aug 2013 21:53:28 -0700 Subject: [PATCH 7/9] Reverting this line. --- lib/forms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/forms.js b/lib/forms.js index 340be45..77036bf 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -27,7 +27,7 @@ exports.create = function (fields) { b.toHTML = f.toHTML; b.fields = {}; Object.keys(f.fields).forEach(function (k) { - b.fields[k] = data[k] ? f.fields[k].bind(data[k]) : f.fields[k].bind(''); + b.fields[k] = f.fields[k].bind(data[k]); }); b.data = Object.keys(b.fields).reduce(function (a, k) { a[k] = b.fields[k].data; From 65ed484e17a73067258cdf537c9b87cb716755a7 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 27 Aug 2013 21:53:36 -0700 Subject: [PATCH 8/9] Adding spacing. --- lib/forms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/forms.js b/lib/forms.js index 77036bf..cc38996 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -99,7 +99,7 @@ exports.create = function (fields) { } return Object.keys(form.fields).reduce(function (html, k) { - var kname = typeof name === 'string' ? name+'['+k+']' : k; + var kname = typeof name === 'string' ? name + '[' + k + ']' : k; return html + form.fields[k].toHTML(kname, iterator); }, ''); } From f5fd167315d08858b1e0b5fbebf7aa0864506ff4 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 27 Aug 2013 21:54:09 -0700 Subject: [PATCH 9/9] Using arguments.length to shift arguments. --- lib/forms.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/forms.js b/lib/forms.js index cc38996..a1c4222 100644 --- a/lib/forms.js +++ b/lib/forms.js @@ -34,8 +34,9 @@ exports.create = function (fields) { return a; }, {}); b.validate = function (obj, callback) { - if (typeof obj === 'function') { - callback = obj; + if (arguments.length === 1) { + obj = callback; + callback = arguments[0]; } async.forEach(Object.keys(b.fields), function (k, callback) { @@ -94,8 +95,9 @@ exports.create = function (fields) { toHTML: function (name, iterator) { var form = this; - if (typeof name === 'function') { - iterator = name; + if (arguments.length === 1) { + name = iterator; + iterator = arguments[0]; } return Object.keys(form.fields).reduce(function (html, k) {