Files
enviPy-bayer/templates/components/ketcher.html
jebus 31c57299e4 [Feature] Ketcher V3 (#427)
Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#427
2026-07-17 08:16:09 +12:00

107 lines
2.8 KiB
HTML

{% load static %}
<div>
<label class="text-base-content/50 mb-4 text-xs font-medium"
>Draw Structure</label
>
<iframe
id="{{ iframe_id }}"
src="{% static '/js/ketcher3/standalone/index.html' %}"
width="100%"
height="{{ height }}"
tabindex="-1"
></iframe>
</div>
<script>
// Used to block write back to text field if "Render" was clicked
var propagate = true;
// Helper function to safely get Ketcher instance from iframe
function getKetcherInstance(iframeId = "{{ iframe_id }}") {
const ketcherFrame = document.getElementById(iframeId);
if (!ketcherFrame) {
console.error("Ketcher iframe not found:", iframeId);
return null;
}
try {
if (
"contentWindow" in ketcherFrame &&
ketcherFrame.contentWindow.ketcher
) {
return ketcherFrame.contentWindow.ketcher;
}
} catch (err) {
console.error("Cannot access Ketcher iframe - possible CORS issue:", err);
}
return null;
}
async function ketcherToInputs(
ketcher,
smilesTargetId = "{{ text_input_id }}",
molfileTargetId = "{{ molfile_input_id }}",
iframeId = "{{ iframe_id }}",
) {
if (!propagate) {
propagate = true;
return;
}
document.getElementById(smilesTargetId).value =
await getSmilesFromKetcher(iframeId);
if (molfileTargetId !== "") {
document.getElementById(molfileTargetId).value =
await getMolfileFromKetcher(iframeId);
}
}
async function getSmilesFromKetcher(iframeId = "{{ iframe_id }}") {
const ketcher = getKetcherInstance(iframeId);
if (ketcher && ketcher.getSmiles) {
return ketcher.getSmiles();
}
}
async function getMolfileFromKetcher(iframeId = "{{ iframe_id }}") {
const ketcher = getKetcherInstance(iframeId);
if (ketcher && ketcher.getMolfile) {
return ketcher.getMolfile();
}
}
function setKetcherMolecule(
smilesOrMolfile,
propagateChange = true,
iframeId = "{{ iframe_id }}",
) {
const ketcher = getKetcherInstance(iframeId);
propagate = propagateChange || false;
ketcher.setMolecule(smilesOrMolfile);
}
document.addEventListener("DOMContentLoaded", function () {
const predictKetcher = document.getElementById("{{ iframe_id }}");
predictKetcher.addEventListener("load", function () {
const checkKetcherReady = () => {
const win = this.contentWindow;
if (win.ketcher && "editor" in win.ketcher) {
window.predictKetcher = win.ketcher;
win.ketcher.editor.event.change.handlers.push({
once: false,
priority: 0,
f: ketcherToInputs,
ketcher: win.ketcher,
});
} else {
setTimeout(checkKetcherReady, 100);
}
};
checkKetcherReady();
});
});
</script>