Web application R&D notes, from the world of Java, Flex, CSS, XHTML, Flash, .NET, cross-browser compatibility, JavaScript, AJAX, ADA compliance, Photoshop, and any and all things related to Web development!
22 November 2010
Switch to Office 2003 menus in Office 2007, 2010
This nifty program (free for personal use) enables Office 2003 menus in Office 2007 and 2010.
18 November 2010
17 November 2010
15 November 2010
Getting JW HTML5 Player to work on IE, Part II
In part 1, we talked about getting the player working on IE with the beta version of the JW HTML5 Player. Now that version 1.0 of the JW Player is out, let's revisit the issue of getting it working on various browsers, including IE.
First off, the full release has a different syntax for initialization of the player. This code demonstrates how to set up the player for all video tags on the page as well as for IE. Don't forget to include the jwplayer.js file on the page.
Note that in the version I was using, there was a bug in Firefox: FF doesn't like the console object being called when without the Firebug window being open. IE has the console object available by default. So if you set debug: "console", you might get errors on Firefox.
In addition, when creating your video tags, ensure that the MP4 source tag comes before OGV: Chrome chokes if you have OGV first, perhaps because it can play both video types via its HTML5 implementation. Also note the event handlers attached to the video player; these are called for the AnythingSlider to stop and start.
First off, the full release has a different syntax for initialization of the player. This code demonstrates how to set up the player for all video tags on the page as well as for IE. Don't forget to include the jwplayer.js file on the page.
$(document).ready(function(){You should try the above code without the if (jQuery.browser.msie){...} to see if it works for you on IE; it didn't for me so I've thrown that in. The code pulls the MP4/M4V video source and applies it to the main video tag as a src attribute. This took quite a bit of trial-and-error to discover.
$("video").each(function(){
if (jQuery.browser.msie){
var vidFile = "";
$(this).parent().find("source").each(function(){
if (jQuery(this).attr("src").indexOf("m4v") != -1 ||
jQuery(this).attr("src").indexOf("mp4") != -1){
vidFile = jQuery(this).attr("src"); //.substring(jQuery(this).attr("src").lastIndexOf("/")+1);
//alert("vidFile: " +vidFile);
}
$(this).remove();
});
$("[id="+$(this).attr("id")+"]").attr("src",vidFile);
}
jwplayer($(this).attr("id")).setup({
events: {
onPlay: function() {videoEventHandler(1)},
onComplete: function() {videoEventHandler(0)}
},
//debug: "console",
players:
[
{ type: "html5" },
{ type: "flash", src: "global/vid/player.swf" }
],
components: {
controlbar: {
position: 'bottom'
}
}
});
});
});
function videoEventHandler(type){
switch(type){
case 1:
stopSlider();
break;
case 0:
startSlider();
break;
default:
return;
}
}
Note that in the version I was using, there was a bug in Firefox: FF doesn't like the console object being called when without the Firebug window being open. IE has the console object available by default. So if you set debug: "console", you might get errors on Firefox.
In addition, when creating your video tags, ensure that the MP4 source tag comes before OGV: Chrome chokes if you have OGV first, perhaps because it can play both video types via its HTML5 implementation. Also note the event handlers attached to the video player; these are called for the AnythingSlider to stop and start.
09 November 2010
08 November 2010
04 November 2010
01 November 2010
28 October 2010
19 October 2010
14 October 2010
13 October 2010
"NTLDR is missing" error on Windows 7
I was running a dual-boot XP Pro/Windows 7 box, with Windows 7 running on a second SATA drive. Finally decided to move the drive inside and surplus the XP drive. I hooked up the new drive internally and booted up, only to see it throw this error:
Two issues were going on: I had another external hard drive that was set to "Active" in Disk Management. The second issue had to do with the missing XP drive; apparently, the dual-boot menu was stored on that system. Following the instructions on the Microsoft article, I ran the Bootrec.exe utility with each of the switches, each time testing using the /ScanOs switch. It kept showing that there were 0 Windows installations.
But I crossed my fingers and rebooted anyway. Lo and behold -- it worked! One or more of the switches fixed it. I booted into Windows, logged in, and Windows automatically downloaded and installed the latest drivers for my system -- including dual displays.
NTLDR is missing.No amount of rebooting helped. We tried using the Winternals boot disk to no avail. Finally did some research and found a forum thread that helped.
Press Ctrl+Alt+Del to restart.
Two issues were going on: I had another external hard drive that was set to "Active" in Disk Management. The second issue had to do with the missing XP drive; apparently, the dual-boot menu was stored on that system. Following the instructions on the Microsoft article, I ran the Bootrec.exe utility with each of the switches, each time testing using the /ScanOs switch. It kept showing that there were 0 Windows installations.
But I crossed my fingers and rebooted anyway. Lo and behold -- it worked! One or more of the switches fixed it. I booted into Windows, logged in, and Windows automatically downloaded and installed the latest drivers for my system -- including dual displays.
11 October 2010
08 October 2010
Java JDK installation on Windows
Installing Java on Windows for development can be one of the trickier things, especially if you're looking for Java 1.5 vs. 1.6: Java 1.5 is not readily available for download. However, some digging reveals this great site with a link to the download (which requires registration). From there, you can find the 32- and 64-bit versions of the Windows' installers.
07 October 2010
05 October 2010
04 October 2010
29 September 2010
28 September 2010
27 September 2010
24 September 2010
22 September 2010
21 September 2010
20 September 2010
17 September 2010
14 September 2010
13 September 2010
09 September 2010
Watch out Java, here comes JavaScript
http://www.infoworld.com/d/developer-world/watch-out-java-here-comes-javascript-799
The benefits of JavaScript as a server-side language are clear and striking. It allows Web application developers to implement their entire code base using a single syntax, reducing the clutter and confusion of typical Web apps. JavaScript's performance is increasing at a breakneck pace, which has built-in benefits for developers. Its event-driven programming model makes building parallel applications easy and logical. And JavaScript itself has matured into a fine language, with features that support both the object-oriented and functional programming styles.
08 September 2010
Get Virtual PC to see your localhost on Windows 7
I use Virtual PC to test on IE7 and need it to see the host machine's localhost (IP address). This is disabled by default via the Win 7 firewall. You can re-enable it by following these steps:
- On the host machine, open the Control Panel and choose the Windows Firewall.
- In the firewall, go to "Allow a program or feature through Windows Firewall."
- In the "Allowed programs and features" list, scroll down to "World Wide Web Services (HTTP) and check the box under "Domain."
- Click OK
05 September 2010
03 September 2010
02 September 2010
31 August 2010
Joomla: Read custom article parameters from a module
In implementing a web site on Joomla, I came across a common issue: I needed to pass additional parameters with an article into a 3rd-party module. In this case, the module was the Joomla AnythingSlider, a very slick and flexible content slider/carousel.
The initial task of creating the custom parameters wasn't so bad; the first thread in this post covers that. You add the parameter to the advanced section of the file administrator/components/com_content/models/article.xml:
UPDATE: A good quested was raised about one of the variables used in the above code: $paramdata. Where was it defined? Well, it's not in the above code, but in the AnythingSlider Joomla extension, mod_anythingslider; you can download it from here.
The mod_anythingslider has a helper.php file, which defines the class ModSlideShow:
The initial task of creating the custom parameters wasn't so bad; the first thread in this post covers that. You add the parameter to the advanced section of the file administrator/components/com_content/models/article.xml:
<param name="article_type" type="radio" default="default"However, reading the values in a module is a different story. Here's the syntax to fetch all the parameters from article.xml:
label="Article Type" description="article type">
<option value="default">Default</option>
<option value="picture">Picture (rotator)</option>
<option value="video">Video (rotator)</option>
</param>
$paramsdefs = JPATH_COMPONENT.DS.'models'.DS.'article.xml';And here's how a specific custom parameter is read (in this case, it's called article_type):
$myparams = new JParameter( $paramsdata, $paramsdefs );
echo "Article type: ". $myparams->get('article_type');This is thanks to another reply to the same post on the Joomla forums, but page 2.
UPDATE: A good quested was raised about one of the variables used in the above code: $paramdata. Where was it defined? Well, it's not in the above code, but in the AnythingSlider Joomla extension, mod_anythingslider; you can download it from here.
The mod_anythingslider has a helper.php file, which defines the class ModSlideShow:
<?phpThen in the mod_anythingslider.php, we define a few more variables:
/**
* AnythingSlider Helper Classes
*
* @package Joomla 1.5.0
* @subpackage Modules
* @Copyright Copyright (c)2010 Dnote Software
* @license GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
*
* mod_anythingslider is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Parts of this software are based on AnythingSlider By Chris Coyier: http://css-tricks.com
**/
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
class ModSlideShow
{
/**
* Returns a list of articles
*/
function getSlideshow(&$params, &$access)
{
global $mainframe;
$db =& JFactory::getDBO();
$user =& JFactory::getUser();
$aid = $user->get('aid', 0);
$catid = (int) $params->get('catid', 0);
$items = (int) $params->get('items', 0);
$contentConfig = &JComponentHelper::getParams( 'com_content' );
$noauth = !$contentConfig->get('show_noauth');
$date =& JFactory::getDate();
$now = $date->toMySQL();
$nullDate = $db->getNullDate();
// Ordering
switch ($params->get( 'ordering' ))
{
case 'o_asc':
$ordering = 'a.ordering';
break;
case 'o_dsc':
$ordering = 'a.ordering DESC';
break;
case 'm_dsc':
$ordering = 'a.modified DESC, a.created DESC';
break;
case 'c_dsc':
default:
$ordering = 'a.created DESC';
break;
}
// query to determine article count
$query = 'SELECT a.*,' .
' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,'.
' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug'.
' FROM #__content AS a' .
' INNER JOIN #__categories AS cc ON cc.id = a.catid' .
' INNER JOIN #__sections AS s ON s.id = a.sectionid' .
' WHERE a.state = 1 ' .
($noauth ? ' AND a.access <= ' .(int) $aid. ' AND cc.access <= ' .(int) $aid. ' AND s.access <= ' .(int) $aid : '').
' AND (a.publish_up = '.$db->Quote($nullDate).' OR a.publish_up <= '.$db->Quote($now).' ) ' .
' AND (a.publish_down = '.$db->Quote($nullDate).' OR a.publish_down >= '.$db->Quote($now).' )' .
' AND cc.id = '. (int) $catid .
' AND cc.section = s.id' .
' AND cc.published = 1' .
' AND s.published = 1' .
' ORDER BY '.$ordering ;
$db->setQuery($query, 0, $items);
$rows = $db->loadObjectList();
return $rows;
}
}
?>
$params->set('intro_only', 1);Now we bring it all together in the default.php, which generates the HTML for the slider:
$params->set('hide_author', 1);
$params->set('hide_createdate', 0);
$params->set('hide_modifydate', 1);
// Disable edit ability icon
$access = new stdClass();
$access->canEdit = 0;
$access->canEditOwn = 0;
$access->canPublish = 0;
// Other code here...
$slideShow = ModSlideShow::getSlideshow($params, $access);
/*Hope this helps those confused by the $paramdata variable.
Variables used throughout the main foreach loop.
Don't define these in the loop b/c they'll get
created for each article in the carousel.
*/
$paramsdefs = JPATH_COMPONENT.DS.'models'.DS.'article.xml';
$limitstart = JRequest::getVar('limitstart', 0, '', 'int');
$dispatcher =& JDispatcher::getInstance();
/*
Main foreach loop of the carousel component. Runs
once for each article in the slideshow.
*/
foreach ($slideShow as $item){
echo "<li>";
$aparams =& $item->parameters;
$params->merge($aparams);
$item->text = $item->introtext;
$results = $dispatcher->trigger('onPrepareContent', array (& $item, & $params, $limitstart));
$paramsdata = $item->attribs;
$myparams = new JParameter( $paramsdata, $paramsdefs );
$article_type = $myparams->get('article_type');
// More processing inside the foreach...
}
30 August 2010
27 August 2010
Multiple $(document).ready()
A page can contain multiple jQuery calls to the $(document).ready() function. This comes in handy if you're generating code at run-time or mixing static JavaScript with code generated via PHP or other server-side language. In addition, you can abbreviate the call to:
$(function() {
// do something on document ready
});
How to find element based on a string
Say you're looking for a string in the HTML and wish to get the parent element(s) that contains it. This Stackoverflow.com thread covers the technique, using a wildcard ("*") for all page elements. You can narrow it down by using a specific element type ("div" for example) instead of the wildcard.
26 August 2010
Add Quick Launch bar to Windows 7
The Quick Launch feature can be recreated in Windows 7, though why it's hidden is puzzling. This article provides step-by-step instructions on how to do this and even position it on the left, next to the start button.
24 August 2010
23 August 2010
22 August 2010
20 August 2010
W3C cheatsheet
A nice cheatsheet from the good people at W3C on developing for mobile, accessibility, i18n, and typography.
19 August 2010
Quick Tip: An Introduction to Sammy.js
This tutorial introduces the Sammy.js, a useful jQuery library for writing RESTful evented JavaScript applications.
18 August 2010
SpriteMe: Automated CSS sprite creation
CSS sprites (sometimes referred to as "sliding doors") provide a nifty way to minimize the number of images site visitors have to download. However, creating them can be tricky. The powerful SpriteMe tool comes to the rescue.
Just save this link as a bookmark then go to a page and launch the bookmark. Easy, right?
Just save this link as a bookmark then go to a page and launch the bookmark. Easy, right?
17 August 2010
Disappearing background image in the Web Developer plug-in for Firefox
One of the most powerful ways to view and edit the CSS of web sites on Firefox is the Web Developer extension. However, I recently noticed that when I selected Edit CSS from the extension's toolbar, the background images on the page disappeared.
Some research revealed a good thread on this issue. The problem had to do with the "../" notation in the stylesheet; changing these to be relative to the site root fixed the problem. For example, this:
Some research revealed a good thread on this issue. The problem had to do with the "../" notation in the stylesheet; changing these to be relative to the site root fixed the problem. For example, this:
background: transparentbecomes this:
url(../img/bg.png) no-repeat 0 0;
background: transparentThis is assuming that the background image is here:
url(/cms_prd/global/img/bg.png) no-repeat 0 0;
http://localhost/cms_prd/global/img/bg.png
13 August 2010
10 August 2010
09 August 2010
04 August 2010
03 August 2010
How to install Joomla on Windows
For development purposes, I needed Joomla installed on my Windows XP system. However, Joomla has some infrastructure requirements often not found on Windows boxes. Here are some steps on how to successfully install Joomla on your PC:
Additional resources on installing Joomla with XAMPP on Windows and other platforms can be found on the Joomla docs site.
- Download the XAMPP for Windows package. I downloaded the EXE and installed it at the root C: in the XAMPP folder.
- If you also have IIS running on your system, after the installation, change the default port used by Apache.
- The XAMPP installation will automatically ask you if you want to launch its control panel. If it's not already running, go to Start > XAMPP for Windows > XAMPP Control Panel.
- Click to start the Apache and MySql services (if they're not already running). When they successfully start, you'll see a green indicator saying "Running" next to each service. [Note: If the services take too long to start, it's more than likely because port 80 is being used by IIS; follow Step 2 above to change the Apache port to something else and try to start the services again.]
- Download the latest version of Joomla.
- Create a folder named joomla under C:\xampp\htdocs\
- Unzip the contents of the Joomla ZIP file into this new folder.
- Open your browser and navigate to http://localhost/ or, if you changed the Apache port, to http://localhost:xx/, where xx is the port number you assigned to Apache in Step 2.
- Click the phpMyAdmin link and go to "Privileges" on the MySQL database.
- Choose "Add a new User" and give it a name and password you can remember.
- Under "Global privileges" for this user, click "Check All" to grant all rights to this user.
- Click Go to create the user.
- Go to the Databases tab and create a database for Joomla (could be called joomla).
- Open your browser and navigate to http://localhost/joomla/ or, if you changed the Apache port, to http://localhost:xx/joomla/, where xx is the port number you assigned to Apache.
- Follow the wizard until you get to the database screen. Here, enter the information for the database and user you just created. For the host, use localhost. Important: Do not enter the port number after the host name, such as localhost:xx because this will not work and it won't generate an error; enter only the word localhost into the Host Name field.
- Upon successful completion, Joomla asks you to delete the installation folder. Go ahead and do that.
- To see the Joomla home page, reload http://localhost/joomla/ or, if you changed the Apache port, http://localhost:xx/joomla/, where xx is the port number you assigned to Apache.
Additional resources on installing Joomla with XAMPP on Windows and other platforms can be found on the Joomla docs site.
02 August 2010
Dive Into HTML5 Video With The Masters – Webinar Replay Video
Great webinar on HTML5 video tech from the folks on the cutting edge: http://www.reelseo.com/html5-video-webinar-replay/
30 July 2010
29 July 2010
Firefox Environment Backup Extension
Back up Firefox profiles on Mac, Windows, and Linux with this handy plugin.
28 July 2010
How to minimize MSN Messenger to the system tray in Windows 7
One of the greatest annoyances of Windows 7 is the inability to minimize MSN Messenger to the system tray. Here's a nifty trick to get it to do that.
UPDATE: Sorry for the dead link. It's now working.
UPDATE: Sorry for the dead link. It's now working.
21 July 2010
15 Gorgeous Flash Websites Created using Wix
http://creativefan.com/15-gorgeous-flash-websites-created-using-wix/
Wix is one of these companies that has developed an intuitive and user-friendly free website builder that allows even novice web users to create their own website with ease. Not only does Wix allow users to build a free website, they are also fantastic supporters of the design community, sponsoring many design blogs and companies around the globe.
20 July 2010
19 July 2010
18 July 2010
15 July 2010
14 July 2010
Opera and the OGG video - source location matters
I've recently been working on implementing HTML5 video on a new web site. The challenge I ran into yesterday was to get the OGG video to display on Opera 10.54. Using the following error handler, I found out what the problem was, but couldn't get any closer to a solution:
function failed(e) {Here's the video tag:
// video playback failed - show a message saying why
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
alert('You aborted the video playback.');
break;
case e.target.error.MEDIA_ERR_NETWORK:
alert('A network error caused the video download to fail part-way.');
break;
case e.target.error.MEDIA_ERR_DECODE:
alert('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.');
break;
case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
alert('The video could not be loaded, either because the server or network failed or because the format is not supported.');
break;
default:
alert('An unknown error occurred.');
break;
}
}
<video id="vid-2" width="372" height="209"The problem was the location of the OGG source tag; for Opera, the OGG video has to be the first if you have multiple source elements. Now Opera is happy as well as the other browsers.
poster="global/img/farmfresh.jpg" controls
onPlaying="stopSlider()" >
<source class="source" src="global/vid/farmfresh.ogg" type='application/ogg'
onError="failed(event)">
<source class="source" src="global/vid/farmfresh.mov">
<source class="source" src="global/vid/farmfresh.m4v" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<img src="global/img/farmfresh2.jpg" title="North Carolina Farm Fresh: Monday, April 29 at 9:30 PM"/>
</video>
13 July 2010
Summit: Mobile computing is education’s future
http://www.eschoolnews.com/2010/06/21/summit-mobile-computing-is-educations-future/
"Keynote speaker Peggy Johnson, executive vice president of Qualcomm Inc., pointed to a successful initiative in North Carolina, called Project K-Nect, that uses mobile phones to help teach algebra as an example of how mobile technology can empower learning.
"At-risk ninth graders taking part in the project have access to specially created mobile applications that help explain algebraic principles, and they also can watch videos of other students explaining these principles. In addition, they can text or IM their peers for advice when they get stuck.
"According to early studies of the program’s efficacy, students taking part in this Qualcomm-funded project outscored their peers who did not have access to the mobile phones and content by an average of 30 percent in algebra proficiency."
12 July 2010
Explaining JavaScript scope and closures
Closures are a critical part of JavaScript libraries; this tutorial explains scope and closures: http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/
Another great article on the same subject from the always impressive SmashingMagazine.com: http://www.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/
And more here: http://blog.morrisjohns.com/javascript_closures_for_dummies.html
Another great article on the same subject from the always impressive SmashingMagazine.com: http://www.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/
And more here: http://blog.morrisjohns.com/javascript_closures_for_dummies.html
Why SQL Server is better than any other RDBMS applications?
Pinal Dave has a question on his blog: "Why SQL Server is better than any other RDBMS applications?" Here's my two cents.
I learned RDBMS on SQL Server 2000 back in 2002; picked up a book and read it until the pages came out. It was an easy-to-use, developer-friendly relational database, which tied nicely to classic ASP. I wrote tons of stored procedures from the start, and avoided using ad hoc queries — and never had any security issues.
For a university’s online directory that needed quick response and tons of features, I wrote the entire search engine in a SQL Server stored procedure, with additional user-defined functions. At the time, the school’s data was in flat files stored on OpenVMS. I used a nightly DTS to pull the data and ran cleanup procedures to store it on SQL Server. All of this with great ease. And lets not forget: There’s not an equivalent of DTS/SSIS on Oracle. Going back to SQL Server 2000, this has been a powerful feature of the database, making developers’ lives easier.
For the same directory project, I needed to provide users with the option to leave multiple fields blank and allow searches on any combination of values they provided. The handy “coalesce” function made this a snap. I posted to SQL Server forums and got great help on how to accomplish this. The final SELECT statement looks beastly, but it’s quick and efficient. This was long before Oracle supported the “coalesce” function.
Also, I constantly used the IF EXISTS (SELECT *…) in my stored procedures and user-defined functions. Believe it or not, Oracle still doesn’t have a direct equivalent of this easy feature. If you wanted to insert a row but wanted to check that it didn’t already exist, you’d simply do an IF EXISTS. Easy and intuitive. This is much harder in Oracle.
In addition, the ease of using stored procedures with web apps makes SQL Server a web developer’s best friend. It took us over 2 weeks to get Oracle working with ASP.NET; SQL Server worked with it like a breeze. And the syntax was easy too. If you’ve connected Oracle stored procedures to ASP.NET apps, it’s not a trivial task. We had to install a 200Mb data provider to talk to Oracle. Not my idea of easy.
Moreover, SQL Server installs and runs smoothly with the Visual Studio development suite. SQL Server comes with the Management Studio tool built-in; you often buy extra utilities to get the same functionality out of other RDBMS.
With Oracle, you have to set up TNS files and ensure they have the correct settings on development and production. With SQL Server, you don’t have to worry about any of this.
Reporting tools? Built into SQL Server. As far back as 2002, you could purchase an inexpensive ($5, if I remember correctly) add-on from Microsoft to enable reporting capabilities. Today, the SSRS tool is robust, easy to use, and also developer-friendly. For years I was trying to convince my boss to go with SSRS; she finally went to a conference and saw how powerful it was and she was sold. Instead of a third-party tool that kept crashing daily, the university went with a product that users, admins, and developers love.
I learned RDBMS on SQL Server 2000 back in 2002; picked up a book and read it until the pages came out. It was an easy-to-use, developer-friendly relational database, which tied nicely to classic ASP. I wrote tons of stored procedures from the start, and avoided using ad hoc queries — and never had any security issues.
For a university’s online directory that needed quick response and tons of features, I wrote the entire search engine in a SQL Server stored procedure, with additional user-defined functions. At the time, the school’s data was in flat files stored on OpenVMS. I used a nightly DTS to pull the data and ran cleanup procedures to store it on SQL Server. All of this with great ease. And lets not forget: There’s not an equivalent of DTS/SSIS on Oracle. Going back to SQL Server 2000, this has been a powerful feature of the database, making developers’ lives easier.
For the same directory project, I needed to provide users with the option to leave multiple fields blank and allow searches on any combination of values they provided. The handy “coalesce” function made this a snap. I posted to SQL Server forums and got great help on how to accomplish this. The final SELECT statement looks beastly, but it’s quick and efficient. This was long before Oracle supported the “coalesce” function.
Also, I constantly used the IF EXISTS (SELECT *…) in my stored procedures and user-defined functions. Believe it or not, Oracle still doesn’t have a direct equivalent of this easy feature. If you wanted to insert a row but wanted to check that it didn’t already exist, you’d simply do an IF EXISTS. Easy and intuitive. This is much harder in Oracle.
In addition, the ease of using stored procedures with web apps makes SQL Server a web developer’s best friend. It took us over 2 weeks to get Oracle working with ASP.NET; SQL Server worked with it like a breeze. And the syntax was easy too. If you’ve connected Oracle stored procedures to ASP.NET apps, it’s not a trivial task. We had to install a 200Mb data provider to talk to Oracle. Not my idea of easy.
Moreover, SQL Server installs and runs smoothly with the Visual Studio development suite. SQL Server comes with the Management Studio tool built-in; you often buy extra utilities to get the same functionality out of other RDBMS.
With Oracle, you have to set up TNS files and ensure they have the correct settings on development and production. With SQL Server, you don’t have to worry about any of this.
Reporting tools? Built into SQL Server. As far back as 2002, you could purchase an inexpensive ($5, if I remember correctly) add-on from Microsoft to enable reporting capabilities. Today, the SSRS tool is robust, easy to use, and also developer-friendly. For years I was trying to convince my boss to go with SSRS; she finally went to a conference and saw how powerful it was and she was sold. Instead of a third-party tool that kept crashing daily, the university went with a product that users, admins, and developers love.
11 July 2010
Web Safe Area - PSDs for designers
These PSDs are designed for different optimal web resolutions and browsers: http://www.designerstoolbox.com/designresources/safearea/
This online tool can give you an idea of different browser window resolutions: http://browsersize.googlelabs.com/
This online tool can give you an idea of different browser window resolutions: http://browsersize.googlelabs.com/
10 July 2010
The 9 best (and free) cross-browser testing tools
One common problem for web developers is how to test their sites with the different versions of browsers and platforms. Because IE is often the most troublesome, I start with those:
- Internet Explorer Application Compatibility VPC Image: Virtual PC VHD files with the browser preinstalled. A Windows-centric solution, but provides the most comprehensive testing solution. To use, you'll need the free Virtual PC app; then create a new VMC and point it to one of the downloaded VHD files above.
- MultipleIE: Another Windows-only tool, which provides a way for IE3 IE4.01 IE5 IE5.5 and IE6 to run on the same box. I've had some limited success with this; the browsers can be very temperamental (that is, they can crash without notice).
- Spoon Browser Sandbox: Run different versions of browsers from the web without having to install them on your machine. Though I've not yet used Spoon, it holds great promise.
- Adobe BrowserLab: Upload your pages securely to this Flex app and view snapshots of what they look like on different browsers. This tool is built into Dreamweaver CS5 and holds great potential for easing the testing process.
- BrowserShots.org: Free and comprehensive alternative to BrowserCam, generates screenshots of your design in an incredible list of browsers and platforms. Because the tool is free, a lot of developers use it. For best results, limit your testing to just a few browsers; this speeds up the results.
- IETester: Free browser for testing pages against IE 5.5 - 9. It's relatively new but holds promise.
- NetRenderer: Choose IE version and enter a URL -- it's that simple.
- iPhoney: Free tool for testing designs on the iPhone.
- iPad Seek: Online tool to test your designs on the iPad in a similar fashion to iPhoney.
08 July 2010
Getting JW HTML5 Player to work on IE
In my continuing adventures with HTML5 video, I arrived at IE testing, and noticed that IE does not like the JW HTML5 Player (mainly because it's in beta right now). But I have to demo my site and can't wait until Version 1.0 of the player; so, I rolled up my sleeves for another non-trivial challenge.
The problem is that the current versions of IE can't display the HTML5 video tag; IE 9 will address this, but we'll be living with lower versions for some years. And the beta JW HTML5 Player doesn't remove the video tag completely from IE. The answer is to do some jQuery coding to find the video tags and replace them with swfobject elements. There are plenty of gotchas along the way as to file paths and filenames.
Here's the finished code:
In addition, you'll need to add the following to the page to prevent IE from throwing an error:
UPDATE: Please see part 2 of this post for how to get the release version of the player working on IE and other browsers.
The problem is that the current versions of IE can't display the HTML5 video tag; IE 9 will address this, but we'll be living with lower versions for some years. And the beta JW HTML5 Player doesn't remove the video tag completely from IE. The answer is to do some jQuery coding to find the video tags and replace them with swfobject elements. There are plenty of gotchas along the way as to file paths and filenames.
Here's the finished code:
<script type="text/javascript"One gotcha with swfobject: You need to ensure the path of the 'file' that you wish to play is relative to the player.swf or you'll get an error saying 'Can't find file or access denied.' This thread talks about the issue.
src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
// If this is IE...
if (jQuery.browser.msie){
var el = "";
var vidFileName = "";
var posterPath = "";
var videoTag = "";
var boxId = "";
var so = "";
var flashId = "";
var flashVars = "";
var params = "";
var attributes = "";
var anchorId = "";
// For each video element...
$("[id^='vid-']").each(function(){
// Clear out the variables.
el = "";
vidFileName = "";
posterPath = "";
videoTag = "";
flashId = "";
flashVars = "";
params = "";
attributes = "";
anchorId = "";
// Get a handle to the current object.
el = $(this);
// Set some variables we'll shortly.
boxId = this.id + "_flashBox";
flashId = this.id + "_flashPlayer";
anchorId = this.id + "_anchor";
/*
Set the ID of the first DIV element of the current
object's parent's parent. This will allow us to
reference that DIV later.
*/
el.parent().parent().find("div:first").attr("id",boxId);
/*
Loop over each 'source' tag inside the video; check
the 'source' tag's 'src' attribute. If it contains
'm4v' or 'mp4', then it's usable for the Flash
player in IE.
*/
el.parent().children("source").each(function(){
if ($(this).attr("src").indexOf("m4v") != -1 ||
$(this).attr("src").indexOf("mp4") != -1){
/*
We don't need the filename + path of the video,
only the filename. So we remove the path and
fetch only the filename.
*/
vidFileName = $(this).attr("src").substring($(this).attr("src").lastIndexOf("/")+1);
}
});
// Get the poster's filename and path.
posterPath = el.parent().find("img").attr("src");
// Get a reference to the video's containing DIV.
el = $("[id="+boxId+"]");
// Empty the DIV of all contents.
el.empty();
/*
Append an anchor tag with the anchor ID to the DIV.
We'll replace this anchor tag with the Flash player.
*/
el.append("<a id='" + anchorId + "'></a>");
// Set flashvars, params, and attributes.
flashvars =
{
file: vidFileName,
autostart: 'false',
image: posterPath
};
params =
{
allowfullscreen: 'true',
allowscriptaccess: 'always',
wmode: 'opaque'
};
attributes =
{
id: flashId,
name: flashId
};
/*
Embed the Flash player object using the swfobject.
The embedSWF() method replaces the anchorId element
with the Flash player. For more information on the
various arguments, please see the documentation here:
http://code.google.com/p/swfobject/wiki/documentation
*/
swfobject.embedSWF('global/vid/player.swf', anchorId, '372',
'209', '9.0.124', false, flashvars, params, attributes);
});
}
});
</script>
In addition, you'll need to add the following to the page to prevent IE from throwing an error:
if (!jQuery.browser.msie){This ensures that the JW HTML5 Player is fired off only on non-IE browsers. My previous post on HTML5 video and the JW Player has links to all my other posts on the subject.
$('video').jwplayer({
flashplayer:'global/js/jwplayer/player.swf',
skin:'global/js/jwplayer/five/five.xml'
});
}
UPDATE: Please see part 2 of this post for how to get the release version of the player working on IE and other browsers.
06 July 2010
04 July 2010
03 July 2010
01 July 2010
YouTube backs Adobe Flash over HTML5
http://www.infoworld.com/d/developer-world/youtube-backs-adobe-flash-over-html5-849
"While HTML5's video support enables us to bring most of the content and features of YouTube to computers and other devices that don't support Flash Player, it does not yet meet all of our needs," said YouTube software engineer John Harding in the post. "Today, Adobe Flash provides the best platform for YouTube's video distribution requirements."
Automatically put HTML5 videos in Fancybox
Here's a tricky one: Safari 5 and the iPad have issues with HTML5 video tags if those objects move. They show "black holes" on the screen, especially inside content rotators. Solution? Do a "popup" (via Lightbox, Fancybox, etc.) to handle the video, while leaving the video as is on the other browsers.
Adding to the complexity of the problem is the fact that Safari strips off the poster attribute from the video tag; not sure why. So I ended up using an img inside the video tag; we'll see the reason below. Here's the video tag as it appears in the HTML; the closing source tags are to prevent IE from throwing an error:
I've documented additional adventures and solutions with the content rotator and HTML5 video in these posts:
Adding to the complexity of the problem is the fact that Safari strips off the poster attribute from the video tag; not sure why. So I ended up using an img inside the video tag; we'll see the reason below. Here's the video tag as it appears in the HTML; the closing source tags are to prevent IE from throwing an error:
<video id="vid-1" width="372" height="209"To get Safari/iPad to pop these up in a Fancybox, we follow these steps:
poster="global/vid/historydetectives-poster.jpg" controls onPlaying="stopSlider()">
<source src="global/vid/historydetectives.mov"></source>
<source src="global/vid/historydetectives.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'></source>
<source src="global/vid/historydetectives2.ogg" type='application/ogg'></source>
<img src="global/vid/historydetectives-poster.jpg" />
</video>
- Loop over all the video tags on the page. In this case, their IDs all start with "vid-".
- Get each video's HTML; for this we have to get the parent element.
- Get the img tag's src attribute (Safari stripped out the poster attribute on the video tag).
- Generate some HTML for a linked image, with its src set to the img tag above.
- Ensure the link has a unique ID.
- Replace the video tag with the generated HTML.
- Instantiate a Fancybox for the video and set its content to the video's HTML.
$(window).load(function () {One other caveat: We can't call the following in the each function:
if (jQuery.browser.safari) {
var videoTag = "";
var posterPath = "";
var replacement = "";
var boxId = "";
var el = "";
/* Fetch all the video tags with ID
starting with 'vid-'.
*/
$("[id^='vid-']").each(function(){
// Extra precaution: reset variables.
videoTag = "";
posterPath = "";
replacement = "";
boxId = "";
el = "";
// Get a reference to this element.
el = $('[id='+this.id+']');
/*
To get the enclosing video tag,
fetch the parent's HTML.
*/
videoTag = el.parent().html();
/*
Get the path to the video's poster image.
Safari strips off the poster attribute, so
we use an image within the video tag to hold
the image path.
*/
posterPath = el.parent().find("img").attr("src");
/*
We're manually instantiating and setting
properties on a Fancybox, so we add "_manual"
to the ID.
*/
boxId = this.id + "_manual";
/*
Concatenate some HTML: We'll create an image tag
with its source set to the image tag inside the video.
Wrap it in an anchor tag and set its ID to what we
created above so we can attach it to the Fancybox.
*/
replacement = "<a title='' id='" + boxId +
"' href='javascript:;'><img src='" +
posterPath + "' style='float:left; padding-left:5px; '/></a>";
/*
Replace the video element with the concatenated HTML
we just created.
*/
el.parent().replaceWith(replacement);
/*
Instantiate a Fancybox and attach it to the
linked image. Set its 'content' to the video
tag's HTML.
*/
$("[id="+boxId+"]").fancybox(
{
'content' : videoTag,
'autoDimensions' :true,
'padding' : 9,
'showCloseButton' : true,
'enableEscapeButton': true
}
); // end click function
}); // end each function
} // end if
else {
/*
This next line is needed only if we use an HTML5 video
player library (such as JW HTML5 Player from LongTail
Video). These libraries often include their own controls
and if we don't remove the 'controls' attribute from
the video tag, the other HTML5-ready browsers produce
"double" controls. We're including the 'controls'
attribute on the video tag for the iPad to be happy;
without that attribute, the video pops up with a black
screen on Fancybox. So we strip it from the video tag.
*/
$("[id^='vid-']").each(function(){
$('[id='+this.id+']').removeAttr("controls");
});
} // end else
} // end load function
$("[id="+boxId+"]").click(function()The reason? We need to instantiate a Fancybox for each of the videos.
{
$.fancybox( ....
I've documented additional adventures and solutions with the content rotator and HTML5 video in these posts:
30 June 2010
27 June 2010
26 June 2010
25 June 2010
A GPU-Powered HTML5 Flickr Photo Viewer
http://blogs.msdn.com/b/ie/archive/2010/06/03/a-gpu-powered-html5-flickr-photo-viewer.aspx
Flickr Explorer is written using standard HTML, CSS and JavaScript. It uses AJAX to asynchronously search Flickr based on your search terms and display image results through an interactive and visually compelling experience. You can zoom in, pan around, and open each photo’s Flickr page with by control+clicking.
WebGL - OpenGL ES 2.0 for the Web
http://www.khronos.org/webgl/
WebGL is a cross-platform, royalty-free web standard for a low-level 3D graphics API based on OpenGL ES 2.0, exposed through the HTML5 Canvas element as Document Object Model interfaces.
24 June 2010
23 June 2010
22 June 2010
.NET: String.IsNullOrWhiteSpace Method
http://msdn.microsoft.com/en-us/library/system.string.isnullorwhitespace%28VS.100%29.aspx
Indicates whether a specified string is Nothing, empty, or consists only of white-space characters.Handy little static method added in .NET 4.0, used in this way:
using System;
public class Example
{
public static void Main()
{
string[] values = { null, String.Empty, "ABCDE",
new String(' ', 20), " \t ",
new String('\u2000', 10) };
foreach (string value in values)
Console.WriteLine(String.IsNullOrWhiteSpace(value));
}
}
// The example displays the following output:
// True
// True
// False
// True
// True
// True
Open Source JavaScript Slider Component
A very cool slider component that is mobile-aware: http://www.webappers.com/2010/06/15/open-source-javascript-slider-component/
Solution for AnythingSlider and duplicate IDs
If you ever use the JW Player inside the AnythingSlider, and you place a video in the last panel of your UL list, you'll run into a pesky and non-trivial headache: The AnythingSlider automatically duplicates the last "panel" -- so it duplicates the video tag. This code fixes it by looking for the duplicate ID of my video tag (all my video tags start with "vid-") and renaming the ID to something random:
$(window).load(function () {All the browsers that will need to use the Flash fallback player will now work correctly. Of course, you'd need to change the "vid-" to the start of whatever ID you've given your video tag. This issue may also manifest itself in other situations where duplicate IDs are not desirable.
$('[id]').each(function(){
var ids = $('[id='+this.id+']');
if(ids.length>1 && ids[0]==this){
if (this.id.indexOf("vid-") != -1){
this.id = this.id + "_" + Math.floor(Math.random()*11);
console.warn('Multiple ID #'+this.id);
}
}
});
});
HTML5 Canvas tag JavaScript library
http://processingjs.org/
Processing.js is an open programming language for people who want to program images, animation, and interactions for the web without using Flash or Java applets. Processing.js uses Javascript to draw shapes and manipulate images on the HTML5 Canvas element. The code is light-weight, simple to learn and makes an ideal tool for visualizing data, creating user-interfaces and developing web-based games.
21 June 2010
How to stop AnythingSlider from code
I covered this as part of a post on HTML5 video, but wanted to give it its own article here because a lot of folks have run into the issue: How do you stop the AnythingSlider by using JavaScript? The answer isn't as intuitive as it should be.
A somewhat related question on StackOverflow.com provided a part of the answer:
A somewhat related question on StackOverflow.com provided a part of the answer:
$("div.anythingSlider a#start-stop").trigger("click");However, that solution toggles the current state of the "start-stop" by triggering the click action. Here's a complete solution. Assuming that the startText has been set to "Go", this function will stop the AnythingSlider:
function stopSlider(){The code triggers the "click" on the "start-stop" element, checking after each click to see if the HTML of the element contains the word "Go"; if it does, it break out of the loop. Of course, you'll have to modify it if you're using text other than "Go" on the "start-stop" anchor tag.
// This is a way to "cache" the element and not have
// to fetch it again and again.
var el = $("div.anythingSlider a#start-stop");
// Loop while triggering the click action on the element.
while (1 == 1){
el.trigger("click");
// If the HTML of the element contains "Go", then
// it's stopped and we can break out of the loop.
if (el.html().indexOf("Go") != -1) break;
}
}
20 June 2010
19 June 2010
18 June 2010
Event handler for HTML5 video
I'm using the HTML5 video tag inside the AnythingSlider. An interesting problem arose: How do you stop the AnythingSlider when the user starts playing the video? You don't want the slider to keep going in this situation.
Well, here's a solution. The HTML5 video events are described in the "4.8.9.12 Event summary" section of the W3C document. At first, you'd guess that you'd use the onPlay event handler. Nope. That only works when you play the video the first time; on the second play, it won't call the function. The event handler to use is onPlaying.
But how do you stop the AnythingSlider programmatically? The good folks on StackOverflow.com provided the answer.
So here's the video tag:
Well, here's a solution. The HTML5 video events are described in the "4.8.9.12 Event summary" section of the W3C document. At first, you'd guess that you'd use the onPlay event handler. Nope. That only works when you play the video the first time; on the second play, it won't call the function. The event handler to use is onPlaying.
But how do you stop the AnythingSlider programmatically? The good folks on StackOverflow.com provided the answer.
So here's the video tag:
<video controls preload onPlaying="stopSlider()">And here's the function to stop the AnythingSlider:
....
</video>
function stopSlider(){Note what appears to be an infinite while loop: Actually, the code is designed to stop the AnythingSlider. It triggers the "click" on the "start-stop" element, checking after each click to see if the HTML of the element contains the word "Go"; if it does, it break out of the loop. Of course, you'll have to modify it if you're using text other than "Go" on the "start-stop" anchor tag.
while (1 == 1){
$("div.anythingSlider a#start-stop").trigger("click");
if ($("div.anythingSlider a#start-stop").html().indexOf("Go") != -1)
break;
}
}
15 June 2010
OGV/OGG and the HTML5 player in Firefox
I tried playing an OGV video on Firefox using the new HTML5 video tag; the video played fine in the latest versions of Opera, Chrome, and Safari. But Firefox 3.6.3 would only show a big "X" -- no errors, nothing.
Some research revealed the answer: The video is being served as application/octet-stream. The other browsers can detect the type from the extension; Firefox, following good standards, is checking the mime type. The same issue existed on my localhost, with IIS running.
Solution is to add the OGV/OGG mime type to the server; different servers have different ways of doing this. For IIS, it's pretty simple. Follow the linked article, and simply replace the "Extension" with .ogg and the "MIME type" with application/ogg and restart IIS. Additional information on Firefox and mime type configuration can be found here. I recommend the OGG file extension and application/ogg mime type because they're included on Apache servers by default -- so no need to update configuration files and restart your production server.
But there's more to it. The type attribute on the source has to be shorter (this is a known Firefox bug). In addition, the OGG file has to be encoded correctly for it to work in all the browsers supporting the HTML5 video tag. The best encoding tool I've found thus far is FireFogg. It created the OGV that works like a charm on all the appropriate browsers (I just renamed the extension to OGG).
One last gotcha: IE doesn't like the source tag not being closed and will throw JavaScript errors; the other browsers don't care. So simply add a closing tag to the source tag and IE is happy. Now, why use a video tag in IE, when IE doesn't support that yet? Simple: The html5media library automatically replaces the video tag in unsupported browsers, such as IE, with the Flowplayer Flash player.
The final result is this; note the closing source tags; also, the MP4 source has to come first for it to work correctly on the iPhone/iPad:
Some research revealed the answer: The video is being served as application/octet-stream. The other browsers can detect the type from the extension; Firefox, following good standards, is checking the mime type. The same issue existed on my localhost, with IIS running.
Solution is to add the OGV/OGG mime type to the server; different servers have different ways of doing this. For IIS, it's pretty simple. Follow the linked article, and simply replace the "Extension" with .ogg and the "MIME type" with application/ogg and restart IIS. Additional information on Firefox and mime type configuration can be found here. I recommend the OGG file extension and application/ogg mime type because they're included on Apache servers by default -- so no need to update configuration files and restart your production server.
But there's more to it. The type attribute on the source has to be shorter (this is a known Firefox bug). In addition, the OGG file has to be encoded correctly for it to work in all the browsers supporting the HTML5 video tag. The best encoding tool I've found thus far is FireFogg. It created the OGV that works like a charm on all the appropriate browsers (I just renamed the extension to OGG).
One last gotcha: IE doesn't like the source tag not being closed and will throw JavaScript errors; the other browsers don't care. So simply add a closing tag to the source tag and IE is happy. Now, why use a video tag in IE, when IE doesn't support that yet? Simple: The html5media library automatically replaces the video tag in unsupported browsers, such as IE, with the Flowplayer Flash player.
The final result is this; note the closing source tags; also, the MP4 source has to come first for it to work correctly on the iPhone/iPad:
<video id="vid" width="372" height="209" poster="global/vid/historydetectives-poster.jpg" controls preload>
<source src="global/vid/historydetectives.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'></source>
<source src="global/vid/historydetectives.ogg" type='application/ogg'> </source>
</video>
12 June 2010
Resurrecting User Interface Prototypes (Without Creating Zombies)
http://www.smashingmagazine.com/2010/05/17/resurrecting-user-interface-prototypes-without-creating-zombies/
11 June 2010
10 June 2010
07 June 2010
04 June 2010
Subscribe to:
Posts (Atom)