Entries Tagged as 'Web development'

Federal CTO Envisions a Purpose-Driven, Collaborative Internet

Miscellaneous , Podcasts , Technology , Web development No Comments »

One of my favorite podcasts is Buzz Out Loud, a weekday live video stream and podcast from CNET.com that reports, analyzes, and banters about the tech news of the day. This past week, they conducted an interview with Federal CTO Aneesh Chopra, which I just finished listening to today.

The entire interview was quite interesting, but there were two particular discussions that struck me.

The first one was about broadband penetration: the Buzz Out Loud podcasters wanted to know what plans, if any, were being made to promote the rollout of broadband to those areas where such service was limited or unavailable. Chopra said that they hoped to address that issue with a national broadband plan due to be revealed in February 2010, but he said that his personal focus was more on encouraging innovation in developing applications that would further the adoption and development of a robust broadband infrastructure. In other words, it's not just about building the infrastructure for people, businesses, and government organizations to have, but creating compelling applications of that infrastructure that bring people on board and give them more reasons for wanting ubiquitous Internet access.

As web/Internet application developers, we tend to think of broadband, high bandwith, and Internet access as the infrastructure that allows us to build robust applications. It's kind of exciting to look at it the other way around, that creating useful, effective, compelling applications that people want (or perhaps even need) could promote and justify the expanse of the broadband infrastructure.

The second discussion was in response to a viewer question about the use of open source software within government agencies (SUSE and RedHat were specifically mentioned). Chopra said that that was really in the federal CIO's arena of concern, but that he personally was more interested in promoting the principles of "open collaboration" and the "sharing of intellectual property as we build value." He went on to explain that what he meant by that was that he didn't care so much if an application built for the government was built on a proprietary platform so long as that application became shared intellectual property between government agencies. That again was another point that I hadn't heard anyone make before.

I'd encourage anyone who has an interest in how the federal government hopes to leverage technology to the country's advantage to listen to this podcast episode. You can watch the video version or listen to the audio version, either streaming or as a download, at the following address:

http://www.cnet.com/8301-19709_1-10302978-10.html?tag=mncol;title

Testing jQuery Commands With Firebug Or With a Bookmarklet

JavaScript , jQuery , Web development No Comments »

Before I went on vacation last week, I read a blog post by Ben Nadel where he demonstrated code for stepping through the search path of a jQuery selector in order to debug the selector. As Ben pointed out, if you make a mistake in your selector, it will fail silently, making it hard to figure out exactly where you went wrong.

In the comments to the blog post, Shayne Sweeny pointed out that you can run jQuery commands directly from the blue command prompt in the Console view of the Firefox Firebug plugin, like so:

 

I like this technique because it lets me write any jQuery code I want (selectors don't usually give me problems, it's the DOM traversing that sometimes trips me up), and I can use it on any of my pages that use the jQuery library without adding extra code to the page.

But what if you're trying to troubleshoot a jQuery command in a browser other than Firefox (for some reason)?  Well, I did a bit of tinkering and came up with a bookmarklet that does something similar.  If you're not familiar with bookmarklets, they are bookmarks you can add to your browser's bookmark collection that run JavaScript code instead of opening up a different web page.

The bookmarklet I created adds a <div> at the top of the page with a text input and three buttons.  Any jQuery command entered into the text box will be executed on the page and then recorded below the text box for reference.  Here's a screenshot of it in action in Opera:

It works in Opera, Safari, and Chrome:  I couldn't get it to work in IE 7 (surprise, surprise).

To use it, all you have to do is go into whatever browser you want to use it with and create a bookmark that has the following code in place of a normal bookmark URL:

javascript:var%20d=%20document.createElement("div");d.style.width="100%;";d.style.border="1px%20solid%20#ccc";d.style.margin="5px%200px;";d.style.padding="7px";d.id="jqtD";var%20t=%20document.createElement("input");t.type="text";t.id="jqtT";t.size="80";var%20b=%20document.createElement("input");b.type=%20"button";b.id="jqtB";b.value="Execute";var%20c=%20document.createElement("input");c.type="button";c.id="jqtC";c.value="Clear";var%20s=%20document.createElement("input");s.type="button";s.id="jqtS";s.value="Close";var%20bd=document.getElementsByTagName('body')[0];%20b.appendChild(d);var%20frst=%20bd.firstChild;bd.insertBefore(d,frst);d.appendChild(t);d.appendChild(b);d.appendChild(c);d.appendChild(s);jqtEvts();function%20jqtEvts()%20{$("#jqtB").click(function()%20{var%20tst=%20$(this).prev().val();eval(tst);$("#jqtD").append("<br%20/>"+tst);});$("#jqtC").click(function()%20{$(this).siblings("input[type='text']").val("");});
$("#jqtS").click(function()%20{$("#jqtD").remove();});}

...Just make sure to remove any spaces or line breaks that may have been introduced during the copy and paste process.

The Risk of Performing JavaScript Operations Around User-Generated HTML

JavaScript , jQuery , Web development No Comments »

Last year I wrote a ColdFusion application that included a page where an editor could take a list of short news abstracts and manipulate them (reorder them, place them in categories, add divider lines, create anchor links to highlighted stories, etc.) using a number of jQuery-powered JavaScript functions. It gives them a lot of control over the final layout, and they're pretty happy about it.

However, there have been occasions when this layout tool doesn't work at all. Why? Unclosed HTML tags in the abstract data.

The page they use to enter the news abstracts is comprised of several plain HTML text fields, a set of category checkboxes and two WYSIWYG textarea boxes (powered by JavaScript) for the abstract itself. I gave them the WYSIWYG boxes because I knew they would want to be able to do some basic HTML formatting on the abstract text (boldface, italics, etc.), and the WYSIWYG editors do produce solid, clean HTML.

What they do that gets them in trouble is they enter HTML tags (usually for italics) into the title form field, which is a normal HTML text field. Every once in awhile, they forget the closing tag or maybe just an angle bracket...the abstract itself saves correctly but when they get to the layout tool, that unclosed HTML tag messes up the entire DOM structure the layout tool is programmed to manipulate, rendering it non-functional.

They've now learned that when the header text of the various layout tools appears in italics, that usually means they've got an unclosed italics tag that needs fixing. It's easy enough to fix once they figure out which news item is responsible.

So a word of warning: if your JavaScript functions are designed to act upon HTML code that you yourself don't have complete control over (or the ability to make sure the HTML is clean and proper), consider the possibility that your JavaScript may end up breaking due to the content.

Bug In How Safari 3.2.1 Renders the Links For RSS Feeds

Miscellaneous , Web development 4 Comments »

One of my clients contacted me yesterday to tell me that there was a problem with reading their RSS feed in Safari (and only in Safari).

Over the next hour or so, I learned quite a bit about how the current version of Safari (3.2.1 as of this writing) handles RSS:

  • By default, Safari is configured to open up your default e-mail client to handle/read RSS feeds, resulting in a lot of head-scratching by your truly when I tried to navigate to the feed and ended up with a "Compose New Message" window in Thunderbird. While a lot of people do prefer the RSS-reading capabilities of their mail client over what the browser does with feeds, make that decision for the user is a questionable call on Apple's part, and some sort of alert/notice that this was the deal would have been nice.

  • A lot of browsers these days will apply a style to the RSS feed XML (probably using some sort of built-in XSL, I'm guessing) prior to display so that it's more human-readable and the hyperlinks for each news item are clickable. But you can still view the raw XML using the "View Source" option of the browser. Safari, on the other hand, transforms the feed into an HTML file with JavaScript, leaving no trace of the original XML. Again, another somewhat presumptuous decision by Apple to buck convention in order to enhance the user experience.

...Those two issues are annoyances rather than bugs. The problem affecting my client's RSS feed, however, is a bug in regards to how Safari is transforming the RSS data before displaying it to the user.

Each news item in an RSS feed can contain a number of elements/nodes, two of which are the <link> and <guid> elements. The <link> element is meant to contain the URL where the reader can access the full text of the item. The <guid> element contains a string that uniquely identifies that RSS feed item within the feed (like a primary key in a database).

If the <guid> element contains the "isPermaLink" attribute and that attribute value is set to "true", then that indicates that the <guid> element also contains a URL (a permanent one) to the full text of the item (one that might be different from the URL in the <link> element), and an RSS client could legitimately used the URL in the <guid> as the link to the story instead.

What I discovered, though, was that Safari was creating the hyperlink for each news item by combining the value of the <link> element in the <channel> node of the RSS feed with the value of the <guid> element of each item (which was simply a unique numeric value), even though the <guid> elements did NOT contain the "isPermaLink" parameter. So instead of using the value of the <link> element of each item as per the RSS specs, Safari ended up creating non-existent URLs.

The solution, of course, was simple: I just put the URL for each news item in the <guid> element as well as the <link> element. Point is, I shouldn't have had to.

Once I applied the solution, I did some searching to find out if this is a known problem that was being worked on. I found one mention of it in a generic tech support forum post published in 2008, so it looks like the problem has existed for awhile but hasn't gotten much attention (probably because most people read RSS feeds through actual RSS clients). I used Safari's built-in bug report mechanism to report it to Apple, but I don't hold out much hope for that having an impact.

Still, I thought it worth a post, on the off-chance this information might help someone else.

Using jQuery UI Sortables To Move Items From One List To Another

JavaScript , jQuery , Web development 11 Comments »

During my most recent project, my clients asked me to build a web-based tool that would help them place volunteers into various standing committees. Placements would be made based on the preferences of the volunteers (who were asked to choose up to three committees they would like to serve on), the vacancies created in each committee by outgoing members, and the desire to have a diversity of units and divisions represented in each committee.

I decided pretty quickly that the most natural way to represent this placement process on a web page would be to let them "physically" move a volunteer into a committee. I had built similar tools before (even before I started using jQuery), but never with more than two lists or collections, so I went to the jQuery UI site to see what my options were.

I started with the most obvious place to start, the Droppable interaction, but soon realized that a better choice for this task was the Sortables interaction.

The primary focus of the Sortable interaction is to let you reorder a collection of DOM elements by dragging them up-and-down through the collection. It's extremely easy to implement in its most basic form. If you wanted to make all of the <li> elements in a <ul> with an "id" attribute "listA" sortable, you can do it in one line:

$(document).ready() {
  $("#listA").sortable();
});

...you can see that code in action on the home page of the Sortables interaction.

What I discovered was that it was almost as easy to connect one Sortable list to another, so that in addition to being able to move reorder items within each list, you could drag items from one list to the other, simply by using the "connectWith" option:

$(document).ready() {
  $("#listA").sortable({
    connectWith: ['#listB']
   });

$("#listB").sortable({
   connectWith: ['#listA']
  });

});

...In the code above, the first sortable() function call makes listA sortable and uses the "connectWith" option to allow items from listA to be dragged into listB. The second sortable() function call lets you sort items in listB and drag items from listB over to listA (even items that originally belonged to listA). If you wanted the movement to only go in one direction (from listA to listB but not back again), you could leave out the "connectWith" option for listB.

Again, the jQuery UI site has a nice ready-made demo of this.

All well and good, but right now all this code does is create the visual effect of moving an item from one list to another. Actually recording the fact that a particular item was moved from one list to the other requires more code, code that is invoked whenever such a move takes place. Being the smart guys and gals that they are, the jQuery UI team built a couple of custom events into the Sortables interaction so you can run additional functions when a certain event has taken place. For my purposes, I only needed to utilize two of these events: receive and remove:

$(document).ready({
  $("#listB").sortable({
    connectWith: ['#listA'],
    receive: function(event, ui) {
       //Run this code whenever an item is dragged and dropped into this list 
       var itemText= ui.item.text();
alert(itemText + " just joined this list");
}, remove: function(event, ui){ //Run this code whenever an item is dragged and dropped out of this list var itemText= ui.item.text(); alert(itemText + " just left this list"); } }); });

...The code is, for the most part, self-explanatory, save for one line (repeated twice): var itemText= ui.item.text()

The ui object is a "prepared" object created by jQuery UI that holds a number of objects and data associated with the event that just took place. The item object within the ui object represents the item that was moved in or out of the list, so I can treat it as a jQuery object and retrieve the text of the item using the standard text() function. You can find a full list of the data contained in the ui object by clicking on the "Overview" tab at the bottom of the main Sortables interaction web page.

I created my own demo page to illustrate how this code works (with a homage to the Fox TV show "Fringe"):

http://www.swartzfager.org/blog/demoFiles/connectedSortables/connectedSortableEvents.cfm

Two things worth mentioning at this point:

  • If one of your lists starts off empty, or if there's any chance that a user might remove all of the items from a list and then try to put items back into the now-empty list, you need to set a minimum height for that <ul>, so that even when empty, the <ul> is large enough to accomodate a single list element. In Firefox and Safari, you can set the minimum height using the min-height CSS style, but if you have to support IE 7, you'll have to add two additional height styles (like so):
    • min-height:50px;
      height:auto !important;
      height:50px;

  • In my demo, you'll notice that as you drag a person out of the Candidates list, the list item's width gets shrunk to the width of the longest unbroken string of text in the list item. I'm not sure why it does that, but you can negate that effect by either defining a set width for the <li> elements, or by defining a "helper" with a set width (a helper is a visual representation of the item being moved, using something graphical like an icon).

So, armed with this knowledge about the Sortables interaction, I was able to build the tool required by my clients. Every time a volunteer was moved into or out of a committee, the receive or remove event would make an AJAX call to update the volunteer's record (either providing the id of the committee they were placed in or removing it), and it would run a function that updated the vacancy count for that committee specific to that type of person and counted the overall number of vacancies for that committee (to determine if the committee had been "filled"). I also added a few toggles allowing them to hide extraneous information when they only wanted to see the data pertinent to doing placements for a particular committee. The final challenge was to scale everything so that the tool could be viewed with a projector, so that the members of the group responsible for making the placements could work on it collaboratively.

I wasn't comfortable sharing an exact copy of the tool I created, but I have posted a facsimile that's fairly close to it, minus any real-life data and any AJAX calls to save the placements between page reloads. You can view it here (Note: it doesn't work in IE 7):

http://www.swartzfager.org/blog/demoFiles/connectedSortables/volunteerPlacement.cfm

...I provided instructions at the top, but quite honestly I think most IT-inclined folks could figure it out without them.

It's just one example of some of the really cool (yet practical) user interfaces made possible with jQuery and jQuery UI.