Drawing .svg with javascript module "RDKIT-JS" - javascript

first of all I'm relatively new to javascript. So I'm sorry if my question is dumb. I would like to draw a molecule on my webiste by using this tool https://github.com/rdkit/rdkit-js. I also found an example here https://iwatobipen.wordpress.com/2021/12/29/create-desktop-chemoinformatics-application-with-js-chemoinformatics-rdkit-js/comment-page-1/. This example works in my case but when i try to invoke a function to draw a molecule as a .svg without using the example code, I fail. I get this error-message in my browser:
Uncaught ReferenceError: RDKit is not defined
at drawmol (results:21:15)
at results:33:5
In the following code example you can see the first case where it works and the second case were it doesn't. In both cases i use the same function.:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/#rdkit/rdkit/dist/RDKit_minimal.js"></script>
<title>Document</title>
<script>
window
.initRDKitModule()
.then(function (RDKit) {
console.log("RDKit version: " + RDKit.version());
window.RDKit = RDKit;
})
.catch(() => {
});
</script>
<script> var drawmol = function() {
var mol = RDKit.get_mol("C1=CC=C(C=C1)O"); // the string here is a string representation of chemical molecules, it could also be something like "CO" or "CCCCC", shouldnt be important
var svg = mol.get_svg();
document.getElementById("drawer").innerHTML = svg;
};
</script>
</head>
<body>
<button type='button' onclick='drawmol()'> <!-- this works -->
draw
</button><br>
<script>
// drawmol() //this doesnt work
</script>
<div id='drawer'></div>
</body>
</body>
</html>
Later i would like to use the module to dynamically make those images. I use django as the framework. In this case i tried to present a minimal example without the django stuff.
Thanks in advance for your effort!

You are calling drawmol() before RDKit is ready.
To fix this, place it after RDKit is loaded:
window
.initRDKitModule()
.then(function (RDKit) {
console.log("RDKit version: " + RDKit.version());
window.RDKit = RDKit;
//Now RDKit is loaded you can safely call drawmol()
drawmol();
})
.catch(() => {
});

Related

JQuery partly triggered

I'm a beginner with JQuery and I was trying to create a button that dynamically changes the colors defined in the CSS depending on what color it is right now (just switch between blue / red) and also change the text on the button.
The .draggable() part executes just fine and so does the first and last console.log, so everything but the part within the click event handler works ... but why?
Relevant html code:
<!DOCTYPE html>
<html>
<head>
<title>Meine Website</title>
<meta charset="utf-8">
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type="text/javascript">
</script>
<script
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"
type="text/javascript">
</script>
<script src="home_jquery.js"></script>
<script src="home_javascript.js"></script>
<link rel="stylesheet" type="text/css" href="home_style_blau.css">
</head>
<body>
<input type="button" id="farbwechsel_button" value="Rot" />
/* rest of html (taschenrechner_box, etc.) */
</body>
Here's the jQuery part:
var blau = true;
$(document).ready(function () {
$('#taschenrechner_box').draggable();
console.log("test1");
$('#farbwechsel_button').click(function() {
console.log("test2");
if (blau == true) {
console.log("blau = " + blau);
$('body').css({"background-color": "8b0000"});
$('#farbwechsel_button').value = "Blau";
blau = false;
}
else {
console.log("blau = " + blau);
$('body').css({"background-color": "lightsteelblue"});
$('#farbwechsel_button').value = "Rot";
blau = true;
}
console.log("test3");
})
console.log("test4");
});
In your HTML you have:
<input type="button" id="farbwechsel_button" value="Rot" />
But in your JS you refer to
$('#farbwechel_button').click(function() {
Note the forgotten s in your JS. So the JS should be:
$('#farbwechsel_button').click(function() {
Edit: you've forgotten the s in al your referrals to the button. Don't forget to add it everywhere. You've also forgotten a ; just before the last console.log() function.
Edit 2: Here's a Fiddle with a working example. It's pretty much self explanatory. In this case you preferably should make use of classes which you toggle on pressing the button.

How do I use JQuery inside an object constructor in my own javascript namespace?

I can't even find a hint of an answer to this question anywhere, so maybe I'm totally barking up the wrong tree...
I'm making a javascript namespace, inside of which I am putting a constructor function:
var SEP=SEP||{};
SEP.person=function(name)
{
this.name=name
this.sayName=sayName
function sayName()
{
return this.name;
$(document).ready
(
function()
{
$('body').css('background', 'red');
}
);
}
}
Then I am calling the function from the HTML...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>test</title>
<meta name="generator" content="BBEdit 10.5" />
</head>
<body>
<script src="libraries/jquery/javascript/jquery-1.11.0-min.js"></script>
<script src="libraries/sep/javascript/sep.js"></script>
<p>Hello</p>
<script>
var bob=new SEP.person("bob");
word=bob.sayName();
document.write(word);
</script>
</body>
</html>
Question one is, why doesn't this work?
Question two is how can I make it work?
Question three is, if I want to make a more involved constructor, with JQuery peppered thoughout, do I need to do the document ready thing over and over, or is there a better way?
Many thanks in advance.
Actually your constructor is working fine. But you should not use document.write in your code. Instead you can append the value to a html tag, using either .append() .html() or .text() methods. Also there should be a small change in your sayName() method, Css should apply before return. Otherwise it will not hit on those lines of code.
var SEP = SEP || {};
SEP.person = function (name) {
this.name = name
this.sayName = sayName
function sayName() {
$('body').css('background', 'red');
return this.name;
}
}
var bob = new SEP.person("bob");
word = bob.sayName();
$("span").text(word);
Demo

'javascript:close()' doesn't seem to be working

I'm really new to JavaScript, but I think this should be pretty simple. I'm just trying to create a link to close my window using: document.write("Close this window");
However, when I click the link created by the above code nothing happens. What am I doing wrong? my entire code is below:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Loops demo</title>
</head>
<body>
<script type="text/javascript">
function openActor() {
actorWin = window.open("","actorWin","height=200,width=600,resizable");
actorWin.document.write("<!doctype html>");
actorWin.document.write("<html lang=\"en\">");
actorWin.document.write("<head>");
actorWin.document.write("<meta charset=\"utf-8\">");
actorWin.document.write("<title>Keira Knightley</title>");;
actorWin.document.write("</head>");
actorWin.document.write("<body>");
actorWin.document.write("Info on, one of the great actors of our time.");
actorWin.document.write("</body>");
actorWin.document.write("</html>");
}
function Movie(title, actor, web1, web2) {
this.title = title;
this.actor = actor;
this.link = web1;
this.link2 = web2;
}
var movie1 = new Movie('Pride and Prejudice', 'Keira Knightley', 'http://movies.yahoo.com/movie/pride-and- prejudice-2005/','http://keiraknightleyfan.com/');
document.write(movie1.title + '<blockquote>“A lady\'s imagination is very rapid; it jumps from admiration to love, from love to matrimony in a moment.” ― Jane Austen, Pride and Prejudice</blockquote>');
document.write('Read more about Pride Prejudice<br>');
document.write("<a href='javascript:openActor()'>Click here for info on the lead actor</a><br>");
document.write("<a href='javascript:close()'>Close this window</a>");
</script>
</body>
</html>
You cannot close windows by using close() when they haven't been opened via javascript
There is no function named close.
javascript:close(); simply calls the function close.
If you want to close the popup window, you will need to call close on that.
Like: javascript:actorWin.close();
In that case, make sure you declare the actorWin in the global scope (put var actorWin; just above function openActor...).
Try window.close()
document.write("<a href='javascript:window.close()'>Close this window</a>");

Multiple modes Codemirror

I want my TextArea to be able to support multiple CodeMirror modes. For now I want it to support json and xml. Is this possible?
Also, is it possible to automatically detect whether the user placed json or xml in the area?
Thanks.
CodeMirror actually has an example very close to what you are looking for here.
Here is a more specific example that does what you want.
Create a CodeMirror instance.
When the content changes we determine if we should switch modes.
The logic I put in for determining what mode you are in is very simplistic and can be refactored to support as robust a check as you deem appropriate for either mode. (Regex is good for complex checking if you want to get fancy...that is the only reason I used it even in my simple example) Currently, my example code just checks for any content where the first non-space character is "<" thus indicating xml mode. When deciding to switch back it just checks that the first non-space character is not "<" and that it is not blank (in case the user just deleted everything to start over with more xml).
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Code Mirror Example</title>
<script src="lib/codemirror.js"></script>
<link rel="stylesheet" href="lib/codemirror.css">
<script src="mode/javascript/javascript.js"></script>
<script src="mode/xml/xml.js"></script>
<style type="text/css">.CodeMirror{border:1px solid black;}</style>
</head>
<body>
<div><span>Mode: </span><span id="modeType">JSON</span></div>
<textarea class='codeEditor'></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
function determineCodeMirrorType(cm)
{
if (cm.getMode().name == 'javascript')
{
checkAndSwitchToXML(cm, cm.getValue());
}
else if (cm.getMode().name == 'xml')
{
checkAndSwitchToJSON(cm, cm.getValue());
}
}
function checkAndSwitchToXML(cm, val)
{
if (/^\s*</.test(val))
{
cm.setOption("mode", "xml");
$('#modeType').html("XML");
}
}
function checkAndSwitchToJSON(cm, val)
{
if (!/^\s*</.test(val) && val.match(/\S/))
{
cm.setOption("mode", "javascript");
$('#modeType').html("JSON");
}
}
function buildCMInstance(mode, value)
{
var cm = CodeMirror.fromTextArea($('.codeEditor')[0], {
mode:mode,
value:value,
lineNumbers:true,
onChange:function(cmInstance){
determineCodeMirrorType(cmInstance);
}
});
return cm;
}
$(document).ready(function(){
//mode changing demo: "http://codemirror.net/demo/changemode.html";
var cm = buildCMInstance("javascript");
});
</script>
</body>
</html>

Why is my custom module not available after YUILoader.onSuccess event fires?

Trying to write better JavaScript, woohoo!
First step for me: YUILoader dependency loader so all of my custom code is available to use at a reliable point in time.
My current environment:
YUI (2.8.1) library path: C:\wamp\www\lib\js\yui\2\build\ (http://localhost/lib/js/yui/2/build/)
All YUI min, debug and raw files located in above location
Custom library path: C:\wamp\www\lib\js\ (http://localhost/lib/js/)
Custom Module 'fln-min.js' located in above location
Testing in Chrome
Notes:
Below is my example HTML page, my custom module follows the HTML code. No CSS or anything funky yet, I just want to get this working as a proof of concept. If you run my code, you'll see that both onSuccess events fire, but in the nested callback data is null, and my custom module seems to be unavailable. I've tried a few things, like the path concatenation, hence 'base' in the first YUILoader instance, and the commented out 2nd 'fullpath' in the 2nd YUILoader instance.
Demo HTML page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>External file Loader</title>
<script src="/lib/js/yui/2/build/yuiloader/yuiloader-min.js"></script>
<script>
new YAHOO.util.YUILoader({
base: '/lib/js/yui/2/build/',
require: ['yahoo-dom-event'],
// require: ['yahoo-dom-event','reset-fonts-grids','container'],
// allowRollup: true,
// combine: true,
onSuccess: function() {
alert('YAHOO: '+YAHOO);
var loader = new YAHOO.util.YUILoader();
//
loader.addModule({
name:'FLN',
// varName:'FLN',
type:'js',
fullpath:'/lib/js/fln-min.js'
// fullpath:'../../../fln-min.js'
});
loader.onSuccess = function(o) {
//
alert('o.data: '+YAHOO.lang.dump(o.data));
alert('FLN: '+FLN);
//
};
loader.onFailure = function(o) {
//
alert('Error: '+YAHOO.lang.dump(o));
//
};
loader.insert();
}
}).insert();
</script>
</head>
<body>
<div id="output"></div>
</body>
</html>
Custom module (fln-min.js):
var FLN = function(){
var _debug = false ;
var _masterDebug = false ;
return {
loaded: function(){ return true; }
}
}();
alert('...');
The correct answer was: new Loader() #1's config object was missing the custom module key name FLN from its requires array.

Categories

Resources