Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Find Facebook Friends with Your Facebook Connect Application

InformIT.com has just published the last article in my Facebook Connect series. This uses the common task of finding the Facebook friends of your Facebook Connect user to explain the intricacies of FQL (Facebook Query Language).

Create client-side charts with Highcharts

I’ve stumbled across a Highcharts announcement on ajaxian.com a few days ago. Highcharts looked like something I’ve been (passively) looking for for years: a simple tool that could take values generated by the server and turn them into a fancy graph. It lived up to the promise: after struggling with it for a few hours, I’ve deployed my first chart-on-a-page to production (note to myself: still have to fix the caching issues).

The tool works great, but there are (as always) a few hidden gotchas:

  • The reference manual gives you all the information, the How to use page is somewhat cryptic.
  • The demo pages show you incomplete code; all the formatting parameters are missing.
  • Although it’s obvious in the hindsight, the documentation “forgets” to mention that you have to style all the elements of the graph, otherwise you’ll get a nice white-on-white nothingness. You can dig through the demo code to find the routines that do that (they’re hidden in a JavaScript file) or look at my code.
  • Another missing bit: if you want to apply the same format to multiple graphs, set the default options with the Highcharts.setOptions(chartFormat) call.
  • Last but not least: the series parameter is an array of objects (each object having at least the data property). If you read the documentation too literally and define series as an object (not array), you’ll get a nicely formatted empty canvas (assuming you’ve got the formatting parameters in place).

Publish stories on Facebook

In my first Facebook-related article published by InformIT, I’ve described the basics of Facebook Connect – a JavaScript API that can connect your web application with millions of Facebook users. The next step is pretty obvious: once you’ve attracted the Facebook users, it makes sense to publish their activity on your web to their Facebook news feed. The process is described in my next InformIT article “Publish Your Application Stories to Facebook”.

Use Facebook Connect to Bring Your Application to Millions of Users

Almost a year ago, I’ve joined Facebook which has at that time rolled out the initial sandbox of the Facebook Connect environment. I’ve developed a very simple application and waited for the FB Connect rollout. A few months later (around December 2008) they got so far and I’ve deployed my application on my production server … only to get user complains a while later telling me the application has stopped working.

It turned out Facebook has (somewhat silently) changed their API enough that it broke my code. However, I only had to fix a few functions to adapt them to a now better-documented API. I’ve also used a few extra bits-and-pieces Facebook engineers threw in after discovering what we really need. The second FB Connect experience was so good that I’ve decided to write a series of articles for InformIT describing how you can integrate your web site with Facebook. The first one, Use Facebook Connect to Bring Your Application to Millions of Users, has just been published on the InformIT web site.

My second jQuery article: refactoring a web page

When I’ve decided to switch from X library to jQuery, I was faced with tons of (now outdated) pages in my web site that I had to migrate to jQuery. As it turns out, doing the migration job properly is a great idea: armed with the CSS experience (and believing in the need for using tags that make sense) I was able to make compact, more readable and better degradable (an awful word to use in this context) web pages.

I’ve described some of the lessons I’ve learned in this process in the Web Page Refactoring with jQuery article that was published by InformIT.

Refactoring a simple menu

Years ago I had to implement a drop-down menu. Nothing fancy; no open-on-hover magic, but a simple line of buttons with drop-down boxes that would open on clicking the button.

There were just a few annoying details: clicking a top-row button should obviously open a drop-down box, but also change state the button’s state to “depressed” and close any other open drop-down box (and change the state of corresponding buttons).

Here is my five-year-old HTML code …

<div style="float: left; position: relative; z-index: 100;" id="IDAHYJQB">
  <p class="btn170">
    <a href="/climbing/myClimbs/myClimbs.asp">First page</a>
  </p>
</div>
<div style="float: left; position: relative; z-index: 100;" id="IDAKYJQB">
  <script>menuRegister('IDAKYJQB')</script>
  <p class="btn170" id="IDAKYJQB_main">
    <a href="javascript:menuClick('IDAKYJQB')">Add ...</a>
  </p>
  <div style="position: absolute; display: none;" id="IDAKYJQB_sub">
    <p class="btn170">
      <a onclick="menuSelect('IDAKYJQB')" 
        href="/climbing/myClimbs/myClimbs_add.asp">New entry </a>
    </p>
    <p class="btn170">
      <a onclick="menuSelect('IDAKYJQB')" 
        href="/climbing/myClimbs/myClimbs_editWall.asp?a=add">Edit</a>
    </p>
    … more …
  </div>
</div>

… the corresponding CSS …

.btn170, .btn170_down { background-repeat: no-repeat; 
    width: 170px; height: 20px; line-height: 18px; overflow: hidden; 
    padding: 0 0; margin: 0 0; text-align: center;
    font-family: Verdana, Arial, Helvetica, sans-serif; 
    font-weight: 700; font-size: 11px; }

.btn170
  { background-image: url('images/button_170.gif');  }   
.btn170_down
  { background-image: url('images/button_down_170.gif'); }

… and JavaScript code …

var topMenuItems = [] ;

function addClass(id,sfx) {
  var se = getElement(id) ;
  if (se.className.indexOf(sfx) < 0) se.className = se.className + sfx ;
}
function removeClass(id,sfx) {
  var se = getElement(id) ;
  var i = se.className.indexOf(sfx) ;
  if (i > 0) se.className = se.className.substr(0,i) ;
}

function menuShow(id) {
  var se = getElement(id) ; se.menuActive = true ; 
  showElement(id + "_sub") ; addClass(id+"_main","_down"); }

function menuHide(id) { 
  var se = getElement(id) ; se.menuActive = false ; 
  hideElement(id + "_sub") ; removeClass(id+"_main","_down"); }

function menuGo(id,l) { menuHide(id); location.href = l; }
function menuSelect(id) { menuHide(id) ; }

function menuClick(id) {
  var i,se ;
  se = getElement(id) ;
  if (se.menuActive) {
    menuHide(id) ; return ;
  }
  for (i = 0 ; i < topMenuItems.length ; i++) {
    if (topMenuItems[i] != id) menuHide(topMenuItems[i]);
  }
  menuShow(id) ;
}

function menuRegister(id) { 
  topMenuItems[topMenuItems.length] = id ;
}

I will not try to explain what this code does, as it’s way too painful. As I’ll walk through the refactoring process, I’ll show you the changes I’ve made and the stupidities in the original code.

Poor man's AJAX: Browser-side XSLT transformation in IFRAME

One of the oldest methods to provide AJAX-like functionality in a browser that does not support XmlHttpRequest object is loading the dynamic content into a hidden IFRAME. It’s an unreliable technique that should not be used, but it can still provide a viable workaround in scenarios where you need to perform browser-side XSLT transformation in browsers with lousy JavaScript-based XSLT support (it looks like Chrome is still in this category).

This is a conceptual step-by-step description of the process:

  • Create a hidden IFRAME in the main page.
  • Define a callback function in the main page that will receive the results of the transformation. This callback function will have to insert the transformation results into the main page’s HTML/DOM structure.
  • When you need to download additional content, set the IFRAME.href attribute to the URL of the dynamic content.

You should use a timeout in the main page to capture failed loads of the dynamic content. The timeout code should display an error message and kill the download process in IFRAME by resetting the IFRAME.href attribute.

  • The dynamic content loaded into the IFRAME should have XML MIME type and contain the xml-stylesheet processing instruction. This will cause the browser to perform XSLT transformation on the XML data.
  • The resulting HTML should include JavaScript call of the callback function in the parent frame, for example <body onload="parent.callback(document.body.innerHTML)">

Alternatively, you can use the onload handler in the IFRAME element to call the callback function.

JavaScript: the good parts

If your brain hasn't been polluted with awful JavaScript practices yet (or if you're willing to submit to a proper brainwashing), read the JavaScript: The Good Parts book from Douglas Crockford. He covers what he believes (and is usually right) are the good parts of JavaScript, resulting in scalable, easy-to-maintain code. Although the book targets beginner audiences (or programmers not yet familiar with JavaScipt), it's an interesting read for anyone who wants to write better JavaScript code. Even I found a few interesting topics (for example, multiple ways to implement object constructors and inheritance) after working with JavaScript for 15+ years.

jQuery: Read This First

If you're paid for your programming efforts (or if you put even a marginal value on your time), I would strongly recommend that you buy and read a few jQuery-related books before jumping into the code writing. This approach is usually way more efficient (and gives you a broader picture) than relying on snippets provided by good uncle Google. If, on the other hand, you believe everything should be free, be my guest ... but then your time is probably worth approximately as much :)

The following two books were a perfect fit for my level of JavaScript/CSS experience. The first one is a great step-by-step introduction to jQuery (focusing on jQuery, not on mundane JavaScript or CSS details) and the second one serves me as a great paper reference (I am old enough to prefer paper to pixels).

jQuery.convert++

Readers of articles I wrote for InformIT have probably noticed that I've avoided using high-level JavaScript libraries and relied on thin browser abstraction layers: Sarissa for AJAX and X library for cross-browser DOM/DHTML compatibility.

Recently I've decided to try jQuery and got persuaded within a day. My new projects are using jQuery ... and you'll see a number of reasons in my future blog posts. Repetitive operations that I had to code previously became much simpler and more streamlined with jQuery functions.

Poor man's capitalization in JavaScript

I wanted to have simple capitalization in JavaScript (the first letter of the string should be upper-case, the rest of the string unchanged). Although the String object provides uppercase and lowercase functions, there is no capitalization function. The simplest expression I could come up with is this:
txt.substr(0,1).toUpperCase()+txt.substr(1)
Do you have a better solution?

Fix Your Web Site Performance Problems (InformIT article)

If you've realized that you might have HTTP-related performance problems when reading my Why is my web site so slow article published by InformIT, you can find a variety of quick fixes and more permanent solutions in my Fix Your Web Site Performance Problems article (also published by InformIT).

Create post excerpts in Blogger

One of the features sorely missing in Blogger is the ability to write an excerpt for your post (Wordpress supports several different methods), so I had to write my own JavaScript solution that provides functionality similar to the more tag in Wordpress. It hides parts of the post’s text and displays a More button which reveals the hidden text. The hidden text is enclosed within SCRIPT tags:

<script>startHide()</script>
… extra text …
<script>endHide()</script>

I’m including a JavaScript library from one of my web sites into the Blogger template. If you want to have a Blogger-only solution, include the following JavaScript code in your template:

var isMainPage = 0;
var hideCount = 0;

function dw(t) { document.write(t); }

function setMainPage() { isMainPage = 1; }

function startHide() {
hideCount ++ ;
if (!isMainPage) { dw('<div id="show_'+hideCount+'">') ; return; }
dw ('<p class="hideMenu" id="hideMenu_'+hideCount+
'"><a href="javascript:showRest('+hideCount+')">More ...</a></p>');
dw ('<div id="hide_'+hideCount+'" style="display: none;">');
}

function showRest(id) {
var e = document.getElementById('hide_'+id);
if (e && e.style) e.style.display = "" ;
e = document.getElementById('hideMenu_'+id) ;
if (e && e.style) e.style.display = "none" ;
}

function endHide() {
dw ('</div>') ;
}

Microsoft's XMLHttpRequest Objects

If you don't want to use a wrapper library like Sarissa and plan to work out the differences between Microsoft's and other vendors' implementation of XMLHttpRequest, you'll find a lot of details in this post by Jonathan Snook.

Enhance Your AJAX Applications with Visual Cues

In the Enhance Your AJAX Applications with Visual Cues article published by InformIT, I'm describing various techniques you can use to help your users get the most out of your AJAX application.

Add a truly modal dialog box to your web application

If you do a search on "JavaScript Modal Dialog", you'll get a lot of hits and a variety of solutions … but most of them tend to forget that the browser users can use the keyboard keys as well as the mouse to navigate around the web page. The solution I'm describing in my new InformIT article Building Modal Dialogs into Your Web Application addresses both input devices, giving you a truly modal dialog box that captures all key- and mouse clicks.

A few must-read JavaScript documents

If you're serious about JavaScript programming, read these first:

Keyboard shortcuts in web user interface

Keyboard shortcuts can make an application significantly quicker to use; however, if you want to implement then in your web applications, you'll have to wade through murky waters of non-standard keyboard events (the only major browser event type not standardized in currently supported DOM standards). I've documented most of the pitfalls (and the workarounds) in my InformIT article Adding Keyboard Shortcuts to Your Web User Interface.

Firefox vulnerabilities when using data: or jar: protocols

Just stumbled across two articles describing vulnerabilities in the ways Firefox handles the data: and jar: protocols. If you're at least a bit interested in securing web applications (or your network), read them (and try to understand what's going on). It looks like the data: protocol vulnerability is a bug, but the jar: thing is a clear FAD (Functions-As-Designed).

Fading background made simple

I wanted to implement fading background for HTML elements that are changed in the background based on XMLHttpRequest calls made in my AJAX applications, the idea being that the user's attention would shift toward the changed element without the visual cue being too intrusive. As I've had excellent experience with the X library, I started my search there … and found the xAnimation.rgb function that does exactly what I've needed. The following short function changes the element's background from page default (white) to dark yellow and back in a second:
function setFading (e) {
  e.style.backgroundColor = "#FFFFFF";
  if (!e.xa) e.xa = new xAnimation();
  e.xa.rgb(e,"background-color","#EDC226",1000,1,1);
}