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

<channel>
	<title>The Braindonor Network &#187; jQuery</title>
	<atom:link href="http://www.braindonor.net/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.braindonor.net</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 01 Jun 2010 17:42:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>jQuery and ASP UpdatePanel Integration</title>
		<link>http://www.braindonor.net/coding-blog/jquery-and-asp-updatepanel-integration/328/</link>
		<comments>http://www.braindonor.net/coding-blog/jquery-and-asp-updatepanel-integration/328/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 17:42:10 +0000</pubDate>
		<dc:creator>John Hoff</dc:creator>
				<category><![CDATA[Coding Blog]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=328</guid>
		<description><![CDATA[With my latest gig sending me back into the .NET world, I have been busy migrating quite a few of my tools and experience to play nice with ASP.NET sites. One of my favorite open-source tools that is gaining popularity in .NET is jQuery. For several years now, I have been using jQuery heavily to [...]]]></description>
			<content:encoded><![CDATA[With my latest gig sending me back into the .NET world, I have been busy migrating quite a few of my tools and experience to play nice with ASP.NET sites.  One of my favorite open-source tools that is gaining popularity in .NET is <a href="http://jquery.com/" target="_blank">jQuery</a>.  For several years now, I have been using jQuery heavily to provide rich interaction on websites.  When faced with the basic UpdatePanel in ASP.NET, I was presented with a challenge.  I wanted a solution that would automatically call jQuery so that new content was properly parsed and updated.<span id="more-328"></span>  Because I had been managing all the AJAX calls in my other development, this was trivially easy to do.  UpdatePanel hides all of this inside the ASP AJAX libraries and scripts&#8212;making it difficult to figure out where and how to structure my jQuery code.  After some research and experimentation, I have a solution up and running on multiple sites now that integrates everything in a very clean manner.<br /><br />

<b>Scoping jQuery Rewrites</b><br />
The first step is to scope all of the jQuery rewrites.  The typical method of integrating jQuery rewrites into a website is to add a document.ready function like so:
<code>$(document).ready(function() {
	$('.content_tab_button').click(function(){
		$('.content_tab_container').load('/newcontent.html');
	});
});</code><br />
Because the rewrites are only called when the document.ready event fires, integrating with new content pulled in from AJAX needs to be done differently.  By placing our rewrites in a new function that recieves the scope being updated, we can have a single initialization handle all of the updating:
<code>function my_initializer(data){
	data.find('.content_tab_button').click(function(){
		$('.content_tab_container').load('/newcontent.html');\
		my_initializer($('.content_tab_container').html());
	});
}
$(document).ready(function() {
	my_initializer($(document));
});</code><br />
Everything is now scoped cleanly.  The rewrites are applied to the document when the page is loaded, and the new content when the tab button is clicked. Even if you are not an ASP.NET developer, please take the above scoping strategy with you!<br /><br />

<b>How The UpdatePanel Works</b><br />
At the highest level, an UpdatePanel refreshes its entire contents when a specificied event occurs within the panel.  Server-side, the event triggering the refresh is processed, and the entire page-stae is regenerated.  Then, only the content inside the UpdatePanel is pushed out.  This is important for any developer using UpdatePanel to understand: UpdatePanel is much more convenient than it is efficient.  As a result, our solution must follow that model.<br /><br />

With that in mind, we look to javascript class that is already managing the UpdatePanel, the <a href="http://msdn.microsoft.com/en-us/library/bb311028.aspx" target="_blank">Sys.WebForms.PageRequestManager</a> class.  In this class, we see an event handler for the <a href="http://msdn.microsoft.com/en-us/library/bb397523.aspx" target="_blank">pageLoad event</a>.  In the documentation, you can see that we are able to fetch the update panels that were just updated.  In the example, they are looking for a panel with a specific ID.  In our case, we are looking at having our rewrites applied to any panel that was updated:
<code>var panels = args.get_panelsUpdated();
if (panels.length > 0) {
    for (i = 0; i < panels.length; i++) {
        my_initializer($(panels[i]));
    }
}</code><br />
Because we have already scoped our jQuery code, this will work like a charm.<br /><br />

<b>Putting It All Together</b><br />
We can put all of the code together now, and we'll have a script that will play cleanly with the UpdatePanel:
<code>function my_initializer(data){
	data.find('.content_tab_button').click(function(){
		$('.content_tab_container').load('/newcontent.html');
		my_initializer($('.content_tab_container').html());
	});
}
function my_pageloaded_initializer(sender, args) {
    var panels = args.get_panelsUpdated();
    if (panels.length > 0) {
        for (i = 0; i < panels.length; i++) {
            my_initializer($(panels[i]));
        }
    }
}
$(document).ready(function() {
	my_initializer($(document));
	Sys.WebForms.PageRequestManager.getInstance()
	    .add_pageLoaded(my_pageloaded_initializer);
});</code><br />
All of our rewrites are called once&#8212;and only once&#8212;during page load and UpdatePanel refresh.  Enjoy!




]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/coding-blog/jquery-and-asp-updatepanel-integration/328/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hijack the WordPress Media Gallery</title>
		<link>http://www.braindonor.net/coding-blog/hijack-the-wordpress-media-gallery/228/</link>
		<comments>http://www.braindonor.net/coding-blog/hijack-the-wordpress-media-gallery/228/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 21:05:57 +0000</pubDate>
		<dc:creator>John Hoff</dc:creator>
				<category><![CDATA[Coding Blog]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=228</guid>
		<description><![CDATA[I have a friend that wants to update a banner on his WordPress blog homepage without changing the template files. I tell him I'd be glad to help him out and start working on a plugin that provides a custom administration page to allow for this. As I am a firm believer in the power [...]]]></description>
			<content:encoded><![CDATA[I have a friend that wants to update a banner on his <a href="http://wordpress.org/" target="_blank">WordPress</a> blog homepage without changing the template files. I tell him I'd be glad to help him out and start working on a plugin that provides a <a href="http://codex.wordpress.org/Adding_Administration_Menus" target="_blank">custom administration page</a> to allow for this. As I am a firm believer in the power of a lazy coder to get things done faster and better, my first thought was: "Why don't I just see if I can hijack the 'Select Image From Gallery' page to do this?"<span id="more-228"></span> After all, it just pops up into an Iframe page and tells post editer to insert an image. Hijacking that process for my own ends shouldn't take me but a few minutes...and a lot less time than trying to build my own media selector. Like nearly all the content on my site, if you are reading this, I wasn't able to find my answer elsewhere.<br /><br />

First, we will examine how the media library iframe is launched from the post editor and how we can duplicate that in our plugin. So lets crack open the page source and see what we can find:<br />
<code>&lt;a href="media-upload.php?post_id=-1249588072&amp;type=image&amp;TB_iframe=true" id="add_image" class="thickbox" title='Add an Image' onclick="return false;"&gt;&lt;img src='images/media-button-image.gif' alt='Add an Image' /&gt;&lt;/a&gt;
</code><br />

Looks like a standard hyperlink, with some extra information in the tag. What first jumps out at me is the <b>onclick="return false;"</b>. By having an onclick return <i>false</i> in a hyperlink, you ensure that a browser with javascript will never open the link when it is clicked. Sounds pretty silly until you remember that WordPress is a big user of <a href="http://jquery.com/" target="_blank">JQuery</a>. From there, we know to look at the class of the hyperlink, <b>class="thickbox"</b>.  This is a reference to the Thickbox 3.1 library found at /wp-includes/js/thickbox/thickbox.js.  This is a library to load an iframe inside an overlay with the background greyed out.  Further, it uses the href of the anchor tag to know where to pull the iframe content from.
<br /><br />

A quick check of the source on our custom page shows that Thickbox is being loaded in the footer, so we do not have to call it directly from our custom wp-admin page. I can just call up the media library with some html code:
<code>&lt;a href="media-upload.php?type=image&amp;TB_iframe=true" class="thickbox" title="Select A Banner Image From Gallery" onclick="return false;" class="thickbox"&gt;
&lt;img id="banner_image" src="&lt;?php echo(htmlentities($banner_image)); ?&gt;" width="450" height="25" /&gt;
&lt;/a&gt;
&lt;input type="hidden" id="banner_image_input" name="banner_image" value="&lt;?php echo(htmlentities($banner_image)); ?&gt;" /&gt;
</code><br />

The snippet displays an image with the source of <b>$banner_image</b> that can be clicked on to open the Media Gallery iframe. I have also added a hidden form input to store the resulting information passed back from the media library.  Once done, I now have an image on my admin page that I can click on to call up the media library.<br /><br />

We're half-way there now! All we have to do next is figure out how the media library sends an image to the post editor. This part isn't as easy. Thanks to thickbox, the media library opens up in an inline-iframe. This means that we can't just view the page source and find our answer. Instead, the only clue we have to hunt for is the "Insert into Post" button.  A quick file search turns that up in /wp-admin/includes/media.php. From there, we discover the onclick of the button, <b>onclick="addExtImage.insert();"</b>, which is thankfully also in the media.php file. At the end of the function, we see exactly what we are looking for:
<code>var win = window.dialogArguments || opener || parent || top;
win.send_to_editor(html);
</code><br />

The media library calls the function <b>send_to_editor</b> in the scope of the window that opened the media library--our admin page! We can add our own function into the admin page and collect the html that the media library sends us:
<code>function send_to_editor(html) {
    alert(html);
    tb_remove();
}
</code><br />

Once done, we can open the media library from our admin page and select an image.  When we hit the "Insert into Post" button, we get an alert with the following content:<br />
<code>&lt;img src="http://127.0.0.1/devel/wp-content/uploads/2009/09/banner.jpg" alt="banner" title="banner" class="alignnone size-full wp-image-494" /&gt;
</code><br />

All we have to do now, is strip out everything but the image source and updates the form.  First, the function eliminates all of the text returned except the image source.  It then updates the banner image and the hidden input value that I am using in my form:
<code>function send_to_editor(html) {
    var source = html.match(/src=\".*\" alt/);
    source = source[0].replace(/^src=\"/, "").replace(/" alt$/, "");
    $("#banner_image").attr('src', source);
    $('#banner_image_input").attr('value', source);
    tb_remove();
}
</code><br />

I fire up the admin page a final time, and everything works! I now have a custom admin page that allows my friend to update a banner on his wordpress site using the media gallery.
]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/coding-blog/hijack-the-wordpress-media-gallery/228/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
