Skip to content

Instantly share code, notes, and snippets.

@jlongster
Last active May 8, 2017 14:15
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlongster/75ef6271f81527574125 to your computer and use it in GitHub Desktop.
Save jlongster/75ef6271f81527574125 to your computer and use it in GitHub Desktop.
higher-order form components w/react
// Simple wrapper to use bootstrap's grid system to position elements side-by-side
var VerticalFieldsElement = React.createClass({
render: function() {
return dom.div(
{ className: 'clearfix' },
React.Children.map(this.props.children, function(child) {
if(!child) {
return child;
}
return React.addons.cloneWithProps(child, {
groupClassName: 'col-lg-3'
});
})
);
}
});
var VerticalFields = React.createFactory(VerticalFieldsElement);
// This is the much more interesting one: instead of having to
// deconstruct the data object and manually stick a `value` and
// change handler for every single field, make a `FusedInputs`
// element that takes the data object and an update callback which
// does this automatically
function fuseInputs(children, data, onUpdate) {
return React.Children.map(children, function(child) {
if(!child) {
return child;
}
if(child.type === ReactBootstrap.Input ||
child.type === TextElement) {
var name = child.props.name;
return React.cloneElement(child, {
value: data && data[name],
onChange: function(e) { onUpdate(name, e); }
});
}
else if(child.props && child.props.children) {
return React.cloneElement(
child,
child.props,
fuseInputs(child.props.children, data, onUpdate)
);
}
return child;
});
}
var FusedInputsElement = React.createClass({
handleUpdate: function(field, e) {
this.props.onUpdate(field, e.target.value);
},
render: function() {
return dom.div(
null,
fuseInputs(this.props.children, this.props.data, this.handleUpdate)
);
}
});
var FusedInputs = React.createFactory(FusedInputsElement);
// Usage:
// (assume that the `Text` input is the same as a normal <input>)
FusedInputs(
{ data: data,
onUpdate: this.handleUpdate },
Text({ label: 'Item Title',
name: 'Desc_Title',
groupClassName: 'col-lg-12' }),
VerticalFields(
null,
Text({ label: 'Width', name: 'Desc_Width' }),
Text({ label: 'Height', name: 'Desc_Height' }),
Text({ label: 'Auction ID', name: 'Auction_ID' }),
Text({ label: 'Auction Lot Number', name: 'Auction_LotNumber' })
),
VerticalFields(
null,
Text({ label: 'Date Received', name: 'Date_Received' }),
Text({ label: 'Date Returned', name: 'Date_Returned' }),
Text({ label: 'Period', name: 'Desc_Period' }),
Text({ label: 'Featured Text', name: 'Featured_Text' })
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment