<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ash Searle's Blog &#187; JavaScript</title>
	<atom:link href="http://hexmen.com/blog/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://hexmen.com/blog</link>
	<description>On programming, and other things...</description>
	<lastBuildDate>Thu, 03 Dec 2009 10:29:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>JavaScript Date to&#160;Time</title>
		<link>http://hexmen.com/blog/2009/12/javascript-date-to-time/</link>
		<comments>http://hexmen.com/blog/2009/12/javascript-date-to-time/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 10:29:14 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hexmen.com/blog/?p=98</guid>
		<description><![CDATA[Subtle differences sometimes indicate the proficiency of a programmer. Here are three ways to get the current time in JavaScript: var t1 = (new Date()).getTime(); // 1 var t2 = new Date().getTime(); // 2 var t3 = (new Date).getTime(); // 3 The bracket placement is as much about language awareness as personal taste. In JavaScript, [...]]]></description>
			<content:encoded><![CDATA[<p>Subtle differences sometimes indicate the proficiency of a programmer.</p>
<p>Here are three ways to get the current time in JavaScript:</p>
<pre class="javascript"><code>var t1 = (new Date()).getTime(); // 1
var t2  = new Date().getTime(); // 2
var t3 = (new Date).getTime(); // 3

</code></pre>
<p>The bracket placement is as much about language awareness as personal taste.  In JavaScript, the brackets are optional for a zero-argument constructor: <code>new Date</code> creates a new <code>Date</code> instance without requiring brackets.  But due to JavaScript operator precedence, you can&#8217;t write <code>new Date.getTime()</code> because the interpreter sees that as trying to call the constructor for a <code>Date.getTime</code> class (cf. <code>MyPackage.MyClass</code>) &#8211; in this case the brackets are required for the statement to parse as intended.</p>
<p>Reflecting on the three versions above: Version 1 doesn&#8217;t do anything to show a deep understanding of JavaScript.  Version 2 and 3 are sort of interchangeable, but version 3 just edges ahead because the coder&#8217;s displayed knowledge to drop the optional brackets.</p>
<p>Of course, if you want the most compact code possible, you&#8217;d write:</p>
<pre class="javascript"><code>var t4 = +new Date; // 4

</code></pre>
<p>This little gem creates a new Date, then coerces it into a number using a unary <code>+</code> operator &#8211; and coercing a Date to a number is defined in the language spec to go via <code>valueOf</code> and <code>getTime</code>.</p>
<p>Checking the character-count: <code>(new Date).getTime()</code> is 20 characters, while <code>+new Date</code> is 9.</p>
<p>That 11 character saving might come in handy on, say, the new Google home-page, where they currently use <code>(new Date).getTime()</code> <em>seven times</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hexmen.com/blog/2009/12/javascript-date-to-time/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>All-in-one cookie&#160;function</title>
		<link>http://hexmen.com/blog/2009/03/all-in-one-cookie-function/</link>
		<comments>http://hexmen.com/blog/2009/03/all-in-one-cookie-function/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 10:18:06 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hexmen.com/blog/?p=75</guid>
		<description><![CDATA[Users stumbling across jQuery may notice the API&#8217;s designed so a method&#8217;s behaviour varies depending on the number and type of arguments passed in a call (have a look at the jQuery method!). In the right hands, this flexibility produces clean and elegant code without burdening the developer with 101 new method names to learn. [...]]]></description>
			<content:encoded><![CDATA[<p>Users stumbling across jQuery may notice the API&#8217;s designed so a method&#8217;s behaviour varies depending on the number and type of arguments passed in a call (have a look at the <a href="http://docs.jquery.com/Core/jQuery">jQuery method</a>!).  In the right hands, this flexibility produces clean and elegant code without burdening the developer with 101 new method names to learn.</p>
<p>Let&#8217;s do the same for cookies (source: <a href="http://hexmen.com/js/cookie.js">cookie.js</a>).</p>
<h3>Three into one does go</h3>
<p>Googling for &#8216;<a href="http://www.google.com/search?q=javascript+cookie+functions">javascript cookie functions</a>&#8216; brings back Peter-Paul Koch&#8217;s trio of functions from <a href="http://www.quirksmode.org/js/cookies.html">QuirksMode</a>.  The functions are named <code>setCookie</code>, <code>readCookie</code> and <code>eraseCookie</code>.  Browsing through the next few search-results we see the same thing going by different names: <code>get</code>, <code>set</code> and <code>deleteCookie</code>; <code>add</code> &#038; <code>remove</code>, <code>erase</code> &#038; <code>delete</code>, <code>read</code>, <code>get</code> and <code>check</code> &#8211; all variations on a theme, all separating functionality into a trio of functions.</p>
<p>Let&#8217;s look at the method signatures:</p>
<ul>
<li><code>createCookie(<em>name</em>, <em>value</em>, <em>days</em>)</code></li>
<li><code>readCookie(<em>name</em>)</code></li>
<li><code>eraseCookie(<em>name</em>)</code></li>
</ul>
<p>It&#8217;s pretty basic stuff.</p>
<p>To merge the three functions into one, we have to differentiate between reading, writing and deleting a cookie by the number and value of arguments; I&#8217;ve chosen an implementation where deleting a cookie is achieved by setting it to <code>null</code>.</p>
<p>Here&#8217;s some example usage:</p>
<pre><code>  // create a cookie:
  cookie('name', 'value');

  // read it:
  alert(cookie('name'));

  // erase it:
  cookie('name', null);

</code></pre>
<h3>Flexibility</h3>
<p>All those cookie calls pass at least one parameter&#8230; but isn&#8217;t there something useful we can do with a plain parameterless <code>cookie()</code> call?  Of course there is &#8211; let&#8217;s return an associative array of all cookie values!</p>
<p>By default (without specifying an explicit expiry time) cookies survive until you restart the browser.  It&#8217;s kinda mandatory to provide some way of specifying an <strong>expiry</strong> time.</p>
<p>We&#8217;ll accept an <em>optional</em> third parameter specifying an expiry time in <em>days</em>:</p>
<pre><code>  // create cookie for 1 year
  cookie('theme', 'minimal', 365);

  // grab all cookies:
  var cookies = cookie();
  alert(cookies.theme);

</code></pre>
<p>Looking good so far.  But there&#8217;s more.</p>
<p>Like several of the cookie libraries, our function defaults to setting cookies on the top-level path &#8220;/&#8221; &#8211; this is a more common requirement than the browsers default behaviour, which sets a cookie so it&#8217;s only used at or below the current page level (i.e. a cookie set while looking at &#8220;<a href="http://ewelike.com/products/Nintendo-DSi-Console_Black/978372">/products/Nintendo-DSi-Console_Black/978372</a>&#8221; wouldn&#8217;t be available when looking at any other product.)</p>
<p>To give developers flexibility I&#8217;ve made <strong>path</strong> another <em>optional</em> parameter &#8211; it could be used to share cookies between &#8220;/product/*&#8221; pages, but withhold them from any other area of a site.</p>
<p>While we&#8217;re on the subject of sharing &#8211; what about cross-domain cookies?  Cookies are naturally assigned to the domain the page is being viewed on, but sometimes we want to make sure a cookie&#8217;s available to all sub-domains too.  <strong>domain</strong> is also an <em>optional</em> parameter.</p>
<p>Having both <em>path</em> and <em>domain</em> as optional parameters could be confusing &#8211; after all, they&#8217;re both strings.  Fortunately, we know paths begin with &#8216;/&#8217; and domains don&#8217;t &#8211; and if you want to specify both you just stick to the right order: <em>path</em> then <em>domain</em>:</p>
<pre><code>  // share cookie between product pages:
  cookie('view-description', 'hidden', '/products');

  // share cookie between domains:
  cookie('id', '_', '.ewelike.com');

  // save preferences cross-domain for 1 year:
  cookie('prefs', '_', 365, '/products', '.ewelike.com');

</code></pre>
<p>Finally, there&#8217;s an optional &#8216;secure&#8217; parameter.  I&#8217;ve never used this myself, but it&#8217;s there if you want it.  It&#8217;s handy if you&#8217;re storing sensitive information in cookies and you only want to allow the browser to transfer the cookie value when it&#8217;s request pages via https.  The code will take any <em>truthy</em> value hanging off the end of the parameters (anything that&#8217;s not been interpreted as expiry date, path or domain.):</p>
<pre><code>  // set a secure cookie on the default path and domain
  // (expires when the browser closes)
  cookie('name', 'value', true);

</code></pre>
<p>Want the code?  Grab it now&#8230; <a href="http://hexmen.com/js/cookie.js">download cookie.js</a> (dual-licensed under MIT and GPL, exactly the same as jQuery)</p>
]]></content:encoded>
			<wfw:commentRss>http://hexmen.com/blog/2009/03/all-in-one-cookie-function/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>sprintf for&#160;JavaScript</title>
		<link>http://hexmen.com/blog/2007/03/printf-sprintf/</link>
		<comments>http://hexmen.com/blog/2007/03/printf-sprintf/#comments</comments>
		<pubDate>Wed, 14 Mar 2007 14:59:09 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hexmen.com/blog/2007/03/printf-sprintf/</guid>
		<description><![CDATA[Avoid writing formatting functions in JavaScript by grabbing yourself a decent sprintf implementation &#8211; handling padding, truncation, floating-point numbers, left/right alignment and re-ordered arguments. You can download sprintf for JavaScript, available under the Create Commons Attribution License. Now license free (use it where/when/how you like.) The version I&#8217;ve written is based strongly on Perl&#8217;s sprintf [...]]]></description>
			<content:encoded><![CDATA[<p>Avoid writing formatting functions in JavaScript by grabbing yourself a decent sprintf implementation &#8211; handling padding, truncation, floating-point numbers, left/right alignment and <em>re-ordered arguments</em>.</p>
<p>You can <a href="http://hexmen.com/js/sprintf.js">download sprintf for JavaScript</a>, <del datetime="2007-04-27T17:30:00+01:00">available under the <a href="http://creativecommons.org/licenses/by/2.5/">Create Commons Attribution License</a></del>.  <ins datetime="2007-04-27T17:30:00+01:00">Now license free (use it where/when/how you like.)</ins></p>
<p>The version I&#8217;ve written is based strongly on <a href="http://perldoc.perl.org/functions/sprintf.html">Perl&#8217;s sprintf implementation</a>, allowing argument reordering to help with internationalisation (i18n).  Some overly simplistic examples follow, leaving room for obvious improvements like:</p>
<ol>
<li>letting the user specify their locale as a preference</li>
<li>set default locale based on visitor demographics</li>
<li>use locale-specific message-bundles with a fall-back to the default locale</li>
</ol>
<p>On with the examples:</p>
<pre><code class="javascript">var locale = 'es';
var messages = {
    'en': 'I am %d years and %d months old.',
    'es': 'Tengo %2$d meses y %1$d años.'
};
var message = sprintf(messages[locale], 31, 7);
</code></pre>
<p>You could also use it for </p>
<pre><code class="javascript">var date = new Date;
var dateFormats = [
    /* ISO-8601: */ '%04d-%02d-%02d %02d:%02d:%02d',
    /* British:  */ '%3$02d/%2$02d/%1$02d',
    /* U.S.:     */ '%2$02d/%3$02d/%1$02d'
];

// for example only: choose random date format
var dateFormat = dateFormats[3 * Math.random() >>> 0];

var formatted = sprintf(dateFormat,
    date.getFullYear(), date.getMonth() + 1, date.getDate(),
    date.getHours(), date.getMinutes(), date.getSeconds());
alert(formatted);
</code></pre>
<p>The Perl documentation has more examples in the &#8220;<a href="http://perldoc.perl.org/functions/sprintf.html#order-of-arguments">order of arguments section</a>&#8220;.<br />
Note: this implementation allows the <var>precision</var> of a number to be set from a specific argument (using e.g. &#8220;%.*3$f&#8221;), which the perldocs (<code>perldoc -f sprintf</code>) say hasn&#8217;t been implemented yet.</p>
<p><script type="text/javascript" src="/js/sprintf.js"></script><br />
I haven&#8217;t (re)written any documentation for it, but you should be able to use Firebug (or the <code>javascript:</code> protocol) to try out <code>sprintf</code> on this page, and you can also check out the <a href="/tests/sprintf.html">test page for sprintf</a> for more input/output samples.</p>
<p>As usual, writing test-cases uncovered a couple of browser-dependent issues.  Safari has some bizarre behaviour with <a href="javascript:alert(Math.abs(0).toFixed(6))"><code>Maths.abs(0).toFixed(6)</code></a> resulting in <code>"0.0000-0"</code> instead of <code>"0.000000"</code>.  Another issue I came across is that <a href="javascript:alert((0.5).toFixed())"><code>0.5</code> rounds to <code>0</code> or <code>1</code> depending on browser</a> (worded differently: numbers are rounded off inconsistently across browsers.)</p>
<h3>Dependencies</h3>
<p>On modern browsers, there are no dependencies.  But to run <code>sprintf</code> on older browsers you&#8217;ll need to patch the <code>Number</code> and <code>String</code> objects.  <code>Number</code> needs <code>toFixed</code>, <code>toExponential</code> and <code>toPrecision</code> methods, while <code>String</code> needs a <code>replace</code> method capable of using functions in the replacement parameter.</p>
]]></content:encoded>
			<wfw:commentRss>http://hexmen.com/blog/2007/03/printf-sprintf/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>undefined is not a reserved&#160;word</title>
		<link>http://hexmen.com/blog/2007/01/undefined-is-not-a-reserved-word/</link>
		<comments>http://hexmen.com/blog/2007/01/undefined-is-not-a-reserved-word/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 20:31:33 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hexmen.com/blog/2007/01/undefined-is-not-a-reserved-word/</guid>
		<description><![CDATA[With the new release of Prototype (1.5.0) comes a new website for the Prototype JavaScript Library. The home-page of the new website features a snippet of JavaScript: cells: function(row) { if(row == undefined) return this.tab... return $(row).getElementsBySelector(... } Let&#8217;s get this straight: undefined is not a reserved word. It&#8217;s safer and more logical to make [...]]]></description>
			<content:encoded><![CDATA[<p>With the new release of Prototype (1.5.0) comes a new website for the <a href="http://prototypejs.org/">Prototype JavaScript Library</a>.  The home-page of the new website features a snippet of JavaScript:</p>
<pre><code class="javascript">cells: function(row) {
  if(row == undefined) return this.tab...
  return $(row).getElementsBySelector(...
}</code></pre>
<p>Let&#8217;s get this straight: <code>undefined</code> is not a reserved word.  It&#8217;s safer and more logical to make the comparison to <code>null</code>:</p>
<pre><code class="javascript">cells: function(row) {
  if(row == null) return this.tab...
  return $(row).getElementsBySelector(...
}</code></pre>
<p>As <code>null</code> <strong>is</strong> a reserved word (and it&#8217;s quicker to type) I&#8217;d expect the Prototype community to favour it.</p>
<p><em>Note: assuming <code>undefined</code> hasn&#8217;t been redefined, the two code fragments are functionally identical.  i.e. the equals operator (<code>==</code>) treats <code>null</code> and the primitive value <code>undefined</code> exactly the same.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://hexmen.com/blog/2007/01/undefined-is-not-a-reserved-word/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Numbers in&#160;form-fields</title>
		<link>http://hexmen.com/blog/2007/01/numbers-in-form-fields/</link>
		<comments>http://hexmen.com/blog/2007/01/numbers-in-form-fields/#comments</comments>
		<pubDate>Mon, 08 Jan 2007 12:39:58 +0000</pubDate>
		<dc:creator>Ash</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://hexmen.com/blog/2007/01/numbers-in-form-fields/</guid>
		<description><![CDATA[JavaScript is often used for client-side form validation to save unnecessary round-trips to the server. Unfortunately, lots of client-side validation relies on lenient JavaScript methods such as parseInt, allowing numbers to be input in ways totally unacceptable to your server-side code. Let&#8217;s have a look at the problems and some solutions. Server-side validation It&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript is often used for client-side form validation to save unnecessary round-trips to the server.  Unfortunately, lots of client-side validation relies on lenient JavaScript methods such as <code>parseInt</code>, allowing numbers to be input in ways totally unacceptable to your server-side code.  Let&#8217;s have a look at the problems and some solutions.</p>
<h3>Server-side validation</h3>
<p>It&#8217;s a golden-rule of web-development that you <em>never depend on client-side validation</em>.  Users can turn JavaScript off, and hackers can send any data they like at your servers.  So, the first thing you have to decide is what data is acceptable to your <strong>server</strong>.  For numbers on the server, are you planning on storing them in a database or performing calculations with them?  In either case, what format do the numbers need to be in: integers? decimals?  Are you going to manually trim white-space from the number, are you going to allow negative numbers?<span id="more-11"></span></p>
<p><em>(it&#8217;s tempting to make the server-side validation anally-retentive, not accepting anything except a strict sequence of decimal numbers.  I&#8217;d suggest that you at least accept (and remove) white-space around submitted numeric values.  This will avoid frustrating JavaScript-disabled users in the case where a form-field has some trailing white-space in it &#8211; impossible to see, and annoying to find and remove after receiving an &#8220;invalid input&#8221; error.)</em></p>
<h3>Client-side validation</h3>
<p>Once you&#8217;ve decided on and coded-up your server-side validation, it&#8217;s time to think about client-side validation.  Remember, the point of client-side validation is to avoid unnecessary round-trips to the server.  If you can determine that user-input on the client isn&#8217;t going to be acceptable to the server, don&#8217;t even bother sending it; instead, display informative and instructive messages to the user indicating which input you don&#8217;t like, why, and what type of input you want from them.</p>
<p>We need an example to work with.  I&#8217;m feeling unimaginative, so I&#8217;m going to use the stock order-form example.  Let&#8217;s suppose we have a <var>quantity</var> field that (for arbitrary business reasons) we will only accept with an integer from 0 &#8211; 100.  One naïve approach to validation may be:</p>
<pre><code class="javascript">var quantity = document.orderForm.quantity.value;
if (quantity &lt; 0 || quantity &gt; 100) {
  // inform user of invalid input
}</code></pre>
<p>Remember, form-field values are always strings, so the code above is relying on automatic type-conversion from strings to numbers using the <code>&lt;</code> and <code>&gt;</code> operators.  Unfortunately, if the user doesn&#8217;t input anything (<code>quantity === ""</code>), this would be treated exactly the same as if they&#8217;d entered <code>0</code>; and the <var>quantity</var> would pass our input validation.</p>
<p>I just mentioned that the validation would pass for an empty-string; in fact, validation would pass for any input consisting solely of white-space.  That&#8217;s due to the JavaScript behaviour:  <code>"\s*" &lt; 0</code> is <code>false</code> and <code>"\s*" == 0</code> is <code>true</code> (where I&#8217;ve used <code>\s*</code> to mean &#8216;optional white-space&#8217;.)</p>
<h3>Considering parseInt</h3>
<p>So, we don&#8217;t want white-space to be treated as <code>0</code>.  Fortunately (for now), <code>parseInt</code> (and <code>parseFloat</code>) will return <code><abbr title="Not a Number">NaN</abbr></code> for white-space input.  We could try to improve our code like this:</p>
<pre><code class="javascript">var quantity = parseInt(document.orderForm.quantity.value);
if (isNaN(quantity) || quantity &lt; 0 || quantity &gt; 100) {
  // inform user of invalid input
} else {
  // assume everything's hunky-dory?
}</code></pre>
<p>But, oh dear lord, what a can-of-worms we&#8217;ve just opened: <code>parseInt</code> accepts numbers in octal and hexadecimal as well as base-10, and it&#8217;s unlikely that we want to send octal or hexadecimal numbers to our server.  The sensible thing to do would seem to be to specify that we want to parse base-10 numbers using <code>parseInt(quantity, 10)</code>.</p>
<p>This just makes things worse.  Where we would have had <code>parseInt("0xFF")</code> returning <code>255</code> (and failing validation), we now have <code>parseInt("0xFF", 10)</code> returning 0 which passes our validation.  In other words, our client-side code has passed and we&#8217;re going to send the server &#8220;0xFF&#8221; as the quantity.  Hopefully your server-side code would validate this and return an error, but it feels like a waste of a round-trip.</p>
<p>There are also problems with floating-point numbers and scientific notation.  i.e. parseInt(&#8220;2.34&#8243;, 10) returns <code>2</code> as does parseInt(&#8220;2e04&#8243;, 10), but either of these inputs could cause problems on the server (&#8220;2e04&#8243; is scientific notation for <code>20000</code>, but <code>parseInt(x, 10)</code> stops parsing as soon as it reads a non-digit character.)</p>
<p>And then there&#8217;s the just-plain-strange input: <code>parseInt("3 bikinis", 10)</code> returns <code>3</code>.  What are you going to do with <code>"3 bikinis"</code> on the server?  It&#8217;s crazy-talk.</p>
<p>Clearly, <code>parseInt</code> is not enough on it&#8217;s own.</p>
<h3>Regular Expressions</h3>
<p>We&#8217;re talking about a <code>quantity</code> field, where we want a non-negative integer.  A simple-regular expression to check for a sequence of decimal digits is: <code>/\d+/</code>.  That still doesn&#8217;t help us avoid any trailing characters, so we need to pin it down using the <code>^</code> and <code>$</code> markers.  Remembering that the user can&#8217;t see white-space, we&#8217;ll show some tolerance by allowing leading and trailing white-space round the character (usually, you&#8217;d <em>trim</em> the field before validating, but I&#8217;m just adding some optional white-space to the regular-expression for now.)</p>
<pre><code class="javascript">var quantity = document.orderForm.quantity.value;
if (!/^\\s*\\d+\\s*$/.test(quantity) || quantity &lt; 0 || quantity &gt; 100) {
  // inform user of invalid input
} else {
  // do something with quantity?
}</code></pre>
<p>We&#8217;re pretty happy that <var>quantity</var> has been entered in the right format, and we&#8217;ve used some implicit JavaScript type-conversion to check it&#8217;s in the right range (0 &#8211; 100.)  But surely if we want to do some calculations on it, then we&#8217;re going to have to use <code>parseInt</code> or some other method of converting strings to numbers?</p>
<h3>Unary <code>+</code> for type-conversion</h3>
<p>Forget <code>parseInt</code>.  If you know that a variable only contains digits (optionally wrapped in white-space) you can convert it to a number using a single <code>+</code>.  Let&#8217;s assume we have a couple of hidden fields: <var>unitPrice</var> and <var>shipping</var>.  We can assume these hidden fields contain numbers, and we know that the multiplication operator &#8216;<code>*</code>&#8216; will do automatic string-to-number conversion for us.  But the binary &#8216;<code>+</code>&#8216; operator doesn&#8217;t (i.e. <code>4 + "5"</code> equals <code>"45"</code> not <code>9</code>.)  Here&#8217;s unary <code>+</code> in action:</p>
<pre><code class="javascript">var form = document.orderForm;
var quantity = form.quantity.value;
<em>...validation omitted...</em>
var subtotal = form.unitPrice.value * quantity;
var total = subtotal + <strong>+</strong>form.shipping.value;</code></pre>
<p>I need to be explicit about octal numbers.  Although <code>parseInt</code> will (by default) parse octal, hexadecimal and base-10; when it comes to operators, octal is ignored.  In other words, <code>"0xff" == 255</code> is <code>true</code>, but <code>"010" == 8</code> is <code>false</code>.  Similarly <code>+"0xff"</code> is <code>255</code> but <code>+"010"</code> is <code>10</code>.</p>
<p>Unary <code>+</code> has a lot going for it, and if you&#8217;re using <a href="http://prototype.conio.net/" title="Prototype JavaScript Framework">prototype</a> this should appeal:
<pre><code class="javascript">var total = ($F('unitPrice') * $F('quantity')) + +$F('shipping');</code></pre>
<p><em>(though I&#8217;ll never understand why they chose to use <code>$F</code> instead of <code>$V</code>.  &#8216;F&#8217; for field, &#8216;V&#8217; for value, surely?  But I digress)</em></p>
<h3>Summary</h3>
<p>I set-out to briefly demonstrate how nice and compact unary <code>+</code> is, but managed to get side-tracked once again.  The original summary would have been &#8220;<code>+</code> rocks! <code>parseInt</code> sucks&#8221;, but instead, we&#8217;ve got:</p>
<ul>
<li>Beware of white-space</li>
<li>Know your number formats</li>
<li>Unary <code>+</code></li>
<li>Use regular-expressions to check user-input matches a required format</li>
<li>Show <em>some</em> lenience</li>
</ul>
<h3>Coming Soon&#8230;</h3>
<p>The next two articles are very likely to touch on <code>getComputedStyle</code> and CSS&#8217;s <code>!important</code> modifier.  The first should be quite short (but I tend to waffle, so it&#8217;ll probably end up long), and I need to work on some examples or illustrations for the second one.  After that, I&#8217;m not sure.  I&#8217;ve got some ridiculous code for creating PNGs in JavaScript, so I&#8217;ll probably give that an outing at some point.</p>
<p>Thanks for reading.</p>
]]></content:encoded>
			<wfw:commentRss>http://hexmen.com/blog/2007/01/numbers-in-form-fields/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
