<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2titles.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemtitles.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>jensbits</title>
	
	<link>http://www.jensbits.com</link>
	<description>my code snips</description>
	<lastBuildDate>Tue, 24 Jan 2012 23:38:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/jensbits" /><feedburner:info uri="jensbits" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by/2.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><feedburner:emailServiceId>jensbits</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/jensbits" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fjensbits" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>Output SQL Server Reporting Services (SSRS) Report as PDF from URL with VB.NET or C#.NET</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/jkWMJ-ggaHs/</link>
		<comments>http://www.jensbits.com/2012/01/23/output-sql-server-reporting-services-ssrs-report-as-pdf-from-url-with-vb-net-or-c-net/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 20:55:32 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[reporting]]></category>
		<category><![CDATA[ssrs]]></category>
		<category><![CDATA[vb.net]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1449</guid>
		<description><![CDATA[Outputting an existing SQL Server Reporting Services (SSRS) report to a PDF via a web URL is a convenient way to distribute SSRS reports, invoices, or anything else from SSRS. This post focuses on an existing report; however, links to the basic set up for a report are included. The code to output an existing <a href="http://www.jensbits.com/2012/01/23/output-sql-server-reporting-services-ssrs-report-as-pdf-from-url-with-vb-net-or-c-net/"> read more <span class="meta-nav">&#187;</span></a>
No related posts.]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1449" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2012%2F01%2F23%2Foutput-sql-server-reporting-services-ssrs-report-as-pdf-from-url-with-vb-net-or-c-net%2F&amp;via=jensbits&amp;text=Output%20SQL%20Server%20Reporting%20Services%20%28SSRS%29%20Report%20as%20PDF%20from%20URL%20with%20VB.NET%20or%20C%23.NET&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2012%2F01%2F23%2Foutput-sql-server-reporting-services-ssrs-report-as-pdf-from-url-with-vb-net-or-c-net%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>Outputting an existing SQL Server Reporting Services (SSRS) report to a PDF via a web URL is a convenient way to distribute SSRS reports, invoices, or anything else from SSRS. This post focuses on an existing report; however, links to the basic set up for a report are included. The code to output an existing report as PDF are given and uses a ReportViewer control.</p>
<p>You can skip to the PDF Output section if your server is all set up with the ReportViewer controls.</p>
<p>The pieces and parts to output an SSRS report as a PDF were culled from several disparate sources. All sources are given appropriate credit for their work. </p>
<p>As an added bonus, VB.NET and C#.NET versions are shown.</p>
<h2>Add Report Viewer Redistributable to Server</h2>
<p>The ReportViewer controls need to be installed on the server and <a href="http://www.microsoft.com/download/en/details.aspx?id=6576">Microsoft provides the redistributable for that in their download center</a>.</p>
<blockquote><p>
The Microsoft Report Viewer 2008 Redistributable Package includes Windows Forms and ASP.NET Web server controls for viewing reports designed using Microsoft reporting technology.</p></blockquote>
<h2>Add HTTP Handler Web Server</h2>
<p>The server has to know what it is dealing with when it is asked to generate a ReportViewer control. To help the server out, add the appropriate handlers.</p>
<p><a href="http://www2.briteglobal.com/en/blogs/Lists/Posts/Post.aspx?ID=15">Brite Global provides some excellent instructions</a> on how to add the handlers.</p>
<h2>Create Report on SSRS Server</h2>
<p>The <a href="http://www.datasprings.com/resources/articles-information/sql-server-reporting-services-getting-started">&#8220;Who Needs SQL Server’s Reporting Services?&#8221;</a> article by DataSprings is an excellent tutorial for getting started with your first report.</p>
<h2>Add Generic User to Report Server</h2>
<p>For security reasons, a generic user will need to be added to the SSRS server. These credentials will be used by the .aspx page to access the report. </p>
<p>Give this user &#8220;Browser &#8211; May view folders, reports and subscribe to reports&#8221; only rights.<br />
<img src="http://www.jensbits.com/wp-content/uploads/2012/01/ssrs_roles.gif" alt="" title="ssrs_roles" width="550" height="275"  /><br />
This generic (aka anonymous) user&#8217;s credentials will be stored in a separate config file and pulled into the web.config. That way if they change, you are not mucking about in the web.config file.</p>
<p>Create a appSetting.config and add the following information:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;appSettings&gt;
    &lt;add key=&quot;SSRS&quot; value=&quot;http://YOUR-REPORTSERVER-URL&quot; /&gt;
    &lt;add key=&quot;rvUser&quot; value=&quot;GENERIC-USERNAME&quot; /&gt;
    &lt;add key=&quot;rvPassword&quot; value=&quot;GENERIC-PASSWORD&quot; /&gt;
    &lt;add key=&quot;rvDomain&quot; value=&quot;YOUR-REPORTSERVER-DOMAIN&quot; /&gt;
  &lt;/appSettings&gt;
</pre>
<p>Pop it into the web.config as such:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;appSettings file=&quot;appSettings.config&quot;&gt;
&lt;!-- Could have other keys here --&gt;
&lt;/appSettings&gt;
</pre>
<p>The authorization is handled by using the <a href="http://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.ireportservercredentials%28v=vs.80%29.aspx">IReportServerCredentials Interface</a> which &#8220;allows applications to provide credentials for connecting to a Reporting Services report server.&#8221; </p>
<h2>PDF Output</h2>
<p>Add the ReportViewer control the an .aspx page by adding an assembly reference and the control itself:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;%@ Page Language=&quot;VB&quot; AutoEventWireup=&quot;false&quot; CodeFile=&quot;YOUR-FILE_NAME.vb&quot; Inherits=&quot;YOUR-INHERITS&quot; %&gt;

&lt;%@ Register Assembly=&quot;Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&quot;
    Namespace=&quot;Microsoft.Reporting.WebForms&quot; TagPrefix=&quot;rsweb&quot; %&gt;

&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;

&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head runat=&quot;server&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;
    &lt;div&gt;
        &lt;rsweb:ReportViewer ID=&quot;ReportViewer1&quot; runat=&quot;server&quot;&gt;
        &lt;/rsweb:ReportViewer&gt;

    &lt;/div&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The code behind page got a lot of help from <a href="http://beyondrelational.com/blogs/viral/archive/2010/07/09/generating-ssrs-reports-programatically.aspx">Viral at Beyond Relational&#8217;s post &#8220;Generating and exporting SSRS reports programatically using Report Viewer Control&#8221;</a> and using Microsoft&#8217;s <a href="http://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.ireportservercredentials%28v=vs.80%29.aspx">IReportServerCredentials Interface</a> that was mentioned earlier:</p>
<h3>VB.NET</h3>
<pre class="brush: vb; title: ; notranslate">
Imports System.Net
Imports System.IO
Imports System.Security.Principal
Imports Microsoft.Reporting.WebForms

Partial Class YOUR_PAGE_CLASS
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        SetReportParameters()
    End Sub

    Private Sub SetReportParameters()
        'Set Processing Mode
        ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote
        ' Set report server and report path
        ReportViewer1.ServerReport.ReportServerUrl = _
           New Uri(SSRS)

        ReportViewer1.ServerReport.ReportPath = _
           &quot;/YOUR-REPORT-PATH&quot;

        Dim paramList As New Generic.List(Of ReportParameter)
        Dim pInfo As ReportParameterInfoCollection
        pInfo = ReportViewer1.ServerReport.GetParameters()

        'if you have report parameters - add them here
        paramList.Add(New ReportParameter(&quot;PARAM1-EXAMPLE&quot;, &quot;1&quot;, True))
        paramList.Add(New ReportParameter(&quot;PARAM2-EXAMPLE&quot;, &quot;2&quot;, True))

        ReportViewer1.ServerReport.SetParameters(paramList)

        ' Process and render the report
        ReportViewer1.ServerReport.Refresh()

        'output as PDF
        Dim returnValue As Byte()
        Dim format As String = &quot;PDF&quot;
        Dim deviceinfo As String = &quot;&quot;
        Dim mimeType As String = &quot;&quot;
        Dim encoding As String = &quot;&quot;
        Dim extension As String = &quot;pdf&quot;
        Dim streams As String() = Nothing
        Dim warnings As Microsoft.Reporting.WebForms.Warning() = Nothing

        returnValue = ReportViewer1.ServerReport.Render(format, deviceinfo, mimeType, encoding, extension, streams, warnings)
        Response.Buffer = True
        Response.Clear()

        Response.ContentType = mimeType

        Response.AddHeader(&quot;content-disposition&quot;, &quot;attachment; filename=YOUR-OUTPUT-FILE-NAME.pdf&quot;)

        Response.BinaryWrite(returnValue)
        Response.Flush()
        Response.End()
    End Sub

    Protected Sub Page_Init(ByVal sender As Object, _
                            ByVal e As System.EventArgs) _
                            Handles Me.Init

        ReportViewer1.ServerReport.ReportServerCredentials = _
            New MyReportServerCredentials()

    End Sub
End Class

&lt;Serializable()&gt; _
Public NotInheritable Class MyReportServerCredentials
    Implements IReportServerCredentials
    Public userName As String = ConfigurationManager.AppSettings(&quot;rvUser&quot;)
    Public password As String = ConfigurationManager.AppSettings(&quot;rvPassword&quot;)
    Public domain As String = ConfigurationManager.AppSettings(&quot;rvDomain&quot;)

    Public ReadOnly Property ImpersonationUser() As WindowsIdentity _
            Implements IReportServerCredentials.ImpersonationUser
        Get
            'Use the default windows user.  Credentials will be
            'provided by the NetworkCredentials property.
            Return Nothing
        End Get
    End Property

    Public ReadOnly Property NetworkCredentials() As ICredentials _
            Implements IReportServerCredentials.NetworkCredentials
        Get
            'Read the user information from the web.config file.
            'By reading the information on demand instead of storing
            'it, the credentials will not be stored in session,
            'reducing the vulnerable surface area to the web.config
            'file, which can be secured with an ACL.

            If (String.IsNullOrEmpty(userName)) Then
                Throw New Exception(&quot;Missing user name from web.config file&quot;)
            End If

            If (String.IsNullOrEmpty(password)) Then
                Throw New Exception(&quot;Missing password from web.config file&quot;)
            End If

            If (String.IsNullOrEmpty(domain)) Then
                Throw New Exception(&quot;Missing domain from web.config file&quot;)
            End If

            Return New NetworkCredential(userName, password, domain)

        End Get
    End Property

    Public Function GetFormsCredentials(ByRef authCookie As Cookie, _
                                        ByRef userName As String, _
                                        ByRef password As String, _
                                        ByRef authority As String) _
                                        As Boolean _
            Implements IReportServerCredentials.GetFormsCredentials

        authCookie = Nothing
        userName = Nothing
        password = Nothing
        authority = Nothing

        'Not using form credentials
        Return False

    End Function

End Class
</pre>
<h3>C#</h3>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Configuration;
using System.Net;
using System.Security.Principal;
using Microsoft.Reporting.WebForms;
partial class YOUR_PAGE_CLASS : System.Web.UI.Page
{
    public string SSRS = ConfigurationManager.AppSettings[&quot;SSRS&quot;];
    protected void Page_Load(object sender, System.EventArgs e)
    {
        SetReportParameters();
    }
    private void SetReportParameters()
    {
        //Set Processing Mode
        //ReportViewer1.ProcessingMode = ProcessingMode.Remote
        ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote;
        // Set report server and report path
        ReportViewer1.ServerReport.ReportServerUrl = new Uri(SSRS);

        ReportViewer1.ServerReport.ReportPath = &quot;/YOUR-REPORT-PATH&quot;;

        System.Collections.Generic.List&lt;ReportParameter&gt; paramList = new System.Collections.Generic.List&lt;ReportParameter&gt;();
        ReportParameterInfoCollection pInfo = default(ReportParameterInfoCollection);
        pInfo = ReportViewer1.ServerReport.GetParameters();

        //if you have report parameters - add them here
        paramList.Add(new ReportParameter(&quot;PARAM1-EXAMPLE&quot;, &quot;1&quot;, true));
        paramList.Add(new ReportParameter(&quot;PARAM1-EXAMPLE&quot;, &quot;2&quot;, true));

        ReportViewer1.ServerReport.SetParameters(paramList);

        // Process and render the report
        ReportViewer1.ServerReport.Refresh();

        //output as PDF
        byte[] returnValue = null;
        string format = &quot;PDF&quot;;
        string deviceinfo = &quot;&quot;;
        string mimeType = &quot;&quot;;
        string encoding = &quot;&quot;;
        string extension = &quot;pdf&quot;;
        string[] streams = null;
        Microsoft.Reporting.WebForms.Warning[] warnings = null;

        returnValue = ReportViewer1.ServerReport.Render(format, deviceinfo, out mimeType, out encoding, out extension, out streams, out warnings);
        Response.Buffer = true;
        Response.Clear();

        Response.ContentType = mimeType;

        Response.AddHeader(&quot;content-disposition&quot;, &quot;attachment; filename=YOUR-OUTPUT-FILE-NAME.pdf&quot;);

        Response.BinaryWrite(returnValue);
        Response.Flush();
        Response.End();
    }

    protected void Page_Init(object sender, System.EventArgs e)
    {
        ReportViewer1.ServerReport.ReportServerCredentials = new MyReportServerCredentials();

    }
    public YOUR-PAGE-CLASS()
    {
        Init += Page_Init;
        Load += Page_Load;
    }
}
[Serializable()]
public sealed class MyReportServerCredentials : IReportServerCredentials
{
    public string userName = ConfigurationManager.AppSettings[&quot;rvUser&quot;];
    public string password = ConfigurationManager.AppSettings[&quot;rvPassword&quot;];

    public string domain = ConfigurationManager.AppSettings[&quot;rvDomain&quot;];
    public WindowsIdentity ImpersonationUser
    {

        //Use the default windows user.  Credentials will be
        //provided by the NetworkCredentials property.

        get { return null; }
    }

    public ICredentials NetworkCredentials
    {

        get
        {
            //Read the user information from the web.config file.
            //By reading the information on demand instead of storing
            //it, the credentials will not be stored in session,
            //reducing the vulnerable surface area to the web.config
            //file, which can be secured with an ACL.

            if ((string.IsNullOrEmpty(userName)))
            {
                throw new Exception(&quot;Missing user name from web.config file&quot;);
            }

            if ((string.IsNullOrEmpty(password)))
            {
                throw new Exception(&quot;Missing password from web.config file&quot;);
            }

            if ((string.IsNullOrEmpty(domain)))
            {
                throw new Exception(&quot;Missing domain from web.config file&quot;);
            }

            return new NetworkCredential(userName, password, domain);

        }
    }

    public bool GetFormsCredentials(out Cookie authCookie,
               out string userName, out string password,
               out string authority)
    {
        authCookie = null;
        userName = null;
        password = null;
        authority = null;

        // Not using form credentials
        return false;
    }

}
</pre>
<p>Now just run your URL in a browser (http://YOUR-DOMAIN.com/YOUR-PAGE.aspx) and the File Download warning box will pop up for the PDF.</p>
<h2>PDF Layout Tips and Things to Look Out For</h2>
<ol>
<li>Set Report PageSize to 8.5in, 11in for portrait or 11in, 8.5in for landscape.</li>
<li>Set the Report Margins as you would like.</li>
<li>Make sure your Report Body (white staging area in Visual Studio) does not exceed your Report PageSize minus your margins.</li>
<li>Remove any unused white space in Report Body no matter what you set the sizes at.</li>
</ol>
<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=jkWMJ-ggaHs:Dnj_tRzaWg0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=jkWMJ-ggaHs:Dnj_tRzaWg0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=jkWMJ-ggaHs:Dnj_tRzaWg0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=jkWMJ-ggaHs:Dnj_tRzaWg0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=jkWMJ-ggaHs:Dnj_tRzaWg0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/jkWMJ-ggaHs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2012/01/23/output-sql-server-reporting-services-ssrs-report-as-pdf-from-url-with-vb-net-or-c-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2012/01/23/output-sql-server-reporting-services-ssrs-report-as-pdf-from-url-with-vb-net-or-c-net/</feedburner:origLink></item>
		<item>
		<title>Demos</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/-GOFlBr_S4Q/</link>
		<comments>http://www.jensbits.com/demolinks/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 18:55:09 +0000</pubDate>
		<dc:creator>jen</dc:creator>
		
		<guid isPermaLink="false">http://www.jensbits.com/?page_id=1420</guid>
		<description><![CDATA[Skip the post. Go straight to the demo. Google Analytics Core Reporting API (Data Export) with Google Chart Visualizations You can punch into the Google Analytics Core Reporting (Data Export) API, pull out some stats, and stuff them into some nice graphical charts using Google Chart Visualizations. Authenticating with OAuth 2.0 for Google API Access <a href="http://www.jensbits.com/demolinks/"> read more <span class="meta-nav">&#187;</span></a>
No related posts.]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1420" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2Fdemolinks%2F&amp;via=jensbits&amp;text=Demos&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2Fdemolinks%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>Skip the post. Go straight to the demo.</p>
<div>
<ul>
<li>
<a href="http://www.jensbits.com/demos/ga/app/">Google Analytics Core Reporting API (Data Export) with Google Chart Visualizations</a></p>
<blockquote><p>You can punch into the Google Analytics Core Reporting (Data Export) API, pull out some stats, and stuff them into some nice graphical charts using Google Chart Visualizations. </p></blockquote>
</li>
<li>
<a href="http://www.jensbits.com/demos/ga/app/oauth2.php">Authenticating with OAuth 2.0 for Google API Access with PHP</a></p>
<blockquote><p>Google is leading developers to OAuth 2.0 for access to its API’s</p></blockquote>
</li>
<li>
<a href="http://www.jensbits.com/demos/ga/app/oauth2refreshtoken.php">Google API Offline Access Using OAuth 2.0 Refresh Token</a></p>
<blockquote><p>Offline access for Google APIs is achieved through a refresh token that is issued when a user first visits the app and grants offline access.</p></blockquote>
</li>
<li>
<a href="http://www.jensbits.com/demos/autocomplete_php/zipselect.php">Using jQuery Autocomplete to Populate Another Autocomplete – ASP.NET, ColdFusion, and PHP Examples</a></p>
<blockquote><p>Using one jquery autocomplete to populate another jquery autocomplete on the same page.</p></blockquote>
</li>
<li>
<a href="http://www.jensbits.com/demos/jqsubmit/index.php">jQuery.ajax and jQuery.post Form Submit Examples with PHP</a></p>
<blockquote><p>Two jQuery functions that allow for the submission of form are the jQuery.ajax function and the jQuery.post function.</p></blockquote>
</li>
<li>
<a href="http://www.jensbits.com/demos/forms/index.php">Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties</a></p>
<blockquote><p>Modal dialog box that confirms submission of a form.</p></blockquote>
</li>
</ul>
</div>
<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=-GOFlBr_S4Q:eMbR76ntx-0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=-GOFlBr_S4Q:eMbR76ntx-0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=-GOFlBr_S4Q:eMbR76ntx-0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=-GOFlBr_S4Q:eMbR76ntx-0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=-GOFlBr_S4Q:eMbR76ntx-0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/-GOFlBr_S4Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/demolinks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/demolinks/</feedburner:origLink></item>
		<item>
		<title>Google API Offline Access Using OAuth 2.0 Refresh Token</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/SEbGw0_LcSc/</link>
		<comments>http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 19:22:31 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1372</guid>
		<description><![CDATA[Offline access for Google APIs is achieved through a refresh token that is issued when a user first visits the app and grants offline access. Essentially, you have to ask for offline access, Google warns them that you are asking for it, and then they have to grant it. The return contains the golden ticket <a href="http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/"> read more <span class="meta-nav">&#187;</span></a>
Related posts:<ol>
<li><a href='http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/' rel='bookmark' title='Google API Requests with OAuth 2.0 Access Token'>Google API Requests with OAuth 2.0 Access Token</a></li>
<li><a href='http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/' rel='bookmark' title='Authenticating with OAuth 2.0 for Google API Access with PHP'>Authenticating with OAuth 2.0 for Google API Access with PHP</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1372" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2012%2F01%2F09%2Fgoogle-api-offline-access-using-oauth-2-0-refresh-token%2F&amp;via=jensbits&amp;text=Google%20API%20Offline%20Access%20Using%20OAuth%202.0%20Refresh%20Token&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2012%2F01%2F09%2Fgoogle-api-offline-access-using-oauth-2-0-refresh-token%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>Offline access for Google APIs is achieved through a refresh token that is issued when a user first visits the app and grants offline access. Essentially, you have to ask for offline access, Google warns them that you are asking for it, and then they have to grant it. The return contains the <del datetime="2012-01-19T20:10:17+00:00">golden ticket</del> refresh token.</p>
<blockquote><p>The first time a given user&#8217;s browser is sent to this URL, they see a consent page. If they grant access, then the response includes an authorization code which may be redeemed for an access token and a refresh token.</p></blockquote>
<p>Once a refresh token is obtained, it can be used to access Google APIs that the user has access to without re-authorizing.</p>
<p>See <a href="http://code.google.com/apis/accounts/docs/OAuth2WebServer.html">Google&#8217;s documentation on OAuth 2 for web apps</a> for more information.</p>
<h2>Asking for Offline Access</h2>
<h3>Parameters for Login URL</h3>
<p>Client id and client secret are set by Google when the app is registered for api access in the <a href="https://code.google.com/apis/console/#access">Google APIs Console</a>. </p>
<p>The redirect uri is a location on the server that the user is sent to after authenticating. This uri is registered in the Google APIs Console during app registration.</p>
<p>These values can be included as a separate file so the values can easily be swapped out on a per app basis.</p>
<pre class="brush: php; title: ; notranslate">
$client_id = &quot;1111111111111.apps.googleusercontent.com&quot;; //your client id
$client_secret = &quot;xXasdfd212312_dfdf dfxxdf&quot;; //your client secret
$redirect_uri = &quot;http://YOUR-SITE.com/YOUR-PATH/&quot;;
$scope = &quot;https://GOOGLE-SCOPE-TO-ACCESS&quot;; //google scope to access
$state = &quot;profile&quot;; //optional - could be whatever value you want
$access_type = &quot;offline&quot;; //optional - allows for retrieval of refresh_token for offline access
</pre>
<h3>User Login URL</h3>
<p>The login URL will prompt the user for permission to access their Google content via the app and  a &#8220;code&#8221; request variable will be returned in the URL. See <a href="http://code.google.com/apis/accounts/docs/OAuth2Login.html#formingtheurl">Forming the URL</a> for more detailed information.</p>
<pre class="brush: php; title: ; notranslate">
$loginUrl = sprintf(&quot;https://accounts.google.com/o/oauth2/auth?scope=%s&amp;state=%s&amp;redirect_uri=%s&amp;response_type=code&amp;client_id=%s&amp;access_type=%s&quot;, $scope, $state, $redirect_uri, $client_id, $access_type);

&lt;a href=&quot;&lt;?php echo $loginUrl ?&gt;&quot;&gt;Login with Google account using OAuth 2.0&lt;/a&gt;
</pre>
<p>Returned URL example (http://YOUR-SITE.com/YOUR-PATH/ is your redirect uri):</p>
<pre class="brush: xml; title: ; notranslate">

http://YOUR-SITE.com/YOUR-PATH/?state=profile&#038;code=1/fFBGRNJru1FQd44AzqT3Zg
</pre>
<h2>Get Access Token and Refresh Token</h2>
<p>They said &#8220;Yes!&#8221; Initial consent received for offline access and a &#8220;code&#8221; was returned as a request parameter:</p>
<pre class="brush: php; title: ; notranslate">
//Initial grant for access approved by user returns 'code' URL param
if(isset($_REQUEST['code'])){
    $accessToken = get_oauth2_token($_REQUEST['code'],&quot;online&quot;);
}
</pre>
<p>The get_oauth2_token does double duty. It will return an access token for either online or offline access grants.</p>
<p>For the initial grant, if a refresh token is returned, the function puts the refresh token into &#8216;global $refreshToken&#8217;</p>
<p>Why not store the refresh token here instead of putting it in a var? Because there is no reference for the refresh token at this point other than the scope of the grant request. You don&#8217;t know who it belongs to. The initial access token returned with the refresh token can be used to query the API and get data to associate with the refresh token for the database. </p>
<p>If there is a known value (like it belongs to you) to associate with the refresh token that can be used to retrieve it later on, put a call to the database save function in here.</p>
<pre class="brush: php; title: ; notranslate">
//returns session token for calls to API using oauth 2.0
//set global refreshToken var if refresh token is returned
function get_oauth2_token($grantCode,$grantType) {
	global $client_id;
	global $client_secret;
	global $redirect_uri;

	$oauth2token_url = &quot;https://accounts.google.com/o/oauth2/token&quot;;
	$clienttoken_post = array(
	&quot;client_id&quot; =&gt; $client_id,
	&quot;client_secret&quot; =&gt; $client_secret);

	if ($grantType === &quot;online&quot;){
		$clienttoken_post[&quot;code&quot;] = $grantCode;
		$clienttoken_post[&quot;redirect_uri&quot;] = $redirect_uri;
		$clienttoken_post[&quot;grant_type&quot;] = &quot;authorization_code&quot;;
	}

	if ($grantType === &quot;offline&quot;){
		$clienttoken_post[&quot;refresh_token&quot;] = $grantCode;
		$clienttoken_post[&quot;grant_type&quot;] = &quot;refresh_token&quot;;
	}

	$curl = curl_init($oauth2token_url);

	curl_setopt($curl, CURLOPT_POST, true);
	curl_setopt($curl, CURLOPT_POSTFIELDS, $clienttoken_post);
	curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

	$json_response = curl_exec($curl);
	curl_close($curl);

	$authObj = json_decode($json_response);

	//if offline access requested and granted, get refresh token
	if (isset($authObj-&gt;refresh_token)){
		global $refreshToken;
		$refreshToken = $authObj-&gt;refresh_token;
	}

	$accessToken = $authObj-&gt;access_token;
	return $accessToken;
}
</pre>
<h3>Storing the Refresh Token</h3>
<p>The refresh token will need to be stored for retrieval in the future. This example puts it in a MySQL database.</p>
<p>If a refresh token has been granted, store it in a database. Otherwise, retrieve a refresh token from the database. And, use the refresh token to set an access token for API calls.</p>
<pre class="brush: php; title: ; notranslate">
//get name on account to use as reference in database for retrieving the refresh token
//can be done with data from primary API that is being queried

$googleUserInfoAPI = &quot;https://www.googleapis.com/oauth2/v1/userinfo&quot;;

if (isset($accessToken)){
    //got access token, get data
    $accountObj = call_api($accessToken, $googleUserInfoAPI);
    $account_name =  $accountObj-&gt;name;
}

//refresh token handling - save to db if returned with access token
//or retrieve from db if needed for app
if(isset($refreshToken)){
    $accessToken = dbRefreshToken($account_name,$demo_scope,$refreshToken);
} else {
    $accessTokenFromRefresh = dbRefreshToken('ACCT_NAME_HERE',$demo_scope);
}
</pre>
<p>&#8216;ACCT_NAME_HERE&#8217; is a string that is used to identify for retrieval the refresh token you want to use.</p>
<p>The dbRefreshToken function for saving or retrieving from database and returning an access token:</p>
<pre class="brush: php; title: ; notranslate">
function dbRefreshToken($name,$scope,$refreshToken = &quot;&quot;){
    global $serverpath;
    $path = $serverpath.&quot;/config/token_config.php&quot;;
    include_once($path);
    $path = $serverpath.&quot;/config/db.php&quot;;
    include_once($path);

    if ($conn){
	if (strlen($refreshToken)){
	//if refreshToken in param list, save to db
	    $query = &quot;INSERT INTO tokens (name, scope, token) VALUES (:name, :scope, :refreshToken)&quot;;
	    $result = $conn-&gt;prepare($query);
	    $result-&gt;bindValue(':name', $name, PDO::PARAM_STR);
	    $result-&gt;bindValue(':scope', $scope, PDO::PARAM_STR);
	    $result-&gt;bindValue(':refreshToken', $refreshToken, PDO::PARAM_STR);
	    $result-&gt;execute();
	    $token = $refreshToken;
       } else {
        //else retrieve refresh token from db
	    $query = &quot;SELECT token from tokens where name = :name and scope = :scope&quot;;
	    $result = $conn-&gt;prepare($query);
	    $result-&gt;bindValue(':name',$name, PDO::PARAM_STR);
	    $result-&gt;bindValue(':scope', $scope, PDO::PARAM_STR);
	    $result-&gt;execute();
	    $row = $result-&gt;fetch(PDO::FETCH_ASSOC);
	    $token = $row[&quot;token&quot;];
        }

    mysql_close($conn);

    $accessTokenfromRefresh = get_oauth2_token($token,&quot;offline&quot;);
    return $accessTokenfromRefresh;
   }
}
</pre>
<p>Note that config.php contains your database configuration parameter (username, password, database name) and db.php contains the actual connection string. Put them in a folder and restrict web browsing to that folder.</p>
<p>The table is called &#8216;tokens&#8217; and the columns are name, scope, and token.</p>
<p id="demo"><a href="/demos/ga/app/oauth2refreshtoken.php"><span>Demo</span></a></p>
<p id="download"><a href="/demos/ga/app/ga_app_oauth2_refreshtoken.txt"><span>Download code</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>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<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="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>
<!-- End PayPal Donations -->

<p>Related posts:<ol>
<li><a href='http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/' rel='bookmark' title='Google API Requests with OAuth 2.0 Access Token'>Google API Requests with OAuth 2.0 Access Token</a></li>
<li><a href='http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/' rel='bookmark' title='Authenticating with OAuth 2.0 for Google API Access with PHP'>Authenticating with OAuth 2.0 for Google API Access with PHP</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=SEbGw0_LcSc:bArxkpHTHxY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=SEbGw0_LcSc:bArxkpHTHxY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=SEbGw0_LcSc:bArxkpHTHxY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=SEbGw0_LcSc:bArxkpHTHxY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=SEbGw0_LcSc:bArxkpHTHxY:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/SEbGw0_LcSc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/</feedburner:origLink></item>
		<item>
		<title>Google API Requests with OAuth 2.0 Access Token</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/IJtneQA4P_A/</link>
		<comments>http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 19:42:00 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1351</guid>
		<description><![CDATA[In the Authenticating with OAuth 2.0 for Google API Access with PHP post, an access token was retrieved for calls to Google APIs for data. In this post, the user&#8217;s name will be retrieved from their account. To do that, the access token needs to be sent as a header param or query param with <a href="http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/"> read more <span class="meta-nav">&#187;</span></a>
Related posts:<ol>
<li><a href='http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/' rel='bookmark' title='Google API Offline Access Using OAuth 2.0 Refresh Token'>Google API Offline Access Using OAuth 2.0 Refresh Token</a></li>
<li><a href='http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/' rel='bookmark' title='Authenticating with OAuth 2.0 for Google API Access with PHP'>Authenticating with OAuth 2.0 for Google API Access with PHP</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1351" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F12%2F29%2Fgoogle-api-requests-with-oauth-2-0-access-token%2F&amp;via=jensbits&amp;text=Google%20API%20Requests%20with%20OAuth%202.0%20Access%20Token&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F12%2F29%2Fgoogle-api-requests-with-oauth-2-0-access-token%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>In the <a href="http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/">Authenticating with OAuth 2.0 for Google API Access with PHP</a> post, an access token was retrieved for calls to Google APIs for data. In this post, the user&#8217;s name will be retrieved from their account.</p>
<p>To do that, the access token needs to be sent as a header param or query param with the call to the userinfo Google API. See <a href="http://code.google.com/apis/accounts/docs/OAuth2WebServer.html#callinganapi">Calling a Google API</a> for more information. The header param method is shown below.</p>
<p>A PHP object containing the account info will be returned by a call to &#8220;call_api&#8221; function with the access token and API URL passed in:</p>
<pre class="brush: php; title: ; notranslate">
$accountObj = call_api($_SESSION['accessToken'],&quot;https://www.googleapis.com/oauth2/v1/userinfo&quot;);
</pre>
<p>&#8220;call_api&#8221; calls the api and gets the data:</p>
<pre class="brush: php; title: ; notranslate">
function call_api($accessToken,$url){
	$curl = curl_init($url);

	curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	$curlheader[0] = &quot;Authorization: Bearer &quot; . $accessToken;
	curl_setopt($curl, CURLOPT_HTTPHEADER, $curlheader);

	$json_response = curl_exec($curl);
	curl_close($curl);

	$responseObj = json_decode($json_response);

	return $responseObj;
}
</pre>
<p>From the account object, the name can be accessed;</p>
<pre class="brush: php; title: ; notranslate">
$your_name =  $accountObj-&gt;name;

echo &quot;&lt;p class='successMessage'&gt;The name on your Google account is: &quot; . $your_name . &quot;&lt;/p&gt;&quot;;
</pre>
<p id="demo"><a href="/demos/ga/app/oauth2api.php"><span>Demo</span></a></p>
<p id="download"><a href="/demos/ga/app/ga_app_oauth2.txt"><span>Download code</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>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<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="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>
<!-- End PayPal Donations -->

<p>Related posts:<ol>
<li><a href='http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/' rel='bookmark' title='Google API Offline Access Using OAuth 2.0 Refresh Token'>Google API Offline Access Using OAuth 2.0 Refresh Token</a></li>
<li><a href='http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/' rel='bookmark' title='Authenticating with OAuth 2.0 for Google API Access with PHP'>Authenticating with OAuth 2.0 for Google API Access with PHP</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=IJtneQA4P_A:zAcdd9nh6xc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=IJtneQA4P_A:zAcdd9nh6xc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=IJtneQA4P_A:zAcdd9nh6xc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=IJtneQA4P_A:zAcdd9nh6xc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=IJtneQA4P_A:zAcdd9nh6xc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/IJtneQA4P_A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/</feedburner:origLink></item>
		<item>
		<title>Authenticating with OAuth 2.0 for Google API Access with PHP</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/hd4aMW0jyW8/</link>
		<comments>http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 00:21:22 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1327</guid>
		<description><![CDATA[Google is leading developers to OAuth 2.0 for access to its API&#8217;s: Given the security implications of getting the implementation correct, we strongly encourage developers to use OAuth 2.0 libraries when interacting with Google&#8217;s OAuth 2.0 endpoints (see Client libraries for more information). Over time, more features will be added to these libraries. Steps Register <a href="http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/"> read more <span class="meta-nav">&#187;</span></a>
Related posts:<ol>
<li><a href='http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/' rel='bookmark' title='Google API Requests with OAuth 2.0 Access Token'>Google API Requests with OAuth 2.0 Access Token</a></li>
<li><a href='http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/' rel='bookmark' title='Google API Offline Access Using OAuth 2.0 Refresh Token'>Google API Offline Access Using OAuth 2.0 Refresh Token</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1327" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F12%2F20%2Fauthenticating-with-oauth-2-0-for-google-api-access-with-php%2F&amp;via=jensbits&amp;text=Authenticating%20with%20OAuth%202.0%20for%20Google%20API%20Access%20with%20PHP&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F12%2F20%2Fauthenticating-with-oauth-2-0-for-google-api-access-with-php%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>Google is leading developers to OAuth 2.0 for access to its API&#8217;s:</p>
<blockquote><p>Given the security implications of getting the implementation correct, we strongly encourage developers to use OAuth 2.0 libraries when interacting with Google&#8217;s OAuth 2.0 endpoints (see Client libraries for more information). Over time, more features will be added to these libraries.</p></blockquote>
<h2>Steps</h2>
<ol>
<li><a href="https://code.google.com/apis/console/#access">Register the app with Google</a></li>
<li>Create login URL and retrieve &#8220;code&#8221;</li>
<li>Exchange &#8220;code&#8221; for access token</li>
<li>Send access token with API requests (<a href="http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/">details in this post</a>)</li>
</ol>
<p>Google details the instructions in <a href="http://code.google.com/apis/accounts/docs/OAuth2.html">Using OAuth 2.0 to Access Google APIs</a>.  </p>
<p>Steps for registering your app can be found in <a href="http://code.google.com/p/google-api-php-client/wiki/OAuth2">APIs Client Library for PHP</a>. </p>
<p>Google scope values for its API&#8217;s can be found in the <a href="https://code.google.com/oauthplayground/">OAuth 2.0 Playground</a>.</p>
<h2>Create Login URL and Retrieve &#8220;Code&#8221;</h2>
<h3>Parameters for Login URL</h3>
<p>Client id and client secret are set by Google when the app is registered for api access in the <a href="https://code.google.com/apis/console/#access">Google APIs Console</a>. </p>
<p>The redirect uri is a location on the server that the user is sent to after authenticating. This uri is registered in the Google APIs Console during app registration.</p>
<p>These values can be included as a separate file so the values can easily be swapped out on a per app basis.</p>
<pre class="brush: php; title: ; notranslate">
$client_id = &quot;1111111111111.apps.googleusercontent.com&quot;; //your client id
$client_secret = &quot;XxxXXxxXXxXXxXxXXXxXXXX&quot;; //your client secret
$redirect_uri = &quot;http://YOUR-SITE.com/YOUR-PATH/&quot;;
$scope = &quot;https://GOOGLE-SCOPE-TO-ACCESS&quot;; //google scope to access
$state = &quot;profile&quot;; //optional
$access_type = &quot;offline&quot;; //optional - allows for retrieval of refresh_token for offline access
</pre>
<h3>User Login URL</h3>
<p>The login URL will prompt the user for permission to access their Google content via the app and  a &#8220;code&#8221; request variable will be returned in the URL. See <a href="http://code.google.com/apis/accounts/docs/OAuth2Login.html#formingtheurl">Forming the URL</a> for more detailed information.</p>
<pre class="brush: php; title: ; notranslate">
$loginUrl = sprintf(&quot;https://accounts.google.com/o/oauth2/auth?scope=%s&amp;state=%s&amp;redirect_uri=%s&amp;response_type=code&amp;client_id=%s&amp;access_type=%s&quot;, $scope, $state, $redirect_uri, $client_id, $access_type);

&lt;a href=&quot;&lt;?php echo $loginUrl ?&gt;&quot;&gt;Login with Google account using OAuth 2.0&lt;/a&gt;
</pre>
<p>Returned URL example (http://YOUR-SITE.com/YOUR-PATH/ is your redirect uri):</p>
<pre class="brush: xml; title: ; notranslate">

http://YOUR-SITE.com/YOUR-PATH/?state=profile&#038;code=1/fFBGRNJru1FQd44AzqT3Zg
</pre>
<h2>Exchange &#8220;Code&#8221; for Access Token</h2>
<p>If access type was set to &#8220;offline&#8221; in the login URL, a refresh token will be sent with the access token so the data can be accessed without prompting the user again.</p>
<pre class="brush: php; title: ; notranslate">
//Oauth 2.0: exchange token for session token so multiple calls can be made to api
if(isset($_REQUEST['code'])){
	$_SESSION['accessToken'] = get_oauth2_token($_REQUEST['code']);
}

//returns session token for calls to API using oauth 2.0
function get_oauth2_token($code) {
	global $client_id;
	global $client_secret;
	global $redirect_uri;

	$oauth2token_url = &quot;https://accounts.google.com/o/oauth2/token&quot;;
	$clienttoken_post = array(
	&quot;code&quot; =&gt; $code,
	&quot;client_id&quot; =&gt; $client_id,
	&quot;client_secret&quot; =&gt; $client_secret,
	&quot;redirect_uri&quot; =&gt; $redirect_uri,
	&quot;grant_type&quot; =&gt; &quot;authorization_code&quot;
	);

	$curl = curl_init($oauth2token_url);

	curl_setopt($curl, CURLOPT_POST, true);
	curl_setopt($curl, CURLOPT_POSTFIELDS, $clienttoken_post);
	curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

	$json_response = curl_exec($curl);
	curl_close($curl);

	$authObj = json_decode($json_response);

	if (isset($authObj-&gt;refresh_token)){
        //refresh token only granted on first authorization for offline access
        //save to db for future use (db saving not included in example)
		global $refreshToken;
		$refreshToken = $authObj-&gt;refresh_token;
	}

	$accessToken = $authObj-&gt;access_token;
	return $accessToken;
}
</pre>
<p>You now have an access token to present to the Google API of your choice (specified in the scope) for data.</p>
<p id="demo"><a href="/demos/ga/app/oauth2.php"><span>Demo</span></a></p>
<p id="download"><a href="/demos/ga/app/ga_app_oauth2.txt"><span>Download code</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>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<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="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>
<!-- End PayPal Donations -->

<p>Related posts:<ol>
<li><a href='http://www.jensbits.com/2011/12/29/google-api-requests-with-oauth-2-0-access-token/' rel='bookmark' title='Google API Requests with OAuth 2.0 Access Token'>Google API Requests with OAuth 2.0 Access Token</a></li>
<li><a href='http://www.jensbits.com/2012/01/09/google-api-offline-access-using-oauth-2-0-refresh-token/' rel='bookmark' title='Google API Offline Access Using OAuth 2.0 Refresh Token'>Google API Offline Access Using OAuth 2.0 Refresh Token</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=hd4aMW0jyW8:Mx8HMABZQxc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=hd4aMW0jyW8:Mx8HMABZQxc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=hd4aMW0jyW8:Mx8HMABZQxc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=hd4aMW0jyW8:Mx8HMABZQxc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=hd4aMW0jyW8:Mx8HMABZQxc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/hd4aMW0jyW8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/12/20/authenticating-with-oauth-2-0-for-google-api-access-with-php/</feedburner:origLink></item>
		<item>
		<title>Jquery Datepicker with Masked Input and Current Time</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/nxIa9STqZfc/</link>
		<comments>http://www.jensbits.com/2011/09/22/jquery-datepicker-with-masked-input-and-current-time/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 18:43:49 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[jquery datepicker]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1283</guid>
		<description><![CDATA[Examples of using a jquery ui datepicker with masked input and current time as input values. Input is editable for manual change of date and/or time. Help in this post can from Adding time to jQuery UI Datepicker by Derek Allard and the Masked Input Plugin 1.3 by Josh Bush. There are two functions: getTimeAmPm <a href="http://www.jensbits.com/2011/09/22/jquery-datepicker-with-masked-input-and-current-time/"> read more <span class="meta-nav">&#187;</span></a>
No related posts.]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1283" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F22%2Fjquery-datepicker-with-masked-input-and-current-time%2F&amp;via=jensbits&amp;text=Jquery%20Datepicker%20with%20Masked%20Input%20and%20Current%20Time&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F22%2Fjquery-datepicker-with-masked-input-and-current-time%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>Examples of using a jquery ui datepicker with masked input and current time as input values. Input is editable for manual change of date and/or time.</p>
<p>Help in this post can from <a href="http://www.derekallard.com/blog/post/adding-time-to-jquery-ui-datepicker">Adding time to jQuery UI Datepicker by Derek Allard</a> and the <a href="http://digitalbush.com/2011/03/27/masked-input-plugin-1-3/">Masked Input Plugin 1.3 by Josh Bush</a>.</p>
<p>There are two functions: </p>
<ol>
<li>getTimeAmPm &#8211; formats time for standard AM/PM display</li>
<li>getTime24 &#8211; format time for 24-hour display (sometimes called military time)</li>
</ol>
<pre class="brush: jscript; title: ; notranslate">
function getTimeAmPm() {

    var date_o = new Date();

    var date_mins = date_o.getMinutes() &lt; 10 ? &quot;0&quot; + date_o.getMinutes() : date_o.getMinutes();

    var date_hours = date_o.getHours() &gt; 12 ? &quot;0&quot; + (date_o.getHours() - 12) : date_o.getHours();

    var date_am_pm = date_o.getHours() &lt; 12 ?  &quot; AM&quot; : &quot; PM&quot;;

    // handle midnight
    date_hours = date_hours === 0 ? 12 : date_hours;

    return &quot;'&quot; + date_hours + &quot;:&quot; + date_mins + &quot; &quot; + date_am_pm + &quot;'&quot;;
}

function getTime24() {

    var date_o = new Date();

    var date_hours = date_o.getHours() &lt; 10 ? &quot;0&quot; + date_o.getHours() : date_o.getHours();

    var date_mins = date_o.getMinutes() &lt; 10 ? &quot;0&quot; + date_o.getMinutes() : date_o.getMinutes();

    return &quot;'&quot; + date_hours + &quot;:&quot; + date_mins + &quot;'&quot;;
}
</pre>
<p>The datepickers concatenate on the result from one of the time format functions and they both have the mask jquery plugin function by Josh applied to them:</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;.datepicker&quot;).datepicker({dateFormat: 'yy-mm-dd ' + getTimeAmPm()});

$(&quot;.datepicker&quot;).mask(&quot;9999-99-99 99:99 aa&quot;);

$(&quot;.datepicker24&quot;).datepicker({dateFormat: 'yy-mm-dd ' + getTime24()});

$(&quot;.datepicker24&quot;).mask(&quot;9999-99-99 99:99&quot;);
</pre>
<p>The HTML just has a couple of inputs for the examples:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;input class=&quot;datepicker&quot; type=&quot;text&quot; /&gt; AM / PM
&lt;br /&gt;
&lt;input class=&quot;datepicker24&quot; type=&quot;text&quot; /&gt; 24 hour
</pre>
<h2>Recommended</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=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=047097723X" 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=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=1849516545" 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=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=1430237953" 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=0321509021" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</div>
</div>
<h2>Demo</h2>
<p><iframe style="width: 100%; height: 150px" src="http://jsfiddle.net/jensbits/3yUes/embedded/result,js,html/"></iframe></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>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<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="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>
<!-- End PayPal Donations -->

<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=nxIa9STqZfc:WcY7FQekbwU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=nxIa9STqZfc:WcY7FQekbwU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=nxIa9STqZfc:WcY7FQekbwU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=nxIa9STqZfc:WcY7FQekbwU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=nxIa9STqZfc:WcY7FQekbwU:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/nxIa9STqZfc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/09/22/jquery-datepicker-with-masked-input-and-current-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/09/22/jquery-datepicker-with-masked-input-and-current-time/</feedburner:origLink></item>
		<item>
		<title>Breaking Development 2011 Nashville – Mobile Goodness</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/CNSMnv9sTvA/</link>
		<comments>http://www.jensbits.com/2011/09/21/breaking-development-2011-nashville-mobile-goodness/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 15:15:58 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1273</guid>
		<description><![CDATA[On September 12th, 2011 the Breaking Development conference rolled into Nashville. With two full days of talks and one full day of workshops, this single-track, superbly organized event did not disappoint. Previously in Dallas, Breaking Development: Nashville focused on new, emerging techniques for web development and design for mobile devices. Topics of the talks included <a href="http://www.jensbits.com/2011/09/21/breaking-development-2011-nashville-mobile-goodness/"> read more <span class="meta-nav">&#187;</span></a>
No related posts.]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1273" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F21%2Fbreaking-development-2011-nashville-mobile-goodness%2F&amp;via=jensbits&amp;text=Breaking%20Development%202011%20Nashville%20%26%238211%3B%20Mobile%20Goodness&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F21%2Fbreaking-development-2011-nashville-mobile-goodness%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p><a href="http://lanyrd.com/2012/bdconf-orlando/"><img src="http://www.jensbits.com/wp-content/uploads/2011/09/bdconf.gif" alt="breaking development logo" title="bdconf" width="250" height="72" class="alignright size-full wp-image-1274" /></a>On September 12th, 2011 the Breaking Development conference rolled into Nashville. With two full days of talks and one full day of workshops, this single-track, superbly organized event did not disappoint. Previously in Dallas, Breaking Development: Nashville focused on new, emerging techniques for web development and design for mobile devices. Topics of the talks included responsive design, resource and page optimization, designing mobile web experiences, designing for touch, building mobile apps with web technology, and native mobile apps versus mobile web apps.</p>
<p>This was simply the best conference I have attended. Every session had real-world, immediately applicable techniques and ideas.</p>
<p>Some of the featured concepts included:</p>
<ul>
<li>Mobile is minefield. Ground is still shifting.</li>
<li>Mobile apps are good at certain type of activity but porting to multiple devices is painful.</li>
<li>Visual design on mobile is about usability not pixel perfection.</li>
<li>People are accessing your content on phone web browser whether you want them to or not so make it good because clients want positive experience with brand.</li>
<li>Every unoptimized mobile link perpetuates negative perception.</li>
<li>80% of mobile web users would access web content more often if experience was good.</li>
<li> 80% of branded apps achieve less than 1,000 downloads and whether or not users keep app on phone is up to them.</li>
<li>Create best experience for most devices. And superior support for top devices to site.</li>
<li>Mobile is the most important technology since the printing press.</li>
</ul>
<p><a href="http://lanyrd.com/2011/bdconf/">View the presentation slides and session descriptions.</a></p>
<p>Next <a href="http://2012.bdconf.com/">Breaking Development conference is in Orlando</a>. Worth your time and money. Updates for Orlando can be found on <a href="http://lanyrd.com/2012/bdconf-orlando/">Lanyrd</a>.</p>
<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=CNSMnv9sTvA:1WWFsQqjLnA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=CNSMnv9sTvA:1WWFsQqjLnA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=CNSMnv9sTvA:1WWFsQqjLnA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=CNSMnv9sTvA:1WWFsQqjLnA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=CNSMnv9sTvA:1WWFsQqjLnA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/CNSMnv9sTvA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/09/21/breaking-development-2011-nashville-mobile-goodness/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/09/21/breaking-development-2011-nashville-mobile-goodness/</feedburner:origLink></item>
		<item>
		<title>Using jQuery Datepicker and Dialog Box To Select Date Range</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/1cFQh5RZ4S0/</link>
		<comments>http://www.jensbits.com/2011/09/06/using-jquery-datepicker-and-dialog-box-to-select-date-range-2/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 14:46:58 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[datepicker]]></category>
		<category><![CDATA[jquery ui]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1265</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 <a href="http://www.jensbits.com/2011/09/06/using-jquery-datepicker-and-dialog-box-to-select-date-range-2/"> read more <span class="meta-nav">&#187;</span></a>
Related posts:<ol>
<li><a href='http://www.jensbits.com/2009/12/03/using-jquery-datepicker-and-dialog-box-to-select-date-range/' rel='bookmark' title='Using jQuery Datepicker and Dialog Box To Select Date Range'>Using jQuery Datepicker and Dialog Box To Select Date Range</a></li>
<li><a href='http://www.jensbits.com/2010/01/29/pop-up-survey-with-jquery-ui-dialog/' rel='bookmark' title='Pop-up Survey with jQuery UI Dialog'>Pop-up Survey with jQuery UI Dialog</a></li>
<li><a href='http://www.jensbits.com/2009/08/10/modal-confirmation-dialog-on-form-submit-javascript-jquery-ui-and-thickbox-varieties/' rel='bookmark' title='Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties'>Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1265" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F06%2Fusing-jquery-datepicker-and-dialog-box-to-select-date-range-2%2F&amp;via=jensbits&amp;text=Using%20jQuery%20Datepicker%20and%20Dialog%20Box%20To%20Select%20Date%20Range&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F06%2Fusing-jquery-datepicker-and-dialog-box-to-select-date-range-2%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><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; title: ; notranslate">
&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.php&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>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; title: ; notranslate">
$(&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; title: ; notranslate">
$('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 (alternate javascript validation of date range included below)</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; title: ; notranslate">
$('#dialog').dialog({
    autoOpen: false,
    width: 400,
    modal: true,
    resizable: false,
    close: function() {
        $('#message').html(&quot;&quot;);
	    $('#dateRangeForm :input').each(function() {
	    $(this).val('');
	});
    },
    buttons: {
        &quot;Close&quot;: function() {
            $(this).dialog(&quot;close&quot;);
	        $('#message').html(&quot;&quot;);
	        $('#dateRangeForm :input').each(function() {
	        $(this).val('');
	    });
	},
	&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.error == &quot;invalid&quot;){
				    $('#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;);
			        }
               } //end of success
            }); //end of ajax
         } //end of if(errors == 0)
      } //end of Submit button function
    } //end of buttons:
}); //end of dialog
</pre>
<p>Alternate method using javascript (no ajax call) to validate dates:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#dialog').dialog({
		autoOpen: false,
		width: 400,
		modal: true,
		resizable: false,
		close: function() {
			$('#message').html(&quot;&quot;);
			$('#dateRangeForm :input').each(function() {
				$(this).val('');
			});
		 },
		buttons: {
			&quot;Close&quot;: function() {
				$(this).dialog(&quot;close&quot;);
				$('#message').html(&quot;&quot;);
			     $('#dateRangeForm :input').each(function() {
				$(this).val('');
					 });
			},
			&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){
					var start_date = new Date($(&quot;#startdate&quot;).val());
					var end_date = new Date($(&quot;#enddate&quot;).val());
					if(end_date &lt; start_date){
						$('#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;);
					}
         } //end of if(errors == 0)
      } //end of Submit button function
   } //end of buttons:
}); //end of dialog
</pre>
<p>The daterange.php is pretty straightforward:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
$start_date = new DateTime($_POST[&quot;startdate&quot;]);
$end_date = new DateTime($_POST[&quot;enddate&quot;]);

if ($start_date &gt; $end_date){
    $return_json = '{&quot;error&quot;:&quot;invalid&quot;}';
}else{
    $return_json = '{&quot;error&quot;:&quot;valid&quot;}';
}

echo $return_json;
?&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>
<h2>Recommended:</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=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=047097723X" 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=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=1849516545" 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=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=1430237953" 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=0321509021" 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 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>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<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="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>
<!-- End PayPal Donations -->

<p>Related posts:<ol>
<li><a href='http://www.jensbits.com/2009/12/03/using-jquery-datepicker-and-dialog-box-to-select-date-range/' rel='bookmark' title='Using jQuery Datepicker and Dialog Box To Select Date Range'>Using jQuery Datepicker and Dialog Box To Select Date Range</a></li>
<li><a href='http://www.jensbits.com/2010/01/29/pop-up-survey-with-jquery-ui-dialog/' rel='bookmark' title='Pop-up Survey with jQuery UI Dialog'>Pop-up Survey with jQuery UI Dialog</a></li>
<li><a href='http://www.jensbits.com/2009/08/10/modal-confirmation-dialog-on-form-submit-javascript-jquery-ui-and-thickbox-varieties/' rel='bookmark' title='Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties'>Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=1cFQh5RZ4S0:eCrLRUiwDOA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=1cFQh5RZ4S0:eCrLRUiwDOA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=1cFQh5RZ4S0:eCrLRUiwDOA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=1cFQh5RZ4S0:eCrLRUiwDOA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=1cFQh5RZ4S0:eCrLRUiwDOA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/1cFQh5RZ4S0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/09/06/using-jquery-datepicker-and-dialog-box-to-select-date-range-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/09/06/using-jquery-datepicker-and-dialog-box-to-select-date-range-2/</feedburner:origLink></item>
		<item>
		<title>Targeting Dynamic Element IDs with jQuery</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/blxkZiW4y2E/</link>
		<comments>http://www.jensbits.com/2011/09/01/targeting-dynamic-element-ids-with-jquery/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 15:40:33 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1234</guid>
		<description><![CDATA[When elements are added dynamically through a scripting language (usually by a database pull) they can have sequential identifiers in one or more of their attributes. For this example, a series of checkboxes that, when checked, will populate an input box by matching up the numeric portion of the id attribute. To make the matching <a href="http://www.jensbits.com/2011/09/01/targeting-dynamic-element-ids-with-jquery/"> read more <span class="meta-nav">&#187;</span></a>
Related posts:<ol>
<li><a href='http://www.jensbits.com/2009/05/17/jquery-selection-and-targeting-of-dynamic-id-attributes/' rel='bookmark' title='jQuery Selection and Targeting of Dynamic ID Attributes'>jQuery Selection and Targeting of Dynamic ID Attributes</a></li>
<li><a href='http://www.jensbits.com/2011/05/29/jquery-ajax-get-xml-parsing-error-no-element-found-location-moz-nullprincipal/' rel='bookmark' title='jQuery Ajax Get XML Parsing Error: no element found Location: moz-nullprincipal'>jQuery Ajax Get XML Parsing Error: no element found Location: moz-nullprincipal</a></li>
<li><a href='http://www.jensbits.com/2011/06/19/position-jquery-ui-dialog-relative-to-link/' rel='bookmark' title='Position jQuery UI Dialog Relative to Link or Page Element'>Position jQuery UI Dialog Relative to Link or Page Element</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1234" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F01%2Ftargeting-dynamic-element-ids-with-jquery%2F&amp;via=jensbits&amp;text=Targeting%20Dynamic%20Element%20IDs%20with%20jQuery&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F09%2F01%2Ftargeting-dynamic-element-ids-with-jquery%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>When elements are added dynamically through a scripting language (usually by a database pull) they can have sequential identifiers in one or more of their attributes. For this example, a series of checkboxes that, when checked, will populate an input box by matching up the numeric portion of the id attribute.</p>
<p>To make the matching easier to set up and understand, setting the id&#8217;s should be consistent. In this example the id&#8217;s will have a pattern of <em>prefix</em>_00. The elements to be matched will have the same pattern.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;p&gt;
    &lt;input type=&quot;checkbox&quot; id=&quot;checkbox_01&quot; name=&quot;checkbox&quot; value=&quot;red was checked&quot; /&gt;red&lt;br /&gt;
    &lt;input type=&quot;checkbox&quot; id=&quot;checkbox_02&quot; name=&quot;checkbox_02&quot; value=&quot;green was checked&quot; /&gt;green&lt;br /&gt;
    &lt;input type=&quot;checkbox&quot; id=&quot;checkbox_03&quot; name=&quot;checkbox_03&quot; value=&quot;blue was checked&quot; /&gt;blue
&lt;/p&gt;

&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;color 01&lt;input type=&quot;text&quot; id=&quot;color_01&quot; name=&quot;color_01&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;color 02&lt;input type=&quot;text&quot; id=&quot;color_02&quot; name=&quot;color_02&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;color 03&lt;input type=&quot;text&quot; id=&quot;color_03&quot; name=&quot;color_03&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
</pre>
<p>The jquery/javacript will strip off the prefix of an element&#8217;s id to grab the numeric value. It will then concatenate the numeric value onto the prefix of the matching element.</p>
<p>The function to grab the number:</p>
<pre class="brush: jscript; title: ; notranslate">
function getNum(element, attrPrefix) {
    //set prefix, get number
    var prefix = attrPrefix;
    var num = element.attr(&quot;id&quot;).substring((prefix.length));
    return num;
}
</pre>
<p>A checkbox change function calls the getNum function and concatenates the id for the matching element. Then it sets the value of the matched element.</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;:checkbox&quot;).change(function() {
    var num = getNum($(this), &quot;checkbox_&quot;);
    if ($(this).is(&quot;:checked&quot;)) {
        $(&quot;#color_&quot; + num).val($(this).val());
    } else {
        $(&quot;#color_&quot; + num).val(&quot;&quot;);
    }
});
</pre>
<p>Fiddle Demo:<br />
<iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/jensbits/XM3mV/embedded/result,js,html/"></iframe></p>
<p>Related posts:<ol>
<li><a href='http://www.jensbits.com/2009/05/17/jquery-selection-and-targeting-of-dynamic-id-attributes/' rel='bookmark' title='jQuery Selection and Targeting of Dynamic ID Attributes'>jQuery Selection and Targeting of Dynamic ID Attributes</a></li>
<li><a href='http://www.jensbits.com/2011/05/29/jquery-ajax-get-xml-parsing-error-no-element-found-location-moz-nullprincipal/' rel='bookmark' title='jQuery Ajax Get XML Parsing Error: no element found Location: moz-nullprincipal'>jQuery Ajax Get XML Parsing Error: no element found Location: moz-nullprincipal</a></li>
<li><a href='http://www.jensbits.com/2011/06/19/position-jquery-ui-dialog-relative-to-link/' rel='bookmark' title='Position jQuery UI Dialog Relative to Link or Page Element'>Position jQuery UI Dialog Relative to Link or Page Element</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=blxkZiW4y2E:R0YDTfMlKlQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=blxkZiW4y2E:R0YDTfMlKlQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=blxkZiW4y2E:R0YDTfMlKlQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=blxkZiW4y2E:R0YDTfMlKlQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=blxkZiW4y2E:R0YDTfMlKlQ:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/blxkZiW4y2E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/09/01/targeting-dynamic-element-ids-with-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/09/01/targeting-dynamic-element-ids-with-jquery/</feedburner:origLink></item>
		<item>
		<title>Using jQuery Autocomplete When Remote Source JSON Does Not Contain ‘Label’ or ‘Value’ Fields</title>
		<link>http://feedproxy.google.com/~r/jensbits/~3/bYutdf57S-g/</link>
		<comments>http://www.jensbits.com/2011/08/24/using-jquery-autocomplete-when-remote-source-json-does-not-contain-label-or-value-fields/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 17:52:15 +0000</pubDate>
		<dc:creator>jen</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[autocomplete]]></category>

		<guid isPermaLink="false">http://www.jensbits.com/?p=1223</guid>
		<description><![CDATA[If the jQuery autocomplete plugin uses a remote datasource, the autocomplete expects it to return json data with a &#8216;label&#8217; and/or a &#8216;value&#8217; field. If you return one, either &#8216;label&#8217; or &#8216;value&#8217;, the autocomplete uses it for both the suggestion menu and the value of the input box. If you return both, it uses the <a href="http://www.jensbits.com/2011/08/24/using-jquery-autocomplete-when-remote-source-json-does-not-contain-label-or-value-fields/"> read more <span class="meta-nav">&#187;</span></a>
Related posts:<ol>
<li><a href='http://www.jensbits.com/2011/04/28/jquery-ui-autocomplete-search-from-beginning-of-string/' rel='bookmark' title='jQuery UI Autocomplete: Search from Beginning of String'>jQuery UI Autocomplete: Search from Beginning of String</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div id="tweetbutton1223" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Fwww.jensbits.com%2F2011%2F08%2F24%2Fusing-jquery-autocomplete-when-remote-source-json-does-not-contain-label-or-value-fields%2F&amp;via=jensbits&amp;text=Using%20jQuery%20Autocomplete%20When%20Remote%20Source%20JSON%20Does%20Not%20Contain%20%26%238216%3BLabel%26%238217%3B%20or...%20&amp;related=jensbits&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.jensbits.com%2F2011%2F08%2F24%2Fusing-jquery-autocomplete-when-remote-source-json-does-not-contain-label-or-value-fields%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.jensbits.com/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;"></a></div><p>If the jQuery autocomplete plugin uses a remote datasource, the autocomplete expects it to return json data with a &#8216;label&#8217; and/or a &#8216;value&#8217; field. If you return one, either &#8216;label&#8217; or &#8216;value&#8217;, the autocomplete uses it for both the suggestion menu and the value of the input box. If you return both, it uses the &#8216;label&#8217; for the suggestion menu and the &#8216;value&#8217; for the value of the input box.</p>
<p>What happens when the remote source returns neither a &#8216;label&#8217; or &#8216;value&#8217; and you cannot change the returned json of the remote source? Or, better yet, it does return them but you want different values used in the autocomplete?</p>
<p>For example, the remote source json string below has neither a &#8216;label&#8217; or a &#8216;value&#8217; field. Using this would result in the autocomplete not functioning at all.</p>
<pre class="brush: jscript; title: ; notranslate">
[{&quot;id&quot;:&quot;3&quot;,&quot;state&quot;:&quot;Alaska&quot;,&quot;abbrev&quot;:&quot;AK&quot;},{&quot;id&quot;:&quot;4&quot;,&quot;state&quot;:&quot;Alabama&quot;,&quot;abbrev&quot;:&quot;AL&quot;},{&quot;id&quot;:&quot;9&quot;,&quot;state&quot;:&quot;California&quot;,&quot;abbrev&quot;:&quot;CA&quot;}]
</pre>
<p>You can work around this by modifying the &#8216;source&#8217; option of the autocomplete to assign one or both of the &#8216;label&#8217; and &#8216;value&#8217; fields values found in the json result.</p>
<p>To modify the &#8216;source&#8217; option of the autocomplete, we add an ajax call to the source and, in the &#8216;success&#8217; callback, we assign the values of all the variables we want the autocomplete to use.</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;#state&quot;).autocomplete({
				source: function( request, response ) {
				$.ajax({
					url: &quot;states_remote.php&quot;,
					dataType: &quot;json&quot;,
					data: {term: request.term},
					success: function(data) {
            					response($.map(data, function(item) {
                				return {
									label: item.state,
									id: item.id,
									abbrev: item.abbrev
									};
            				}));
						}
					});
				},
				minLength: 2,
				select: function(event, ui) {
					$('#state_id').val(ui.item.id);
					$('#abbrev').val(ui.item.abbrev);
				}
			});
</pre>
<p>To break this down, the ajax function has the following options:</p>
<ol>
<li>url: url of page that returns the json; subject to same origin policy (you should use jsonp for cross-domain url&#8217;s)</li>
<li>dataType: sets the data coming back to the ajax function as json</li>
<li>data: sets the query parameter of &#8216;term&#8217; to the value of &#8216;request.term&#8217; which is what the user types into the input box</li>
<li>success: callback function that maps the returned json and sets the variables that the autcomplete will use</li>
</ol>
<p>In this example, the &#8216;select&#8217; option of the autocomplete sets the label field used by the autocomplete in the suggest menu and as the value of the input box. It also sets the values of some additional fields in the form. They are returned to the page in the demo to verify that they are set. &#8216;id&#8217; is a hidden field in the form and &#8216;abbrev&#8217; populates a read-only input box in the form.</p>
<p>And, if the json result does set the &#8216;label&#8217; and/or &#8216;value&#8217; fields but you don&#8217;t want those values in the autocomplete, you can adjust the &#8216;return&#8217; of the &#8216;success&#8217; function in th &#8216;ajax&#8217; call:</p>
<pre class="brush: jscript; title: ; notranslate">
return {
    label: item.value,
    yourVar1: item.id,
    yourVar2: item.label
};
// or however you want it as long as a 'label' and/or 'value' field is set
</pre>
<p>Remember, the autocomplete needs a &#8216;label&#8217; or &#8216;value&#8217;. Don&#8217;t forget to set one, the other, or both.</p>
<p id="demo"><a href="/demos/autocomplete/remote.php" ><span>Demo</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>

<!-- Begin PayPal Donations by http://wpstorm.net/ -->
<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="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>
<!-- End PayPal Donations -->

<p>Related posts:<ol>
<li><a href='http://www.jensbits.com/2011/04/28/jquery-ui-autocomplete-search-from-beginning-of-string/' rel='bookmark' title='jQuery UI Autocomplete: Search from Beginning of String'>jQuery UI Autocomplete: Search from Beginning of String</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/jensbits?a=bYutdf57S-g:RctRNYLo72w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/jensbits?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=bYutdf57S-g:RctRNYLo72w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/jensbits?i=bYutdf57S-g:RctRNYLo72w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/jensbits?a=bYutdf57S-g:RctRNYLo72w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/jensbits?i=bYutdf57S-g:RctRNYLo72w:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/jensbits/~4/bYutdf57S-g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.jensbits.com/2011/08/24/using-jquery-autocomplete-when-remote-source-json-does-not-contain-label-or-value-fields/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.jensbits.com/2011/08/24/using-jquery-autocomplete-when-remote-source-json-does-not-contain-label-or-value-fields/</feedburner:origLink></item>
	</channel>
</rss>

