Archive for September, 2006

“Save as” real data when the page is generated with Javascript document.write

September 27, 2006

I ran into an interesting problem today that involved the need to “Save as” a web page that is 99% generated with Javascript document.writes. Of course, saving this page will give you only the javascript code, not what you are seeing on the screen – in my case, lots of table rows created by parsing a text file.

Having javascript read in a text file meant I was doing everything local, using FileSystemObject, so that was (A) Why I could not use a server side language to generate the file, and (B) good that I had the proper security to read and write files.

I found a lot of people pulling their hair out over this and no real solution. If you are working locally, can use FileSystemObject and need to save actual data, not javascript document.writes, then I think this may help you.

First off, I import my text file, parse the data, and document.write it into tables, such as:

document.write("<tr'>");
document.write(" <td valign='top'>"+(i+1)+"</td>");
document.write(" <td valign='top'>"+sfc[0]+"</td>");
document.write(" <td valign='top'>"+sfc[1]+"</td>");
document.write(" <td valign='top'>"+sfc[2]+"</td>");
document.write("</tr>");

On screen, I may get something like:

1 01-002 Artist Need to remove border from the image.
2 01-003 Programmer Make the next link disabled until they click on ‘Note’
3 01-003 Programmer Change the direction text to “Continue” when they click on ‘Note’

But if I try to save that page to the desktop, I get the javascript document.writes listed above… until you do this:

Surround your javascript with a div and give it an ID:

<body>
<div id=”content”>
<script>
//… tons of JS code to parse and write your document.
</script>
</div>
</body>

Now, right after that div, call a function and pass it the div’s innerHTML:

<body>
<div id=”content”>
<script>
//… tons of JS code to parse and write your document.
</script>
</div>
<script>
saveHTML(document.getElementById('content').innerHTML);
</script>
</body>

This is going to take the HTML contained within the div and send it to a function. It sends the javascript code, but also it sends the generated HTML table. Perfect! Now, in that function, I split the code on the closing </script> tag to get rid of all my JS code, and wrap what’s left in simple html, head, body tags and write a new .html file.

Now, all we have to do is redirect. So after our call to saveHTML, add:

<body>
<div id=”content”>
<script>
//… tons of JS code to parse and write your document.
</script>
</div>
<script>
saveHTML(document.getElementById('content').innerHTML);
document.location.href = html;
</script>
</body>

Oh, and the variable ‘html’ is just the location/filename I use to write the file to, and now redirect to. For instance

var html = “c://some/directory/to/write/to.html”

Now, once we redirect, we are on a true HTML page with no content being generated by Javascript and we can successfully “Save as” and have a document with actual data in it.

Hope this helps.

Simple Div Scrolling

September 25, 2006

I needed a simple interaction to scroll an overlay:hidden div when the mouse is over a certain area. The resources I found online where bloated or part of larger packages that you had to buy, so I threw this together.

Here’s what screen looks like:

scrollingDiv screenshot

bullet_1 We have a list of connected users to our application, within a limited space.
bullet_2 This area scrolls the user list up. This area is brighter because it is active; the mouse is over it.
bullet_3 This area scrolls the user list down.
 

The code behind the layout is a three row table. The top and bottom rows contain the code to scroll, and the middle row has a div, overflow set to hidden, that contains our HTML for listing the users. Briefly:

<table width="300" border="0" cellspacing="1" cellpadding="0" bgcolor="#ffffff">
<tr>
<td bgcolor="#F3F9F1" width="100%" id="peopleUp" onMouseOver="scrollStart('Up', 'people', 'peopleUp');" onMouseOut="scrollEnd('peopleUp');">
<img src="gfx/spacer.gif" height="5" width="1">
</td>
</tr>
<tr>
<td>
<div id="people" style="height:100px; overflow-y:hidden; overflow-x:hidden;">
Loading user list…
</div>
</td>
</tr>
<tr>
<td bgcolor="#F3F9F1" id="peopleDown" onMouseOver="scrollStart('Down', 'people', 'peopleDown');" onMouseOut="scrollEnd('peopleDown');">
<img src="gfx/spacer.gif" height="5" width="1">
</td>
</tr>
</table>

Now, our JS on the page contains:

var ourInterval;
var origColor = "#F3F9F1";
var overColor = "#36FF00";
var scrollSpeed = 50;
var scrollHeight = 5;

Most of the above vars should be self explanatory, but just in case, scrollHeight is how many pixels the div moves up of down every millisecond, which is determined by scrollSpeed.

Next we have our functions that are called by the mouse over and out of the table’s top and bottom TD.

function scrollStart(direction, divID, elementID){
//CHANGE THE BACKGROUND COLOR OF THE TD THE MOUSE IS OVER
document.getElementById(elementID).style.backgroundColor = overColor;
// REPEATED CALL EITHER scrollUp OR scrollDown
ourInterval = setInterval("scroll"+direction+"('"+divID+"')", scrollSpeed);
}
function scrollEnd(which){
// OUR MOUSE IS OUT, SO RETURN TD TO ORIGINAL COLOR
document.getElementById(which).style.backgroundColor = origColor;
// STOP CALLING THE SCROLL FUNCTION
clearInterval(ourInterval);
}

And finally:

function scrollUp(which){
// SET THE SCROLL TOP
document.getElementById(which).scrollTop = document.getElementById(which).scrollTop - scrollHeight;
}
function scrollDown(which){
// SET THE SCROLL TOP
document.getElementById(which).scrollTop = document.getElementById(which).scrollTop + scrollHeight;
}

Quick and easy. The scrollUp and scrollDown functions could even be combined… we could just send it the direction var in scrollStart and then determine if we should add or subtract our scrollTop with that.

I hope this helps if you are looking for an easy way to handle div scrolling.

TNT Feed Parser

September 19, 2006

I recently saw mention of a web app called Fwicki via Ajaxian. Fwicki is labeled as a “RSS reader that you can tailor to your interest” and that remind me of a personal project I was working on a few months ago called TNT Feeder.

tnt_example

bullet_1 Add a RSS feed here. You can see in the example, I have three feeds; Techcrunch, Digg and Slashdot
bullet_2 Each feed is expanded and inside the feeds are filters. The one selected is called “Just Titles and Diggs” under the Digg feed, which, you guessed it, took the feed from the Digg site, parsed it, and spit out a feed that only contained Titles and digg counts
bullet_3 The selected filter in step two causes this area to populate with the feed/filter information
bullet_4 The is the link to the feed that will generate based on my filter
bullet_5 Here are the nodes contained in the original feed. I can check off which nodes I want in my parsed feed, as well as specify a character limit on the data in that node
bullet_6 Set up the number of items to return
bullet_7 Set up the access to this feed. Whoever I give the parsed RSS link to, I could limit the number of times they can request new data

I don’t think this project is a tool worth building for mass use, but it sure was a fun experiment and also helped me get more practice navigating XML nodes with PHP.