Skip to content

Commit

Permalink
Added Formset.prototype.prefixFormat
Browse files Browse the repository at this point in the history
Added API docs for prefixFormat.

Closes #70
  • Loading branch information
insin committed Mar 11, 2015
1 parent 9bb0ac0 commit 6b3c273
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
* Added new core `Field` argument: `field.widgetAttrs` - this allows you to
provide additional widget attributes without having to redefine the entire
widget ([#62](https://github.com/insin/newforms/issues/62))
* Added `Form.prototype.prefixFormat` (`'{prefix}-{name}'`) and
`FormSet.prototype.prefixFormat` (`'{prefix}-{index}'`) to define how prefixes
are generated. These can be overridden when extending these components to
customise now field names are generated when prefixes are used
([#70](https://github.com/insin/newforms/issues/70))

## Changes

Expand Down
12 changes: 12 additions & 0 deletions docs/forms_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ Forms API
:param Boolean kwargs.emptyPermitted:
if ``true``, the form is allowed to be empty -- defaults to ``false``.

**Prototype Properties**

.. js:attribute:: Form#prefixFormat

This string defines the format used to generate ``name`` attributes for
fields when a form instance is given a ``prefix``. It must contain
``{prefix}`` and ``{name}`` placeholders.

The default format is ``'{prefix}-{name}'``.

:type String:

**Instance Properties**

Form options documented in ``kwargs`` above are all set as instance
Expand Down
12 changes: 12 additions & 0 deletions docs/formsets_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ Formsets API
:param Object constructorProps:
properties to be set directly on the new constructor function.

**Prototype Properties**

.. js:attribute:: FormSet#prefixFormat

This string defines the format used to generate a ``prefix`` for forms in
the formset to ensure they have unique ``name`` attributes. It must
contain ``{prefix}`` and ``{index}`` placeholders.

The default format is ``'{prefix}-{index}'``.

:type String:

**Instance Properties**

Formset options documented in ``kwargs`` above are set as instance properties.
Expand Down
5 changes: 4 additions & 1 deletion src/FormSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
var Concur = require('Concur')
var getFormData = require('get-form-data')
var is = require('isomorph/is')
var {formatObj} = require('isomorph/format')
var object = require('isomorph/object')

var constants = require('./constants')
Expand Down Expand Up @@ -61,6 +62,8 @@ var ManagementForm = (function() {
* @param {Object=} kwargs
*/
var FormSet = Concur.extend({
prefixFormat: '{prefix}-{index}',

constructor: function FormSet(kwargs) {
// TODO Perform PropType checks on kwargs in development mode
kwargs = object.extend({
Expand Down Expand Up @@ -897,7 +900,7 @@ FormSet.prototype.nonFormPending = function() {
* @param {Number} index the index of a form in the formset.
*/
FormSet.prototype.addPrefix = function(index) {
return this.prefix + '-' + index
return formatObj(this.prefixFormat, {prefix: this.prefix, index: index})
}

FormSet.prototype.getDefaultPrefix = function() {
Expand Down
28 changes: 28 additions & 0 deletions tests/formsets-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,34 @@ QUnit.test("Basic FormSet", 5, function() {
strictEqual(formset.hasChanged(), false)
})

QUnit.test('Custom prefix format', function() {
// By default, formsets append a hyphen between the prefix and theform index,
// but a formset can alter that behaviour by overriding prefixFormat, which
// should be a string containing {prefix} and {index} placeholders.
var ChoiceForm = forms.Form.extend({
prefixFormat: '{prefix}[{name}]',
choice: forms.CharField(),
votes: forms.IntegerField()
})

var ChoiceFormSet = forms.FormSet.extend({
form: ChoiceForm,
prefixFormat: '{prefix}[{index}]'
})

var initial = [{choice: "Calexico", votes: 100}]
var formset = new ChoiceFormSet({initial: initial, autoId: false, prefix: 'choices'})
reactHTMLEqual(renderAll(formset.forms()),
'<div>\
<div>Choice: <input type="text" name="choices[0][choice]" value="Calexico"></div>\
<div>Votes: <input type="number" name="choices[0][votes]" value="100"></div>\
</div>\
<div>\
<div>Choice: <input type="text" name="choices[1][choice]"></div>\
<div>Votes: <input type="number" name="choices[1][votes]"></div>\
</div>')
})

QUnit.test("Formset validation", 2, function() {
// FormSet instances can also have an error attribute if validation failed for
// any of the forms.
Expand Down

0 comments on commit 6b3c273

Please sign in to comment.