-
Notifications
You must be signed in to change notification settings - Fork 48
Home
- Changes to onChange & active validation
- ☑ Rename
onStateChange
toonChange
- ☑ Detect
onStateChange
, reassign toonChange
and warn of deprecation in 0.9 dev version
- ☑ Detect
- ☑ Passing
onChange
now implies `validation: 'auto'- ☑ Check for both being passed and warn that it's not necessary in 0.9 dev version
- ☑ Always hook up an
onChange
handler to widgets to keepform.data
up to date with user input, even if it's not being validated
- ☑ Rename
- ☑ Use
form.validate()
as a means of forcing a full clean with the form's current data (always populated by onChange) - FormSet & FormSet-related changes
- ☑ Add
formset.validate([form])
- ☑ Add
formset.addError(error)
for adding cross-form errors externally - ☑ Add
formset.deleteForm(index)
- ☑ Add
form.notEmpty()
- ☑ Cache the result of
hasChanged()
each time it's executed - Indicates that
emptyPermitted
no longer applies - use for highlighting required fields in extra forms in FormSets once the user has made a change.
- ☑ Cache the result of
- ☑ Make
addAnother()
anddeleteForm()
call back to re-render whenonChange()
is available
- ☑ Add
- ☑ Allow cross-form validation method to specify which fields it uses (to avoid calling it when possible)
-
API:
clean: ['field1', 'field2', function() { ... }]
-
☑ Detect this in
DeclarativeFieldsMeta
and transform to equivalent of:var clean = function() { ... } clean.fields = {'field1': true, 'field2': true}
-
- ☑ Remove
onStateChange
- ☑ Fix for using
this.addError()
inclean()
- now checks for duplicates. - How can we avoid clearing async validation messages unnecessarily?
- ☑ Only validate if data has changed since the last validation was triggered.
- Special cases for
onBlur
:- ☑ Trigger any pending validation.
- ☑ Always validate if the field is required and empty.
- ☑ New conditional CSS class Form properties:
optionalCssClass
&pendingCssClass
- Async validation
- API (allow fields to have custom but separate sync and async validation):
- ☑
form.clean<Field>: function([cb]) { }
- use existing method, callback optional - ☑
form.clean: function(cb) { }
- use existing method, callback optional - ☐
formset.clean: function(cb) { }
- use existing method, callback optional - ☐ Async version of any top-level API which triggers the equivalent of full-form/
onSubmit
validation.- TBD
- ☑
- ☑ Async
onChange
(hooked up automatically by newforms)- Custom field validation functions now get a callback if they have an arity of 1
- Async
onSubmit
(user's responsibility to hook up)- ☐ Callback once all async validation completes
- ☑ New form state for pending validations
- ☑ These need to be cancellable for cases where multiple async validations are running simultaneously and some of their results need to be ignored
- Can be used to display "working" status to the user and to delay final callback for full-form validation until al async validations are complete.
- ☑ Add a method to BoundField to retrieve this status per-field
- ☑ Use this to implement display of pending async field validation in default rendering methods.
- ☐ Add
pendingCssClass
and generate it from BoundField
- ☐ Add a method to BaseForm to retrieve pending status for all fields
- ☐ A Form should never be
isComplete()
orisValid()
if still pending async validation
- ☐ A Form should never be
- ☐ Add a method to BaseForm to retrieve this status for cross-field validation
- ☐ Implement display of pending cross-field/whole-form validation in default rendering methods.
- ☑ Add a method to BoundField to retrieve this status per-field
- API (allow fields to have custom but separate sync and async validation):
Everywhere
Improve default rendering
- Make
asDiv()
the default and make the existing CSS class configuration more prominent in the docs. - Errors appearing above the fields and pushing them down in asTable() is horrible default UX!
Integration between React components and Widgets - e.g. make a CharField use a Widget which renders a component which can mask input based on a format passed to the Field.
- Add a BoundField method which returns the attributes it would have passed to the widget for use with JSX spread operator
Create a React component for default rendering?
- Having each Form and Field render via component could also offer better default performance out of the box.
Come up with a better/more intuitive name for BoundField
- its name was never day-to-day API in Django due to Python having an iteration protocol and .
vs []
.
Documentation
- Split guide sections up into client/server pages
- Retain most of the existing docs as the server pages - they're focussed on usage of
isValid()
etc. and use examples which are equivalent to POST data. - Extract and rewrite client docs into client pages, with a focus on interactive validation and typical use cases around it, as it's going to be the default mode of operation. No POST-like data examples!
Create a "Field" which wraps a FormSet, allowing you to manage a list of items with a Form.
Disabled/hidden fields
- Add Field properties for hiding a field entirely or rendering its widget as disabled.
- Validation/cleaning should skip over disabled/hidden fields
- Pro: Enables future dynamic use of these, as fields are always present rather than being added or deleted in the constructor
- Removes the need to construct a new form instance for dynamic fields in correct order.
Client
Break everything up into individual modules
- Distribute npm version as flattened modules - people who want to save on dependency file size can directly import only what they need.
FileFields need an overhaul on the client side - there are a growing number of Widget.prototype flags which could potentially be used by custom Widgets, but in the core library are only there for special handling of FileFields.
- See https://github.com/insin/newforms/wiki/Client-side-FileField-Enhancements
- Need to get a better picture of what typical file input usage is in React apps - I doubt many people will be using them in s submitted via POST, but that's the original use case this API was designed around.
- Resetting file inputs - can't change the value (in all browsers) due to security restrictions!
- Keep a number somewhere which is used only in file input
key
attrs and increment it when an attempt is made to update a file input, to force React to recreate it?-
form.fields
is effectively part of Form instance state, as it's deep-cloned fromform.baseFields
- could add an own property toFileField
for this. - After prototyping, may need to introduce (more) special case API:
Field.prototype.renderKwargs()
-
- Keep a number somewhere which is used only in file input
Is there a common approach that could be used to tweak particular field or widget properties on the fly?
- Dynamic hidden/disabled fields
- Dynamic field choices
- These would be reacting to a change in...?
- initial/data
- cleanedData
- any additional state the user needs to pass in
- Example: Showing/hiding form fields based on external controls/state.
Add support for populating data onChange
without providing a containing <form>
.
Server
Get usage in String template engines working again
- toString() methods which are only included in a specific build and call Reaact.renderComponentToString, wrapping with React.createClass as neccessary?
- Stick with server/browser flag or move to separate builds, source never directly used?
- Version solely for use with server-side string-based templates? Created an html branch which avoids direct references to React.DOM
Bonus
Theoretically, it should be easy to persist form state should the user refresh or accidentally navigate away - put form.data
in localStorage
in the onStateChange
callback, pass it as initial
if present when creating initial component state, clear it after successfully using form.cleanedData
.
- Investigate and document - any helpers which could be provided?
Externalise mutable form state - a form/formset should provide a reference to an object to be set in a component's state.
- Changes to properties within this object by the form/formset should use
React.addons.update()
. - Form would need to be passed a callback which calls setState() for all data/error changes.
- This would allow easier creation of form-wrapping components which can skip rendering if nothing has changed.
- For FormSets, with this in place can we create a single form instance and reuse it, tweaking a variable indicating a virtual index within the set? We just then need to keep lists of cleanedData and errors which are actually held independently of the workhorse instance.