March 25, 2008

Implementing IE min-width with Javascript

min-width works in Firefox and Safari, and even IE 7, but not IE 6 -- big surprise. However, we can fake it fairly well. With a little jQuery fun, we can read the min-width value, and then implement it using javascript fairly nicely.

First off, we know we have to attach this to the resize of the browser. IE seems to execute the resize event many, many times during an actual window resize1 -- almost as if it were trying to execute it once every pixel resized (just a guess).

Enter the wresize jQuery plugin. This plugin tries to catch when the resize starts, and more importantly, when it finishes, and then executes a function. The one downside to this plugin is that we cant execute a function that requires us to pass any variables to it. Luckily, we don't need to for this.

Here are the things we need to do:

  1. Get the min-width value; if it's not set then we'll default to 760px.
  2. jQuery will give us the value text, so it will return "960px" or the like. We need to strip out the text to convert it from a string to a number.
  3. Then, we need to calculate what size the browser window should be before we invoke the min-width.
  4. Then, we wait. Wait for the browser to be just the right size.
  5. Set the min-width on the first div inside the body element.
  6. Un-set the min-width when the browser window widens.

Simple, right? Here's the actual min-width function:


function minwidth() {
  if ( (jQuery.browser.msie) && (jQuery.browser.version==6) ) {
    var cssprop = jQuery("body div").css("min-width");
    if ( cssprop == null ) {
      cssprop = 760; //No min-width; default to min-width of 760
    } else {
      cssprop = parseInt(cssprop); //Convert value to numeric;
    };
    
    //get document margin to figure browser width to look for
    var margin = parseInt( jQuery("body").css("margin-left") ) + parseInt( jQuery("body").css("margin-right") );

    //21px is the width of the scroll bar.
    if (clientwidth() < (cssprop + margin + 21)) {
      jQuery(document.body).width(cssprop); //Set fixed-width
    } else {
      jQuery(document.body).width("auto"); //Un-set fixed-width
    };
  };
};

Now that's just the function; we haven't used it yet. We need to execute this function on page load, and use the wresize plugin to execute the same function on resize. Luckily, that's simple too.


$(document).ready(function(){
  minwidth(); //call IE minwidth on page load
  $( window ).wresize( minwidth ); //IE Resize event - resize for min-width
});

We didn't cover the clientwidth() function -- that's how we're getting the browser's window size. Check out the example page for the final result.

1http://snook.ca/archives/javascript/ie6_fires_onresize/

Google Reader-like Interface Bug Resolved

Well I know everyone was on the edge of their seats, however, all can relax: the bug has been fixed.

All I did was create a way to manage what ‘view state’ I was in, rather then doing a if/then of the current class name.  My only made-up explanation I can come up with for why this works is that on page load, jQuery builds a giant array of your page elements and properties.  When I start swapping class names around, that array isn’t being updated. Therefor, I just needed to come up with a method for tracking the state and query that rather then the current class name. Now all is well.

See it in action, or, you can download the .NET project and see it in action.  I don’t care for .NET, but it’s what I had at the time—that and I don’t know php (yet).

March 14, 2008

Creating Google Reader Interface from Scratch; but Stuck on a Bug

With a little down time at work, I started to make a few jQuery example pages for some quick documentation.  One thing led to another, and I’ve decided to build a light version of the Google Reader interface. Check it out.

Ground Rules

  1. No cheating. I didn’t want to see how Google did it—I wanted to plan the app from scratch. This way, I get a little practice planning the app’s architecture; How I track if each article is read, collapsed, etc.
  2. Baby steps. Rome wasn’t built in a day, and this app won’t be up and running full speed ahead any time soon.  For starters, I’m just building the thread view.  Perhaps sometime later we’ll have the feed menu on the side, but not today.

Progress

Day 1
Day 1 was basic framework and concept. This is were I started with the basic expand and collapse example, and it grew from there.
Day 2
Thread views done. Mark all read and mark all unread buttons working, threads expanding and collapsing, and a read all button.
Day 3
I realized that I was missing the Expanded View and List View tabs.  Adding these in required changing the way I track the read state of each thread, basically a complete change on my methodology—more on this later.  I also found a doozy of a bug—more on this later, too.
Day 4
Major code overhall.  Slimmed down my code to make shorted lines and smarter actions.  I pulled out any duplicate actions and created reusable, chainable functions.

The Bug

I wrote a detailed, albeit probably jumbled, post to on jQuery’s Google Group about my bug.  Here’s a quick recap:  I have two functions that depend on a wrapper div’s class.  When I first load the page, I set that wrapper’s class based on a cookie.  From then on, my two functions don’t function based on what the wrapper div currently is, but what it was at page load. Somehow it’s not seeing the current wrapper class.  Do you know why? Two gold stars to anyone who solves it!

The Future

I started building this interface just to see what I could do with jQuery. Once I get all the bugs worked out, I'd be nice to hook it up to a RSS feed and see it actually function. Perhaps a good excuse to start learning PHP, and maybe even Code Igniter.

March 06, 2008

Implimenting Syntax Highlighting on Instiki

Instiki is a light wiki built on Ruby On Rails, however I'm not sure if it is still be maintained. I use it to maintain a lot of ideas and examples, mostly code heavy content. One thing that could make Instiki better would be syntax highlighting -- so lets implement it.

Implementation

First off, download Syntax Highlighter by Alex Gorbatchev. Move the respective files to:
  • /instiki/public/javascripts/highlighter/
  • /instiki/public/stylesheets/highlighter/
  • /instiki/public/flash/highlighter/
You'll need to make the 'flash' folder and the highlighter folders, but I think this keeps things organized. Now, lets open /instiki/app/views/layouts/default.rhtml and start implementing. I'm not entirely sure how/where all the javascript is being rolled into the main template page of Instiki, so instead of tracking that down we can just put some good ol' fashioned <style></style> links. Right after <%= javascript_include_tag :defaults %> put:
	<link type="text/css" rel="stylesheet" href="/stylesheets/highlighter/SyntaxHighlighter.css"></link>
	
	<script type="text/javascript" src="/javascripts/highlighter/shCore.js"></script>
	<script type="text/javascript" src="/javascripts/highlighter/shBrushCss.js"></script>
	<script type="text/javascript" src="/javascripts/highlighter/shBrushJScript.js"></script>
	<script type="text/javascript" src="/javascripts/highlighter/shBrushXml.js"></script>
	<script type="text/javascript" src="/javascripts/highlighter/shBrushVb.js"></script>
Now I only added the few language files that I needed -- You, of course, should link to whichever ones you need. At the bottom of default.rhtml, right above </body> put:
	<script language="javascript">
		dp.SyntaxHighlighter.ClipboardSwf = '/flash/highlighter/clipboard.swf';
		dp.SyntaxHighlighter.HighlightAll('code');
	</script>

Usage

Using a <pre> tag, set name attribute to code and class attribute to the language of your choosing.
<pre name="code" class="js">
... some code here ...
</pre>
For the full run down of it's usage and options, check out the project page.

Languages

LanguageClass Name(s)
C++cpp, c, c++
C#c#, c-sharp, csharp
CSScss
Delphidelphi, pascal
Javajava
Java Scriptjs, jscript, javascript
PHPphp
Pythonpy, python
Rubyrb, ruby, rails, ror
Sqlsql
VBvb, vb.net
XML/HTMLxml, html, xhtml, xslt

Caveat

The name attribute on a <pre> tag is not valid XHTML.

3 of 4 « FirstP  <  1 2 3 4 >

Who?

Howdy. I'm Richard W. Baker - a designer based in Jacksonville, Florida with a passion for information architecture and usable interfaces. At my day job, I work for the City of Jacksonville as a User Interface Designer.

If you still have questions, or you're interested in hiring me for your next project, .

Active ingredients: XHTML + CSS + Expression Engine
Page rendered in 2.0757 seconds  |  50 SQL queries total