Last active
May 24, 2019 09:13
-
-
Save wvbe/d38a6ac8a374c546ea16ae98db25d8ff to your computer and use it in GitHub Desktop.
A React hook for Fonto applications that makes it easy to build a (metadata) form for an XML subtree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is an example of how the `useXQueryDataBinding` hook can be implemented for a simple form field (in this case the | |
* FDS `TextInput` component. | |
* The readQuery argument to `useXQueryDataBinding` returns a format (string) that is useful for the TextInput. I | |
* another case you might choose to return an XPath `map` or `array` instead and distribute that over multiple or more | |
* complex form components. | |
* | |
* The writeQuery argument is given the `$data('value')` XPath variable, which is whatever `TextInput` returns in its | |
* `onChange` callback - for this component, that is also a string. | |
*/ | |
import React from 'react'; | |
import { | |
FormRow, | |
TextInput | |
} from 'fds/components'; | |
import useXQueryDataBinding from './useXQueryDataBinding.js'; | |
export default function ExampleMetadataTextInput ({ contextNodeId }) { | |
const [value, setValue] = useXQueryDataBinding( | |
contextNodeId, | |
`./meta/doi/string()`, | |
`replace value of node $data('contextNode')/meta/doi with $data('value')`); | |
return <FormRow label="Digital object identifier" labelPosition='before'> | |
<TextInput | |
value={ value } | |
onChange={setValue} | |
/> | |
</FormRow>; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect } from 'react'; | |
import documentsManager from 'fontoxml-documents/src/documentsManager.js'; | |
import evaluateXPath from 'fontoxml-selectors/src/evaluateXPath.js'; | |
import operationsManager from 'fontoxml-operations/src/operationsManager.js'; | |
import readOnlyBlueprint from 'fontoxml-blueprints/src/readOnlyBlueprint.js'; | |
function getValue(contextNodeId, readQuery) { | |
return evaluateXPath(readQuery, documentsManager.getNodeById(contextNodeId), readOnlyBlueprint); | |
} | |
export default function useXQueryDataBinding(contextNodeId, readQuery, writeQuery) { | |
const [value, setValue] = useState(getValue(contextNodeId, readQuery)); | |
// Whenever the `contextNodeId` prop changes, update state with the new value: | |
useEffect(() => { | |
setValue(getValue(contextNodeId, readQuery)); | |
}, [contextNodeId]); | |
return [ | |
value, | |
function setXQueryDataBindingValue (value) { | |
// Update React state | |
setValue(value); | |
// Update XML document using the `execute-update-script` operation. The React state is made available | |
// as XQuery variable `$data('value')`. | |
operationsManager | |
.executeOperation('execute-update-script', { | |
contextNodeId, | |
expression: writeQuery, | |
value | |
}) | |
.catch(error => { | |
console.warn('Could not update', error.message, value, contextNodeId, writeQuery); | |
}); | |
} | |
]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment