WordPress Editor Custom Buttons and Dialog Windows

When building a custom website on WordPress one goal is to ensure that it’s as easy as possible for the client to be able to create, update, and maintain their own content. Depending on the complexity of the site, or custom features that are added, there are times that the built-in editor doesn’t provide enough functionality. So, being able to add your own buttons or menus is critical. Thankfully, with the release of WordPress 3.9 which incorporated TinyMCE 4.0, customizing the WordPress editor is easier than ever. In this guide I’ll explain how to create custom buttons and dialog windows, packaged as a simple TinyMCE 4.x plugin, in order to customize the WordPress editor.

Getting Started

The first thing we need to do is add the necessary actions and filters to our WordPress plugin or theme to let it know that we’re wanting to customize the editor. The action we’ll be hooking into is “admin_head” and the filters are “mce_external_plugins”, and “mce_buttons”. Let’s go ahead and gets some code added.

The “admin_head” action hook is checking to see if the current admin screen being viewed represents a post type, whether it be “post”, “page”, or any other custom post type. Next it’s adding the necessary filter hooks needed in order to actually add the TinyMCE plugin and TinyMCE button. Next we’ll need to created the callback functions for each of the filters.

This callback function is pushing our TinyMCE plugin into the $plugin_array variable so that WordPress is aware of its existence. In this case I’ve named the plugin “my_mce_plugin”, but you’ll want to change this to match the naming of your own plugin. I’m also assuming your plugin is being added to your WordPress theme within a “js” folder, so if this is not the case you’ll need to make necessary edits.

This callback function is pushing the “my_mce_plugin” into the $buttons array so that WordPress knows to add our plugin to the list of buttons in the editor. Note that this specific filter hook will add the button to the top, primary toolbar, row. If you’d like to add your button to the second, advanced toolbar, row you will need to use the “mce_buttons_2” filter instead. There are filters for the third and fourth toolbar rows, however WordPress disables these toolbars by default so in many cases they will not be used.

Creating the TinyMCE Plugin

Now that all of the necessary WordPress action and filter hooks are in place the only thing left to do is actually create the TinyMCE plugin. First, we’ll add the framework for the plugin. Note that this will go into a new JavaScript file.

There are a couple of things to point out in the above code. First, what we’re doing is creating a plugin using the tinymce API and then registering it with the tinymce plugin manager. Next, within the plugin creation code, you can see that we’re adding a button to the editor. This button happens to be a menu (menubutton) with three menu items. Each menu item has an onclick event listener that then executes a tinymce command. The commands are registered just below the menu code. Right now the commands are simply inserting text into the WordPress editor as shortcodes. However, wouldn’t it be nice to allow your client to be able to visually select options for the shortcode and then have the corresponding shortcode text insert into the WordPress editor? This is where the TinyMCE Dialog box (windowManager) comes into play.

To illustrate this we’ll customize the “shortcode3” command to open a dialog box, allow for user input, and then output the shortcode text. To do this we will completely rewrite the shortcode3 command. For now, we’ll create two inputs within the dialog box. One will allow the client to enter a title shortcode attribute and the other will allow them to enter a limit shortcode attribute. Note that these attributes will not do anything, since the shortcode does not exist, but are used to illustrate how you could accomplish this and adapt it to your own project.

Going through the above code, line by line, the first thing we did was create a data object to store the default values that we’d like to use for title and limit. Next we tell the window manager to open a new window with the settings we’ve specified. Within the new window we specify a title, data, body, and onSubmit object properties. The body takes in an array of tinymce input objects. I’ve given an example of two different types, textbox and listbox, but more information about these can be found in the TinyMCE 4.x API documentation and by looking through the TinyMCE source. The onSubmit property takes a function and is called when the OK button is clicked on the dialog box. Lastly, we’re using the same command to actually insert the shortcode text, mceInsertContent.

There are other things that you can do with TinyMCE such as getting the current selected text and modifying it (similar to how you add a link in the WordPress editor) or use AJAX to pull information from WordPress to allow for dynamic user input, but those are things to be covered in a follow-up guide. At this point, you should have a fully functioning custom button in the WordPress editor that can easily be adapted to what ever project you may be working on.

As always, I hope this has been an insightful guide, but let me know if you have any questions or comments.

Update – March 30, 2016

The TinyMCE api documentation has been updated and doesn’t include as detailed of information as it previously did, so it may be useful to look through the TinyMCE source. Specifically, the UI Classes will be helpful if you’re wanting to use different TinyMCE widgets than what was used in this article.

Events Manager Custom Event Attributes and Conditionals

The Events Manager plugin for WordPress can be used to build a fantastic event and calendaring system, with countless features and expandability, but there are times that the built in event attributes just aren’t enough. Thankfully the plugin is very developer friendly and allows users to create custom event attributes directly in the dashboard. However, what if you need to display a custom event attribute if it’s used, and not display it if it’s not used? That’s where event attribute conditional placeholders come in, however if you’re wanting to use a conditional placeholder with custom event attributes you’ll have to create it yourself. That’s what we’ll cover in this article.

Creating Custom Event Attributes

First in order to use a custom conditional placeholder you’ll need to have custom event attributes, so let’s create those first. To do this simply login to your WordPress dashboard and go to Events > Settings > General (tab) > General Options and scroll down until you find the radio input for “Enable event attributes?” and be sure that is set to “Yes”. Next you will need to scroll down to the “Event Attributes” text area and add your own custom event attributes. Note that in order for the custom conditional placeholder to function properly the custom event attribute should have no spaces, such as “#_ATT{this_is_my_custom_event_attribute}”. Also note that the custom event attribute is strictly case sensitive so be sure the exact same name is used throughout. For the sake of this article I will be creating a custom event attribute called test, so it will be added using the code below.

Once you’ve finished adding your custom event attributes be sure to save changes.

Creating Custom Conditional Placeholders

Next, we’ll add the necessary code to process our custom conditional placeholders. To do this we’ll implement the use of a filter hook that is called by the Events Manager plugin. Note that the code for the conditional placeholders will be added to your theme’s functions.php file. Thankfully the code for creating custom conditional placeholder is fairly simple, so I’ll show the code that I’ve used for the “test” custom event attribute and then explain how it works, and what you need to change.

It’s as simple as that! Once the above code has been added to the functions.php file the “#_ATT{test}” custom event attribute and “{has_test}” custom conditional placeholder are ready to be used.

Explaining the above code, we’re making use of the “em_event_output_condition” filter that is called by the Events Manager plugin each time it encounters a conditional placeholder that doesn’t match one of the built-in conditional placeholders.

Here is a description of the passed attributes:

  • $replacement (string) will almost always be empty
  • $condition (string) will be the custom conditional placeholder name (such as, “has_test”)
  • $match (string) will contain the text from the beginning of the custom conditional placeholder to the end (such as, “{has_test} #_ATT{test} {/has_test}”)
  • $EM_Event (event object) will be the event object of the current event being viewed

Essentially what the above code does is check for the existence of our custom conditional placeholder, then checks to see if the custom event attribute exists and if it has a non-empty value. If those conditions are met, then the content within the custom conditional placeholder, inside $match, is returned. If those conditions are not met then an empty string is returned.

Due to the simplicity of this filter, in order to modify the above code to work with your custom conditional placeholders simply change the word “test” on lines 2 and 3 to be the name of your custom event attribute, such as “my_custom_event_attribute”.

There you have it! You’ve now created a custom event attribute and a corresponding custom conditional placeholder. You may be wondering, “what if I need to create multiple custom conditional placeholders?”, or “where do I use the custom conditional placeholder?”, and I’ll cover both of those questions in the final section.

Wrapping Everything Up

In the case that you’re needing to create multiple custom conditional placeholders you simply duplicate a portion of the filter code above.

This is the code that actually does the processing, and duplicating it (and placing it above or below the existing code) and then replacing the custom event attribute with your additional custom event attribute is all you need to do. The reason that this works is because the Events Manager will call this filter *each* time it encounters a conditional placeholder that doesn’t match the built-in conditional placeholders. Note that your duplicated code MUST come before the line noted below.

Lastly, in order for the custom event attribute and custom conditional placeholder to have any effect we need to add it to the front-end. The most common, and simple, way to do this is to login to your WordPress dashboard and then go to Events > Settings > Formatting (tab) > Events and scroll down to the  “Default single event format” text area. This is where you can add your custom event attribute and custom conditional placeholder code where ever you’d like it to display on the single event page.

What About no_attribute Conditionals

Update – September 26, 2014: As a follow up to  Koen’s question in the comments I’ve also added a snippet below that will allow you to use a conditional placeholder in the case that a custom attribute is not used.

This can simply be used in addition to your other conditions (has_attribute or no_attribute) within the “em_event_output_condition_filter” filter function.

Nesting Conditionals

Update – October 23, 2014: If you plan to nest conditionals within other conditionals (whether they’re custom or built-in) you will first need to enable this functionality. By default the Events Manager plugin will only look for the first level of conditionals, and unfortunately there is no option for enabling conditional recurrence within the Events Manager Settings within the dashboard. Instead you will need to add some additional code to your functions.php theme file. Once the below code has been added you will need to go to the Events Manager Settings and click save (no changes necessary) to fire the “em_options_save” action. I used this action since this is technically updating an Events Manager option and it prevents the update_option method from being called each page load.

 

The Events Manager plugin checks for the dbem_conditional_recursions option upon instantiation. If this option is set it will use its value, and if not then it will use the default value of one. So, the above code sets the option value to two thus overriding the default.  This will allow for one conditional to be nested within another, however you will need to adjust the above code if you plan nest conditionals at an even deeper level. Keep in mind high levels of recursion can negatively impact performance.

In Conclusion

Overall, the process of adding a custom event attribute and custom conditional placeholder is relatively simple and provides nearly infinite customizability to the Events Manager plugin. I hope this has been an easy to follow and informative guide on how to create custom event attributes. Be sure to post comments and let me know if you’ve ran into any problems or have any questions.

Fancybox Position Problem

When it comes to web design and development it’s always nice to be able to use well established libraries and frameworks to speed up development and deployment. JQuery is probably the best example of how a framework can be used to speed up development, and through its success many plugins have been built on top of it to provide custom functionality and features. One such plugin is fancyBox, by fancyApps, which allows for extremely simple implementation of lightbox modals for single images, image galleries, videos, or even entire web pages. Being able to add sleek functionality like this to a website with just a few lines of code is quite impressive… until it all falls apart.

The Problem

Using someone else’s library or framework is always subject to adhering to the confines and constraints needed for their code to work properly, but when things don’t work properly it can sometimes be difficult to determine what is causing the problem. I recently ran into a couple problems with the fancyBox plugin (while using it for an image gallery) that, though it didn’t break the functionality, completely broke the user experience. The first problem was that each time an image was viewed in the fancyBox modal and then closed the page would immediately be scrolled to the very top. The second problem was that the open and closing effect for opening the fancyBox modal (set to elastic) was zooming in and out of the center of the window rather than the location of the thumbnail that was clicked. As mentioned before, neither of these problems caused the plugin to fail entirely, but visitors would certainly be thrown off by the odd behavior.

The Solution

Initially I searched Google to see if I was alone or if others were experiencing the same problem. Though not much was found, it did appear that others were having similar problems, however none of them provided concrete ways to resolve the problems. One such solution to the “scrolling to the top” problem was to add a helper object to the settings for fancyBox initialization, which disabled locking scrolling. The resulting code is listed below.

By adding the overlay, locked: false, helper it prevented fancyBox from adding the overlay (and setting the body overflow value to hidden), and thus fixed the problem. However, this shouldn’t have ever been a problem in the first place, and it also allowed users to scroll while viewing a modal, so I decided this was unacceptable and set the locked value back to true.

Some quick debugging with the Chrome inspector revealed that both problems were being caused by CSS set in my sites main and reset files. Knowing that the problems were caused by CSS I began methodically removing blocks of CSS (in the Chrome inspector) until the problem went away. This allowed me to narrow down the offending code that was causing the problem and eventually fix the problem, properly.

Eventually what I found was that the first problem, where closing a modal scrolled to the top of the page, was caused by my CSS reset file. The reset had a line that was setting “html” and “body” to a height of 100%, and since this was unnecessary for my project I simply removed the line and the scrolling problem went away. I didn’t inspect further the exact reason this was a problem, but I believe it was related to the overlay being hidden/removed and the browser temporarily thinking the page was only as tall as the window height (since overflow hidden was set on the html), and thus it scrolled to the top.

With the first problem resolved I moved on to the next, repeating the same debugging steps as the first time, only this time the offending line was in my main stylesheet. I eventually found that the fancyBox thumbnails were nested inside divs that were displaying block, anchors that were displaying inline, and then images (the thumbnails) that were displaying block. The problem was the anchors displaying as inline and the thumbnail children displaying block. This was causing the anchor elements to receive a default width and height of zero and was apparently causing problems with jQuery getting their position. Setting the anchors to display as block fixed the problem.

Overall, these weren’t big problems and weren’t very difficult to debug, but seeing the limited posts about similar problems in Google I thought I would share my experience in hopes that I could save a little time for others who are running into the same problems.

WordPress Custom Post Type Pagination

Looking around the internet it’s easy to find several examples of how you can create WordPress custom post type pagination links using multiple different methods. The problem is many of them require overwriting or modifying the $wp_query global variable, which can break functionality with plugins, themes, or theme widgets. It’s almost always better practice to create an entirely new WP_Query instance and store it in your own custom variable.

Another added complication is that many methods also assume that the custom post type has the archive enabled, but what if it’s not? There are situations where you may want to create an entirely custom post archive using a page template and assigning that page template to a page. This allows the archive to be viewed using any path you desire (by setting it in the post editor) and more importantly it allows the archive page to be added to a WordPress menu using the normal page selector. However, page numbers are appended as sub nodes in the url, such as /news/page/2. Depending on your site map WordPress may not properly resolve the url and report that the page cannot be found. In most cases this is due to the custom archive page conflicting with the custom post type rewrite slug value. An example of this problem would be the custom archive page url being http://laubsterboy.com/news and the custom post type rewrite slug being ‘news’. In this example when the archive page 2 is viewed WordPress assumes you’re trying to view a news custom post type with a url / title of /news/page/2. Obviously this is not what you’re wanting. To fix this either the archive page url needs to be changed (possibly to something like /all-news), or the custom post type rewrite slug needs to be changed (possibly to something like ‘news-item’).

With the problem outlined lets look at some code.

Here is an example of creating a custom WP_Query object to display the custom post type archive.

The above code assumes that you’re using, or modifying, the WordPress Twenty Fourteen Theme. Next, we’ll need to modify the inc/template-tags.php file to allow the twentyfourteen_paging_nav function to accept the max_num_pages parameter.

The above code simply looks for the max_num_pages parameter and if it’s set then it will override the wp_query max_num_pages value.

At this point you should have a functioning custom post type archive page, with the custom post type has_archive set to false, that uses the WordPress reading settings to set how many posts to show per page.

I hope this has been helpful and let me know if you have any questions or suggestions for improvement.

Hangry Shark – An HTML5 Canvas Experiment

A couple months ago there seemed to be a handful of blogs posting about new HTML5 canvas games that they were creating, most spawning off of Flappy Birds’ popularity. The premise being that they wanted to challenge themselves to recreate a simple game using the modern web client stack (HTML5, CSS3, and JavaScript) instead of a specific mobile platform, such as iOS or Android. Having developed arcade style Flash game in the past, and being a web developer, I thought it was finally time that I put together my first HTML5 canvas game. As with many of my personal projects I refused to use any SDKs or libraries, but instead develop the entire project from the ground up.

After many hours of work, spread across a couple weeks, and completely rewriting the codebase a couple times I ended up with a simple game called Hangry Shark. The gameplay focuses on a shark looking for a meal that, with nothing else around except clownfish, must avoid touching the jelly fish. Being purely a personal project I decided to only develop and test the game on webkit powered web browsers. Initially the game was developed using DOM elements for all game sprites and user interface elements, which has its benefits, but due to significant performance limitations the codebase was rewritten to allow all game sprites to be drawn via HTML5 canvas. Doing so allowed the game to run smoothly on desktop devices at high resolutions and mobile devices, including mobile devices several years old such as the iPhone 4s. Using techniques such as only one update loop for all game logic and drawing, as well as requestAnimationFrame for the timing of the loop which also ensures the graphics adapter is used for drawing rather than the CPU, helped to increase performance.

Ultimately it was  a fun project, I learned a lot, and I hope to use it as a starting point for future projects. You can check out the game below, or click on the link to open it in a new window. Keep in mind, the game is technically a web-app that supports click and touch events, and uses iOS web-app constructs so it can be added to the home screen to behave as if it were a native app. Give it a try and let me know what you think!

Hangry Shark link

WordPress Richtext Editor for Excerpts

Occasionally when creating a WordPress theme the design relies on using the excerpt meta box, but forcing the end user to manually type html tags defeats the entire purpose of using WordPress (or any CMS for that matter) and adds a layer of unnecessary complexity to editing posts, pages, or any other post type. To make things simpler you can replace the Excerpt meta box with a rich-text editor, just like the main content editor. This can be done by installing an additional plugin, however with just a couple extra lines of code it can also be done through your theme.

Thats it! The above code can be placed in the functions.php file of your theme or placed in its own plugin file. Note that typically with custom meta boxes additional code must be added to save the meta box value when the post/page is published or updated, however since the meta box is replacing the excerpt WordPress automatically handles this process.

Running a Development Copy of WordPress Multisite – Part 2

I recently made a detailed post explaining how I created a production and development environment that share a database using WordPress in a Multisite configuration.

One thing that I felt was missing from the production environment was the ability to quickly jump from production to development while making changes to site content. With the new WordPress adminbar it’s already easy to jump back and forth between the post/page and the dashboard, but I wanted a way to view the current site or current page in the development environment. So, I created a plugin that adds a menu to the WordPress adminbar that lists links to the development environment for the “Current Site”, “Current Page” (if a page is being viewed), and links to the homepage for each site within the WordPress Multisite network.

Since I will not likely ever enter this into the WordPress plugin repository I will simply post the code here. All you need to do is copy the following code into a text editor and save it as a php file and upload it into your production site’s plugin directory. Note that this will only work if you have created a production and development environment in accordance with my guide.

 

Running a Development Copy of WordPress Multisite

The Problems with Multisite

I had recently been tasked with setting up production and development environments for WordPress Multisite with the intention of following traditional development methods. Having a dedicated development environment allows for testing themes, plugins, and updates without affecting the production environment. While researching best practices for creating production and development environments for WordPress I found frustratingly little examples or documentation covering WordPress in a Multisite configuration. Much of what I found was also dated to the point of being obsolete.

I came across a page in the WordPress Codex titled Running a Development Copy of WordPress (reading this article before proceeding will clarify what follows) which seemed to document the exact configuration that was needed. It made no mention of Multisite, however its merits were worth following. Proceeding with testing the concepts covered in the article I found that the “dev” site did indeed work, however only the main site would load properly, thus being an unusable solution for Multisite.

To clarify, the Multisite test environment that I was using was a sub-directory install using an IP address as the domain. So, at the time I thought moving the “dev” WordPress install from a sub-directory on the web server (being the production server, called WP-1 from now on) over to the web root of a clone of WP-1 (being the development server, called WP-2 from now on) would fix the problem, assuming the word “dev” in the url was causing the problem. Ultimately I planned to be using the WordPress MU Domain Mapping plugin, which requires WordPress to be in the web root so this step would eventually be required anyway.

Once WP-2 was setup (pointing to the same database used by WP-1) I quickly realized that regardless of which site was being viewed it always redirected back to WP-01, which is obviously not what is wanted.

The solution

After many hours of troubleshooting and testing I was finally able to get WP-2 to directly mirror WP-1, whether WP-1 used an A record or IP address as the primary domain. In short, here is what you need to do to setup a production and development environment that share the same database using WordPress Multisite.

Before proceeding, note that none of what is mentioned below is intended to be applied to already existing production/development environments and if attempted please backup your WordPress files and database right now!

What You’ll Need

  1. WP-1: A web server with WordPress 3.8 installed in the web root as a sub-directory Multisite setup, using either an IP address or an A record.
  2. WP-2: A clone of WP-1.
  3. DB: A MySQL server with the WordPress database and separate users for WP-1 and WP-2. The WP-1 user account should have full access to the WordPress database while the WP-2 user account should only have SELECT privileges so that WP-2 cannot “break” the production environment.

Next, be sure to update the wp-config.php file (in the WordPress root) on WP-2 to be sure it’s using the WP-2 MySQL user account. Also, note that the wp-config.php file on WP-2 should be identical to that on WP-1 with the exception of the MySQL user and the items listed below.

While editing the wp-config.php on WP-2, I recommend adding the following lines of code to make troubleshooting plugins and themes easier.

Within the wp-config.php file of both WP-1 and WP-2 add the following lines of code. These variables will allow the WP-1 or WP-2 domains to change and only need to change the domain names in one place. Note that the IP addresses are only examples and should be changed to match your own server environments, and the WP_PRODUCTION_DOMAIN should match DOMAIN_CURRENT_SITE.

Once that is done, install the WordPress MU Domain Mapping plugin on WP-1 and then copy the sunrise.php file (in the wp-content directory) and domain-mapping plugin files to WP-2.

Next, you’ll need to make some edits to the sunrise.php file on WP-2. This will remove the error stating that escape is deprecated, if WP_DEBUG is set to true.

Also, add the following code to the sunrise.php file, just before the closing php tag.

Since urls are stored in the WordPress database using absolute paths, if a site is viewed on WP-2 all hyperlinks will point to WP-1, so navigation would require manually typing in the url of a page wanting to be viewed. The above code essentially intercepts the WordPress option for siteurl and home, and post/page content, and changes it to match the domain of WP-2 which changes dynamically generated hyperlinks, such as the page title and menus, to point to the WP-2 server. In addition to changing link urls there are several attachment and upload filters to do the same thing, thus allowing us to upload images to the Production environment in the WordPress dashboard and the Development environment will point to the same location so attachments don’t need to be cloned. This allows for natural navigation of WP-2 in a web browser where all hyperlinks (and requests for external CSS and JavaScript files) will point to WP-2.

Now that most of the heavy lifting is done there are just a few things left to fix, mostly because WordPress is still redirecting all requests from WP-2 over to WP-1.

WARNING: The following code requires making some changes to the WordPress Core and the WordPress MU Domain Mapping files on WP-2, which may cause problems with plugins or themes, but most importantly these changes would need to be made each time WordPress is updated.

Comment out the following lines of code in the domain_mapping.php file inside the domain mapping plugin directory. This will prevent the domain mapping plugin from redirecting requests from WP-2 to WP-1.

Comment out the following lines of code in the ms-settings.php file inside the wp-includes directory. This will prevent WordPress from redirecting requests from WP-2 to WP-1.

Add the following lines of code to the ms-blogs.php file inside the wp-includes directory. The code will be placed within the scope of the get_blog_details function.

Instead of modifying the WordPress core files please read my follow up guide, which explains how to do this using a new filter brought in with WordPress 3.9.

Congratulations! At this point, provided nothing went wrong during the changes listed above, you should have a production environment using a database that is shared by the development environment, thus alleviating the need for migrating database tables as development stages progress. The idea is that new sites can be created in the production environment (with no CNAME pointing to it so it is not visible to the public) and then built in the production environment. Once the new site is ready for a soft launch the theme files can be copied to the production environment and a domain can be mapped to the site, thus making it visible to the public. The same concept can be applied to already existing sites that need updates to the theme, where changes can be made in the development environment (thus thankfully not visible to the public when you create a typo in the functions.php file and completely break the site) and once finished migrated to the production environment.

There are unfortunately a few drawbacks, such as not being able to make content changes in only the development environment (without duplicating it to a non public url), not being able to make changes to plugins that require scheme changes, and so on. However, themes can be completely developed and edited in the development environment and then migrated to the production environment by simply moving the theme files, completely avoiding database migrations and search/replace processes altogether. This type of setup isn’t for everyone, obviously, but for those who have large amount of users/editors/administrators who can make changes to posts, pages, calendars, and terms/categories, who are outside of the web development team, being able to avoid direct interaction with the database and being able to develop using “live” data is priceless!

Lastly, when it comes to testing plugin updates or WordPress updates my current thought is to clone WP-1 and the DB to another virtual server, and once vetted the updates will be installed on WP-1 and copied over to WP-2, so the drawbacks above are not much of a concern in my situation.

When it comes to WordPress there are certainly other ways of accomplishing the same thing and I’d be very excited to hear feedback from others, but for now this is a solution that will meet my needs and I hope will help others who are in the same situation I was.

Update – January 8, 2014

I’ve extended this post in a Part 2 where I shared a plugin that I created to add a “development sites” menu to the adminbar to allow easy switching between viewing the production environment and development environment.

Update – August 8, 2014

I’ve written a follow up guide, now that WordPress 3.9 has been released, explaining how to get the same functionality out of the Development environment without needing to modify WordPress core files.

Using JavaScript to Determine the Number of Days Between the Beginning of the Year and a Given Date

I recently came across the need to determine how many days fell between the beginning of the year and a given date. The most convenient way to do this is to add a new method to the Date object. Let’s get started!

Looking at the above code, line one allows us to add a new method to the Date object by adding a new function to its prototype. This will allow the getDOY method to be invoked on any Date object, such as myDateObject.getDOY(). The getDOY function name stands for “get day of year” and will return the day of year between 1 and 365. The way this works is by first creating a new Date object with the current year, January for the month, and 1 for the day. Next, the Date object (referenced by the keyword this) is equal to the amount of milliseconds since January 1, 1970 to present time, and subtracting the amount of milliseconds from January 1, 1970 to January 1 of the current year will leave you with the amount of milliseconds from the beginning of the year to the current date and time. The only thing left to be done is to convert the milliseconds to days, which can be done by dividing the number by 86,400,000 (1000 milliseconds  x  60 seconds  x  60 minutes  x  24 hours).

There you have it!

JavaScript Implicit and Explicit Context

Several years ago I was having a conversation with a friend about the future of the web and if it involved Abobe Flash or if it would eventually be replaced by HTML5 / JavaScript / CSS. The argument between the two went many different directions, however by the end of the conversation it was obvious that regardless of which remained dominant I really needed to learn more about HTML5, JavaScript, and CSS.

Coming from a background in Flash (ActionScript) the part that intrigued me most was JavaScript, specifically using it as a OOP language. I read several books, scoured the web for articles and tutorials, and quickly felt that I had a decent handle on how it was commonly used. As I continued to experiment with increasingly complex interface designs and coding techniques I ran into the same problem time and time again. The context of the keyword this was very inconsistent and at times not at all what I expected it to be. If you’ve ever used this in conjunction with an event listener or timeout callback function to reference a dynamically created variable or an object property then it’s quite likely that you too have had the pleasure of seeing how JavaScript handles implicit references. Let’s take a look at some code to see exactly what is going on.

In the below example we’ll create a simple list of collapsible paragraphs.

In the above example we’ve created the Collapsible class which contains references to the pairs of titles and content containers, and added a click event listener to each of the titles. The problem with the above example right now is that the keyword this within the scope of the titleClickListener function refers to the collapsibleTitle anchor element rather than the instance of the Collapsible object. The click event listener is working properly, except that the listener is only operating within the scope of the collapsibleTitle anchor element and thus it doesn’t have access to any of the Collapsible object properties or prototype functions.

One way to resolve this problem is to bring the click event listener function into the scope of the Collapsible class constructor and provide it with a reference to the scope of the Collapsible class.

Problem solved! Now when you click on any of the titles the corresponding content will collapse or expand. However, there are a few things left to be desired with this approach. First, the code is much more difficult to read and understand, mostly due to the self keywords and functions nested within functions. Second, the titleClickListener function is no longer a prototype of the Collapsible class but rather a property, so it is no longer shared by each Collapsible instance object which uses more memory and in larger projects would slow performance. Lastly, since the function is declared locally within the scope of the addEventListener call there is no way for it to be shared with other events if it were ever necessary.

Since the root problem is that the context of the keyword this is being implicitly set by JavaScript and changing within the scope of the titleClickListener, a better approach would be to explicitly set the context of the keyword this when calling titleClickListener. This would mean that the keyword this could reference the Collapsible instance object rather than the collapsibleTitle anchor element. Thankfully there are two methods for doing this within JavaScript, Call and Apply. Call accepts an argument list while Apply accepts an argument array.

So, let’s incorporate the Call method into our code to see just how this works. If we revert back to the first code example and replace line 25 with the code below, everything should be working properly.

One last adjustment that we could make is to add a delegate prototype function to the Collapsible class. This could be invoked each time the context of an object needs to be adjusted when calling a function.

Once the delegate function is added we can now make our last adjustment to the addEventListener call.

That’s it! The delegate call will return a function that will call this.titleClickListener with the context of this, which is referencing the Collapsible object.

Learning about and understanding these two methods have had a dramatic impact on what I’ve been capable of accomplishing with JavaScript, taking my skill to an entirely new level, and I genuinely hope that this post has helped you to learn something new or at least inspire you to do some research and studying of your own.