diff --git a/README.md b/README.md
index 68ff79b7..6ce1a6ed 100644
--- a/README.md
+++ b/README.md
@@ -161,36 +161,62 @@ Here's an example of a basic ProfileUploader component, demonstrating how to add
We currently re-expose withWebId and LogoutButton so you can use the basic components without installing other libraries.
-### ShexFormBuilder
+### ShExFormBuilder
+
**Note**: This is an early preview build of a work-in-progress component and subject to large-scale changes in future releases.
This component allows you to create a fully functional form, complete with submit, cancel, and validation rules, from a [ShEx](http://shex.io/shex-primer/index.html) Shape.
+#### Supported Field Types:
+
+##### Textbox
+Textboxes are the default input type for each field in a shape. In future versions, there will be a way to determine if you want a textbox vs a textarea based on properties such as maxlength.
+
+##### Select / Dropdown
+Dropdowns are displayed when the shape has a reference to another shape that is only a list of values. The values are displayed in the dropdown.
+
+
+#### Validation
+Validation is done using ShEx constraints. You can read more about these constraints on the [ShEx website](http://shex.io/). Examples include:
+
+* Required vs Optional fields.
+* Repeatable fields, and the min/max number of times they can be repeated.
+* Min and/or max length of strings.
+* Length of numbers, and min/max number values.
+* Regular expression patterns.
+
+#### Labels
+Currently, labels are assigned to a field by either:
+
+* Adding an rdfs:label annotation to the field in the ShEx shape (see [example shapes](https://shexshapes.inrupt.net/public/) for examples).
+* Parsing the name of the predicate assigned to that field.
+
+In the future, labels will be generated more dynamically.
-Usage:
+#### Usage
```
```
-| Props | Type | Default | Description |
-| ------------------ | -------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
-| documentUri | string | null | Required. The URL representing the root subject to save the form data to, for example a webID or file in the user's pod. |
-| shexUri | string | null | Required. The URL to the shex shape to use to render the form |
-| rootShape | string | null | Optional. The shape in the shexUri file to begin parsing. If a START shape is defined in the shape, this is not necessary. |
-| theme | Object | null | Optional. An object (defined below) allowing custom overrides to the look and feel of the form
+| Props | Type | Default | Description
+| ------------------ | -------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------
+| documentUri | string | null | Required. The URL representing the root subject to save the form data to, for example a WebID or file in the user's Pod.
+| shexUri | string | null | Required. The URL to the ShEx shape to use to render the form.
+| rootShape | string | null | Optional. The shape in the shexUri file to begin parsing. If a START shape is defined in the shape, this is not necessary.
+| theme | Object | null | Optional. An object (defined below) allowing custom overrides to the look and feel of the form.
| language | string | null | Optional. The language identifier to translate text. For example, 'en' or 'es'.
| successCallback | Function | Function that writes a success message to console | Optional. Overrides the existing success callback and allows custom success functions.
-| errorCallback | Function | Function that writes the error message to console | Optional. Overrides the existing error callback function
-| messageValidation | Object | null | An Object containing an array of error strings. The error strings will be used in most non-validation situations
+| errorCallback | Function | Function that writes the error message to console | Optional. Overrides the existing error callback function.
+| messageValidation | Object | null | An Object containing an array of error strings. The error strings will be used in most non-validation situations.
Theme object:
| Key | Type | Default | Description
-| ------------------ | -------- | ------------------------------------- | --------------------
-| input | string | solid-input-shex | Custom class name for input fields in the form
-| select | string | solid-input-shex solid-select-shex | Custom class name for select fields in the form
-| deleteButton | string | solid-button-shex | Custom class name for the delete button
-| form | string | solid-shex-form | Custom class name for the form
+| ------------------ | -------- | ------------------------------------- | ------------------------------------------------
+| input | string | solid-input-shex | Custom class name for input fields in the form.
+| select | string | solid-input-shex solid-select-shex | Custom class name for select fields in the form.
+| deleteButton | string | solid-button-shex | Custom class name for the delete button.
+| form | string | solid-shex-form | Custom class name for the form.
##### Shapes
A set of example shapes can be found [here](https://shexshapes.inrupt.net/public/), which show various ShEx shapes.
\ No newline at end of file
diff --git a/package.json b/package.json
index d8a27f9e..be9bc79e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@inrupt/solid-react-components",
- "version": "0.3.2",
+ "version": "0.4.0-rc.1",
"description": "Solid React Components",
"main": "build/index.js",
"scripts": {
diff --git a/src/demo/components/HandleShexForm/handle-shex-form.component.js b/src/demo/components/HandleShexForm/handle-shex-form.component.js
index b3f6dcc4..3794b37f 100644
--- a/src/demo/components/HandleShexForm/handle-shex-form.component.js
+++ b/src/demo/components/HandleShexForm/handle-shex-form.component.js
@@ -40,9 +40,11 @@ const HandleShexForm = ({ webId }:Props) => {
// By default addButton and deleteButton will be Add new and Delete
const languageTheme = {
language: 'en',
- addButtonText: '+ Add new ',
- deleteButton: 'Delete',
- dropdownDefaultText: '- Select -'
+ saveBtn: "Save",
+ resetBtn: "Reset",
+ addButtonText: "+ Add new ",
+ deleteButton: "Delete",
+ dropdownDefaultText: "- Select -"
};
return(
diff --git a/src/lib/components/ShexFormBuilder/shex-form-builder.component.js b/src/lib/components/ShexFormBuilder/shex-form-builder.component.js
index 7db461c1..1a44767d 100644
--- a/src/lib/components/ShexFormBuilder/shex-form-builder.component.js
+++ b/src/lib/components/ShexFormBuilder/shex-form-builder.component.js
@@ -12,7 +12,7 @@ type Props = {
shexUri: String,
rootShape: String,
theme: Object,
- language: String
+ languageTheme: Object
};
const ShexFormBuilder = ({
@@ -70,6 +70,8 @@ const ShexFormBuilder = ({
if (!formError) {
updateShexJ(deleted, "delete");
successCallback();
+ } else {
+ errorCallback();
}
} catch (e) {
errorCallback(e);
@@ -86,7 +88,6 @@ const ShexFormBuilder = ({
errorCallback(e);
}
});
-
return (
@@ -103,9 +104,9 @@ const ShexFormBuilder = ({
}}
/>
)}
-
+
@@ -121,6 +122,14 @@ ShexFormBuilder.defaultProps = {
select: "solid-input-shex solid-select-shex",
deleteButton: "solid-button-shex",
form: "solid-shex-form"
+ },
+ languageTheme: {
+ language: "en",
+ saveBtn: "Save",
+ resetBtn: "Reset",
+ addButtonText: "+ Add new ",
+ deleteButton: "Delete",
+ dropdownDefaultText: "- Select -"
}
};
diff --git a/src/lib/hooks/useForm.js b/src/lib/hooks/useForm.js
index d36cb259..ef20aad9 100644
--- a/src/lib/hooks/useForm.js
+++ b/src/lib/hooks/useForm.js
@@ -30,7 +30,7 @@ export const useForm = (documentUri: String) => {
parentName: e.target.getAttribute('data-parent-name')
}
};
-
+ onError(null);
setFormValues({ ...formValues, ...data });
};
@@ -189,6 +189,7 @@ export const useForm = (documentUri: String) => {
const onSubmit = async (e: Event) => {
try {
+ onError(null);
if (!documentUri || documentUri === "") {
throw Error("Document Uri is required");
}
@@ -241,10 +242,12 @@ export const useForm = (documentUri: String) => {
return true;
} else {
setFormValues({...updatedFields});
- return false;
+ if (keys.length !== 0) {
+ onError('Please ensure all values are in a proper format.');
+ }
}
} catch (error) {
- throw Error(error);
+ onError(error);
}
};
diff --git a/src/lib/hooks/useShex.js b/src/lib/hooks/useShex.js
index 171a2471..8752eded 100644
--- a/src/lib/hooks/useShex.js
+++ b/src/lib/hooks/useShex.js
@@ -310,10 +310,10 @@ export const useShex = (fileShex: String, documentUri: String, rootShape: String
if (newExpressions[i]._formValues[y]._formFocus.name === options.key) {
if (action === 'delete') {
- // If field is the last one will keep it but will update value and name
- let toIndex = newExpressions[i]._formValues.length === 1 ? 1 : 0;
+ const _formValues = newExpressions[i]._formValues;
+ const currentFieldName = newExpressions[i]._formValues[y]._formFocus.name;
- newExpressions[i]._formValues.splice(y, y + toIndex);
+ newExpressions[i]._formValues = _formValues.filter(val => val._formFocus.name !== currentFieldName);
} else {
newExpressions[i]._formValues[y] = {