I have 2 codemirror components on a page and when you click the "Run" button, I want it to run the code above the button only.
The issue I am having is it is only running the last codemirror component and does not run the individual code the way I like it to.
Is there any way in the button onClick function below to set that up dynamically?
Codemirror components with onClick buttons:
<div id="content">
<section class="method first-of-group" id="intro">
<div class="method-area method-area-expanded">
<div class="method-copy">
<h1 class="lesson-name">python title</h1>
<div class="method-example">
<div id="side-view">
<div id="side-left">
<textarea id="yourcode" cols="40" rows="10">
my_name = "Sir Python"
print("Hello and welcome " + my_name + "!")
</textarea
>
<script type="text/javascript">
// insert codemirror
var myCodeMirror = CodeMirror.fromTextArea(yourcode, {
lineNumbers: true,
mode: "python"
});
</script>
</div>
<br />
<div id="side-right">
<div id="console">
<pre id="output"></pre>
</div>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas"></div>
</div>
<button type="button" onclick="runit()">Run</button>
</div>
</div>
</div>
</section>
<section class="method first-of-group" id="intro">
<div class="method-area method-area-expanded">
<div class="method-copy">
<h1 class="lesson-name">python title</h1>
<div class="method-example">
<div id="side-view">
<div id="side-left">
<textarea id="authcode" cols="40" rows="10">
# This code will print out Hello World
print("Hello World")
</textarea
>
<script type="text/javascript">
// insert codemirror
var myCodeMirror = CodeMirror.fromTextArea(authcode, {
lineNumbers: true,
mode: "python"
});
</script>
</div>
<br />
<div id="side-right">
<div id="console">
<pre id="output"></pre>
</div>
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas"></div>
</div>
<button type="button" onclick="runit()">Run</button>
</div>
</div>
</div>
</section>
</div>
Here is the onClick function:
<script type="text/javascript">
// output functions are configurable. This one just appends some text
// to a pre element.
function outf(text) {
var mypre = document.getElementById("output");
mypre.innerHTML = mypre.innerHTML + text;
}
function builtinRead(x) {
if (
Sk.builtinFiles === undefined ||
Sk.builtinFiles["files"][x] === undefined
)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
// Here's everything you need to run a python program in skulpt
// grab the code from your textarea
// get a reference to your pre element for output
// configure the output function
// call Sk.importMainWithBody()
function runit() {
var prog = myCodeMirror.getValue();
var mypre = document.getElementById("output");
mypre.innerHTML = "";
Sk.pre = "output";
Sk.configure({ output: outf, read: builtinRead });
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = "mycanvas";
var myPromise = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(
function(mod) {
console.log("success");
]
},
function(err) {
console.log(err.toString());
}
);
}
</script>
The issue is that you're reusing the same variable name myCodeMirror
. Since the scripts on the page are executed in DOM order, the last value is used.
Additionally, you're using the same runit()
method without differentiating which mirror to run, so it will always run on the last CodeMirror you setup.
First, you need to store the CodeMirrors in different variables:
var myCodeMirror1 = CodeMirror.fromTextArea(yourcode, {
lineNumbers: true,
mode: "python"
});
[...]
var myCodeMirror2 = CodeMirror.fromTextArea(authcode, {
lineNumbers: true,
mode: "python"
});
Then each button needs to tell runit
which one to use:
<button type="button" onclick="runit(myCodeMirror1)">Run</button>
[...]
function runit(mirrorToRun) {
var prog = mirrorToRun.getValue();
[...]
}