Find Facebook Friends with Your Facebook Connect Application
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
jQuery: Read This First
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++
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
txt.substr(0,1).toUpperCase()+txt.substr(1)Do you have a better solution?
Fix Your Web Site Performance Problems (InformIT article)
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
Enhance Your AJAX Applications with Visual Cues
Add a truly modal dialog box to your web application
A few must-read JavaScript documents
Keyboard shortcuts in web user interface
Firefox vulnerabilities when using data: or jar: protocols
Fading background made simple
function setFading (e) {
e.style.backgroundColor = "#FFFFFF";
if (!e.xa) e.xa = new xAnimation();
e.xa.rgb(e,"background-color","#EDC226",1000,1,1);
}