reptile7's JavaScript blog
Tuesday, June 19, 2012
 
More Accept to Enable
Blog Entry #255

We return now to our discussion of HTML Goodies' "How To Use JavaScript To Ensure Users Agree Before Posting" tutorial. The JavaScript part of the "Ensure Users Agree" code is posted here as an agreeBeforePosting.js file for your downloading convenience. The tutorial's third paragraph presents and describes a demo for the code.

Commenter nullWeirdo has an eval( ) question:
simple script but many programmer said to avoid eval( )... maybe someone can explain why we need to avoid eval( )
Mozilla's current eval( ) page features a Don't use eval( ) needlessly! section that begins:
eval( ) is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval( ) with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage/extension.
Mozilla is referring here to the role that eval( ) can play in cross-site scripting (XSS) attacks. To my understanding, the "Ensure Users Agree" myform form - or any other form that accepts text input for that matter - could indeed be vulnerable to XSS attacks depending on what is done with the form, but such attacks should be independent of the agreeBeforePosting.js eval( ) calls, which have their own dedicated tasks (they either get the checked status of the mycheck checkbox or enable/disable the myform text inputs) and are completely separated from whatever a rogue user might enter into the myform text inputs.

Mozilla also notes:
eval( ) is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.
Fair enough. In any event, we can greatly simplify the agreeBeforePosting.js code and throw out those eval( ) calls by leveraging the myform form's elements[ ] property/collection:

function toggleform(agreeForm, isChecked) {
    if (isChecked) {
        for (i = 1; i < agreeForm.elements.length; i++) agreeForm.elements[i].disabled = false;
        document.myform.pname.focus( ); }
    else for (i = 1; i < agreeForm.elements.length; i++) agreeForm.elements[i].disabled = true; }
...
<input type="checkbox" name="mycheck" value="" onclick="toggleform(this.form, this.checked);"> I Accept


elements[ ] is in the HTML DOM but is best documented in the JavaScript 1.3 Client-Side Reference. If you add a <button disabled>Submit</button> button as elements[4] to the myform form, then it will be enabled or redisabled along with the text inputs by the above code.

Commenter Mark A offers an alternate script that displays a style="visibility:hidden;" myform form if the user checks the mycheck checkbox, which is placed outside and before the form, and rehides the form if the user unchecks the checkbox. Mark's event handler code

function DisplayHide(DisplayValue) {
    if (DisplayValue) { this.document[myform.name].style.visibility = "visible"; }
    else { this.document[myform.name].style.visibility = "hidden"; } }
...
<input type="checkbox" name="mycheck" onclick="DisplayHide(mycheck.checked);"> I agree ...


works verbatim with IE and Opera and works with other browsers once the mychecked.checked DisplayHide( ) argument is changed to this.checked. I myself prefer the original design that allows the user to see the text inputs; however, if I did want to initially invisibilize the myform form, then I wouldn't reach for the CSS visibility property but rather the CSS display property, to be toggled between none and block, as a visibility:hidden; form would unnecessarily take up space on the page.

wrap aside

Interestingly, Mark equips the myform form's textarea element with a wrap="physical" attribute. The wrap attribute has widespread browser support and has been standardized via HTML5; however, neither the W3C, Microsoft, nor Mozilla lists physical as a legitimate value for wrap.

On my iMac, the effect of the wrap="physical" attribute is browser-dependent. With IE, Chrome, and Safari, wrap="physical" is equivalent to wrap="hard", which treats an unforced line break as a CR-LF (carriage return-line feed) and encodes it as %0D%0A; with the Mozilla browsers and Opera, wrap="physical" is equivalent to wrap="soft", which treats an unforced line break as a space and replaces it (plus any preceding white space) with a +. Given this discrepancy, and given that I see no point in keeping track of all of the line breaks in the user's textarea input even if wrap="physical" consistently mapped onto wrap="hard", and given that wrap defaults to soft, I'd say that we should throw the wrap="physical" attribute out.

Microsoft alleges, To detect the difference between soft and hard you must submit the content within the textArea to an HTTP server: not true. Mark includes a button with his form and sets the form method to get; upon typing a wrapping string in the myform textarea field and clicking the button, I am easily able to sort out the various wrap values from the resulting query string(s) in the browser window's address bar right on the desktop.

All good things must come to an end, and it's time for us to finally break free from the HTML Goodies site. Per Blog Entry #115, we will in the next entry switch gears and begin working through and modernizing the examples in Part 2 of Netscape's "Dynamic HTML in Netscape Communicator" resource: first up is the Fancy Flowers Farm Example.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)