Skip to content

Instantly share code, notes, and snippets.

@dillonhafer
Created July 9, 2018 19:31
Show Gist options
  • Select an option

  • Save dillonhafer/04936dda21f7f0331167c8ff1cc9c5eb to your computer and use it in GitHub Desktop.

Select an option

Save dillonhafer/04936dda21f7f0331167c8ff1cc9c5eb to your computer and use it in GitHub Desktop.
Expo Document Picker workaround
import React, { Component } from 'react';
import {
View,
Text,
TouchableOpacity,
} from 'react-native';
import WebViewHack from './WebViewHack';
class ImportFileScreen extends Component {
selectFile = async () => {
try {
const file = await DocumentPicker.getDocumentAsync({ type: 'text/csv' });
if (file.type === 'success') {
this.parseFile(file.uri);
}
} catch (err) {
// Expo didn't build with iCloud, expo turtle fallback
this.webview.injectJavaScript('selectFile()');
}
};
onSelectFile = event => {
const base64file = event.nativeEvent.data;
this.parseFile(base64file);
};
parseFile(file) {
// do something with the file
}
render() {
return (
<View>
<TouchableOpacity onPress={this.selectFile}>
<Text>Attach File</Text>
</TouchableOpacity>
<WebViewHack
ref={webview => {
if (webview && webview.webview) {
this.webview = webview.webview;
}
}}
onSelectFile={this.onSelectFile}
/>
</View>
)
}
}
import React, { PureComponent } from 'react';
import { WebView } from 'react-native';
const html = `
<input id='csv' type="file" accept="text/csv,text/plain">
<script>
function selectFile(event) {
document.getElementById('csv').click();
}
function getBase64(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
window.postMessage(reader.result)
};
reader.onerror = function (error) {
console.log("Something went wrong:", error)
};
}
document.getElementById('csv').addEventListener('change', getBase64)
</script>
`;
class WebViewHack extends PureComponent {
render() {
const { onSelectFile } = this.props;
return (
<WebView
ref={webview => (this.webview = webview)}
onMessage={onSelectFile}
style={{
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
width: 0,
height: 0,
}}
source={{
html,
}}
/>
);
}
}
export default WebViewHack;
@spanwair
Copy link

spanwair commented Oct 25, 2020

this worked for me for expo

const html = `
      <label for="input" style="">
        <div style="
          width: 100%;
          background-color: blue;
          border: 1px solid blue;
          display: flex;
          justify-content: center;
          padding: 50px;
          border-radius: 10px;
        ">
          <span style="
            font-size: 45px;
            font-weight: 500;
            color: white;
          ">
            text
          </span>
        </div>
      </label>
      <input
        id="input"
        accept="*/*"
        type="file"
        multiple
        style="display: none;"
      >
      <script>
        const fileToRead = document.getElementById("input");

        fileToRead.addEventListener("change", function(event) {
          const filesBase64 = [];
          for (let i = 0; i < event.target.files.length; i++) {
            const file = event.target.files[i];
            const reader = new FileReader();
            reader.onload = function () {
              filesBase64.push({result: reader.result, len: event.target.files.length});
              window.ReactNativeWebView.postMessage(JSON.stringify(filesBase64))
            };
            reader.readAsDataURL(file);
          }
        });
      </script>
    `;

<WebView
          style={{width: '100%', height: 60}}
          javaScriptEnabled
          domStorageEnabled
          onMessage={event => this.pickedFiles((event.nativeEvent as unknown) as PickedFile)}
          source={{html}}
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment