Forum Moderators: coopster & phranque

Message Too Old, No Replies

Using Javascript inside Perl-generated HTML

         

bondra12

4:27 pm on Oct 20, 2006 (gmt 0)

10+ Year Member



Hi everyone, just a noob with a (easy?) question...

It is possible to embed Javascript into a Perl file that builds HTML pages so that you can take advantage of all the cool UI capabilities of JS like onChange and onClick events. My problem is, I'm not clear on how I can interchange data between my Perl variables and newly-declared Javascript variables. I have an example in a different file where a Javascript array element is assigned the value of a Perl scalar variable (cscsArray[0] = "$scalar_var";), but what I need to do is somewhat going the opposite direction, i.e. assign a JS String the value of a hash or list element. Such as...

.
.
.
%brn_hash = ();
$remainder = "some string of data";
.
.
print <<END_of_quotes;

<script type="text/javascript" language="JavaScript">
function foo(brn) {
var tempstr = new String();

tempstr = "$remainder"; <-- works OK
tempstr = "$brn_hash{brn}"; <-- this doesn't work, is it because we're dealing with a non-scalar type that can't be subscripted/evaluated before tempstr takes on its value?

}
END_of_quotes
.
.

I feared that mixing client- and server-side stuff like this wouldn't work but I found a working example that seems almost identical to what I'm doing. The one difference is that in my case the Perl variable is non-scalar (a hash) and needs subscripted before assignment takes place (should I have used a hash reference var instead?). I'm new to both Javascript and Perl, so if my attempt to do "tempstr = " makes anyone giggle, I won't complain... :) We're all new at some point, right?

perl_diver

8:18 pm on Oct 20, 2006 (gmt 0)

10+ Year Member



this is a scalar:

$brn_hash{brn}

it should work if the key 'brn' is defined in the hash %brn_hash. Now, it could be a reference to some other data, in which case you would see some odd appearing string in the source code, which would be the memory location of the referenced data. Do you know if $brn_hash{brn} is a simple scalar or a reference to some other data?

On the larger question, javascript is javascript. Once the javascript code is constructed by the perl script and printed to the browser the browser doesn't know the difference. As long as it's good javascript code it will work like it would with any other html document.

rocknbil

4:29 am on Oct 23, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You will also find that to do any sort of escaped characters you need to double-escape them. \\n to get \n in the JS.

bondra12

7:30 pm on Oct 23, 2006 (gmt 0)

10+ Year Member



As far as the critical line of all this, I either get...

tempstr = "", or
tempstr = "$brn_hash{brn}" (the string not being evaluated)

...in my source code once the page is served to the browser. Ideally, I'm trying to pass the brn_hash's lookup value by key "brn". I know my slice of JS code has the correct value in "brn", but for whatever reason it isn't getting evaluated the way I had hoped. That's why I had wondered whether I should be using reference subscripting to access the elements within brn_hash instead of direct referencing like $brn_hash{brn}...

And thanks for the dialogue *everyone*, I've been banging my head on my desk for 2 weeks on this little hiccup and hopefully talking this through with more knowledgable Perl folks will help me "see the light".

perl_diver

8:13 pm on Oct 23, 2006 (gmt 0)

10+ Year Member



I think you are mixing javascript data with perl data, that will not work.

function foo(brn) {

'brn' is passed to the javascript function, this only works in the browser, the perl script on the server has no idea what javascript is.

rocknbil

7:34 pm on Oct 25, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Two suggestions:

One, verify that this value is being populated. Before your print << command, do this:

print "content-type: text/html\n\n";
print "Is value? $brn_hash{brn}";
exit 0;

I know it's academic. :-) But I put the text up front to verify it's not erroring before that and is indeed printing the line. I'm guessing that this value is blank or undefined because the print_to_here should work.

Second, if you indeed get a value out of that, just try printing in a different way:


$js = qq¦
<script type="text/javascript">
function foo(brn) {
var tempstr = new String();
tempstr = "$remainder";
tempstr = "$brn_hash{brn}";
alert('brn? '+ tempstr);
}
</script>
¦;

print $js;

This is really no different than print_to_here, but give it a shot, always works for me. :-)

perl_diver

8:17 pm on Oct 25, 2006 (gmt 0)

10+ Year Member



I think he is trying to pass a javascript variable to the function and use that variable as the key in a perl hash, all in the browser. Obviously this will not work as the perl hash is not accessible in the browser. He would need to print a javascript data structure into the source code of the html page and use that to run the javascript function. Or maybe I have totally misunderstood the question.

bondra12

1:35 pm on Oct 26, 2006 (gmt 0)

10+ Year Member



Hey everyone,
Again, thanks for just logging onto here and offering assistance to total strangers in need, its a great idea and I'm glad its out here. Maybe one day I'll have good suggestions to offer...
As it turns out, I think I've fixed the problem. I wasn't getting out of my here-document to do the Perl-to-Javascript variable assignments and that seemed to be the problem. It looks like you can pre-load a Javascript variable with Perl variable contents as long as you do so outside the scope of the here-doc stuff. I'll post the final contents below so everyone can see how to do this. I must say that with all the data I'm passing into this page, 550K is awfully large and I'm glad this is on an internal high-bandwidth network where page size is less important.

open(CSV, $data);
@datalist = <CSV>;
close(CSV);

print <<END_of_quotes;

<script type="text/javascript" language="JavaScript">
<!--
var rows = new Array();
var tempstr = new String();

function trim(str) {
return str.replace(/^\s*¦\s*\$/g,"");
}

END_of_quotes

foreach $rec(@datalist) {
@entry = split /,/ , $rec;
foreach $elem(@entry) {
$elem =~ s/^\s*¦\s*$//; ## eliminate all whitespace from each item in the @entry list (since we'll do string comparisons later...
}
$brn = shift @entry;
chomp($brn);
$rec = join '^' , @entry;

print <<LOADquotes;

row["$brn"] = "$rec";

LOADquotes
} ##foreach

Its not perfect, but you can see where things are going I hope. Pretty fun little problem to work on...

perl_diver

6:57 pm on Oct 26, 2006 (gmt 0)

10+ Year Member



Thats exactly what I was thinking you needed to do. You translated the perl data into javascript data and included it in the source code of the page. This block of code:

foreach $rec(@datalist) {
@entry = split /,/ , $rec;
foreach $elem(@entry) {
$elem =~ s/^\s*¦\s*$//; ## eliminate all whitespace from each item in the @entry list (since we'll do string comparisons later...
}
$brn = shift @entry;
chomp($brn);
$rec = join '^' , @entry;

print <<LOADquotes;

row["$brn"] = "$rec";

LOADquotes
} ##foreach

looks like it could be improved:




my $js_array = '';
foreach $rec (@datalist) {
@entry = split /,/ , $rec;
s/^\s*//, s/\s*$// for (@entry);
$brn = shift @entry;
chomp($brn);
$rec = join '^' , @entry;
$js_array .= qq~row["$brn"] = "$rec"\n~;
} ##foreach
print $js_array;