Browse Source

Add special var for upload: clear_selected_files (#1703)

Martin Xu 1 year ago
parent
commit
51f0339fa4

+ 50 - 0
integration/test_upload.py

@@ -47,6 +47,11 @@ def UploadFile():
                 ),
                 ),
                 id="selected_files",
                 id="selected_files",
             ),
             ),
+            rx.button(
+                "Clear",
+                on_click=rx.clear_selected_files,
+                id="clear_button",
+            ),
         )
         )
 
 
     app = rx.App(state=UploadState)
     app = rx.App(state=UploadState)
@@ -172,3 +177,48 @@ def test_upload_file_multiple(tmp_path, upload_file: AppHarness, driver):
     time.sleep(0.5)
     time.sleep(0.5)
     for exp_name, exp_contents in exp_files.items():
     for exp_name, exp_contents in exp_files.items():
         assert backend_state._file_data[exp_name] == exp_contents
         assert backend_state._file_data[exp_name] == exp_contents
+
+
+def test_clear_files(tmp_path, upload_file: AppHarness, driver):
+    """Select then clear several file uploads and check that they are cleared.
+
+    Args:
+        tmp_path: pytest tmp_path fixture
+        upload_file: harness for UploadFile app.
+        driver: WebDriver instance.
+    """
+    assert upload_file.app_instance is not None
+    token_input = driver.find_element(By.ID, "token")
+    assert token_input
+    # wait for the backend connection to send the token
+    token = upload_file.poll_for_value(token_input)
+    assert token is not None
+
+    upload_box = driver.find_element(By.XPATH, "//input[@type='file']")
+    assert upload_box
+    upload_button = driver.find_element(By.ID, "upload_button")
+    assert upload_button
+
+    exp_files = {
+        "test1.txt": "test file contents!",
+        "test2.txt": "this is test file number 2!",
+        "reflex.txt": "reflex is awesome!",
+    }
+    for exp_name, exp_contents in exp_files.items():
+        target_file = tmp_path / exp_name
+        target_file.write_text(exp_contents)
+        upload_box.send_keys(str(target_file))
+
+    time.sleep(0.2)
+
+    # check that the selected files are displayed
+    selected_files = driver.find_element(By.ID, "selected_files")
+    assert selected_files.text == "\n".join(exp_files)
+
+    clear_button = driver.find_element(By.ID, "clear_button")
+    assert clear_button
+    clear_button.click()
+
+    # check that the selected files are cleared
+    selected_files = driver.find_element(By.ID, "selected_files")
+    assert selected_files.text == ""

+ 2 - 1
reflex/components/forms/__init__.py

@@ -46,11 +46,12 @@ from .select import Option, Select
 from .slider import Slider, SliderFilledTrack, SliderMark, SliderThumb, SliderTrack
 from .slider import Slider, SliderFilledTrack, SliderMark, SliderThumb, SliderTrack
 from .switch import Switch
 from .switch import Switch
 from .textarea import TextArea
 from .textarea import TextArea
-from .upload import Upload, selected_files
+from .upload import Upload, clear_selected_files, selected_files
 
 
 helpers = [
 helpers = [
     "color_mode_cond",
     "color_mode_cond",
     "selected_files",
     "selected_files",
+    "clear_selected_files",
 ]
 ]
 
 
 __all__ = [f for f in dir() if f[0].isupper()] + helpers  # type: ignore
 __all__ = [f for f in dir() if f[0].isupper()] + helpers  # type: ignore

+ 2 - 0
reflex/components/forms/upload.py

@@ -15,6 +15,8 @@ upload_file = BaseVar(name="e => setFiles((files) => e)", type_=EventChain)
 # Use this var along with the Upload component to render the list of selected files.
 # Use this var along with the Upload component to render the list of selected files.
 selected_files = BaseVar(name="files.map((f) => f.name)", type_=List[str])
 selected_files = BaseVar(name="files.map((f) => f.name)", type_=List[str])
 
 
+clear_selected_files = BaseVar(name="_e => setFiles((files) => [])", type_=EventChain)
+
 
 
 class Upload(Component):
 class Upload(Component):
     """A file upload component."""
     """A file upload component."""