ax1lla has asked for the wisdom of the Perl Monks concerning the following question:

Hi, First time posting at PerlMonks. Great site! Anyway, I am a beginner at Perl and have run into a little obstacle. I'm writing some CGI scripts that interact with an Access DB. So far everything has been going great and I have been successfully chugging along. However, one of my pages needs some form validation in which I have an external .js file that will correctly handle the validation I am looking for. I just found out the hard way, that Perl and Javascript don't really play nice together (client vs. server side) and I can't get this to work at all. Is there an easy way to utilize javascript for what I am trying to do?

Replies are listed 'Best First'.
Re: Perl - calling javascript funciton
by CountZero (Bishop) on Mar 09, 2009 at 21:55 UTC
    Have a look at JavaScript::DataFormValidator, it seems to be what you are looking for: a combination of client-side Javascript validation and server-side Perl validation.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Perl - calling javascript funciton
by hbm (Hermit) on Mar 09, 2009 at 23:50 UTC

    In a pinch, I've put the javascript in a string (with a heredoc); printed it with the html header; and accessed it with onClick. Below is a simple example:

    use strict; use CGI qw(:standard); my $js = <<"EOJS"; function someChecked(form) { var boxes = form.getElementsByTagName("input"); for (var i = 0; i < boxes.length; i++) { if (boxes[i].checked == true) return true; } alert("You didn't select any items to delete!"); return false; } EOJS print header, start_html( -TITLE => "My Title", -SCRIPT => {-code=>$js}), start_form, submit(-NAME=>"Page", -VALUE=>"Submit", -ONCLICK=>"return someChecked(this.form);"), checkbox("Test",'','ON','A'), checkbox("Test",'','ON','B'), end_form, end_html;

    Update: Added checkboxes to make the example more sensible.

Re: Perl - calling javascript funciton
by Your Mother (Archbishop) on Mar 09, 2009 at 23:33 UTC

    Your trouble is a bit vague. JS and Perl will skip through fields of rye together if you ask them nicely. If you give a bit more -- code snippets + thorough description -- you'll probably get a more focused answer or two.

      Perl File snippet: <SCRIPT LANGUAGE="JavaScript" SRC="/js_validation/js.js"></SCRIPT> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +"> </head> <body> <form onsubmit="return formValidator()"> <table> <tr><td> Test Field: <input type="text" value="--" size="2" maxlength="2" id="p +lace"><br></td> </tr> <input type='submit' value='Check Form'><br> Javascript: /* SOURCE FILE: form_validation.js */ function formValidator(){ var place = document.getElementById("place"); if(isNumeric(place, "Please enter a valid zip code")){ return true; } return false; } function isNumeric(elem, helperMsg){ var numericExpression = /^[0-9]+$/; if(elem.value.match(numericExpression)){ return true; }else{ alert(helperMsg); elem.focus(); return false; } } Unfortunately, because I'm a newbie I don't really understand how to u +sefully incorporate the various modules that are out there. I instal +led the JavaScript::DataFormValidator module this morning, but am not + sure how to incorporate it yet. The only modules I am utilizng in m +y program currently are DBI and CGI. I don't really know the details + of what they do. I just know that the tutorials I've been taking to +ld me to use them :) The idea of putting my javascript into a perl string is intriguing. H +owever, it seems that my code could get real messy real quick. Is it + common in Perl to call functions/variables/etc from an external Perl + file (like you can in JS "..SRC="/js_validation/js.js"></SCRIPT>" )? If so, maybe storing my javascript in a variable within an external fi +le would be a good way to do this?

        Just some small notes:

        • The "language" attribute of the "script" tag is deprecated, use the "type" attribute instead, typically with a value of "text/javascript".
        • XHTML requires lower case tag names, and using them also in HTML does not hurt.
        • The "meta" tag is only useful if you deliver the HTML content via a protocol that does not allow specifying a content type (file://, ftp://). In HTTP context, use the "Content-Type" HTTP header. In E-Mail context, use the "Content-Type" MIME header.
        • You say you use the CGI module. Read the documentation of its header() method.
        • The usage instructions for most Perl modules are embedded into the module, use http://search.cpan.org/ or the perldoc utility to read them.
        • Placing huge loads of javascript into a variable in a module may seem tempting, but consider placing the javascript into an external javascript file, and have the web server deliver it directly. Delivering content from a CGI script is SLOOOOOOOOOOOOOW.
        • Split the javascript code into a huge reusable part in the external file, and a small configurating part inside your delivered HTML.
        • Remember that (in a typical CGI environment) Perl code runs on the server side and Javascript code runs on the client side, after your Perl code has finished. If you want to mix both, you want to learn about AJAX and JSONRPC. That makes some things look better, but it creates lots of new problems. Try learning ordinary CGI first.

        Alexander

        -- Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)