Spaces:
Sleeping
Sleeping
import streamlit as st | |
# Define the JavaScript to be embedded | |
javascript_code = """ | |
<script> | |
function myJavaScriptFunction() { | |
// Function to return a string | |
return "Hello from JavaScript!"; | |
} | |
// Function to be called on button click; uses window.alert to display the return value | |
function callAndCapture() { | |
const result = myJavaScriptFunction(); | |
// Use Streamlit's via the streamlit:component event to send data back to Python | |
window.parent.postMessage({isStreamlitMessage: true, type: 'streamlit:component', data: result}, '*'); | |
} | |
// Add an event listener to handle messages from the iframe or parent window. | |
window.addEventListener('message', function(event) { | |
if (event.data.type === 'streamlit:buttonClick') { | |
callAndCapture(); | |
} | |
}); | |
</script> | |
<button onclick="callAndCapture()">Run JavaScript Function</button> | |
""" | |
# Create a container for HTML/JS script | |
html_container = st.empty() | |
html_container.html(javascript_code + "<div id='returned_value'></div>", height=300) | |
# Create a placeholder message | |
message_placeholder = st.empty() | |
# Add a button in Streamlit to send a message to the iframe to call JavaScript | |
if st.button("Call JavaScript Function"): | |
js = """ | |
<script> | |
window.parent.postMessage({type: "streamlit:buttonClick"}, "*"); | |
</script> | |
""" | |
html_container.html(javascript_code + js + "<div id='returned_value'></div>", height=300) | |
# Future-proofing to listen for messages from the JavaScript side | |
if "js_result" not in st.session_state: | |
st.session_state["js_result"] = "" | |
# Handle messages from JavaScript | |
st.markdown( | |
""" | |
<script> | |
window.addEventListener('message', (event) => { | |
if (event.data && event.data.isStreamlitMessage) { | |
const result = event.data.data; | |
// Reflect the result back to the Python script | |
window.parent.postMessage({type: 'streamlit:component_with_result', data: result}, '*'); | |
} | |
}); | |
</script> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Python-side listener to write the result to the placeholder | |
try: | |
import streamlit.components.v1 as components | |
messages = components.html( | |
""" | |
<script> | |
window.addEventListener('message', (event) => { | |
if (event.data.type === 'streamlit:component_with_result') { | |
window.parent.postMessage(event.data.data, '*'); | |
} | |
}); | |
</script> | |
""", | |
height=0, | |
) | |
if_messages_received = messages._deserialize() | |
if if_messages_received and if_messages_received != st.session_state["js_result"]: | |
st.session_state["js_result"] = if_messages_received | |
message_placeholder.markdown("_" + if_messages_received + "_") | |
except: | |
pass | |
st.session_state["js_result"] |