React-Native
How to getting started with Joyfill in a React-Native or Expo application
Overview
We currently support any React-Native bare and Expo setup.
Guide
Setup
Project Requirements and Dependencies
Implement your code
Do not wrap JoyDoc component inside of a ScrollView. JoyDoc rendering optimizations will not working properly inside of ScrollView and will introduce unintended bugs.
Below is a usable example of our react-native SDK. This will show a readonly or fillable form view depending on the mode
you use. Learn more about modes
here .
Make sure to replace the userAccessToken
and documentId
at the top of the Document.js
file. documentId
represents the ID of your Joyfill mobile form. Note that the documentId
can be retrieved using the Joyfill Manager or by using the List all documents API.
import React from 'react';
import {SafeAreaView, StatusBar, StyleSheet} from 'react-native';
import Document from './Document';
function App() {
return (
<SafeAreaView style={styles.container}>
<StatusBar />
<Document />
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
});
export default App;
import React, {useState, useEffect} from 'react';
import {
Dimensions,
StyleSheet,
ActivityIndicator,
Text,
View,
TouchableOpacity,
} from 'react-native';
import {JoyDoc} from '@joyfill/components-react-native';
import {joyfillSave, joyfillGenerate, joyfillRetrieve} from './api.js';
const screenWidth = Dimensions.get('window').width;
const userAccessToken = '<REPLACE_ME>';
const documentId = '<REPLACE_ME>';
const FormModes = {
fill: 'fill',
readonly: 'readonly',
};
function Document() {
const [mode, setMode] = useState(FormModes.fill);
const altMode = mode === FormModes.readonly ? FormModes.fill : FormModes.readonly;
const [doc, setDoc] = useState(null);
const [loading, setLoading] = useState(false);
/**
* Retrieve document from Joyfill api. Don't forget to add documentId and userAccessToken
*/
useEffect(() => {
retrieveJofillDocument();
}, []);
const retrieveJofillDocument = async () => {
setLoading('retrieving document...');
const response = await joyfillRetrieve(documentId, userAccessToken);
setDoc(response);
setLoading(null);
};
/**
* Handle saving document changes to Joyfill api.
*/
const saveJoyfillDocument = async () => {
setLoading('saving document & generating pdf...');
const response = await joyfillSave(doc, userAccessToken);
console.log('>>>>>>>>>>>>>>>> repsonse: ', response);
setDoc(response);
setLoading(null);
//Uncomment below to see pdf download
//const downloadableLink = await joyfillGenerate(doc.identifier, userAccessToken);
//console.log(downloadableLink);
};
return (
<>
{loading && (
<View style={styles.loading}>
<ActivityIndicator />
<Text>Loading...</Text>
</View>
)}
<View style={styles.row}>
<Text style={styles.title}>{doc?.name || 'Joyfill Form'}</Text>
</View>
<View style={styles.row}>
<TouchableOpacity
style={styles.button}
onPress={() => setMode(altMode) }
>
<Text style={styles.buttonText}>{`Set to ${altMode}`}</Text>
</TouchableOpacity>
<TouchableOpacity onPress={saveJoyfillDocument} style={styles.button}>
<Text style={styles.buttonText}>Save</Text>
</TouchableOpacity>
</View>
{doc && (
<View style={styles.form}>
<JoyDoc
mode={mode}
doc={doc}
width={screenWidth}
onChange={(params, changes, doc) => {
console.log('changes: ', params, changes, doc);
setDoc(doc);
}}
/>
</View>
)}
</>
);
}
const styles = StyleSheet.create({
loading: {
margin: 20,
justifyContent: 'center',
flexDirection: 'column',
alignItems: 'center',
},
form: {
flex: 1,
backgroundColor: 'white',
borderRadius: 6,
borderWidth: 1,
borderColor: '#E6E6FA',
padding: 2,
},
button: {
backgroundColor: 'white',
borderRadius: 8,
borderWidth: 1,
borderColor: '#1E90FF',
padding: 10,
},
buttonText: {
color: '#1E90FF',
},
row: {
margin: 10,
flexDirection: 'row',
justifyContent: 'space-between',
},
highlight: {
fontWeight: '700',
},
title: {
fontSize: 24,
fontWeight: '600',
color: 'black',
},
});
export default Document;
export const joyfillGenerate = async (identifier, userAccessToken) => {
const response = await fetch(`https://api-joy.joyfill.io/v1/documents/${identifier}/exports/pdf`, {
method: 'POST',
mode:'cors',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ fields: [] })
});
const data = await response.json();
return data.download_url;
}
export const joyfillRetrieve = async (documentIdentifier, userAccessToken) => {
const response = await fetch(`https://api-joy.joyfill.io/v1/documents/${documentIdentifier}`, {
method: 'GET',
mode: 'cors',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
});
const data = await response.json();
return data;
}
export const joyfillSave = async (doc, userAccessToken) => {
const response = await fetch(`https://api-joy.joyfill.io/v1/documents/${doc.identifier}`, {
method: 'POST',
mode:'cors',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(doc)
});
const data = await response.json();
return data;
};
export const getDataUriForFileUpload = async (fileUpload) => {
return new Promise((ful, rej) => {
const reader = new FileReader();
reader.readAsDataURL(fileUpload);
reader.onloadend = async () => {
ful(reader.result);
};
});
};
export const uploadFileAsync = async (documentId, dataUri, userAccessToken) => {
const response = await fetch(`https://api-joy.joyfill.io/v1/documents/${documentId}/files/datauri`, {
method: 'POST',
mode: 'no-cors',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ file: dataUri })
});
const data = await response.json();
return data;
};
export const convertPDFPagesToBase64Async = async (dataUri, userAccessToken) => {
try {
const response = await fetch(`https://api-joy.joyfill.io/v1/utilities/pdf/to/png/datauri`, {
method: 'POST',
mode: 'no-cors',
headers: {
Authorization: `Bearer ${userAccessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ file: dataUri })
});
return await response.json();
} catch (error) {
throw error;
}
};
JoyDoc Properties
Name | Type | Description | Required |
---|---|---|---|
mode | 'fill' | 'readonly' | Enables and disables certain JoyDoc functionality and features. • fill is the mode where you simply input the field data into the form• readonly is the mode where everything in the form is set to read-only. | ✅ |
doc | Object | The default JoyDoc JSON starting object to load into the component view. Must be in the JoyDoc JSON data structure. | |
onChange | Function: (params: object, changes: object, doc: object) => {} | Used to listen to any changes to the style, layout, values, etc. across all modes. • params: Object : Contains information about what field has been changed.• changes: Object : Can contain any of the JoyDoc JSON structure-supported properties.• doc: Object : Fully updated JoyDoc JSON structure with changes applied. |
Updated about 1 month ago