-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible to add ui.update_input_file?? #1583
Comments
TIL you can programmatically set the file value (assuming you know the full contents) 🤯 I thought it was a security risk. Maybe it was in the older DOM days. Related: https://dev.to/code_rabbi/programmatically-setting-file-inputs-in-javascript-2p7i POC of working example: shinylive link Screen.Recording.2024-07-30.at.3.18.23.PM.mov |
Adding the milestone so that the issue receives more eyes |
Working with @schloerke, we came up with this version, where the file content is set purely on the server side (so that it doesn't need to be sent to the client browser). This is a proof of concept -- we would want to make changes to the Shiny package code to make this easier. import os
from shiny import App, reactive, render, ui
app_ui = ui.page_fluid(
ui.h2("File Upload and Code Display"),
ui.input_file("file", "Choose a file to upload"),
ui.input_action_button("create_upload", "Create and Upload Hello World"),
ui.output_ui("file_contents"),
ui.tags.script(
"""
// Custom message handler for receiving the filename
Shiny.addCustomMessageHandler("setFileName", function(filename) {
const fileInputImpl = document.querySelector('#file');
const fileInputPlaceholder = $("div.input-group:has(> label > span > input#file) > input").get(0)
const myFile = new File([''], filename, {
type: 'text/shiny_serverside',
lastModified: new Date(),
});
const dataTransfer = new DataTransfer();
dataTransfer.items.add(myFile);
fileInputImpl.files = dataTransfer.files;
fileInputImpl.dispatchEvent(new Event('change', { bubbles: true }));
});
""",
type="text/javascript",
),
)
example_file = {
"name": "myFile.txt",
"type": "text/plain",
"content": "Hello, world!",
}
def server(input, output, session):
@render.ui
def file_contents():
file = input.file()
if file is not None and len(file) > 0:
# =====================================================
# Inject the content on disk.
# This would be inside of the Shiny package code.
# =====================================================
if file[0]["type"] == "text/shiny_serverside":
with open(file[0]["datapath"], "w") as f:
f.write(example_file["content"])
# Find the file size and assign it here
file[0]["size"] = os.path.getsize(file[0]["datapath"])
file[0]["type"] = example_file["type"]
# =====================================================
print(file[0])
content = file[0]["datapath"]
with open(content, "r") as f:
file_content = f.read()
return ui.div(
ui.h3(f"Contents of {file[0]['name']}:"), ui.pre(file_content)
)
return ui.p("No file uploaded yet.")
@reactive.Effect
@reactive.event(input.create_upload)
async def _():
await session.send_custom_message("setFileName", example_file["name"])
app = App(app_ui, server) |
This should also be able to reset file with a This should also be able use the session file upload manager. Essentially we are uploading the contents already on the server and can use that for the per session cache |
Is it possible to add a method that allows the user to update the path of the input file that was originally set with using ui.input_file? Or possibly allow the user to remove the uploaded file through such a method?
The text was updated successfully, but these errors were encountered: