Permalink
Browse files

Implement inline form type

  • Loading branch information...
1 parent 05da5f4 commit 01ec23ad3eba1aece5e647304096c331bbf8e843 @mhuggins committed Jul 5, 2012
Showing with 182 additions and 22 deletions.
  1. +63 −0 lib/railway-bootstrap/forms/inline.js
  2. +1 −1 lib/railway-bootstrap/helpers.js
  3. +33 −21 readme.md
  4. +85 −0 test/forms/inline-test.js
@@ -0,0 +1,63 @@
+module.exports = InlineForm;
+
+function InlineForm(context, resource, params) {
+ var self = this;
+
+ this.buf = arguments.callee.caller.buf;
+ this.context = context;
+ this.resource = resource;
+ this.params = railway.utils.safe_merge({ class: 'form-inline' }, params);
+}
+
+InlineForm.prototype.fieldsFor = function (block) {
+ var context = this.context;
+ var resource = this.resource;
+ var util = require('./form-util');
+
+ arguments.callee.buf = this.buf;
+
+ context.formTag(this.params, function () {
+ if (block) {
+ block({
+ input: input('input'),
+ file: input('file'),
+ textarea: input('textarea'),
+ submit: submit
+ });
+ }
+ });
+
+ function input(inputType) {
+ return function (name, params) {
+ var output = [];
+ params = params || {};
+
+ context.fields_for(resource, function (form) {
+ params.placeholder = params.label;
+ delete params.label;
+
+ if (params.placeholder === false) {
+ delete params.placeholder;
+ } else {
+ params.placeholder = params.placeholder || util.humanize(name);
+ }
+
+ output.push(form[inputType](name, params));
+ });
+
+ return output.join("\n");
+ };
+ }
+
+ function submit(name, params) {
+ var output;
+ params = params || {};
+
+ context.fields_for(resource, function (form) {
+ params = railway.utils.safe_merge({ class: 'btn btn-primary' }, params);
+ output = form.submit(name, params);
+ });
+
+ return output;
+ }
+};
@@ -31,7 +31,7 @@ exports.bootstrapFormFor = exports.bootstrap_form_for = function (resource, para
/**
* Twitter Bootstrap form tag helpers for specific form types.
*/
-['basic', 'horizontal'].forEach(function (format) {
+['vertical', 'horizontal', 'inline'].forEach(function (format) {
exports[format + 'FormFor'] = exports[format + '_form_for'] = function (resource, params, block) {
params = railway.utils.safe_merge({ format: format }, params);
exports.bootstrapFormFor(resource, params, block);
View
@@ -40,41 +40,34 @@ Assume that your application has a `User` model with properties `username`,
<%- form.textarea('description') %>
<% }) %>
-The `bootstrapFormFor` helper method can accept parameters in the following
-formats:
+The `bootstrapFormFor` helper method has two valid signatures:
1. `bootstrapFormFor(resource, callback)`
2. `bootstrapFormFor(resource, options, callback)`
-In the second format, the `options` parameter represent a basic JS object. Any
-key/value pairs included in the object will be converted to HTML attributes on the
-`<form>` DOM object. For example:
+The parameters are defined as follows:
+
+* `resource`: An instance of a model that the form will represent.
+* `options`: A simple object that includes any extra attributes you wish to
+ define on the form, in addition to a `type` option that is explained in
+ more detail below.
+* `callback`: A function that is used for defining fields within the form.
+
+Below is a simple example of how you might use this helper method.
bootstrapFormFor(user, { action: '/users/new', method: 'put' }, function (form) { ... });
-This will produce the following HTML:
+This example produces HTML like the following:
<form class="well" action="/users/new" method="post">
<input type="hidden" name="authenticity_token" value="f46d9de27e45fef8dce10a36dcdc7be7fa8612af" />
<input type="hidden" name="_method" value="PUT" />
<!-- any other calls made on the form object will render here -->
</form>
-The type of the Bootstrap form that you want to use can be provided in the
-`options` parameter as well. Currently, only "vertical" and "horizontal" are
-provided, with "vertical" being the default. The available types map to the
-following CSS classes. (See the [Forms section of the Twitter Bootstrap docs](http://twitter.github.com/bootstrap/base-css.html#forms)
-for more details on form types.)
-
-* `vertical` = `form-vertical`
-* `horizontal` = `form-horizontal`
-
-Finally, for either format of `bootstrapFormFor` that is used, the `callback`
-parameter will be provided with `form` object. This object provides several
-methods used for rendering form fields.
-
-The `form` object that is provided to your callback has the following methods
-available:
+When using `bootstrapFormFor`, the `callback` parameter will be provided with a
+`form` object as the only parameter. This object provides several methods that
+can be used for rendering form fields.
* `input (name, options)`: Creates an `<input>` element, where `name` is the name of
the resource's property to render. If no `options` are provided, the input type
@@ -86,6 +79,25 @@ available:
* `submit (label, options)`: Creates a `<button type="submit">` element, where
`label` is the text to be rendered on the button.
+Form Types
+----------
+This plugin implements three of the Twitter Bootstraps form types: vertical
+(the default), horizontal, and inline. There are two ways to change the type
+of form being rendered. The first is to use the `type` option when calling
+`bootstrapFormFor`.
+
+ bootstrapFormFor(user, { type: 'horizontal' }, function (form) { ... });
+
+Additionally, there are helper methods provided for each of the types of forms
+implemented.
+
+ horizontalFormFor(user, function (form) { ... });
+ verticalFormFor(user, function (form) { ... });
+ inlineFormFor(user, function (form) { ... });
+
+Refer to the [Forms section of the Twitter Bootstrap docs](http://twitter.github.com/bootstrap/base-css.html#forms)
+for more details on and examples of form types.
+
Created By:
-----------
[Matt Huggins](http://www.matthuggins.com)
View
@@ -0,0 +1,85 @@
+require('railway').createServer();
+require('railway-bootstrap').init();
+
+var vows = require('vows');
+var assert = require('assert');
+var InlineForm = require('railway-bootstrap/forms/inline');
+
+function User() {
+ this.id = 1;
+ this.username = 'AzureDiamond';
+ this.email = 'hunter2@example.com';
+ this.description = 'doesnt look like stars to me';
+ this.avatar = null;
+}
+
+var user = new User();
+
+vows.describe('InlineForm').addBatch({
+ before: function () {
+ railway.helpers.controller = {
+ request: { csrfParam: 'csrf_name', csrfToken: 'csrf_value' }
+ }
+ },
+
+ 'constructor': {
+ topic: function () {
+ arguments.callee.buf = [];
+ return new InlineForm(railway.helpers, user);
+ },
+
+ 'includes class in form tag': function (form) {
+ form.fieldsFor();
+ var output = form.buf.join('');
+ var expected = /<form[^>]*class="form-inline"[^>]*>/;
+ assert.match(output, expected);
+ }
+ },
+
+ 'fieldsFor': {
+ topic: function () {
+ arguments.callee.buf = [];
+ return new InlineForm(railway.helpers, user)
+ },
+
+ 'with type input': {
+ 'creates text input with placeholder': function (form) {
+ form.fieldsFor(function (form) {
+ var output = form.input('username');
+ var expected = '<input name="username" id="username" placeholder="Username" value="' + user.username + '" />';
+ assert.include(output, expected);
+ });
+ }
+ },
+
+ 'with type textarea': {
+ 'creates textarea with placeholder': function (form) {
+ form.fieldsFor(function (form) {
+ var output = form.textarea('description');
+ var expected = '<textarea name="description" id="description" placeholder="Description">' + user.description + '</textarea>';
+ assert.include(output, expected);
+ });
+ }
+ },
+
+ 'with type file': {
+ 'creates file input with placeholder': function (form) {
+ form.fieldsFor(function (form) {
+ var output = form.file('avatar');
+ var expected = '<input name="avatar" id="avatar" type="file" placeholder="Avatar" />';
+ assert.include(output, expected);
+ });
+ }
+ },
+
+ 'with type submit': {
+ 'creates submit button': function (form) {
+ form.fieldsFor(function (form) {
+ var output = form.submit('Register');
+ var expected = '<button type="submit" class="btn btn-primary">Register</button>';
+ assert.include(output, expected);
+ });
+ }
+ }
+ }
+}).export(module);

0 comments on commit 01ec23a

Please sign in to comment.