<?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>WJBryant.com</title>
	<atom:link href="http://wjbryant.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://wjbryant.com</link>
	<description>Bill Bryant&#039;s Web Development Blog</description>
	<lastBuildDate>Fri, 20 Apr 2012 14:18:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Movie Picker Project Analysis, Part I</title>
		<link>http://wjbryant.com/2011/10/21/movie-picker-project-analysis-part-i/</link>
		<comments>http://wjbryant.com/2011/10/21/movie-picker-project-analysis-part-i/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 19:17:15 +0000</pubDate>
		<dc:creator>Bill</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://wjbryant.com/?p=407</guid>
		<description><![CDATA[The Movie Picker project was originally done for a course I took. We had to create a dynamic JavaScript menu system that presents the user with a series of questions that change depending on the answers given. Once enough information &#8230; <a href="http://wjbryant.com/2011/10/21/movie-picker-project-analysis-part-i/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://wjbryant.com/projects/movie-picker/">Movie Picker project</a> was originally done for a course I took. We had to create a dynamic
JavaScript menu system that presents the user with a series of questions that change depending on the answers given. Once enough information is gathered,
the result is displayed. I chose movies as the subject for my menu system. Given the specific requirements of the project, it's more of a demonstration rather than something that most people would find useful.</p>
<p>Nevertheless, I decided to revisit this project several years later with my more advanced JavaScript skills. It was completely rewritten and made more flexible
/ reusable. I decided to release this version under the MIT license in case anyone finds something useful. The following is an overview of how the code works.</p>
<span id="more-407"></span>
<h2>Global Variables</h2>
<p>All of the core code is contained in a closure, so as to not leak any variables into the global scope. There are, however, two global variables that are
created: UTILS and MOVIEPICKERDATA.</p>
<p>Since the project does not rely on any JavaScript libraries, I decided to separate the basic "utility" functions (cookies, Ajax, animation, etc.) from the core
logic of the program, essentially creating a mini JavaScript library. These functions are accessible as properties of the UTILS global variable.</p>
<p>Similarly, the data (selection choices and results) is separated from everything else and is stored in the MOVIEPICKERDATA global variable. This division allows
updates to be applied selectively to different parts of the project.</p>
<h2>Data</h2>
<p>The data is formatted as JSON. Each question is an object with a question property that holds the question text and a choices property which is an array
containing the text for each choice. In addition, this object also has a property for each choice. This property name matches the choice text from the choices
array.</p>
<p>These properties are also question objects. However, if the choice should produce a result instead of another question, the property should be an object that
describes the movie selection with title, studio, year and link properties. Note that an image is displayed from the img directory that matches the title (spaces
are replaced with underscores).</p>
<p>Here is an example of a menu with a single question and two choices:</p>
[javascript]var MOVIEPICKERDATA = {
    "question": "Choose a genre",
    "choices": [
        "Action",
        "Comedy"
    ],
    "Action": {
        "title": "Action Movie",
        "studio": "Movie Studio 1",
        "year": 2011,
        "link": "http://www.imdb.com/title/ttxxxxxxx/"
    },
    "Comedy": {
        "title": "Comedy Movie",
        "studio": "Movie Studio 2",
        "year": 2010,
        "link": "http://www.imdb.com/title/ttxxxxxxx/"
    }
};[/javascript]
<p>If the Comedy choice resulted in another question, it would look like this:</p>
[javascript]// ... code omitted ...
    "Comedy": {
        "question": "What year?",
        "choices": [
            "2010",
            "2011"
        ],
        "2010": {
            "title": "Comedy Movie 1",
            "studio": "Movie Studio 2",
            "year": 2010,
            "link": "http://www.imdb.com/title/ttxxxxxxx/"
        },
        "2011": {
            "title": "Comedy Movie 2",
            "studio": "Movie Studio 2",
            "year": 2011,
            "link": "http://www.imdb.com/title/ttxxxxxxx/"
        }
    }
};[/javascript]
<h3>Data Manipulation</h3>
<p>Since the data is exposed through a global variable, it can be manipulated by other scripts on the page. In other words, the questions, choices and results can
be changed on the fly. Similarly, you can create "expansion" scripts to build on and expand on the data already available. The only requirement is that this script
is executed after the original data script. You may also want to supply an image for any newly created or modified choices.</p>
<p>Here are some examples of expansion scripts:</p>
[javascript]// add another question to the Action choice
MOVIEPICKERDATA.Action = {
    question: 'What format?',
    choices: [
        '35mm',
        'IMAX'
    ],
    '35mm': {
        title: 'Action Movie 1',
        studio: 'Movie Studio A',
        year: 2009,
        link: 'http://www.imdb.com/title/ttxxxxxxx/'
    },
    IMAX: {
        title: 'Action Movie 2',
        studio: 'Movie Studio B',
        year: 2008,
        link: 'http://www.imdb.com/title/ttxxxxxxx/'
    }
};[/javascript]
[javascript]// modify the title of the first Action movie
MOVIEPICKERDATA.Action['35mm'].title = 'Awesome Movie Title!';
[/javascript]
[javascript]// add another choice to the Action - format question
MOVIEPICKERDATA.Action.choices[2] = '3D';
MOVIEPICKERDATA.Action['3D'] = {
    title: 'Cool 3D Movie',
    studio: 'Another Studio',
    year: 2011,
    link: 'http://www.imdb.com/title/ttxxxxxxx/'
};
[/javascript]
<h2>Summary</h2>
<p>This post covered the different parts of the Movie Picker project (main, utils, data), the data structure and data manipulation. Part II will discuss the
selection logic and browser differences.</p>]]></content:encoded>
			<wfw:commentRss>http://wjbryant.com/2011/10/21/movie-picker-project-analysis-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Calculator API</title>
		<link>http://wjbryant.com/2011/09/02/javascript-calculator-api/</link>
		<comments>http://wjbryant.com/2011/09/02/javascript-calculator-api/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 20:55:26 +0000</pubDate>
		<dc:creator>Bill</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://wjbryant.com/?p=320</guid>
		<description><![CDATA[The JavaScript Calculator now includes a public API as of version 1.1a4. This allows much greater flexibility and control of the calculator through code. Note, however, that this is still an alpha version and the API may change in the &#8230; <a href="http://wjbryant.com/2011/09/02/javascript-calculator-api/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The JavaScript Calculator now includes a public API as of version 1.1a4. This allows much greater flexibility and control of the calculator through code. Note, however, that this is still an alpha version and the API may change in the future. With that in mind, the following offers some examples of how to use the new API.</p>
<span id="more-320"></span>
<h2>Adding Calculators to a Page</h2>
<p>There are now two ways to add calculators to a page. The first and simplest way is to add the class "calc" to any elements on the page that should contain a calculator and then call JSCALC.init():</p>
[html]<div class="calc"></div>
<script src="calc-1.1a4-min.js"></script>
<script>JSCALC.init();</script>[/html]
<p>In versions prior to 1.1a4, the calculator script would automatically create calculators. Now, you must call JSCALC.init() to create them. This has the advantage of more control as to when a calculator is inserted in the page. For example, you may want to have a button on the page that displays a calculator when pressed. This way, a calculator is never created unless it's needed.</p>
[html]<input id="calcBtn" type="button" value="Display Calculator" />
<div class="calc"></div>
<script src="calc-1.1a4-min.js"></script>
<script>
document.getElementById('calcBtn').onclick = function () {
    JSCALC.init();
};
</script>[/html]
<p>The second way to create a calculator involves passing an argument to JSCALC.init(). Let's say you have no control over the HTML or do not wish to modify it. In this case, you can create a calculator inside an existing element simply by specifying the element's id.</p>
[html]<div id="tools"></div>
<script src="calc-1.1a4-min.js"></script>
<script>JSCALC.init('tools');</script>[/html]
<p>Alternatively, an element object can be passed to the init() method. Here is an example using nothing but JavaScript:</p>
[javascript](function () { // do not pollute the global scope
    var button = document.createElement('input');
    button.type = 'button';
    button.value = 'Display Calculator';
    
    button.onclick = function () {
        var container = document.createElement('div');
        document.body.replaceChild(container, this);
        JSCALC.init(container);
        button = null;
    };
    
    document.body.appendChild(button);
}());[/javascript]
<h2>Calculator Objects</h2>
<p>The JSCALC.init() method returns one or more Calculator objects that can be used to control the calculators displayed on the page. When called with no arguments (or invalid arguments), the init() method will return an array of objects - one for each calculator that was created. If an element id or element object is passed, however, it will return the single Calculator object or false if one could not be created. Other methods of the JSCALC object also return Calculator objects.</p>
<p>Calculator objects have a remove() method which removes the calculator from the page. Using this method, the previous example can be modified to allow removing the calculator as well as creating it.</p>
[javascript](function () { // do not pollute the global scope
    var button = document.createElement('input'),
        container = document.createElement('div'),
        calc;
     
    button.type = 'button';
    button.value = 'Display Calculator';
     
    button.onclick = function () {
        if (this.value === 'Display Calculator') {
            calc = JSCALC.init(container);
            this.value = 'Remove Calculator';
        } else {
            calc.remove();
            this.value = 'Display Calculator';
        }
    };
     
    document.body.appendChild(button);
    document.body.appendChild(container);
}());[/javascript]
<p>A similar result can be achieved more easily and efficiently by toggling the CSS display property of the containing element. If you don't have a reference to the calculator's parent/containing element, one can be obtained from the container property of the Calculator object.</p>
[html]<input id="calcBtn" type="button" value="Display Calculator" />
<div class="calc"></div>
<script src="calc-1.1a4-min.js"></script>[/html]
[javascript](function () { // do not pollute the global scope
    var calc;
    document.getElementById('calcBtn').onclick = function () {
        if (!calc) {
            calc = JSCALC.init()[0];
        }
        
        if (this.value === 'Display Calculator') {
            calc.container.style.display = 'block';
            this.value = 'Remove Calculator';
        } else {
            calc.container.style.display = 'none';
            this.value = 'Display Calculator';
        }
    };
}());[/javascript]
<p>Calculator objects also have a press() method which simulates pressing buttons on the calculator. Using the press() method, you can pre-populate the calculator display and memory for the user.</p>
[javascript]var CHECKOUT = {
    getTotal: function () {
        // there are 8 items at $4.50 each with 6% tax
        // round to 2 decimal places
        return Math.round(8 * 4.5 * 1.06 * 100) / 100;
    }
};

JSCALC.init('myCalc').press(CHECKOUT.getTotal());[/javascript]
<p>The press method returns the Calculator object on which it was called, so calls to it can be chained together. It also accepts non-numeric button values as strings.</p>
[javascript]JSCALC.init('myCalc')
    .press(22.5).press('+').press(2.5).press('=').press('r');[/javascript]
<p>Please see the <a href="http://wjbryant.com/projects/javascript-calculator/docs/">API documentation</a> for a complete listing of the available properties and methods. A live example and download links are on the <a href="http://wjbryant.com/projects/javascript-calculator/">JavaScript Calculator project page</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://wjbryant.com/2011/09/02/javascript-calculator-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tab Override 3.1</title>
		<link>http://wjbryant.com/2011/06/20/tab-override-3-1/</link>
		<comments>http://wjbryant.com/2011/06/20/tab-override-3-1/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 17:19:38 +0000</pubDate>
		<dc:creator>Bill</dc:creator>
				<category><![CDATA[Tab Override]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://wjbryant.com/?p=295</guid>
		<description><![CDATA[The Tab Override WordPress plugin was just updated to version 3.1. This release includes a new option to add a tabs on/off button to the HTML editor toolbar, allowing you to quickly enable or disable the plugin while editing a &#8230; <a href="http://wjbryant.com/2011/06/20/tab-override-3-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The Tab Override WordPress plugin was just updated to version 3.1. This release includes a new option to add a tabs on/off button to the
HTML editor toolbar, allowing you to quickly enable or disable the plugin while editing a post or page. This release also includes several important bug fixes.</p>
<p>To get complete details and download the latest version, visit the
<a href="http://wordpress.org/extend/plugins/tab-override/">Tab Override page</a> at the WordPress Plugin Directory. You can try out the latest version
of the jQuery plugin on the <a href="http://wjbryant.com/projects/tab-override/">demo page</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://wjbryant.com/2011/06/20/tab-override-3-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending Tab Override</title>
		<link>http://wjbryant.com/2011/06/04/extending-tab-override/</link>
		<comments>http://wjbryant.com/2011/06/04/extending-tab-override/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 16:41:48 +0000</pubDate>
		<dc:creator>Bill</dc:creator>
				<category><![CDATA[Tab Override]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://wjbryant.com/?p=259</guid>
		<description><![CDATA[A common problem with WordPress themes and plugins is users making custom modifications to them only to have their work erased when the theme or plugin is updated. To avoid this, you can create a child theme that extends the &#8230; <a href="http://wjbryant.com/2011/06/04/extending-tab-override/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A common problem with WordPress themes and plugins is users making custom modifications to them only to have their work erased when the theme or
plugin is updated. To avoid this, you can create a child theme that extends the original theme or a plugin that modifies another plugin. Tab Override version 3.0
provides a global object and hooks just for this purpose.</p>
<h2>The $tab_override Global Object</h2>
<p>As soon as the plugin code is executed, a global object named $tab_override is created. This object is an instance of the Tab_Override class. You can use this
object to check if the Tab Override plugin is installed and activated. Normally to check for another plugin you would do something like this:</p><span id="more-259"></span>
[php]if ( in_array(
	'tab-override/tab-override.php',
	get_option( 'active_plugins', array() )
) ) {
	add_action( 'plugins_loaded', 'my_plugin_function' );
}[/php]
<p>If you just need to check for version 3 or higher, you can do this instead:</p>
[php]function my_plugin_function() {
	global $tab_override;
	if ( $tab_override ) {
		// Tab Override is installed and activated
	}
}
add_action( 'plugins_loaded', 'my_plugin_function' );[/php]
<p>An alternative, even better solution, would be to use the plugin hooks.</p>
<h2>Using the Plugin Action Hooks</h2>
<p>As of version 3.0, two action hooks are provided for use by other plugins. They are tab_override_init and tab_override_add_scripts.
They can be used by calling the add_action function just like any other action hooks in WordPress.</p>
<h3>The tab_override_init Action Hook</h3>
<p>This hook is fired when Tab Override has successfully initialized itself. A simpler way to check for the Tab Override plugin is to use this hook like this:</p>
[php]function my_plugin_function() {
	// Tab Override is installed and activated
}
add_action( 'tab_override_init', 'my_plugin_function' );[/php]
<p>This has a couple advantages. Primarily, my_plugin_function will only be executed when Tab Override is running. This means only in the admin area and
when the plugin is installed and activated. The previous examples would run on every page load and check for the plugin, even on the front-end of the site.</p>
<p>The other notable advantage is that this hook is only fired once the plugin has initialized itself, meaning that all the primary actions and filters have been added.
If you plan on modifying or removing any of these actions or filters, it's better to rely on this hook than try to guess another appropriate one or you may end up trying
to remove something that hasn't been added yet.</p>
<p>Here is another example that disables the visual editor when Tab Override is activated. Deactivating the Tab Override plugin will automatically re-enable
the visual editor.</p>
[php]function my_plugin_disable_visual_editor() {
	// the __return_false function is available in WP 3.0+
	add_filter( 'user_can_richedit', '__return_false' );
}
add_action( 'tab_override_init',
	'my_plugin_disable_visual_editor' );[/php]
<h3>The tab_override_add_scripts Action Hook</h3>
<p>This hook is fired after JavaScript is added to the page. You can use this hook to insert additional scripts that change the way Tab Override works. Here is a
simple example that outputs the settings to the console when Tab Override is in use:</p>
[php]function my_plugin_add_script() {
	wp_enqueue_script(
		'display_tab_override_settings',
		plugins_url( 'js/display-settings-1.0.js', __FILE__ ),
		array( 'jquery', 'tab-override', 'tab-override-setup' ),
		'1.0',
		true
	);
}
add_action( 'tab_override_add_scripts',
	'my_plugin_add_script' );[/php]
<p>display-settings-1.0.js:</p>
[javascript]// display Tab Override settings in the console
(function ($) {
    var tabSize = $.fn.tabOverride.getTabSize();
    if (window.console && console.log) {
        console.log(
            'Tab Override Settings\n' +
            '\tTab Size: ' + (tabSize || 'tab') + '\n' +
            '\tAuto Indent: ' + ($.fn.tabOverride.autoIndent ? 'enabled' : 'disabled')
        );
    }
}(jQuery));[/javascript]
<h2>Example Plugin</h2>
<p>This is an example plugin that removes the Tab Override submenu from the Settings menu. It uses the tab_override_init hook and the $tab_override
global object.</p>
[php]&lt;?php
/*
Plugin Name: Tab Override Plus
Description: Removes the Tab Override submenu.
*/

function tab_override_plus_remove_menu() {
	global $tab_override;
	remove_action( 'admin_menu',
		array( $tab_override, 'create_menu' ) );
}
add_action( 'tab_override_init',
	'tab_override_plus_remove_menu' );[/php]
<p>Editing the main plugin files is dangerous, as you risk losing your changes whenever the plugin is updated. Using the above methods provides a safer, cleaner
way to modify the plugin functionality.</p>]]></content:encoded>
			<wfw:commentRss>http://wjbryant.com/2011/06/04/extending-tab-override/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tab Override 3.0</title>
		<link>http://wjbryant.com/2011/06/02/tab-override-3-0/</link>
		<comments>http://wjbryant.com/2011/06/02/tab-override-3-0/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 22:53:40 +0000</pubDate>
		<dc:creator>Bill</dc:creator>
				<category><![CDATA[Tab Override]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://wjbryant.com/?p=248</guid>
		<description><![CDATA[The Tab Override WordPress plugin was updated to version 3.0 today. This is an almost complete rewrite of the plugin and includes several new features, notably: a new auto indent feature translation support the addition of tab_override_init and tab_override_add_scripts hooks &#8230; <a href="http://wjbryant.com/2011/06/02/tab-override-3-0/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://wjbryant.com/projects/tab-override/">Tab Override WordPress plugin</a> was updated to version 3.0 today. This is an almost complete rewrite of the plugin and includes several new features, notably:</p>
<ul>
<li>a new auto indent feature</li>
<li>translation support</li>
<li>the addition of tab_override_init and tab_override_add_scripts hooks</li>
</ul>
<p>In addition, there are enhancements to both security and performance as well as a new uninstall procedure and much improved documentation.
Most of the code was refactored into a class. Since some PHP 5 features were utilized, PHP 4 is no longer supported.
This version of the plugin also includes support for the upcoming WordPress 3.2 release and the fullscreen editor mode.</p>
<p><a href="http://wordpress.org/extend/plugins/tab-override/">Download it</a> and give it a try!</p>]]></content:encoded>
			<wfw:commentRss>http://wjbryant.com/2011/06/02/tab-override-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Website Update</title>
		<link>http://wjbryant.com/2010/10/21/website-update/</link>
		<comments>http://wjbryant.com/2010/10/21/website-update/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 20:47:37 +0000</pubDate>
		<dc:creator>Bill</dc:creator>
				<category><![CDATA[website]]></category>

		<guid isPermaLink="false">http://wjbryant.com/?p=104</guid>
		<description><![CDATA[Welcome to the new version of my website! The biggest changes are the migration to WordPress and the addition of a blog section. It's currently using a slightly modified version of the Twenty Ten theme, but I will create my &#8230; <a href="http://wjbryant.com/2010/10/21/website-update/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Welcome to the new version of my website! The biggest changes are the migration to WordPress and the addition of a blog section. It's currently using a slightly modified version of the Twenty Ten theme, but I will create my own theme for it in the future.</p>
<p>Check out some of <a href="http://wjbryant.com/projects/">my projects</a> or <a href="http://wjbryant.com/contact/">contact me</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://wjbryant.com/2010/10/21/website-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

