Open kevzettler opened 9 years ago
Bump. Also from #1, @insin can you provide how to do this with http://newforms.readthedocs.org/en/latest/forms_api.html#DeclarativeFieldsMeta
The default Widget
implementations are currently the only reference for writing widgets. The Widget docs only contain a custom MultiWidget
example because the base object is useless on its own.
The base Widget
object documents what the various methods are for - the best thing to do at the moment is check out how widgets which are most similar to what you need are implemented.
Note that widgets are currently still effectively direct ports from django.forms
so are fairly dumb and static - still trying to figure out a good way to implement them as React components, which should make it much easier to implement your own.
React 0.13 may be the time to start implementing this, as it adds support for regular JavaScript constructors as components, which allows for extension and tweaking of a base Widget
component.
I haven't tried it yet, but a good patten in the meantime might be to extend Widget
and render a custom React component inside the widget's render(name, value, kwargs)
method. kwargs.attrs
includes the event handler callbacks newforms uses to track changes (there's always a kwargs.attrs.onChange
, plus any other for events you've configure to fire), so you need to either pass those to a rendered React input or handle calling them yourself with an appropriate value.
I haven't tried it yet, but a good patten in the meantime might be to extend Widget and render a custom React component inside the widget's render(name, value, kwargs) method. kwargs.attrs includes the event handler callbacks newforms uses to track changes (there's always a kwargs.attrs.onChange, plus any other for events you've configure to fire), so you need to either pass those to a rendered React input or handle calling them yourself with an appropriate value.
This is what we've been doing so far on our setup. We have this meta thing that converts all our 'Form' components in to newforms
friendly components. @insin let me know if you have any ideas to improve this
var Form = {
CheckBox: require('./form/CheckBox'),
CardInput: require('./form/CardInput'),
QuantitySelector: require('./QuantitySelector')
};
Object.keys(Form).forEach(function(key){
Form["NF"+key] = newforms.Widget.extend({
constructor: function (kwargs) {
if (!(this instanceof Form["NF"+key])) { return new Form["NF"+key](kwargs) }
newforms.Widget.call(this, kwargs);
this.props = kwargs;
},
render: function(name, value, kwargs){
var finalAttrs = this.buildAttrs(Object.assign(kwargs.attrs, this.props), {
type: this.inputType,
name:name
});
var valueAttr = (kwargs.controlled || this.isHidden ? 'value' : 'defaultValue')
finalAttrs[valueAttr] = this.props[valueAttr];
return React.createElement(Form[key], finalAttrs);
}
});
});
Would be cool to see an example of how RenderForm would be used with a custom renderer as well.
@marr a custom renderer for RenderForm
can just be any React component which takes a form
prop with the form instance to be rendered. BootstrapForm
and GridForm
are a couple of examples.
(After React contexts change from being owner-based to parent-based, it won't even have to take a prop, just pick the form off the context, e.g: this is what GridForm should look like then)
Thanks, I hadn't seen that syntax before. Specifically passing children to the RenderForm. Is that something supported in 0.12? I am running into an issue where I'd like to format a fields input using a vendor lib. https://www.npmjs.com/package/payment#paymentformatcardnumber will let me format CC entry a little nicer, but I'm not sure how to hook it into a newforms field. My form looks like: https://github.com/bitwise/status/blob/master/src/scripts/forms/NewCreditCard.js
I can't seem to find any code demonstrating custom widget setup