diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index 8252c8ee52..91aa129f11 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -13,7 +13,7 @@
2. [Second Step]
3. [and so on...]
-Ideally, I'm providing a [sample JSFiddle](https://jsfiddle.net/n1k0/f2y3fq7L/6/) demonstrating the issue.
+Ideally, I'm providing a [sample JSFiddle](https://jsfiddle.net/n1k0/f2y3fq7L/6/) or a [shared playground link](https://mozilla-services.github.io/react-jsonschema-form/) demonstrating the issue.
#### Expected behavior
diff --git a/README.md b/README.md
index e1c0b8e898..2ad800b250 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ A [live playground](https://mozilla-services.github.io/react-jsonschema-form/) i
- [Advanced customization](#advanced-customization)
- [Field template](#field-template)
- [Array Field Template](#array-field-template)
- - [Error list Template](#error-list-template)
+ - [Error List template](#error-list-template)
- [Custom widgets and fields](#custom-widgets-and-fields)
- [Custom widget components](#custom-widget-components)
- [Custom component registration](#custom-component-registration)
diff --git a/playground/app.js b/playground/app.js
index 1db3ec6c6e..49e5cd3a9f 100644
--- a/playground/app.js
+++ b/playground/app.js
@@ -195,7 +195,6 @@ class Editor extends Component {
try {
this.props.onChange(fromJson(this.state.code));
} catch (err) {
- console.error(err);
this.setState({ valid: false, code });
}
});
@@ -274,6 +273,42 @@ function ThemeSelector({ theme, select }) {
);
}
+class CopyLink extends Component {
+ onCopyClick = event => {
+ this.input.select();
+ document.execCommand("copy");
+ };
+
+ render() {
+ const { shareURL, onShare } = this.props;
+ if (!shareURL) {
+ return (
+
+ );
+ }
+ return (
+
+ this.input = input}
+ className="form-control"
+ defaultValue={shareURL}
+ />
+
+
+
+
+ );
+ }
+}
+
class App extends Component {
constructor(props) {
super(props);
@@ -288,11 +323,21 @@ class App extends Component {
editor: "default",
theme: "default",
liveValidate: true,
+ shareURL: null,
};
}
componentDidMount() {
- this.load(samples.Simple);
+ const hash = document.location.hash.match(/#(.*)/);
+ if (hash && typeof hash[1] === "string" && hash[1].length > 0) {
+ try {
+ this.load(JSON.parse(atob(hash[1])));
+ } catch (err) {
+ alert("Unable to load form setup data.");
+ }
+ } else {
+ this.load(samples.Simple);
+ }
}
shouldComponentUpdate(nextProps, nextState) {
@@ -307,11 +352,11 @@ class App extends Component {
this.setState({ ...data, form: true, ArrayFieldTemplate }));
};
- onSchemaEdited = schema => this.setState({ schema });
+ onSchemaEdited = schema => this.setState({ schema, shareURL: null });
- onUISchemaEdited = uiSchema => this.setState({ uiSchema });
+ onUISchemaEdited = uiSchema => this.setState({ uiSchema, shareURL: null });
- onFormDataEdited = formData => this.setState({ formData });
+ onFormDataEdited = formData => this.setState({ formData, shareURL: null });
onThemeSelected = (theme, { stylesheet, editor }) => {
this.setState({ theme, editor: editor ? editor : "default" });
@@ -323,7 +368,19 @@ class App extends Component {
setLiveValidate = ({ formData }) => this.setState({ liveValidate: formData });
- onFormDataChange = ({ formData }) => this.setState({ formData });
+ onFormDataChange = ({ formData }) =>
+ this.setState({ formData, shareURL: null });
+
+ onShare = () => {
+ const { formData, schema, uiSchema } = this.state;
+ const { location: { origin, pathname } } = document;
+ try {
+ const hash = btoa(JSON.stringify({ formData, schema, uiSchema }));
+ this.setState({ shareURL: `${origin}${pathname}#${hash}` });
+ } catch (err) {
+ this.setState({ shareURL: null });
+ }
+ };
render() {
const {
@@ -401,8 +458,21 @@ class App extends Component {
onBlur={(id, value) =>
console.log(`Touched ${id} with value ${value}`)}
transformErrors={transformErrors}
- onError={log("errors")}
- />}
+ onError={log("errors")}>
+
+ }
);