Web Dev Festivus It's a Festivus for the Rest of Us!

21May/100

JQueryUI Accordions with multiple sections open at once

Just a quick one, today.

I recently had to create an accordion that has multiple sections open at the same time (which of course isn't really an accordion at all).  I wanted to use as much of the jQueryUI library as I could, mainly because I really like the themeability but also because I had to include UI for another area on the same site, so it made sense.

This is the solution I came up with:

jQuery('#accordion').accordion({ collapsible:true, active:false, autoHeight: false, disabled:true});

jQuery('#accordion h3.ui-accordion-header').click(function(){
jQuery(this).next().slideToggle();
});

Basically, in order of tricks:

  • collapsible: true allows the accordion to be all closed at once
    active: false makes the accordion all closed at first run
  • autoHeight: false makes the accordion only open as much of each section that it needs, rather than a uniform height equal to the largest section
  • disabled: true makes the accordion disabled, stopping the regular accordion behaviour and allowing us to add in our own control code
  • The click function gets all the headings and adds the ability that when they're clicked on, toggle a slide animation on the corresponding div element, which is always next to them

It's pretty simple code but it's really handy if you, like me, want the appearance of a jQueryUI accordion but differing functionality - try it out for yourselves!

25Jan/100

Become a Web Dev Triple Threat

Introduction

The concept of the "triple threat" in theatre has existed for decades now, but its usage hasn't dwindled at all.  Meaning, specifically, a person that can act, sing and dance, "triple threats" are considered the ultimate in the fields of stage and screen.

In web, there is a similar concept of the triple threat - a person that can design, develop and market.  By being able to do all three, you are effectively able to prepare, launch and propel a personal web project without paying a single salary - a very handy thing! Since this is a web development blog, however, I'd like to discuss the concept of the "web dev triple triple threat":

Threat One: Front End

Irrespective of your scripting ability, mastering the front end almost always comes down to mastering two thins: XHTML and CSS.  If you're reading this, chances are you already know at least a little bit of HTML and CSS, but before you can really say that you've mastered them, there's a few asides that you could probably stand to do a little reading on.

HTML5 has been in production since 2004 and will soon be the new web standard in front end development.  Getting a strong understanding of its ins and outs now would help exponentially once its properly released.  Similarly, CSS3 is inches away from launch and has already been included in many major web browsers.  Don't wait until it becomes the standard - learn it now, enhance your styling knowledge and get that first threat down!

Threat Two: Back End

I've always been an advocate of "the right tool for the right job", so it's hard for me to recommend one back end language over another.  I'm a PHP guy, so it'll always be my first point of call - but, to be fair, it's probably not always the most suitable tool in the shed. What it does have going for it, however, is that it's particularly easy to learn - especially so if you already know a little C or Perl (the languages it was originally based on).  Better yet, if you've already mastered the first threat, then you're half way to mastering your second - as PHP for web relies heavily on HTML.

Getting a solid base in a scripting language and complementing it with some sound front end skills will get you a pretty sweet looking website, but there's one more area to master before you can call yourself a "web dev triple threat"...

Threat Three: Interactivity

Although theoretically an element of the front-end, interactivity is such a broad area that mastering it will take easily as long as mastering technologies like CSS or PHP.

Interactivity is handled, primarily, in websites with the use of JavaScript - but can also be handled in some ways using CSS and HTML.  Still, for the purposes of this article, we'll talk about interactivity as an outcome of using a JavaScript library.

My personal preference in this area is jQuery, but other libraries like Scriptaculous, Mootools and YUI are equally exceptional.  Learning one or many of these will enhance your web building skills endlessly.  They provide assistance for pretty much any kind of interactivity you can think of, from complex animations, to drag-and-droppables, to prettier alert boxes! This is the stuff that really leaves an impression with your visitors too, so no excuses - get your reading on!

Conclusion

Only by mastering all three areas of development can you really offer the best one-man-band service to your clients.  Similarly, only by becoming a true "web dev triple threat" can you start pushing your personal projects from hobby to enterprise.

Filed under: CSS, MySQL, PHP, XHTML, jQuery No Comments
26Sep/090

Making your own API/SDK of an External Site

So, What's All This About?

One thing I've had to do a lot of in programming is making "APIs" or "SDKs" for sites that don't have them already - usally external sites that I have no ownership or control of.

I say "APIs" and "SDKs" (as opposed to without the quotations), since really they're just a collation of the data that is held on each of their pages - but since it's a reinterpretation of the data into a more usable format, I think the name is valid.  Perhaps a better term would be "fAPIs" for "fake APIs".  Okay, are you listening Internet?  From now on a QAD API built from a site you have no control of is called a fAPI.  Good, glad that's done.

Anyway, the reason I've had to make them more and more recently is due to the rise of the iPhone application.  In the old days we only ever needed to make them if we wanted to present data on another site than where it was originally published (in Australia I'm told this is allowed as it falls under "free domain", since it's readily available to anyone - but I'm not sure about where you live), then the RSS feed was invented and every site on the Internet started offering RSS, which could then be captured and reused using tools like MagpieRSS - basically making a fAPI from just two ingredients: the feed and a parser.

These days, sites largely don't offer RSS feeds for data - just for news, blog posts, images, podcasts etc. - which is great, don't get me wrong, but it's hard to make something reusable from any of that!  So what I've been doing, is taking a website, working out a way to capture the data, reading it into a standalone object, then storing it in a database for use later.

I'm going to attempt to explain my process in as little jargon as possible, so that it can be reused for any language - despite the fact that my personal preference is PHP and MySQL.

What You'll Need

  • Scripting language that can grab the contents of external websites
  • Database for storing the data - unless you want to reuse it straight away
  • A mid range knowledge of regular expressions - for finding the data you need amongst messy HTML

Getting Started

  1. View the source of the website you want to get the data from
  2. Find where each of the pieces of data you want to capture are from the page, in the source
  3. For each of these pieces of data, try and see if there's something recognisable on the same line as the data - it could be a class, an ID, a rel attribute - anything! We'll call these "identifiers"
  4. If there's nothing unique, then look for something unique before or after the line - maybe there's a table that always has an open tag three lines before the data you need is available.  Find these identifiers - they're always there, but sometimes you have to think outside the box.
  5. Once you have an identifier for every piece of data you want to collect, it's time to code!

The Algorithm

There may be a simpler way to do this, but I've always found my method to make the most sense to code and the easiest to change later!  The algorithm is as follows:

  create new object for data collection
  file=get_file(url)
  for each line in file{
    if(identifier matches in line and data is on this line){
      get data from line
      store data in object
    }
    if(identifier2 matches in line and data is on this line){
      get data from line
      store data in object
    }
    ...
 
    if(identifier matches in line and data was x lines ago){
      get line from x lines ago
      get data from line
      store data in object
    }
 
    if(identifier matches in line and data is in x more lines){
      set countdown[identifier]=x
    }
 
    for each identifier in countdown{
      if(countdown[identifier] is less than 0){
        get data from line for the identifier that has matched it
        store data in object
        remove identifier from countdown array
      }
      else countdown[identifier]=countdown[identifier]-1
    }
  }

At the end of this algorithm, you will have an object that has all of the data you need in a more usable format - you can either use the data right away or store it to a database for use later!

Keeping Your Data Up to Date

This is where your old buddy cronjobs come into play! In the past, I've always made fAPIs from very large data sources - sports organisations, newspapers, government departments - this means I've been able to create cronjobs that run every minute (since they'll never notice you).  You might not be so lucky - so be careful and set your cronjobs to a realistic time delay.  The last thing you need is to annoy the webmaster of the data source by racking up their bandwidth!  Never forget, it's soooo easy for them to just ban your IP!

Test Case

Just as a quick example of this, take a look at the following table:

Earnings Accounted Tax
$12,300 $190.00 $1,240
$17,750 $190.00 $6,140

Let's say you want to get the "Earnings" and "Tax" columns. Take a look at one way the source could be structured:

<tr><td class="earnings">$12,300</td><td>
$190.00</td><td>
$1,240</td>
</tr>

<tr><td class="earnings">$17,750</td><td>
$190.00</td><td>
$6,140</td>
</tr>

Since 99% of the data sources you'll want to grab from aren't written by hand, they follow a set formula - namely, whatever the scripting language has outputted - this means that once you find the identifier, you can reuse it over and over again to get the matching data columns.  In this example,  the value in the earnings column can be found on the line where class=earnings (the "identifier") and the value in the tax column can be found two lines below that.  So all we need to do now is write the code to capture it!

  create new object for data collection
  file=get_file(url)
  for each line in file{
    if([class="earnings"] matches in line){
      get value from between &lt;td class="earnings"&gt; and &lt;/td&gt;
      store data in object
      set countdown[class="earnings"] to 2
    }
    for each identifier in countdown{
      if(countdown[identifier] is less than 0){
        if(identifier is equal to [class="earnings"]){
          get data from the beginning of the line, to the first &lt;/td&gt;
          store data in object
          remove identifier from countdown[]
        }
      }
      else countdown[identifier]=countdown[identifier]-1
    }
  }

If you have a look at the actual source of the table, you'll see it follows a different structure - one without any class attributes. So how would you get the data from this?  Easy! Just track each time a <tr> opens, and get the first and third <td> contents before the </tr> closes!

Oh and by the way, for all of the string matching, I recommend learning regular expressions - they make the work soooo much easier and can turn ten lines of code into one.

What Can Go Wrong

The biggest problem you'll have with this kind of work is not knowing when the webmaster of the source is going to change the structure or template of their data.  There's no easy answer here - what I do, however, is just check the source once a week to make sure; and when it changes (and it will) I rewrite the code.  I know, it isn't a perfect system - but when you don't own the data, you don't have much of a choice!

Final Notes

If you have any further questions about any of this, please feel free to comment - I'll answer any questions as best I can!  Good Luck!

Tagged as: , , No Comments
19Sep/090

First Entry!

I don't have much to write at this point, so hopefully this will serve as incentive moving forward to adequately update this blog. I'm hoping to add little modules, design tricks, jquery plugins and other useful tricks over the coming weeks, months and years so that I can give back to the community on a broader scale than my existing one-on-one relationships. Oh well - here goes nothing!

Filed under: Generic No Comments