<?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>jensbits.com</title>
	<atom:link href="http://www.jensbits.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jensbits.com</link>
	<description></description>
	<lastBuildDate>Wed, 10 Mar 2010 02:58:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CreateUserWizard Set Email as Username VB.NET 3.5</title>
		<link>http://www.jensbits.com/2010/03/05/createuserwizard-set-email-as-username-vb-net-3-5/</link>
		<comments>http://www.jensbits.com/2010/03/05/createuserwizard-set-email-as-username-vb-net-3-5/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 14:00:57 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=625</guid>
		<description><![CDATA[Commonly, a login username is the individual&#8217;s email address. If you have used the CreateUserWizard in ASP.NET 3.5, you know that the username field and the email field are separate fields. Username is required by the wizard and email is not. If you want to populate the email field in the database with the username [...]]]></description>
			<content:encoded><![CDATA[<p>Commonly, a login username is the individual&#8217;s email address. If you have used the CreateUserWizard in ASP.NET 3.5, you know that the username field and the email field are separate fields. Username is required by the wizard and email is not. If you want to populate the email field in the database with the username field, it is not obvious on the surface how to do it. Fortunately, it&#8217;s just some minor mods to the web.config and the aspx page.</p>
<h2>web.config</h2>
<p>In the web.config file, you will add requiresUniqueEmail=&#8221;false&#8221; to the membership provders add entry. Below is a stripped down example.</p>
<pre class="brush: xml;">
 &lt;membership defaultProvider=&quot;MyMembership&quot;&gt;
      &lt;providers&gt;
        &lt;add name=&quot;MyMembership&quot; type=&quot;System.Web.Security.SqlMembershipProvider&quot; connectionStringName=&quot;MyConnectionString&quot; requiresUniqueEmail=&quot;false&quot; /&gt;
        &lt;/providers&gt;
 &lt;/membership&gt;
</pre>
<h2>aspx page</h2>
<p>On the aspx page itself, you will add RequireEmail=&#8221;false&#8221; so the email textbox is not mandatory and a call to a function in the OnCreatedUser event to the CreateUserWizard. Also, some validation is added to the username field to ensure that it is in a valid email format.</p>
<pre class="brush: vb;">
&lt;asp:CreateUserWizard ID=&quot;CreateUserWizard1&quot; OnCreatedUser=&quot;CreateUserWizard1_CreatedUser&quot; RequireEmail=&quot;false&quot; Runat=&quot;server&quot;&gt;

&lt;asp:TextBox ID=&quot;UserName&quot; Width=&quot;200&quot; runat=&quot;server&quot;&gt;&lt;/asp:TextBox&gt;

&lt;asp:RequiredFieldValidator ID=&quot;UserNameRequired&quot; runat=&quot;server&quot; ControlToValidate=&quot;UserName&quot; ErrorMessage=&quot;E-mail is required.&quot;ValidationGroup=&quot;CreateUserWizard1&quot; /&gt;

&lt;asp:RegularExpressionValidator ID=&quot;regEmail&quot; ControlToValidate=&quot;UserName&quot; Text=&quot;Invalid e-mail&quot; ValidationExpression=&quot;\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*&quot; Runat=&quot;server&quot; /&gt;
</pre>
<p>The function fires right after the user is created and updates the email field with the username.</p>
<pre class="brush: vb;">
Protected Sub CreateUserWizard1_CreatedUser(ByVal sender As Object, ByVal e As EventArgs)
        Dim userNameTextBox As TextBox = CType(CreateUserWizardStep1.ContentTemplateContainer.FindControl(&quot;UserName&quot;), TextBox)
        Dim user As MembershipUser = Membership.GetUser(userNameTextBox.Text)

        user.Email = user.UserName
        Membership.UpdateUser(user)
    End Sub
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/03/05/createuserwizard-set-email-as-username-vb-net-3-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Google Docs to Create a Survey</title>
		<link>http://www.jensbits.com/2010/02/05/using-google-docs-to-create-a-survey/</link>
		<comments>http://www.jensbits.com/2010/02/05/using-google-docs-to-create-a-survey/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 20:25:15 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=597</guid>
		<description><![CDATA[After creating the pop-up survey in jQuery, further exploration on creating online polls has turned up Google Docs quick and dirty form creation.
Google posted a 2-minute video on Google Docs form creation that pretty much sums it up. This has actually been around for a couple of years now but, even though it&#8217;s a little [...]]]></description>
			<content:encoded><![CDATA[<p>After creating the <a href="/2010/01/29/pop-up-survey-with-jquery-ui-dialog/">pop-up survey in jQuery</a>, further exploration on creating online polls has turned up Google Docs quick and dirty form creation.</p>
<p>Google posted a <a href="http://www.youtube.com/watch?v=IzgaUOW6GIs">2-minute video on Google Docs form creation</a> that pretty much sums it up. This has actually been around for a couple of years now but, even though it&#8217;s a little late to the party, here is a quick illustration of my jQuery poll done with Google Docs:</p>
<p><strong>Select &#8220;Form&#8221; from the &#8220;Create New&#8221; menu.</strong></p>
<p><img src="/images/googleforms/form_01_select.gif" alt="" /></p>
<p><strong>Fill in the name of the poll or form, short description, and the first question.</strong></p>
<p><img src="/images/googleforms/form_02_firstquestion.gif" alt="" /></p>
<p><strong>Add a question by clicking the &#8220;Add Item&#8221; button and choose from the menu items. Under &#8220;More Actions&#8221; you can create the confirmation message and allow the submitters to see the results.</strong> </p>
<p><img src="/images/googleforms/form_03_options.gif" alt="" /></p>
<p><strong>You can also get the embed link for putting the poll right on a web page.</strong> </p>
<p><img src="/images/googleforms/form_04_embed.gif" alt="" /></p>
<p><strong>And, you can email the form and have users submit answers right from their email by hitting the &#8220;Email this form&#8221; button and adding the email addresses.</strong></p>
<p><img src="/images/googleforms/form_05_email.gif" alt="" /></p>
<h2>Here it is in all it&#8217;s embedded goodness. Try it out:</h2>
<p><iframe style="border:1px solid;padding: 5px" src="https://spreadsheets.google.com/embeddedform?formkey=dDNhRVB2el9FTmJpSkR1dEdISDdGRXc6MA" width="500" height="400" frameborder="0" marginheight="0" marginwidth="0">Loading&#8230;</iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/02/05/using-google-docs-to-create-a-survey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Analytics Third-Party Shopping Cart (Cross-Domain) Tracking Using Traditional and Asynchronous Snippet</title>
		<link>http://www.jensbits.com/2010/02/01/google-analytics-third-party-shopping-cart-cross-domain-tracking-using-traditional-and-asynchronous-snippet/</link>
		<comments>http://www.jensbits.com/2010/02/01/google-analytics-third-party-shopping-cart-cross-domain-tracking-using-traditional-and-asynchronous-snippet/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 19:04:47 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Google Analytics]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=574</guid>
		<description><![CDATA[Cross-domain tracking is used for several situations the most obvious for third-party shopping carts. Proper installation of the Google Analytics (GA) tracking code is essential for accurate tracking of visitors and sales. 
GA offers two tracking code snippets for you to choose from: traditional (synchronous) and asynchronous. 
First, a short review of the basic installation [...]]]></description>
			<content:encoded><![CDATA[<p>Cross-domain tracking is used for several situations the most obvious for third-party shopping carts. Proper installation of the Google Analytics (GA) tracking code is essential for accurate tracking of visitors and sales. </p>
<p>GA offers two tracking code snippets for you to choose from: traditional (synchronous) and asynchronous. </p>
<p>First, a short review of the basic installation for both the traditional and the asynchronous:</p>
<h2>Basic Tracking Code Installation</h2>
<h3>Traditional (Synchronous) Tracking Code</h3>
<pre class="brush: jscript;">
&lt;script type=&quot;text/javascript&quot;&gt;
var gaJsHost = ((&quot;https:&quot; == document.location.protocol) ? &quot;https://ssl.&quot; : &quot;http://www.&quot;);
document.write(unescape(&quot;%3Cscript src='&quot; + gaJsHost + &quot;google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E&quot;));
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
try{
var pageTracker = _gat._getTracker(&quot;UA-xxxxxx-x&quot;);
pageTracker._trackPageview();
} catch(err) {}
&lt;/script&gt;
</pre>
<p>Traditional (synchronous) basic installation is done by placing the above GA tracking code, after replacing &#8220;UA-xxxxxx-x&#8221; with your account number, before the <strong>closing body (&lt;/body&gt;)</strong> tag on <strong>all</strong> pages of your site. This placement is supposed to decrease the likelihood that it will interfere with other javascript on your page.</p>
<p>The drawbacks with this installation include increased page load time and the possibility it won&#8217;t run at all if the user clicks away from the page before it fully loads.</p>
<p><a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingOverview.html">More on the traditional tracking code installation from Google</a>.</p>
<h3>Asynchronous Tracking Code</h3>
<pre class="brush: jscript;">
var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-X']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
  })();
</pre>
<p>Asynchronous basic installation is done by placing the above GA tracking code, after replacing &#8220;UA-xxxxxx-x&#8221; with your account number, before the <strong>closing head (&lt;/head&gt;)</strong> tag on <strong>all</strong> pages of your site. Like the traditional code, this placement is meant to decrease the likelihood that it will interfere with other javascript on your page.</p>
<p>According to <a href="http://analytics.blogspot.com/2009/12/google-analytics-launches-asynchronous.html">Google</a>, the asynchronous code has the following advantages:</p>
<ul>
<li>Faster tracking code load times for your web pages due to improved browser execution</li>
<li>Enhanced data collection and accuracy</li>
<li>Elimination of tracking errors from dependencies when the JavaScript hasn&#8217;t fully loaded</li>
</ul>
<p><a href="http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html">More on the asynchronous tracking code installation from Google</a>.</p>
<h2>Third-Party Shopping Cart (Cross-Domain) Tracking</h2>
<p>It is essential that your GA tracking code is installed correctly for this to work properly. </p>
<p>GA tracks with first-party cookies. If you do not install this correctly, the cookies will be set incorrectly, have the wrong data in them, or both. More on this later&#8230;</p>
<h3>Traditional (Synchronous) Tracking Code</h3>
<p>Put the following code, replacing &#8220;UA-xxxxxx-x&#8221; with your account number, on <strong>ALL</strong> pages of your site and the shopping cart pages <strong>anywhere between the body tags but ABOVE</strong> any calls to pageTracker:</p>
<pre class="brush: jscript;">
&lt;script type=&quot;text/javascript&quot;&gt;
var gaJsHost = ((&quot;https:&quot; == document.location.protocol) ? &quot;https://ssl.&quot; : &quot;http://www.&quot;);
document.write(unescape(&quot;%3Cscript src='&quot; + gaJsHost + &quot;google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E&quot;));
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var pageTracker = _gat._getTracker(&quot;UA-xxxxxx-x&quot;);
pageTracker._setDomainName(&quot;none&quot;);
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
&lt;/script&gt;
</pre>
<p>Links to the shopping cart when adding items to the cart, for example, must include <code>onclick="pageTracker._link(this.href); return false;"</code></p>
<p>Forms that submit to the shopping cart must include <code>onsubmit="pageTracker._linkByPost(this)"</code></p>
<p>Do not forget to put that on ALL forms if checkout is a multi-form (multi-step) process. Your data will be incorrect if you do not do this.</p>
<p><strong>If your third-party cart already includes built-in GA code, follow their instructions exactly.</strong></p>
<p><a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&#038;answer=55532">More on the traditional code installation of third-party shopping cart tracking from Google</a>.</p>
<h3>Asynchronous Tracking Code</h3>
<p>Put the following code, replacing &#8220;UA-xxxxxx-x&#8221; with your account number, on <strong>ALL</strong> pages of your site and the shopping cart pages just above the <strong>closing head (&lt;/head&gt;) </strong>tag:</p>
<pre class="brush: jscript;">
 var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-xxxxxx-x']);
  _gaq.push(['_setDomainName', 'none']);
  _gaq.push(['_setAllowLinker', true]);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
  })();
</pre>
<p>Links to the shopping cart when adding items to the cart, for example, must include <code>onclick="_gaq.push(['_link', 'https://your-cart.com/cart.html']); return false;"</code></p>
<p>Replace &#8220;https://your-cart.com/cart.html&#8221; with the actual link to your cart.</p>
<p>Forms that submit to the shopping cart must include <code>onsubmit='_gaq.push(['_linkByPost', this]);'</code></p>
<p>Do not forget to put that on ALL forms if checkout is a multi-form (multi-step) process. You will data will be incorrect if you do this incorrectly.</p>
<p><strong>Do not add the asynchronous tracking to third-party cart that have their own GA solution built-in unless specifically instructed to do so.</strong></p>
<p><a href="http://code.google.com/apis/analytics/docs/tracking/asyncMigrationExamples.html">More on the asynchronous code installation of third-party shopping cart tracking from Google</a>.</p>
<h2>Why It&#8217;s Important to Do This Correctly</h2>
<p>The cookies set by GA when the setDomainName parameter is set to &#8220;none&#8221; may in some cases have different HOST setting. That is, it may have a www.mydomain.com when the original code without the setDomainName may set HOST to just .mydomain.com. Or, worse still, you could lose all the visitor data and have the sale appear to have been referred from your site and nothing else.</p>
<p>This results in bad data coming into GA particularly in the referrer area. It probably disassociates your keywords to your sales as well.</p>
<h2>Recommended Reading</h2>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470529393" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470130652" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470562315" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470531282" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees.</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/02/01/google-analytics-third-party-shopping-cart-cross-domain-tracking-using-traditional-and-asynchronous-snippet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pop-up Survey with jQuery UI Dialog</title>
		<link>http://www.jensbits.com/2010/01/29/pop-up-survey-with-jquery-ui-dialog/</link>
		<comments>http://www.jensbits.com/2010/01/29/pop-up-survey-with-jquery-ui-dialog/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 20:47:23 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=564</guid>
		<description><![CDATA[I was tasked with creating a pop-up survey for a project. Fairly simple whether I used the jQuery dialog or not so I added a &#8220;Thank you&#8221; dialog that displays the survey results with a lightweight, css-based bar chart just for fun.

Pop-up Behavior

Pop-up survey opens no matter what page of the website the user enters. [...]]]></description>
			<content:encoded><![CDATA[<p>I was tasked with creating a pop-up survey for a project. Fairly simple whether I used the jQuery dialog or not so I added a &#8220;Thank you&#8221; dialog that displays the survey results with a lightweight, css-based bar chart just for fun.<br />
<img src="/images/survey.gif" alt="pop-up survey" /></p>
<h2>Pop-up Behavior</h3>
<ol>
<li>Pop-up survey opens no matter what page of the website the user enters. </li>
<li>Cookie is set when survey submitted or user opts out (&#8220;No, thanks&#8221; click).</li>
<li>Closing dialog will not set cookie</li>
</ol>
<p>All survey data is stored in a database and jQuery .post is used to shuttle the information back and forth.</p>
<p>Code for the survey dialog:</p>
<pre class="brush: xml;">
&lt;div id=&quot;survey&quot; title=&quot;Pop-Up Survey&quot;&gt;
	&lt;p id=&quot;surveyDenied&quot;&gt;&lt;a href=&quot;#&quot;&gt;No, thanks&lt;/a&gt;&lt;/p&gt;
		&lt;p&gt;Pop-up survey that cookies browser on completion or on opt-out. Short 411 demo survey.&lt;/p&gt;
		&lt;form id=&quot;popup_survey&quot; name=&quot;popup_survey&quot; method=&quot;post&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Pink or blue?&lt;/strong&gt;&lt;br /&gt;
		&lt;input id=&quot;pink&quot; type=&quot;radio&quot; name=&quot;radio_color&quot; value=&quot;pink&quot;  /&gt;Pink&lt;br /&gt;
        &lt;input id=&quot;blue&quot; type=&quot;radio&quot; name=&quot;radio_color&quot; value=&quot;blue&quot;  /&gt;Blue&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Soccer or futbol?&lt;/strong&gt;&lt;br /&gt;
		&lt;input id=&quot;soccer&quot; type=&quot;radio&quot; name=&quot;radio_sport&quot; value=&quot;soccer&quot;  /&gt;Soccer&lt;br /&gt;
        &lt;input id=&quot;futbol&quot; type=&quot;radio&quot; name=&quot;radio_sport&quot; value=&quot;futbol&quot;  /&gt;Futbol&lt;/p&gt;
        &lt;/form&gt;
	&lt;div id=&quot;error_message&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>It&#8217;s just a couple of radio buttons and a place for an error message. The submit is handled by the dialog button.</p>
<p>Here is the survey dialog code:</p>
<pre class="brush: jscript;">
$(function(){
			$('#survey').dialog({
				bgiframe: true,
				autoOpen: false,
				modal: true,
				width: 500,
				resizable: false,
				buttons: {
					Submit: function(){
						if($(&quot;input[name='radio_color']:checked&quot;).val() !== undefined &amp;&amp; $(&quot;input[name='radio_sport']:checked&quot;).val() !== undefined){
							setCookie('POPsurvey','POPsurvey',30);
							$.post(&quot;process_survey.php&quot;, $(&quot;#popup_survey&quot;).serialize(),
							function(data){
								if(data.db_check == 'fail'){
									$(&quot;#error_message&quot;).html(&quot;&lt;p&gt;Database not available. Please try again.&lt;/p&gt;&quot;);
								} else {
									$(&quot;div.pink&quot;).css(&quot;width&quot;,data.perPink);
									$(&quot;.perPink&quot;).html(data.perPink + &quot;% (&quot; + data.totalPink + &quot;)&quot;);

									$(&quot;div.blue&quot;).css(&quot;width&quot;,data.perBlue);
									$(&quot;.perBlue&quot;).html(data.perBlue + &quot;% (&quot; + data.totalBlue + &quot;)&quot;);

									$(&quot;div.soccer&quot;).css(&quot;width&quot;,data.perSoccer);
									$(&quot;.perSoccer&quot;).html(data.perSoccer + &quot;% (&quot; + data.totalSoccer + &quot;)&quot;);

									$(&quot;div.futbol&quot;).css(&quot;width&quot;,data.perFutbol);
									$(&quot;.perFutbol&quot;).html(data.perFutbol + &quot;% (&quot; + data.totalFutbol + &quot;)&quot;);

									$(&quot;.totalRes&quot;).html(data.totalRes);

									$('#survey').dialog('close');
									$('#survey_thanks').dialog('open');
								}
								}, &quot;json&quot;);
						}else{
							$(&quot;#error_message&quot;).html(&quot;&lt;p&gt;Please answer all questions.&lt;/p&gt;&quot;);
						}
					}
				}
			});
		});
</pre>
<p>Lots of stuff but it does several things. First, on submit, it checks that the user answered both questions. Then it sets the cookie. And, finally, it sends the form data off via post and puts the response in elements on the page that are part of the &#8220;Thank you&#8221; dialog. Speaking of which&#8230;</p>
<p>The &#8220;Thank you&#8221; dialog code is thus: </p>
<pre class="brush: xml;">
&lt;div id=&quot;survey_thanks&quot; title=&quot;Pop-Up Survey - Thank You!&quot;&gt;
    &lt;p&gt;Thank you for taking the time to answer our survey. Your input will help us improve the site.&lt;/p&gt;
    &lt;p&gt;Responses: &lt;span class=&quot;totalRes&quot;&gt;&lt;/span&gt;&lt;/p&gt;

    &lt;div class=&quot;progress-container&quot;&gt;
        pink &lt;span class=&quot;perPink&quot;&gt;&lt;/span&gt;
        &lt;div class=&quot;pink&quot;&gt;&lt;/div&gt;
        blue &lt;span class=&quot;perBlue&quot;&gt;&lt;/span&gt;
        &lt;div class=&quot;blue&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;progress-container&quot;&gt;
        soccer &lt;span class=&quot;perSoccer&quot;&gt;&lt;/span&gt;
        &lt;div class=&quot;soccer&quot;&gt;&lt;/div&gt;
        futbol &lt;span class=&quot;perFutbol&quot;&gt;&lt;/span&gt;
        &lt;div class=&quot;futbol&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<pre class="brush: jscript;">
$(function(){
			$('#survey_thanks').dialog({
				bgiframe: true,
				autoOpen: false,
				modal: true,
				width: 500,
				resizable: false,
				buttons: {
					Close: function(){
						$(this).dialog('close');
						}
					}
			});
		});
</pre>
<h2>Cookies</h2>
<p>The code to handle setting, checking, and deleting cookies is standard javascript:</p>
<pre class="brush: jscript;">
function setCookie(c_name,value,expiredays)
{
	var exdate=new Date();
	exdate.setDate(exdate.getDate()+expiredays);
	document.cookie=c_name+ &quot;=&quot; +escape(value)+((expiredays==null) ? &quot;&quot; : &quot;;expires=&quot;+exdate.toGMTString());
} 

function getCookie(c_name)
{
	if (document.cookie.length&gt;0)
	  {
	  c_start=document.cookie.indexOf(c_name + &quot;=&quot;);
	  if (c_start!=-1)
		{
		c_start=c_start + c_name.length+1;
		c_end=document.cookie.indexOf(&quot;;&quot;,c_start);
		if (c_end==-1) c_end=document.cookie.length;
		return unescape(document.cookie.substring(c_start,c_end));
		}
	  }
	return &quot;&quot;;
}

function checkCookie(c_name)
{
	cookie_value=getCookie(c_name);
	if (cookie_value==&quot;&quot;) {
		$('#survey').dialog('open');
	}
}

function deleteCookie(c_name) {
	document.cookie = c_name +'=; expires=Thu, 01-Jan-70 00:00:01 GMT;';
}
</pre>
<p>The style for the &#8220;Thank you&#8221; graph:</p>
<pre class="brush: css;">
div.progress-container {
  border: 1px solid #ccc;
  width: 150px;
  padding: 1px;
  margin-bottom: 5px;
  background: white;
}

div.progress-container &gt; div {
  height: 12px;
  margin-bottom: 2px;
}
div.progress-container &gt; div.pink {
  background-color:#CC6699;
}
div.progress-container &gt; div.blue {
  background-color: #3366CC;
}
div.progress-container &gt; div.soccer {
  background-color: #006633;
}
div.progress-container &gt; div.futbol {
  background-color: #663333;
}
</pre>
<p>You&#8217;ll notice in the .post function that the width of the bar graph is set with the percent of responses for each answer that comes back from the database.</p>
<p id="demo"><a href="/demos/survey/"><span>Demo</span></a></p>
<p id="download"><a href="/media/code/jensbits_popup_survey.zip"><span>Download zip of all files</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/01/29/pop-up-survey-with-jquery-ui-dialog/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Google Analytics Showing My Site as Top Referrer</title>
		<link>http://www.jensbits.com/2010/01/07/google-analytics-showing-my-site-as-top-referrer/</link>
		<comments>http://www.jensbits.com/2010/01/07/google-analytics-showing-my-site-as-top-referrer/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 20:31:30 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Google Analytics]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=533</guid>
		<description><![CDATA[Update (Feb. 1, 2010) &#8211; Important:
After speaking to a few people regarding this issue, some other situations where this will occur have come to light.
First (most important), make sure you tracking code is installed properly on every page of your site. If you use cross-domain tracking or sub-domain tracking, install it correctly on every page [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p style="color:red">Update (Feb. 1, 2010) &#8211; Important:</p>
<p>After speaking to a few people regarding this issue, some other situations where this will occur have come to light.</p>
<p>First (most important), make sure you tracking code is installed properly on every page of your site. If you use cross-domain tracking or sub-domain tracking, <a href="/2010/02/01/google-analytics-third-party-shopping-cart-cross-domain-tracking-using-traditional-and-asychronous-snippet/">install it correctly on every page of the site</a>.</p>
<p>Second, do not mix the asynchronous tracking code with the original synchronous tracking code on the same page. This WILL result in tracking anomalies. Also, if you mix them on the same site but different pages, make sure they do the same thing. In other words, if one is set for cross-domain tracking, the other should be as well. And, finally, if you use third-party tools that incorporate GA tracking like some shopping carts, install the original tracking code unless specifically instructed to install the asynchronous code.</p></blockquote>
<p>I began to notice that my own site, jensbits.com, is listed as the top referrer in Google Analytics. This did not seem to be correct since another site I managed had no such issue. And, I also determined that this began right after certain date, in my case, August 10, 2009. So I began to investigate.</p>
<p>What happened on or about 10 August 2009? I put a post on my site that day that has proven to be quite popular. In that post, there is a link to a demo. When I originally posted the demo link, I typed in an absolute URL of http://jensbits.com/demo/forms/index.php for the link&#8217;s href. Notice the missing &#8216;www.&#8217; And, that was the culprit. Eventually, I went through my site to standardize my links and replaced all absolute paths with relative paths. It turns out, however, that loads of people apparently bookmarked the demo and were hitting it directly.</p>
<p>The cookies set by Google Analytics for the http://jensbits.com link had a host parameter (value) of &#8216;.jensbits.com.&#8217; The cookie also had a correct referrer of (direct). So far so good. All is correct.</p>
<p>The demo page has a link on it to return to the post. That link is relative and it points back to the WordPress post. WordPress will correctly rewrite the URL to include the &#8216;www.&#8217; The demo link was not a WordPress post so it did not get rewritten. After clicking on the &#8216;return to post&#8217; link and looking at the cookies again, I now have double the cookies for my site. One set of cookies has &#8216;.jensbits.com&#8217; as the host value and the other set has &#8216;www.jensbits.com&#8217; as the value.</p>
<p>The cookies set by Google Analytics for the http://www.jensbits.com link had a referrer of jensbits.com. Correct, but incorrect.</p>
<p><img src="/images/cookies-jensbits.gif" alt="I hate cookies" title="I hate cookies" /></p>
<p>The solution was to fix the canonicalization of the URLs. In other words, all the URLs had to resolve to either jensbits.com or www.jensbits.com. I choose www.jensbits.com since WordPress was doing such a fine job for my posts.</p>
<p>Once the rewrite fix was in place, I have the correct amount of cookies and the correct referrer for the site when I retrace my steps from the demo link to the main site just as I did previously.</p>
<p><img src="/images/cookies-www-jensbits.gif" alt="I love cookies" title="I love cookies" /></p>
<p>Don&#8217;t expect to see a precipitous drop off in the referrer number for your site once you institute this. It will decrease over time. Look for a trend, not a miracle. Google Analytics cookies have a lifespan. Return visitors may still carry erroneous cookie data like an albatross around their necks until it eventually dies a natural death.</p>
<p>BTW, the other site I mentioned, I had long ago put in a rewrite rule to include the &#8216;www&#8217; because of a programmatic session cookie issue with a web-based application. It was my determination at the time that is was specific to the way the programming language I was using was setting cookies.</p>
<p>One other thing to consider: If you are the site owner and/or webmaster, you should put a filter into your Google Analytics profile that prevents your visits from being entered into the reports. An<a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&#038;answer=55572"> IP address filter</a> is the preferred method to accomplish this. </p>
<p>Note: This is not a WordPress issue. This can happen to any site that will resolve to with or without the &#8216;www&#8217; in the URL.</p>
<h2>Recommended Reading</h2>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470529393" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470130652" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470562315" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470531282" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/01/07/google-analytics-showing-my-site-as-top-referrer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Passed the ColdFusion 8 Certification Exam</title>
		<link>http://www.jensbits.com/2010/01/05/passed-the-coldfusion-8-certification-exam/</link>
		<comments>http://www.jensbits.com/2010/01/05/passed-the-coldfusion-8-certification-exam/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 19:10:40 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=529</guid>
		<description><![CDATA[Passed the ColdFusion 8 Certification Exam today. Scored a 95 and could not have done it without CF8 Exam Buster. 

I have heard all the debate on whether or not to take the CF exam and I think most arguments against taking it are rubbish.
The real benefit of taking any exam is the fact that [...]]]></description>
			<content:encoded><![CDATA[<p>Passed the ColdFusion 8 Certification Exam today. Scored a 95 and could not have done it without <a href="http://www.centrasoft.com/products.cfm">CF8 Exam Buster</a>. </p>
<p><img   title="ColdFusion 8 Adobe Certified Expert - Advanced" alt="ColdFusion 8 Adobe Certified Expert - Advanced" src="/images/cfcert.gif" /></p>
<p>I have heard all the debate on whether or not to take the CF exam and I think most arguments against taking it are rubbish.</p>
<p>The real benefit of taking any exam is the fact that you get exposed to parts of the language that you never knew existed. Just studying for the exam helped me find tags, attributes, and functions I wouldn&#8217;t even have thought to look for. And, if you are a freelancer, it can only help to have this credential.</p>
<p>So, if you can pony up the $150 for the test and the $40 for Exam Buster, there is no reason why you shouldn&#8217;t take the exam. Just go through the Exam Buster tests until you consistently score in the 90&#8217;s and you are a lock to pass.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2010/01/05/passed-the-coldfusion-8-certification-exam/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ColdFusion and Google Analytics: Getting Out What You Put In</title>
		<link>http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/</link>
		<comments>http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 03:43:27 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Google Analytics]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=510</guid>
		<description><![CDATA[The Hooking into Google Analytics post details how to connect to the Data Export API of Google Analytics (GA) and get a simple visitors count in return. Here we will expand greatly on that and create a cfc that will process just about any result from the API. I submitted this topic to present at [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="/2009/05/02/hooking-into-google-analytics-with-coldfusion/">Hooking into Google Analytics</a> post details how to connect to the Data Export API of Google Analytics (GA) and get a simple visitors count in return. Here we will expand greatly on that and create a cfc that will process just about any result from the API. I submitted this topic to present at <a href="http://cfunited.com/2010/">CFUnited</a> but haven&#8217;t heard back from them yet. Here&#8217;s hoping.</p>
<p>An auth token is needed for requests to the API and two ways to do that are the <a href="http://code.google.com/intl/en/apis/analytics/docs/gdata/gdataAuthentication.html">AuthSub and ClentLogin methods</a>. The method used is up to the developer as once the auth token is retrieved and set into session, data calls to the API can be repeatedly made.</p>
<pre class="brush: coldfusion;">
&lt;cffunction name=&quot;googleLogin&quot; access=&quot;public&quot; hint=&quot;GA account authorization&quot;&gt;
        &lt;cfargument name=&quot;email&quot; type=&quot;string&quot; required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;password&quot; type=&quot;string&quot;required=&quot;yes&quot; default=&quot;&quot;&gt;
        &lt;cfargument name=&quot;gaLoginUrl&quot; type=&quot;string&quot; required=&quot;no&quot; default=&quot;https://www.google.com/accounts/ClientLogin&quot;&gt;

        &lt;cfset var loginAuth = &quot;&quot; /&gt;

        &lt;cfhttp url=&quot;#arguments.gaLoginUrl#&quot; method=&quot;post&quot;&gt;
            &lt;cfhttpparam name=&quot;accountType&quot; type=&quot;url&quot; value=&quot;GOOGLE&quot;&gt;
            &lt;cfhttpparam name=&quot;Email&quot; type=&quot;url&quot; value=&quot;#arguments.email#&quot;&gt;
            &lt;cfhttpparam name=&quot;Passwd&quot; type=&quot;url&quot; value=&quot;#arguments.password#&quot;&gt;
            &lt;cfhttpparam name=&quot;service&quot; type=&quot;url&quot; value=&quot;analytics&quot;&gt;
            &lt;cfhttpparam name=&quot;source&quot; type=&quot;url&quot; value=&quot;my-analytics&quot;&gt;
        &lt;/cfhttp&gt;

        &lt;cfif NOT FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent)&gt;
            &lt;cfset loginAuth = &quot;Authorization Failed&quot; /&gt;
        &lt;cfelse&gt;
            &lt;cfset loginAuth = Mid(cfhttp.filecontent, FindNoCase(&quot;Auth=&quot;,cfhttp.filecontent) + (Len(&quot;Auth=&quot;)), Len(cfhttp.filecontent)) /&gt;
        &lt;/cfif&gt;

         &lt;cflock scope=&quot;session&quot; type=&quot;exclusive&quot; timeout=&quot;5&quot;&gt;
                &lt;cfset session.ga_loginAuth = loginAuth /&gt;
         &lt;/cflock&gt;

    &lt;/cffunction&gt;
</pre>
<p>To retrieve the profile or data feed, a call is made to the API via a function.</p>
<pre class="brush: coldfusion;">
    &lt;cffunction name=&quot;callApi&quot; access=&quot;public&quot; returntype=&quot;array&quot; hint=&quot;GA data as array of structures&quot;&gt;
        &lt;cfargument name=&quot;gaUrl&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;
        &lt;cfargument name=&quot;authToken&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;

        &lt;cfset var authTokenHeader = 'GoogleLogin auth=' &amp; arguments.authToken /&gt;
        &lt;cfset var responseOutput = &quot;&quot; /&gt;

        &lt;cfhttp url=&quot;#arguments.gaUrl#&quot; method=&quot;get&quot;&gt;
            &lt;cfhttpparam name=&quot;Authorization&quot; type=&quot;header&quot; value=&quot;#authTokenHeader#&quot;&gt;
        &lt;/cfhttp&gt;
        &lt;cfset responseOutput = cfhttp.filecontent /&gt;

        &lt;!---remove dxp: prefix from nodes that have it and strip xmlns from feed element---&gt;
         &lt;cfset responseOutput = responseOutput.ReplaceAll(&quot;(&lt;/?)(\w+:)&quot;,&quot;$1&quot;) /&gt;
         &lt;cfset responseOutput = REReplaceNoCase(responseOutput,&quot;&lt;feed[^&gt;]*&gt;&quot;,&quot;&lt;feed&gt;&quot;) /&gt;

         &lt;!---entry nodes hold the data---&gt;
         &lt;cfset entryNodes = XmlSearch(responseOutput, '//entry/') /&gt;

         &lt;cfreturn entryNodes /&gt;
    &lt;/cffunction&gt;
</pre>
<p>Next, a list of the profiles (websites) that the user has access to are retrieved by requesting an account feed. If the user has only one profile associated with their credentials, the data is displayed immediately. If they have more than one, they are presented with a select box to select the profile they want data from.</p>
<pre class="brush: coldfusion;">
&lt;cfinvoke component=&quot;ga&quot; method=&quot;parseProfiles&quot; returnvariable=&quot;profilesArray&quot;&gt;
          &lt;cfinvokeargument name=&quot;gaUrl&quot; value=&quot;https://www.google.com/analytics/feeds/accounts/default&quot; /&gt;
          &lt;cfinvokeargument name=&quot;authToken&quot; value=&quot;#session.ga_loginAuth#&quot; /&gt;
&lt;/cfinvoke&gt;
</pre>
<pre class="brush: coldfusion;">
&lt;cffunction name=&quot;parseProfiles&quot; access=&quot;public&quot; returntype=&quot;array&quot; hint=&quot;GA profiles as array of structures&quot;&gt;
        &lt;cfargument name=&quot;gaUrl&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;
        &lt;cfargument name=&quot;authToken&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;

        &lt;cfset var profileArray = ArrayNew(1) /&gt;
        &lt;cfset var entryStruct = StructNew() /&gt;

        &lt;cfset entryNodes = callApi(arguments.gaUrl,arguments.authToken) /&gt;

        &lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes)#&quot; index=&quot;num&quot;&gt;
            &lt;cfset entryStruct = StructNew() /&gt;

            &lt;cfset entryStruct.id = entryNodes[num].id.XmlText /&gt;
            &lt;cfset entryStruct.title = entryNodes[num].title.XmlText /&gt;
            &lt;cfset entryStruct.tableId = entryNodes[num].tableId.XmlText /&gt;

            &lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes[num].property)#&quot; index=&quot;i&quot;&gt;
                &lt;cfswitch expression='#entryNodes[num].property[i].XmlAttributes[&quot;name&quot;]#'&gt;
                    &lt;cfcase value=&quot;ga:accountId&quot;&gt;
                        &lt;cfset entryStruct.accountId = entryNodes[num].property[i].XmlAttributes[&quot;value&quot;] /&gt;
                    &lt;/cfcase&gt;
                    &lt;cfcase value=&quot;ga:accountName&quot;&gt;
                        &lt;cfset entryStruct.accountName = entryNodes[num].property[i].XmlAttributes[&quot;value&quot;] /&gt;
                    &lt;/cfcase&gt;
                    &lt;cfcase value=&quot;ga:profileId&quot;&gt;
                        &lt;cfset entryStruct.profileId = entryNodes[num].property[i].XmlAttributes[&quot;value&quot;] /&gt;
                    &lt;/cfcase&gt;
                    &lt;cfcase value=&quot;ga:webPropertyId&quot;&gt;
                        &lt;cfset entryStruct.webPropertyId = entryNodes[num].property[i].XmlAttributes[&quot;value&quot;] /&gt;
                    &lt;/cfcase&gt;
                &lt;/cfswitch&gt;
            &lt;/cfloop&gt;

            &lt;cfset arrayAppend(profileArray,duplicate(entryStruct)) /&gt;

        &lt;/cfloop&gt;

        &lt;cfreturn profileArray /&gt;

    &lt;/cffunction&gt;
</pre>
<p>A default date range of one year is set initially. A dialog box that allows the user to change the date range is presented as an option. The date range is limited to a max date of yesterday because GA does not have full data for the current day. This causes the averages that are calculated on the return data to be skewed.</p>
<p>A data feed request url is sent to GA along with the auth token  a via cfhttp tag.</p>
<pre class="brush: coldfusion;">
&lt;cfset reqUrl = &quot;https://www.google.com/analytics/feeds/data?ids=&quot; &amp; session.tableId &amp; &quot;&amp;metrics=ga:newVisits,ga:pageviews,ga:visits,ga:visitors,ga:timeOnSite&amp;start-date=&quot; &amp; session.startdate &amp; &quot;&amp;end-date=&quot; &amp; session.enddate /&gt;
</pre>
<p>The XML response is then parsed out and returned as an array of structures.</p>
<pre class="brush: coldfusion;">
&lt;cffunction name=&quot;parseData&quot; access=&quot;public&quot; returntype=&quot;array&quot; hint=&quot;GA data as array of structures&quot;&gt;
        &lt;cfargument name=&quot;gaUrl&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;
        &lt;cfargument name=&quot;authToken&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;

        &lt;cfset var returnArray = ArrayNew(1) /&gt;
        &lt;cfset var entryStruct = StructNew() /&gt;

         &lt;cfset entryNodes = callApi(arguments.gaUrl,arguments.authToken) /&gt;

         &lt;!---loop through the entries and put each data point for each campaign in structure---&gt;
            &lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes)#&quot; index=&quot;num&quot;&gt;

                &lt;!---rest of the stats data from GA
                first check if dimension exists---&gt;
                &lt;cfif StructKeyExists(entryNodes[num],&quot;dimension&quot;)&gt;
                    &lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes[num].dimension)#&quot; index=&quot;i&quot;&gt;
                     &lt;cfset &quot;entryStruct.#Mid(entryNodes[num].dimension[i].XmlAttributes[&quot;name&quot;],4,
Len(entryNodes[num].dimension[i].XmlAttributes[&quot;name&quot;]))#&quot; = entryNodes[num].dimension[i].XmlAttributes[&quot;value&quot;] /&gt;
                     &lt;/cfloop&gt;
                 &lt;/cfif&gt;

                 &lt;cfloop from=&quot;1&quot; to=&quot;#ArrayLen(entryNodes[num].metric)#&quot; index=&quot;i&quot;&gt;
                         &lt;cfset &quot;entryStruct.#Mid(entryNodes[num].metric[i].XmlAttributes[&quot;name&quot;],4,
Len(entryNodes[num].metric[i].XmlAttributes[&quot;name&quot;]))#&quot; = entryNodes[num].metric[i].XmlAttributes[&quot;value&quot;] /&gt;
                  &lt;/cfloop&gt;

                &lt;cfset arrayAppend(returnArray,duplicate(entryStruct)) /&gt;

           &lt;/cfloop&gt;

        &lt;cfreturn returnArray /&gt;
    &lt;/cffunction&gt;
</pre>
<p>Once the data is in a form you can manipulate, graphs, tables, and charts of all kinds can be made.</p>
<h2>Recommended Reading</h2>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470529393" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470130652" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470562315" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470531282" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="http://cf-jensbits.com/ga/login.cfm" onclick="_gaq.push(['_link', 'http://cf-jensbits.com/ga/login.cfm']); return false;"><span>Demo</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/12/19/coldfusion-and-google-analytics-getting-out-what-you-put-in/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using jQuery Datepicker and Dialog Box To Select Date Range</title>
		<link>http://www.jensbits.com/2009/12/03/using-jquery-datepicker-and-dialog-box-to-select-date-range/</link>
		<comments>http://www.jensbits.com/2009/12/03/using-jquery-datepicker-and-dialog-box-to-select-date-range/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 14:08:11 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=491</guid>
		<description><![CDATA[Using a jquery datepicker in a jquery dialog box to select a date range is a handy, slick way of having users input dates. Date handling and validation in forms when input by the user can be tricky at best.
Here a modal dialog box will be used to allow the user to select a date [...]]]></description>
			<content:encoded><![CDATA[<p>Using a jquery datepicker in a jquery dialog box to select a date range is a handy, slick way of having users input dates. Date handling and validation in forms when input by the user can be tricky at best.</p>
<p>Here a modal dialog box will be used to allow the user to select a date range. That date range will be validated to ensure that it goes from a start date that is prior to the end date. Also, an alternate field will be populated by the datepicker that formats the dates in a specific way. This can be helpful if you are using the dates in a database query or other call that requires a certain format.</p>
<p>First we put a button to open the dialog box and the dialog box itself on the page:</p>
<pre class="brush: xml;">
&lt;button id=&quot;selectDateRange&quot;&gt;Select Date Range&lt;/button&gt;	 

&lt;div id=&quot;dialog&quot; title=&quot;Select Date Range&quot;&gt;
&lt;div id=&quot;message&quot;&gt;&lt;/div&gt;
	&lt;form name=&quot;dateRange&quot; id=&quot;dateRangeForm&quot; action=&quot;index.cfm&quot; method=&quot;post&quot;&gt;
    &lt;label for=&quot;startdate&quot;&gt;Start Date&lt;/label&gt;
    &lt;input id=&quot;startdate&quot; type=&quot;text&quot; readonly /&gt;&lt;input type=&quot;hidden&quot; name=&quot;startdate&quot; 

id=&quot;start_alternate&quot; /&gt;
    &lt;label for=&quot;enddate&quot;&gt;End Date&lt;/label&gt;
    &lt;input id=&quot;enddate&quot; type=&quot;text&quot; readonly /&gt;&lt;input type=&quot;hidden&quot; name=&quot;enddate&quot; id=&quot;end_alternate&quot; 

/&gt;
    &lt;/form&gt;
&lt;/div&gt;
</pre>
<p>A message div is in the dialog box to send the user success or error messages related to their date selection. The input boxes are set to readonly so the user cannot type in a date; they must use the datepicker.</p>
<p>Also needed on the page is a little css to ensure that the datepicker is above the dialog box:</p>
<pre class="brush: xml;">
&lt;style type=&quot;text/css&quot;&gt;
    .ui-datepicker
    {
        z-index: 1003;
    }
&lt;/style&gt;
</pre>
<p>Then the jquery to set the datepicker to the appropriate input box in the dialog box, specify the alternate field and format, and specify min and max dates:</p>
<pre class="brush: jscript;">
$(&quot;#startdate&quot;).datepicker({altField: '#start_alternate',altFormat: 'yy-mm-dd',minDate: '-1y',maxDate: -1});
$(&quot;#enddate&quot;).datepicker({altField: '#end_alternate',altFormat: 'yy-mm-dd',minDate: '-1y',maxDate: -1});
</pre>
<p>The minDate is set to a year from today (user cannot go back more than a year) with &#8216;-1y&#8217; and the maxDate is set to yesterday (user cannot pick today or a future date) with -1. Check the <a href="http://jqueryui.com/demos/datepicker/#option-minDate">jQuery documentation on the datepicker min and maxDates</a> for further explanation.</p>
<p>And, of course, the code for the button that opens our dialog box:</p>
<pre class="brush: jscript;">
$('button#selectDateRange').click(function(){
		$('#dialog').dialog('open');

	});
</pre>
<p>The dialog box code does several things including:</p>
<ul>
<li>Closing the datepicker when the dialog closes</li>
<li>Checking for values in the input boxes</li>
<li>AJAX post to validate the date range</li>
<li>Displaying a message to the user after validating the date range</li>
<li>Sets the additional dialog close button functions</li>
</ul>
<pre class="brush: jscript;">
$(function(){

	// jQuery UI Dialog
	$('#dialog').dialog({
		autoOpen: false,
		width: 400,
		modal: true,
		resizable: false,
		close: function() {
                        $('#message').html('');
			$('#dateRangeForm :input').each(function() {
				$(this).val('');
			});
			$(&quot;#startdate&quot;).datepicker('hide');
			$(&quot;#enddate&quot;).datepicker('hide');
		 },
		buttons: {
			&quot;Submit&quot;: function() {
			var errors = 0;

			$('#dateRangeForm :input').each(function() {
				if($(this).val() == ''){
					$(this).prev().prev().css(&quot;color&quot;, &quot;red&quot;);
					$(this).prev().val('Click box and use calendar to enter date.');
					errors++;
				} else {
					$(this).prev().css(&quot;color&quot;, &quot;black&quot;);
				}
			 });

			if (errors == 0){
				dataString = $('form').serialize();
				$.ajax({
				type: &quot;POST&quot;,
				url: &quot;dateRange.php&quot;,
				data: dataString,
				dataType: &quot;json&quot;,
				success: function(data) {

					if(data == 'invalid'){
						$('#message').html(&quot;&lt;div class='errorMessage'&gt;Date range is invalid.&lt;/div&gt;&quot;);
					} else {
						$('#message').html(&quot;&lt;div class='successMessage'&gt;Date range is valid.&lt;/div&gt;&quot;);
						//location.reload();
					}
				}

			  	});

				return false;

			  }

			  },
				&quot;Close&quot;: function() { 

					$(this).dialog(&quot;close&quot;);
                                        $('#message').html(&quot;&quot;);
			                $('#dateRangeForm :input').each(function() {
				             $(this).val('');
			                });
					$(&quot;#startdate&quot;).datepicker('hide');
					$(&quot;#enddate&quot;).datepicker('hide');
				}
			 }
	});
</pre>
<p>The daterange.php is pretty straightforward:</p>
<pre class="brush: php;">
&lt;?php
	$errormsg = &quot;none&quot;;

	$start_date = new DateTime($_POST[&quot;startdate&quot;]);
	$end_date = new DateTime($_POST[&quot;enddate&quot;]);

	if ($start_date &gt; $end_date)
		$errormsg = &quot;invalid&quot;;

echo json_encode($errormsg);
?&gt;
</pre>
<p>Now, it entirely possible that you can validate the dates without a trip to the server; however, this example sets you up to use the dialog datepicker in more advanced processing or database calls on the server.</p>
<p>Usual recommended jQuery reading:</p>
<div style="height:250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0596159773" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847196705" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0321647491" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847195121" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="/demos/datepicker/index.php"><span>Demo</span></a></p>
<p id="download"><a href="/media/code/datepicker.zip"><span>Download zip of all files</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/12/03/using-jquery-datepicker-and-dialog-box-to-select-date-range/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Positioning Multiple jQuery UI Dialogs</title>
		<link>http://www.jensbits.com/2009/11/12/positioning-multiple-jquery-ui-dialogs/</link>
		<comments>http://www.jensbits.com/2009/11/12/positioning-multiple-jquery-ui-dialogs/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 01:29:09 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=472</guid>
		<description><![CDATA[This post shows one way to position multiple jQuery UI dialogs on the same page. It positions the dialog over the calling button based on the button&#8217;s position in the viewport.
The dialog box contents can be placed anywhere in the body. For this example they look like this:

&#60;div id=&#34;helpDialog1&#34; title=&#34;Help &#62;&#62; Dialog 1&#34;&#62;
   [...]]]></description>
			<content:encoded><![CDATA[<p>This post shows one way to position multiple <a href="http://jqueryui.com/demos/dialog/">jQuery UI dialogs</a> on the same page. It positions the dialog over the calling button based on the button&#8217;s position in the viewport.</p>
<p>The dialog box contents can be placed anywhere in the body. For this example they look like this:</p>
<pre class="brush: xml;">
&lt;div id=&quot;helpDialog1&quot; title=&quot;Help &gt;&gt; Dialog 1&quot;&gt;
        &lt;p&gt;In id imperdiet justo. Sed eu commodo erat. Nullam euismod dapibus magna a porttitor. Vestibulum odio turpis, ullamcorper eu ullamcorper sit amet, blandit id purus. Suspendisse commodo egestas augue, et fringilla lorem consequat et. Sed volutpat sapien at massa gravida sollicitudin. Nunc ut nibh orci.&lt;/p&gt;
        &lt;p&gt;Nam quis odio vel arcu auctor tincidunt. Aenean vulputate, sapien id porttitor placerat, purus magna viverra ligula, eu tristique justo purus sit amet ligula. Etiam viverra, enim in luctus sollicitudin, arcu nulla accumsan quam, ut mattis orci eros at dui.&lt;/p&gt;

    &lt;p style=&quot;text-align:right;color: #cc0202;&quot;&gt;&lt;a id=&quot;closeHelp1&quot; style=&quot;color:#cc0202;&quot; href=&quot;#&quot;&gt;Close&lt;/a&gt; &lt;strong&gt;X&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div id=&quot;helpDialog2&quot; title=&quot;Help &gt;&gt; Dialog 2&quot;&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut aliquam orci eget enim vehicula volutpat. Cras eu tellus quis risus venenatis egestas vitae eget est. Donec nec lorem purus. Duis vitae tortor at lacus placerat rhoncus id sit amet lectus. Suspendisse potenti. Aliquam vitae tortor lorem.&lt;/p&gt;
        &lt;p&gt;Proin ac sem magna. Donec interdum iaculis lacinia. Donec placerat malesuada mi, vitae malesuada sapien tincidunt ut. Mauris a nibh arcu. Etiam a magna a ipsum faucibus sollicitudin. Morbi nisl nunc, porttitor vitae suscipit in, rutrum at augue.&lt;/p&gt;
        &lt;p style=&quot;text-align:right;color:#cc0202;&quot;&gt;&lt;a id=&quot;closeHelp2&quot; style=&quot;color:#cc0202;&quot; href=&quot;#&quot;&gt;Close&lt;/a&gt; &lt;strong&gt;X&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
</pre>
<p>Not much. Just a little styling for sanity&#8217;s sake and lots of Latin. Take note of the id&#8217;s. They are helpDialog1 and helpDialog2. The number will be needed later.</p>
<p>Like, now&#8230;</p>
<pre class="brush: jscript;">
$('[id^=helpDialog]').dialog({
                autoOpen: false,
                modal: false,
                width: 300,
                resizable: false,
                show: 'blind',
                hide: 'blind'
            });
</pre>
<p>The jQuery sets some options for the dialog boxes, and it does this by identifying the dialog boxes with the common part of the id. The &#8216;^&#8217; means &#8217;starts with&#8217; as in the id starts with helpDialog. </p>
<p>Just like that all the dialogs your heart desires are set and ready to go.</p>
<p>The click function on the help buttons does all the heavy lifting.</p>
<pre class="brush: jscript;">
$('.help').click(function() {
              //strip off prefix of buttin id to get number for dialog
                var helpBtnIdPrefix = 'helpBtn';
                var helpBtnNum = $(this).attr('id').substring((helpBtnIdPrefix.length));

                //offset returns top and left of element
                var helpBtnOffset = $('#helpBtn' + helpBtnNum).offset();
                //width of element
                var helpBtnWidth = $('#helpBtn' + helpBtnNum).width();
                //width of dialog box
                var dialogWidth = $('#helpDialog' + helpBtnNum).dialog('option', 'width');

                //x and y positions of dialog box
                $('#helpDialog' + helpBtnNum).dialog('option','position',[helpBtnOffset.left+helpBtnWidth-dialogWidth,helpBtnOffset.top-$(window).scrollTop()]);
                $('#helpDialog' + helpBtnNum).dialog('open');
            });
</pre>
<p>The script starts by stripping off the prefix on the button id to get to the number of the button as it corresponds to the dialog box. </p>
<p>Then it gets the button offset or left and top position on the document. Next, it gets the button&#8217;s width. All this is used to properly place the dialog over the button.</p>
<p>The x position of the dialog are set using the button&#8217;s left position and width along with the dialog box width. The y position is set by using the button&#8217;s top position minus the window scroll position in case the user scrolled down.</p>
<p>After the math, the dialog is opened.</p>
<p>An extra close button was added at the bottom of the dialog box for user convenience.</p>
<pre class="brush: jscript;">
//added close btn at bottom of dialog
            $('[id^=closeHelp]').click(function() {
                var closeHelpPrefix = 'closeHelp';
                var closeHelpNum = $(this).attr('id').substring((closeHelpPrefix.length));
                $('#helpDialog' + closeHelpNum).dialog('close');
            });
</pre>
<p>Usual recommended jQuery reading:</p>
<div style="height:250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0596159773" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847196705" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0321647491" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=1847195121" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<p id="demo"><a href="/demos/dialog/position.php"><span>Demo</span></a></p>
<p id="download"><a href="/media/code/dialogposition.zip"><span>Download zip of all files</span></a></p>
<p class="donate">If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="jen@jensbits.com" /><input type="hidden" name="return" value="http://www.jensbits.com/thank-you/" /><input type="hidden" name="item_name" value="Help pay hosting. All donations go to hosting fees for this site." /><input type="hidden" name="currency_code" value="USD" /><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/11/12/positioning-multiple-jquery-ui-dialogs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passed the Google Analytics Individual Qualification Test</title>
		<link>http://www.jensbits.com/2009/11/06/passed-the-google-analytics-individual-qualification-test/</link>
		<comments>http://www.jensbits.com/2009/11/06/passed-the-google-analytics-individual-qualification-test/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 20:39:31 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[Google Analytics]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=464</guid>
		<description><![CDATA[I took and passed the Google Analytics Individual Qualification test today. It wasn&#8217;t too bad but it did require studying unless you dead set on cheating. I studied all the presentations on Google&#8217;s Conversion University, running through the more difficult stuff twice (AdWords, e-commerce). 
It costs $50 to take. Seems a little steep but I [...]]]></description>
			<content:encoded><![CDATA[<p>I took and passed the Google Analytics Individual Qualification test today. It wasn&#8217;t too bad but it did require studying unless you dead set on cheating. I studied all the presentations on <a href="http://www.google.com/support/conversionuniversity/">Google&#8217;s Conversion University</a>, running through the more difficult stuff twice (AdWords, e-commerce). </p>
<p>It costs $50 to take. Seems a little steep but I did learn so much more than I would have had I not been so motivated. Meaning: I wasn&#8217;t going to waste my $50.</p>
<p><img src="/images/gaCert.gif" alt="I passed!" style="border: 1px solid" /></p>
<h2>Recommended Reading</h2>
<div style="height: 250px;">
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470529393" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470130652" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470562315" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
<div style="float:left;margin-right: 25px">
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=jensbits-20&#038;o=1&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=10FE9736YVPPT7A0FBG2&#038;asins=0470531282" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2009/11/06/passed-the-google-analytics-individual-qualification-test/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
