Skip to content
This repository was archived by the owner on May 25, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 41 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
<ShexFormBuilder documentUri={url} shexUri={} />
```
| 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.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
17 changes: 13 additions & 4 deletions src/lib/components/ShexFormBuilder/shex-form-builder.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Props = {
shexUri: String,
rootShape: String,
theme: Object,
language: String
languageTheme: Object
};

const ShexFormBuilder = ({
Expand Down Expand Up @@ -70,6 +70,8 @@ const ShexFormBuilder = ({
if (!formError) {
updateShexJ(deleted, "delete");
successCallback();
} else {
errorCallback();
}
} catch (e) {
errorCallback(e);
Expand All @@ -86,7 +88,6 @@ const ShexFormBuilder = ({
errorCallback(e);
}
});

return (
<ThemeShex.Provider value={theme}>
<Language.Provider value={languageTheme}>
Expand All @@ -103,9 +104,9 @@ const ShexFormBuilder = ({
}}
/>
)}
<button type="submit">Save</button>
<button type="submit">{languageTheme.saveBtn}</button>
<button type="button" onClick={onReset}>
Reset
{languageTheme.resetBtn}
</button>
</FormComponent>
</Language.Provider>
Expand All @@ -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 -"
}
};

Expand Down
9 changes: 6 additions & 3 deletions src/lib/hooks/useForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const useForm = (documentUri: String) => {
parentName: e.target.getAttribute('data-parent-name')
}
};

onError(null);
setFormValues({ ...formValues, ...data });
};

Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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);
}
};

Expand Down
6 changes: 3 additions & 3 deletions src/lib/hooks/useShex.js
Original file line number Diff line number Diff line change
Expand Up @@ -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] = {
Expand Down