Posted on 3 Comments

I’m done with document.getElementById

I’m working on a project that has compatibility with Internet Explorer 6 as a major requirement. This means all appearances, all Ajaxy functionality, every aspect of the web application should look and perform in IE6 just as it would in Firefox, Chrome, IE7, IE8, and Safari. One of my favorite pieces of code is "document.getElementById()" but special cases have to be considered for IE 6. As an example, you can use getElementById to change the value of a hidden form element:

<input type="hidden" id="foo" name="foo" value="default value">
<input type="submit" id="goBtn" name="goBtn" value="Process..." onclick="document.getElementById('foo').value='anothervalue';">

That code will not always work. jQuery comes to the rescue! Rather than write lines and lines of additional code for browser testing and coding for a special case, we can simply replace "document.getElementById(‘foo’).value=’anothervalue’;" with "$(‘#foo’).val(‘anothervalue’);" and the code will work.

<input type="hidden" id="foo" name="foo" value="default value">
<input type="submit" id="goBtn" name="goBtn" value="Process..." onclick="$('#foo').val('anothervalue');">

I cannot sing jQuery’s praises enough!

Posted on Leave a comment

Seeking Next Project

I am coming to the end of a project and have an opening in my schedule. My strengths are programming in PHP, ColdFusion, JavaScript and jQuery, CSS, and HTML. I most frequently work with MySQL or MS SQL but can work on most database platforms. Code I write validates and is W3C compliant. I can also write Section 508 compliant code. I carry a project from concept to production as project manager, independent developer, and/or project team member. In addition to custom original code, I work well with open source projects and APIs. I usually telecommute but am not adverse to working onsite or traveling. I am not an artist and typically hire a graphic artist to provide the design for each project. I enjoy WordPress customizations (but have not done custom work to either Reality Me or Domestic Psychology). Please send referrals or inquiries to jugger@gmail.com or call +1-865-898-7189. Thank you!

Posted on Leave a comment

Today’s Coding Challenge

Today I am focused on debugging a custom tree control which present hierarchical data created through AJAX calls, custom JavaScript, and jQuery. The data is built dynamically so state must be maintained such that if the user navigates away from the page and returns the exact same data is presented upon return. The collapsers must close only their related data without orphaning any nodes.

The presentation was prototyped as tables nested within tables eight levels deep. Yesterday this was corrected to be a single table with rows dynamically added and removed which broke the handlers. Before someone throws the word sematic out without thinking, a table is semantically correct in this situation. Time to get back to handling the handlers.

Posted on Leave a comment

Coded Self Into a Hole

Had a rockin’ day of coding today. Started fixing some problems. Used jQuery to fix a cross-browser issue and simultaneously made my code lighter. Since this project is an evolutionary prototype, I got bold and evolved a piece of code that was holding the project back. In the process, many things broke of course and I’ve been going through fixing those issues. The code is looking prettier and lighter and the project looks better. Unfortunately, in my weariness, I started to put more bugs in than I was taking out so its time to call it a day.

Posted on Leave a comment

Week Long Programming Debacle

I’ve solved it! A week ago started a series of unfortunate events that program progress on my application to a screeching halt. My efforts and work did not quit but every fix seemed to reveal another bizarre issue. But surely a professional programmer could figure all this out in a day rather than a week? No. Problem solving isn’t always that simple. This was akin to hiring a contractor to add a room to the back of the house but in starting to dig his foundations he discovers an old septic tank buried behind the house and in trying to remove it he discovers a cave under that. My problem began with a test when I cleared all my cookies.

On problem set off another. The development server, long overdue for an upgrade, lost its mind but this wasn’t immediately evident to me so I did a line by line inspection of the code searching for the answer to some really whacked out behavior. Eventually I realized the server was shot and moved to another server. After fixing several issues either hidden and discovered in the line by line inspection or caused by experimentation in attempts to fixed the oddities caused by the flaked out server, I eventually discovered the source of the original issue. In short, jQuery’s .filter gets overridden by jQuery’s .listen plugin so it appears.

jQuery has a built-in traversing function called filter() but handlers for events get bound only on the initial rendering of the DOM. If the DOM is modified dynamically, for instance if content is added with AJAX, then the newly added event handlers will not be recognized by filter(). Fortunately, Ariel Flesler stepped up and created a plugin called listen() (use the 1.0.3 version!) which registers the handlers for the matching events and this works for new content added via AJAX or other DOM manipulation. It seems, unless I am misinterpreting something, that listen() overrides filter() so if you have both filter() and listen() on the same page, your filter() events will never fire.

Posted on 7 Comments

Coding Horror Appears To Be Hardware

The other day some bizarreness slipped into my code. It made no sense. The problem could not be reproduced on the production machine but all the recent changes had not been migrated to it. I examined and tested and pulled hair out and pounded head against wall after wall. Finally, I went to the old staging server and cleaned it up, removed all the code, wiped the database, then made an exact copy of the development code and data on the staging server. Surprisingly enough, I could not reproduce the problem. On examining the development server, I noticed that the hard drive was almost out of space. Could this be a swap space problem? Doesn’t matter. This development server has done its time and needs to be retired. I need a new machine! On the positive side, I can quit chasing ghosts and start moving forward on my application again.

Posted on Leave a comment

Yesterday’s Coding Horror

Yesterday my web application quit working. I simply cleared the domain cookies and the session cookies. It should have been no big deal but an important piece of JavaScript quit working. I have a script that adds some HTML to the DOM and looks similar to:

snafu("<tr><td class=\"fooclass\"><a class=\"expander special\" href=\"index.php\">go somewhere</a></td></tr>");

So this worked fine until I cleared cookies and now the generated source in the browser (confirmed in Firefox and Chrome) looks like:

snafu("<tr><td class=\"fooclass\"><a class="\""expander special\" href=\"index.php\">go somewhere</a></td></tr>");

Note that the anchor has inexplicably changed from <a class=\"expander special\" href= to <a class="\""expander special\" href=. The obvious thought is that a session variable is being expected in building the javascript code which in turn changes the DOM but that session variable is now returning NULL. That is still likely to be the problem but yesterday’s line by line inspection of the code showed no flaws. Today I am going to eliminate the server as an issue. The most recent code changes have not been migrated to the production server and it does not reproduce the problem so I’m setting up a staging server today to see if it shows the same problem as the development server. What a pain!

Posted on 2 Comments

Most of what I do no one will ever see

The question I hate hearing the most is "What’s a website where I can see your work?" Fortunately, I have not had to answer that question in a good long time. As a freelancing web application developer, I end up working on websites briefly and then move to the next project. When I move on, someone else comes in an continues to evolve the website so using that website as an example becomes a risk of misrepresenting my skills. Perhaps I made a site that had valid HTML and CSS and was Section 508 compliant. With 30 seconds and one incorrect tag, another developer could break all that work. Besides, once someone else modifies the site, it no longer represents my work anyway. That would be like the previous home owner coming back to my house with guests to demonstrate her tasteful choice of colors on the walls.

To complicate the ability to demonstrate my skills, most of the work I have done has been on proprietary systems with most of the functionality available to the company. For instance, I spent a year and a half working on a billing system. In no way could I show someone code samples from that project. I cannot even walk them through the client side of the project since I no longer have access to it and even if I did that would be revealing client confidential information. The front end of that website was a single marketing page and a login screen.

And never judge a developer by their own website. I would love my personal websites to represent me professionally, but frankly, I am too busy doing work for others.

I digress. This post was not intended to be a discussion of skills demonstration. Instead I came to exclaim with glee that I spent the morning ironing out some nasty problems in my current application project! Unfortunately, all the changes, no matter how significant, will only be seen by me. The output, the stuff on the screen, does not appear changed. So even my client cannot see what I have done. And this is why I like to work on my house myself…because sometimes, I like to point at something tangible and say, "I did that!"

Posted on Leave a comment

Programming Error of the Day – Global Search and Replace

I had a very unique string to replace throughout my application. Simple enough, instead of being text, it should be an image. I had the image code already written for a different image so I copied it, then went to search and replace the string but forgot to change the name of the image. I originally had 13 replacements across several files. Now I have to manually inspect 32 lines of code to make 13 corrections.

Remember, automated tools are a great way to make mistakes faster. And no, this has nothing to do with Sh*t Creek. That boat is totally about a Thursday deadline and a much needed miracle.

Posted on Leave a comment

Another attempt at jQuery modals

Not long ago, I attempted to use jQuery to ease the pain of creating a modal popup for editing user data. One challenge is that the user data is edited from a tabular list of users. Since the page is not refreshed after the update, the changes must be dynamically reflected in the table. That’s an interesting challenge but not a huge problem. The problem I ran into was the jQuery modal plugins I tried using to make my cross-browser programming faster and easier was that none of them seemed to accommodate my lengthy forms.

jQuery has dozens of modal plugins and options including Dialog built into the UI. Which is your favorite? Have you had success with a modal allowing scrolling and still supporting IE6?

Update: jqModal, Facebox, SimpleModal, and Thickbox, direct link to SimpleModal, and Dialog. Think I’m going with Dialog.

Posted on 2 Comments

Always more to learn

No matter how long you do something, there is always more to learn. You’d think that since I’ve been doing HTML coding since around 1993, I’d pretty much know every in and out and every little tag and peculiarity regarding HTML. Not so. See, we form habits. We get into patterns. Specs change but we retain earlier hacks and assumptions. Today I learned an absurdly simple thing. Maybe I knew this and forgot. I rarely use tab orders on my forms. Most of the forms I create are very top down so the natural tab order is sufficient. In computing, counting starts at zero. But in HTML tab order, zero means exclude that form element from the tab order.

To exclude an element from the tab order, set the value of tabindex to 0. [Source, Webcheatsheet.com, How to Control Tab Order in HTML]

Because of my computer science studies, programming in PHP, JavaScript, C and so on, my inclination is to always begin with zero. Of course, my favorite web application language is ColdFusion and it always starts at one. I can only assume the Allaire brothers were originally targeting non-programmers.

HTML is about to become HTML 5. Funny enough I just traded my HTML 3.2 book at McCay’s a few weeks ago. Maybe I should have kept it and re-read it.

Update Jan 12, 2009: Ian Tempest noted in the comments that zero does not exclude an element but rather moves it to the end of the tab order. From the W3C HTML 4.01 specification:

Those elements that do not support the tabindex attribute or support it and assign it a value of “0? are navigated next. These elements are navigated in the order they appear in the character stream. [Source, W3C, 17.11.1 Tabbing navigation]

Posted on 4 Comments

Today’s Technical Brain Cloud

Having a stupid moment and maybe you can help. I’m trying to count how many times an employee is scheduled using MySQL. I would like to have a column that for George says "3" and for Lucy says "2" but if I group on EmployeeID and use count(e.EmployeeID) I end up with 2 rows instead of 5. How do I retain the 5 rows of data and still get a count of 3 for George and 2 for Lucy? My output will show that George has schedule Sat-Mon, Tues-Fri, and Wed-Sun and will say "George is scheduled 3 times."

CompanyID AffiliateID EmployeeID EmployeeName Schedule
1   23   11   George   Sat-Mon
1   23   11   George   Tues-Fri
1   23   11   George   Wed-Sun
1   23   15   Lucy   Sun-Mon
1   23   15   Lucy   Thur-Fri

SELECT c.CompanyID,
     a.AffiliateID,
     e.EmployeeID,
     e.EmployeeName,
     s.Schedule
FROM companies c
LEFT OUTER JOIN subscription s
     ON c.CompanyID = s.CopmanyID
LEFT OUTER JOIN affiliates a
     ON a.AffiliateID = s.AffiliateID
LEFT OUTER JOIN employees e
     ON ae.AffiliateID = a.AffiliateID
LEFT OUTER JOIN schedules s
     ON s.EmployeeID = e.EmployeeID
          AND s.CompanyID = c.CompanyID
          AND s.AffiliateID = a.AffiliateID
WHERE (s.StartDate <= FROM_UNIXTIME(1227243599)
     AND s.EndDate >= FROM_UNIXTIME(1227157200))
     AND c.CompanyID = 1
ORDER BY c.CompanyName, s.AffiliateID ASC

I know this is not a complex SQL problem. I’ve done this in the past but today I am being dense and am stumped.

Posted on 10 Comments

Twitter API Severely Flawed

Twitter’s API (basically a way to let software developer’s work with Twitter’s data) has been a huge factor in Twitter’s success. When Twitter did not provide adequate search, a developer used the API to create http://summize.com/ which was so good that Twitter purchased it and incorporated the code as http://search.twitter.com/. Twitter does not provide stats but numerous developers have created applications such as Twitter Charts and Twitter Stats to provide statistics. (See also: Now You Can Graph Your Twitter Usage) The API has allowed people to get away from the phone and web interfaces by developing desktop applications such as Twhirl and TweetDeck (which includes features not built into Twitter such as grouping of friends). Twitter by default emails you when someone starts following but never tells you when someone quits following so software developers used the API to write Qwitter and Twitterless.

Where’s the flaw? The flaw is in the authentication. Many of these services or applications developed by a third party require you enter your username and password. There is nothing to say that this third party should be trusted and we give them the keys to the kingdom. With that username and password that developer could maliciously use your account for spam, sign you up for other services, or flat out lock you out of your own Twitter account. If one of these services started sending too many Tweets and causing your followers to quit following (see #7) you, the solution is to change your password. But, changing your password also breaks all the other Twitter services you have signed up to use.

What’s the solution? The solution is simple. For each service or application that requires a username and password to access my Twitter data, I should be able to generate a key instead of giving them my password similarly to the way Amazon Web Services works. This would give me the power to list all the services I use from my Twitter profile and to individually and at my own discretion disable each service. From a developer’s standpoint, the process is easy because a key is simply a GUID. The only challenging part to Twitter developers is changing the authentication process and developing the profile screen to manage the keys.

Until Twitter implements a key scheme, I am no longer giving my password out to third party Twitter applications and services (unless they are really cool and look really trustable!). I made an exception today for TwitterFone so I could compare it to Jott.

See also:
Twitter Guide: How To Do Things With Twitter

Update Dec 15, 2008: See also Is Twitterank Ranking Your Popularity Or Stealing Your Password? Others see the same flaw I do.

Update: OAuth looks like a very viable solution.

Update Dec 29, 2008: Alex Payne, The Twitter API Lead developer, confirms that Twitter is testing OAuth! Yes! OAuth is coming.

Update Jan 2, 2009: See also Allen Stern’s Sheep Line Up in Perfect Twitter Formation and Louis Gray’s Twitterank Can Have My Password, No Questions Asked.

Update Jan 3, 2009: I’ve now officially been phished through Twitter. I didn’t bite. I’m betting someone used a 3rd party website that looked legitimate while collecting usernames and passwords (maybe it promised to send @ replies through email or give Twitter stats or something) and then using the Twitter API ran a muck sending direct messages from "trusted" people hoping to get people to click through to the bad website. The one I received:

softclothing Hey, i found a website with your pic on it… LOL check it out here http://twitterblog.access-logins.com/login

Posted on Leave a comment

The next hour’s challenge

My current project has been experimented on, tweaked, and change requested into a CSS mess. I’m going to dump all the CSS and start fresh. This has to happen and many projects skip this step as cumbersome.

Update: Really cleaned up the development environment and production server by removing test files, unnecessarily included (old and unused) code, and so forth. Much improved!