Skip to content

Commit

Permalink
feat: expose inner element when using HOC (#399)
Browse files Browse the repository at this point in the history
Use `innerRef={(c) => { this.myInput = c; }}` on your HOC to access the internal element
  • Loading branch information
aesopwolf authored Dec 9, 2016
1 parent 15493dc commit 2b24911
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 4 deletions.
26 changes: 24 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
- [validate](#validate)
- [formNoValidate](#formnovalidate)
- [Formsy.HOC](#formsyhoc)
- [innerRef](#innerRef)
- [Formsy.Decorator](#formsydecorator)
- [Formsy.addValidationRule](#formsyaddvalidationrule)
- [Validators](#validators)
Expand Down Expand Up @@ -566,7 +567,7 @@ The same methods as the mixin are exposed to the HOC version of the element comp
```jsx
import {HOC} from 'formsy-react';

class MyInput extends React.Component {
class MyInputHoc extends React.Component {
render() {
return (
<div>
Expand All @@ -575,9 +576,30 @@ class MyInput extends React.Component {
);
}
};
export default HOC(MyInput);
export default HOC(MyInputHoc);
```

#### <a name="innerRef">innerRef</a>

Use an `innerRef` prop to get a reference to your DOM node.

```jsx
var MyForm = React.createClass({
componentDidMount() {
this.searchInput.focus()
},
render: function () {
return (
<Formsy.Form>
<MyInputHoc name="search" innerRef={(c) => { this.searchInput = c; }} />
</Formsy.Form>
);
}
})
```

Sets a class name on the form itself.

### <a name="formsydecorator">Formsy.Decorator</a>
The same methods as the mixin are exposed to the decorator version of the element component, though through the `props`, not on the instance.
```jsx
Expand Down
11 changes: 9 additions & 2 deletions src/HOC.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ module.exports = function (Component) {
return React.createClass({
displayName: 'Formsy(' + getDisplayName(Component) + ')',
mixins: [Mixin],

render: function () {
return React.createElement(Component, {
const { innerRef } = this.props;
const propsForElement = {
setValidations: this.setValidations,
setValue: this.setValue,
resetValue: this.resetValue,
Expand All @@ -22,7 +24,12 @@ module.exports = function (Component) {
showError: this.showError,
isValidValue: this.isValidValue,
...this.props
});
};

if (innerRef) {
propsForElement.ref = innerRef;
}
return React.createElement(Component, propsForElement);
}
});
};
Expand Down
18 changes: 18 additions & 0 deletions tests/Formsy-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,30 @@ import TestUtils from 'react-addons-test-utils';

import Formsy from './..';
import TestInput from './utils/TestInput';
import TestInputHoc from './utils/TestInputHoc';
import immediate from './utils/immediate';
import sinon from 'sinon';

export default {

'Setting up a form': {
'should expose the users DOM node through an innerRef prop': function (test) {
const TestForm = React.createClass({
render() {
return (
<Formsy.Form>
<TestInputHoc name="name" innerRef={(c) => { this.name = c; }} />
</Formsy.Form>
);
}
});

const form = TestUtils.renderIntoDocument(<TestForm/>);
const input = form.name;
test.equal(input.methodOnWrappedInstance('foo'), 'foo');

test.done();
},

'should render a form into the document': function (test) {

Expand Down
13 changes: 13 additions & 0 deletions tests/utils/TestInputHoc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { HOC as formsyHoc } from './../..';

const defaultProps = {
methodOnWrappedInstance(param) {
return param;
},
render() {
return (<input />);
},
};

export default formsyHoc(React.createClass(defaultProps));

0 comments on commit 2b24911

Please sign in to comment.