WeBWorK Problems

Playing with javascript in function setAppletCoefficients()

Playing with javascript in function setAppletCoefficients()

by Nicole Wilson -
Number of replies: 4
I am adding points and line segments to a GeoGebra graph in function setAppletCoefficients()

(lines 200 to 210): Using the following sequential lines is fine
applet.evalCommand("v_1 = Segment($edgesStart[0],$edgesEnd[0])");
applet.evalCommand("v_2 = Segment($edgesStart[1],$edgesEnd[1])");
applet.evalCommand("v_3 = Segment($edgesStart[2],$edgesEnd[2])");
.
.
.
applet.evalCommand("v_{10} = Segment($edgesStart[9],$edgesEnd[9])");

(lines 196 to 199) Trying to replace them with this loop doesn't work
for (var index = 0; index < $numEdges; index++) {
applet.evalCommand("v_" + index+1 +
" = Segment(" + $edgesStart[index] + ',' + $edgesEnd[index] + ")");
}

It squawks about the variable index in $edgesStart[index]

Does anyone know how I can make a javascript variable play nicely with a pg array?
In reply to Nicole Wilson

Re: Playing with javascript in function setAppletCoefficients()

by Davide Cervone -
Does anyone know how I can make a javascript variable play nicely with a pg array?

You are not going to be able to do that. The PG code is running on the server, and the JavaScript is running int he browser, so the array and the index are not even the same machines.

You may not realize how the two languages interact. The "here document" that is the string between the line

TEXT( MODES(TeX=>'', HTML=><
and its corresponding END_SRIPT is being processed by PG with variable substitution.  So all the occurrences of things like $edgeStart[0] and $numEdges are being substituted into the string at the time the PG problem is processed.  That means that the HTML page doesn't include a reference to $edgeStart[0] but rather its value.  If you look at the page source in your browser, you will see the actual letters for the vertices, not the array names and indices.

So in your lines

for (var index = 0; index < $numEdges; index++) {
    applet.evalCommand("v_" + index+1 +
        " = Segment(" + $edgesStart[index] + ',' + $edgesEnd[index] + ")");
}
the Perl interpreter tries to insert the value of $edgesStart[index] into the string at this point. But in Perl (i.e., in PG), index is not a variable, and so it is treated as the string "index", and Perl tries to substitute $edgesStart["index"]. Since @edgesStart is an array, not a hash, there is no element with name "index" (you can only access an array by using a number), you get the error about that. You didn't give the actual error message you receive (you should, by the way), but I suspect it will have been a Perl error during the processing of the problem (i.e., the problem will not have produced output), not a javascript error in the browser console. That tells you that you need to look at the Perl code, not the javascript code, for the problem.

Because the @edgesStart array is only on the server, not the browser, you can not access it from your javascript code. One possible solution would be to output the perl array into code that produces the corresponding javascript array on the browser, and then reference that.

Alternatively, you could use a Perl loop to generate a string of applet.evalCommand() calls dynamically and insert that string into the javascript string in place of your javascript loop.

In any case, you will need to handle the separation between the Perl and JavaScript languages more carefully, and be aware of how the Perl values are being substituted into the javascript.

In reply to Nicole Wilson

Re: Playing with javascript in function setAppletCoefficients()

by Davide Cervone -
Does anyone know how I can make a javascript variable play nicely with a pg array?

You are not going to be able to do that. The PG code is running on the server, and the JavaScript is running int he browser, so the array and the index are not even the same machines.

You may not realize how the two languages interact. The "here document" that is the string between the line

TEXT( MODES(TeX=>'', HTML=><<END_SCRIPT ) );
and its corresponding END_SRIPT is being processed by PG with variable substitution. So all the occurrences of things like $edgeStart[0] and $numEdges are being substituted into the string at the time the PG problem is processed. That means that the HTML page doesn't include a reference to $edgeStart[0] but rather its value. If you look at the page source in your browser, you will see the actual letters for the vertices, not the array names and indices.

So in your lines

for (var index = 0; index < $numEdges; index++) {
    applet.evalCommand("v_" + index+1 +
        " = Segment(" + $edgesStart[index] + ',' + $edgesEnd[index] + ")");
}
the Perl interpreter tries to insert the value of $edgesStart[index] into the string at this point. But in Perl (i.e., in PG), index is not a variable, and so it is treated as the string "index", and Perl tries to substitute $edgesStart["index"]. Since @edgesStart is an array, not a hash, there is no element with name "index" (you can only access an array by using a number), you get the error about that. You didn't give the actual error message you received (you should, by the way), but I suspect it will have been a Perl error during the processing of the problem (i.e., the problem will not have produced output), not a javascript error in the browser console. That tells you that you need to look at the Perl code, not the javascript code, for the problem.

Because the @edgesStart array is only on the server, not the browser, you can not access it from your javascript code. One possible solution would be to output the perl array into code that produces the corresponding javascript array on the browser, and then reference that. A little awkward, but it would work.

Alternatively, you could use a Perl loop to generate a string of applet.evalCommand() calls dynamically and insert that string into the javascript string in place of your javascript loop. That is, you would produce the 10 original lines (using a loop in perl) and insert those lines into the javascript program, so the final output is the same as it was originally (no javascript loop).

In any case, you will need to handle the separation between the Perl and JavaScript languages more carefully, and be aware of how the Perl values are being substituted into the javascript.

In reply to Davide Cervone

Re: Playing with javascript in function setAppletCoefficients()

by Nicole Wilson -
That makes sense, thanks for spelling it out.

It also explains why my work-around with if statements (to execute a variable number of the lines) works.


In reply to Nicole Wilson

Re: Playing with javascript in function setAppletCoefficients()

by Nicole Wilson -
I found a way to make this work and now have three very pretty templates for making simple graphs, digraphs, and small multigraphs.

The trick was to save the list of vertices labels (one letter names) and the list of edges (two letter names) to strings. In the javascript portion of the code, I saved the literal string to a variable with a nice short name and used the length and charAt methods to access the vertex and edge names.

However, this won't generalize all that well.
I could see doing this using delimiters for longer names or even integers if I had to but it would be a complete nightmare with a list of rational numbers.