29 September 2006

Simulating DoubleClick-Edit Behavior on the Web

In the world of Domino Web Design, I've found a neat little procedure for simulating the "doubleclick a document that you're currently reading to put it into edit mode" behavior inherent to the Notes Client:

1) First, create a simple button with the formula code "@Command([EditDocument])" for its Client code (don't worry, it'll be carried over to the web as long as you have "Use JavaScript for generating pages" selected in your database properties).

2) Go to the HTML tab for the button's settings, give it an ID, and then enter "display: none;" into its Style box. This will prevent it from being seen on the web.

3) Finally, enter the following code into the "onDblClick()" event for your form:

document.getElementById("[your edit button's ID]").click();

(Replace [your edit button's ID] with your edit button's ID, if you were wondering. :P )

That's it! Now, whenever the user doubleclicks anywhere on the document during read mode, they'll be automatically catapulted into edit mode. They're probably already expecting this behavior, so they'll definitely thank you!

Of course, you may notice that this doubleclick behavior happens in edit mode, as well (running @Command([EditDocument]) in edit mode takes the document out of edit mode without saving) -- I like this because its a feature that I believe should be in notes, but isn't. If you want it to stop, just add a condition to the onDblClick() event featuring a variable that captures the document's edit status. It's that simple.

FlashBlock :: Firefox Extensions

Flashblock :: Mozilla Add-ons

Well, I just found my new favorite Firefox extension. "Flashblock" actually enables you to selectively allow Flash to run on the websites you visit, something I was unable to do until now. I had been using a great extension called "NoScript" until now to do this, but NoScript is really made to block JavaScript -- its Flash-blocking capabilities are just extra. Not only that, but you can't selectively allow Flash to run -- once you clear a domain in NoScript, all flash runs from that domain from that point on.

Now, I'll still be using NoScript to selectively allow JavaScript to run on my computer, but Flashblock's capabilities are amazing! Yay!!

Easy Form Effects with moo.fx (Update)

mdm-adph: Easy Form Effects with moo.fx

There's something I forgot to mention yesterday - the script I posted is actually usable in HTML 4.01. I had to make sure of this, because that's what Domino servers still use... -_-'

It's one of the main reasons why I chose the "Opacity" filter instead of the "Height" moo.fx filter (even though the Height filter actually would have been a bit neater in my situation) -- the Height filter simply doesn't work in HTML 4.01.

28 September 2006

Easy Form Effects with moo.fx


Here, I'll try and make this quick and get it to work:

It's quick and dirty, but it works! If you'll notice, each checkbox controls a form object -- two control input fields, and two control drop-down menus. Not only do the objects fade in and out (thanks to moo.fx!), but they cannot be hidden if they have been altered.

(IE users: the fade-in and fade-out effect does not work with select objects in your browser, because it stinks. You won't see it.)

This code is very simple to implement -- simply include the library I'm about to show, and then create a line like the following for every checkbox-object pair:

setCheckBoxHandler('[checkbox id]', '[object id]', '[hide, disable]');

Replace [checkbox id], [object id], and choose either "hide" or "disable", of course!

Also, setCheckBoxHandler() has to be called in the onLoad() event for your page (or just put it at the end of your document, whatever suits you best), otherwise the script has nothing to work with, and you'll get errors.

I usually use "hide" with input fields and "disable" with select objects, but it works either way.

So, without further adieu, the code!

// needs moo.fx, the moo.fx.pack, and prototype.lite
// available from http://moofx.mad4milk.net/


// the transition time, in seconds,
// for the checkbox handler transparency effect
var moofxTransitionTime_01 = 0.25;

// the transition time, in seconds,
// for the checkbox handler transparency effect
// (<select> objects, only)
var moofxTransitionTime_02 = 0.50;

// the lower range that <select> objects should fade out to,
// on a scale from 0.0 to 1.0 (with 0 being completely transparent)
var moofxTransition_LowerRange = 0.3;

// the text of the default option choice in any <select>
// objects that have a checkbox handler
var selectObjectDefault = 'none';


// convert user-defined variables to program specs
var mooTime_01 = moofxTransitionTime_01 * 1000;
var mooTime_02 = moofxTransitionTime_02 * 1000;
var mooFloor = moofxTransition_LowerRange;

// initialize handlers array
var moofxHandlers = new Array();

// A shorthand way of referencing the DOM
// From the Dojo ajax toolkit
function byId(id)
return document.getElementById(id);

objectValue(<DOM object>)

Attempts to retrieve value from different types of DOM objects--
Takes, as an argument, an actual object (not just its Id).
function objectValue(obj)
if (obj.options)
// for select objects
return obj.options[obj.selectedIndex].text;
// for everything else: input boxes, textareas, radio buttons
return obj.value;

setCheckBoxHandler(<checkbox id>, <target id>, <hide, disable>)

Creates a connection between a checkbox and a target--
typically, use "disable" as the third parameter for <select>
objects and use "hide" for everything else.
function setCheckBoxHandler(checkBox, target, operation)
// Create function to assign to checkbox's onclick() event
byId(checkBox).onclick = function ()
if (byId(target).options)
// 1) If target is a <select> object...
// 1.1) ...and its value is equal to the default...
if (objectValue(byId(target)) != selectObjectDefault)
// 1.1.1) ...cancel execution.
return false;
else if (byId(target).value.length > 0)
// 2) Else, if target isn't a <select> object and its value has length...
// 2.1) ...cancel execution.
return false;

// Operate checkbox toggle if this point is reached
checkBoxToggle(checkBox, target, operation);

if (operation == 'hide')
// if "hide" operation is desired, create short-timed moofx object
// with inline onComplete function
moofxHandlers[target] = new fx.Opacity(byId(target),
{duration: mooTime_01, onComplete: function ()
// hides target *after* transition
// only if checkbox isn't checked--
// this will happen after target is "dimmed"
if (!(byId(checkBox).checked))
byId(target).style.display = 'none';

// hide target initially, and perform transition so that moofx
// knows what state the target is in
byId(target).style.display = 'none';
// if "disable" operation is desired, create longer moofx object
// with inline onComplete function
moofxHandlers[target] = new fx.Opacity(byId(target),
{duration: mooTime_02, onComplete: function ()
// disables target *after* transition
// only if checkbox isn't checked--
// this will happen after target is dimmed
byId(target).disabled = true;

// disable target initially, and perform transition, dimming partway
byId(target).disabled = true;
moofxHandlers[target].custom(1, mooFloor);

checkBoxToggle(<checkbox id>, <target id>, <hide, disable>)

Operates a connection between a checkbox and its target--
called from the checkbox's onclick() event.
function checkBoxToggle(checkBox, target, operation)
if (operation == 'hide')
// 1) If "hide" operation is desired...
// 1.1) ...and checkbox is checked...
if (byId(checkBox).checked)
// 1.1.1) ...make target visible so transition can be seen
byId(target).style.display = 'block';

// 1.2) perform transition, even if this is a "dimming" event--
// 1.2) onComplete moofx handler will control target visibility
// 1.2) in that case.
else if (operation == 'disable')
// 2) If "disable" operation is desired...
// 2.1) ...and checkbox is checked...
if (byId(checkBox).checked)
// 2.1.1) ...enable object and make opaque.
byId(target).disabled = false;
moofxHandlers[target].custom(mooFloor, 1);
// 2.2) ...and checkbox isn't checked
// 2.2.1) ...just dim object-- onComplete handler will
// 2.2.1) control target disabled status.
moofxHandlers[target].custom(1, mooFloor);


init() // run this during onLoad()
setCheckBoxHandler('cbox-input-01', 'input-01', 'hide');
setCheckBoxHandler('cbox-input-02', 'input-02', 'hide');
setCheckBoxHandler('cbox-select-01', 'select-01', 'disable');
setCheckBoxHandler('cbox-select-02', 'select-02', 'disable');

// -->

<input type="checkbox" id="cbox-input-01" /><input id="input-01" />

<input type="checkbox" id="cbox-input-02" /><input id="input-02" />

<input type="checkbox" id="cbox-select-01" /><select id="select-01" />

<input type="checkbox" id="cbox-select-02" /><select id="select-02" />



Wow -- I would love to implement this simple effect in the app I'm working on, but, unfortunately, I couldn't find any information about downloading the source libaries on this site. (I guess I could just download them manually from the source code, but I'm lazy.) I'm guessing it's part of the new mootools package, but I couldn't find any info on their site about this, either.

(Isn't this guy's English a hoot? Though, of course, I wish I could speak Russian half as good.)

Update: Looks like the guy's got a download link on there now. And, thus, I venture forth.

26 September 2006

Disabling Select Objects via JavaScript -or- When False is True

HTML DOM disabled Property

Yeah, just in case you were wondering (like I was, about half an hour ago), if you're trying to set the disabled status of a <select> object programmatically, "false" (with the quotes) is not the same thing as false (without the quotes).

Take that, ye naysayers whom doth hark that JavaScript be very horribly structured with loosely recognized data types!

For example, if you're trying to set the disabled status of a Select object by the "checked" status of a checkbox:

byId("[selectObjectId]").disabled =
(byId("[checkboxId]").checked ? "false" : "true");

...is not the same as...

byId("[selectObjectId]").disabled =
(byId("[checkboxId]").checked ? false : true);

Trust me -- this may be common knowledge to you, but I was surprised (though gladdened -- tightly controlled data types are a programmer's best friend).

(By the way, the byId() function is part of the dojo JavaScript toolkit -- it simply replaces having to type "document.getElementById("[id]")" every time you want to reference something through its id.)

25 September 2006

No onChange for Checkboxes in IE

HTML DOM Checkbox Object

Ha! I've finally figured out what I've been sitting here all farking morning trying to understand!! Apparently (in IE 6, at least), there is no onChange handler for checkboxes in IE. Great. I guess I'll try and use onClick instead, and then just check for the checked status of the checkbox.

(IE, oh IE, why do you have to be so difficult?)

Me Speak English Gooder Than You

Your Linguistic Profile:
60% General American English
25% Dixie
10% Yankee
0% Midwestern
0% Upper Midwestern

22 September 2006

Bloomberg.com: Advanced Micro Will Sell Chips to Apple in Future

Bloomberg.com:Advanced: Micro Will Sell Chips to Apple in Future

This is what I've been saying should've happened the minute Apple announced it was leaving the PowerPC platform and moving to x86 -- let's hope for the best!

(If you're wondering, I'm no AMD fanboy -- half of my computers run Intels and the other half AMD's -- but I do like having a choice, and I don't like Intel's corporate abuses of the marketplace.)

21 September 2006

Motherfuckers Act Like They Forgot About Printed View

Book of Lotus, Chapter 2, Verse 1:
And, nay, nothing came out when my user went to Print, because I had forgot to make my tables dynamic.
Book of Lotus, Chapter 2, Verse 2:
For they only saw half of the screen, and their document was useless. And there was much weeping and gnashing of teeth.

20 September 2006


Looks like my supervisor found a little error in the client app that I've been working on recently -- when testing it with a test ID, she wasn't able to run the submission action for the form that I had created...

Turns out that my submission action script had an interesting feature -- a double save. Why? Well, because I wanted to use the neat inline validation scripts inherent to every field, that's why! In my final submission script, a save was performed once to automatically run the validation scripts and check to see if all fields are filled, etc., and then depending upon the result of that save, several other fields are set. If the validation scripts don't pass, the rest of the submission script isn't run. I found this very handy to prevent having to put a bunch of lines filled with "@If(FIELD Blah = ""; Blah; Blah)" in my pretty, wonderfully-formatted action script. The document was then saved again programmatically to avoid the user having to see a save box.

Now, that worked fine and well for me and my Manager-level user access, but what happens when a lowly Author-level user tries to do it?

Why, they're able to do the first part of the save, but then the document is no longer new and they get a crappy error box when the rest of the script tries to run!

Hey -- give me a break. I'm new at this user-level stuff, okay? :P

19 September 2006

Poll: Americans don't want net neutrality (or maybe they don't know what it is)

Poll: Americans don't want net neutrality (or maybe they don't know what it is)

This is just sad. Just... sad.

Cookie Deletion: Mozilla/IE cont.

I found out the solution to my problem that I had yesterday!!

It turns out that -- as far as I can tell -- if you set a cookie and assign it a path (i.e., "path=/") and you want to be able to delete that cookie in Mozilla, you better make sure and include a simple path assignment in the deletion string, too. If you don't, the cookie doesn't get deleted. In IE, the cookie is deleted as long as the name is the same.

Now, I don't which of these happens to be the correct behavior -- I guess I could go read some RFC specs, but, to tell you the truth, I can't make hide nor hair of those things. They might as well be written in Greek.

18 September 2006

Cookie Deletion: Mozilla/IE

All right, can anyone tell me why this function:

function deleteCookie(name)
if (getCookie(name))
document.cookie = name + "=" +
"; expires=Thu, 01-Jan-1970 00:00:01 GMT";

isn't deleting my cookies in Firefox anymore?

I don't remember changing anything important, except that I've since added a ";path=/" to all cookies that my script creates now. I wonder if you have to include the ";path=/" when deleting cookies in Mozilla, too...

13 September 2006

Ajax IE Caching Issue

Thank goodness I'm not the only one having this problem. That's all I can say.

This problem made me pull my hair out for weeks, and I'm glad to finally know that it was nothing that I did. Oddly enough, this bug only happened on select XML files that Domino was serving up (it seems that if you have the @Now() function anywhere in your view, IE won't cache it -- don't ask me how I know).

12 September 2006

IBM Redbooks | VSE/ESA as a Web Server

IBM Redbooks | VSE/ESA as a Web Server

Wow... now here's a blast from the past.

It's an old IBM Redbook Article about how to get a mainframe running VSE/ESA to work as a web server.

My-oh-my -- how the mighty have fallen.

(The idea of using a VSE/ESA system to serve web pages is enough to make me weep. I learned on one of these in college -- it was big, and huge, and programming on it made you kind of feel like you were communicating with a HAL 9000.)

Facebook to Adopt Open-Admissions Policy

Advertising Age - Digital - Facebook to Adopt Open-Admissions Policy

Yeah... not having an open-admissions policy is part of what made facebook great. Well, money talks, like it always does.

This is kind of like Facebook getting an STD or something. Sickening.


mootools - From the creators of moo.fx

It looks to be a pretty good little JavaScript library -- from what I've heard, it's absolutely tiny compared to the two most popular libraries out there (Prototype and Scriptaculous). By tiny, I mean it's like 20kb compared to over 100kb for the Prototype/Scriptaculous combination.

Now, I've never used the Prototype/Scriptaculous (or really any JavaScript engine, for that matter), but I really, really like the code that the team of moo.fx makes -- it's compact, it's clean, and from what little that I've seen of it, it works.

I'll definitely have to start using some kind of JavaScript library in the near future -- my employer is going to want to me start "webifying" pretty heavily, and that means emulating a lot of native Notes behavior, such as dragging and dropping files to folders, etc.

[From Ajaxian]

11 September 2006



Well, apparently JSON is now an RFC standard, though I've never heard of the site "rfc-editor.org" before. However, it seems pretty legit.

(via SleepyHead)

08 September 2006

Firefox Security

Something else I just learned -- for a long time, I've been wondering why sometimes I have to enter in my master password in Firefox and sometimes I don't. What's the connection?

Well (and this may just be in the latest versions), it turns out that you only have to enter it in once per browsing session. Firefox knows you're its master for the rest of the session, and fills in password and username fields appropriately.

I'm stupid, I know, but seriously -- I just found this out.

Programmer's Pane Tricks

I just found out the neatest thing -- if, while editing a form, you'd like to expand your programmer's pane to fill up the entire screen (but are tired of clicking on and dragging the little bar), just double click the title bar of your programmer's pane. It will immediately expand to fill up the entire display area.

Need to see the work pane again? Just doubleclick on the title bar once more.

06 September 2006

Slashdot | Will Solve Captcha for Money?

Slashdot | Will Solve Captcha for Money?

A pretty neat discussion on Slashdot about spammers hiring teams of Russians and Indonesians and whoever else to solve batches of Captchas per hour. (Golly, the world's getting to be a complex place...)

Seriously, though -- they can hire as many people as they want to, it's never going to be enough. Comment spam and message board spam gets its power through automated bots, and Captchas have effectively killed them (at least until some pretty far advanced AI comes out, but that won't be for a long, long time).



I think...

I fixed it.

(Don't tell anyone, or they'll give me something else to do!)

(By the way, don't ever add a new field to a form and then try and reference it in any old documents that you may have already created. If you're like me, you'll sit there for hours wondering why your documents just keep sending Form 500 errors.)

05 September 2006


I finally fixed my problem with a few select views' XML files not showing up! (Turns out, for whatever reason, IE was caching them, eventhough I had caching disabled. Oh, silly IE...)

Unfortunately, there's now another bug that's cropped up -- turns out I've made a change in the past week or so that's broken the displaying of my old documents. Back to the drawing board...


Wired.com: Spam Blogs = Trouble

Just read all of this really neat article about the growth of "splogs," or fake blogs designed as spamming portals.

Interestingly enough, the solution that the author talks about on the last page of his article (i.e., a kind of net identity card) has already been thought of -- unified authentication tokens. Everybody will have to be carrying around one of these several years from now, if you're hoping to use the internet.

01 September 2006

A bug? A bug? Did I just find a bug?

Seems like it to me.

Get this -- my formula code for the "HTML Head Content" of my web form I'm working on had the following:

REM {Here are necessary HTML headers.};
"<meta http-equiv=\"CACHE-CONTROL\" content=\"NO-CACHE\">" +
"<meta http-equiv=\"PRAGMA\" content=\"NO-CACHE\">";

REM {Here is a collection of variables used by JavaScript that are captured from Domino.};
"<script type=\"text/javascript\">" +
" var webDbName = '" + @WebDbName + "';" +
" var targetView = '" + @UrlQueryString("targetView") + "';" +
" var canEditJournal = " + @If(@IsNotMember("[EditJournal]"; @UserRoles); "false"; "true") + ";" +
" var canEditTask = " + @If(@IsNotMember("[EditTask]"; @UserRoles); "false"; "true") + ";" +
" var isIncidentManager = " + @If(@IsNotMember("[IncidentManager]"; @UserRoles); "false"; "true") + ";" +
" </script>"

Nothing too fancy -- just some Domino formula variables and Role information that I'm bringing into JavaScript.

However, I noticed that my form was starting to act funny -- almost like it was caching when it shouldn't have been. I checked the rendered HTML code by viewing the source in IE, and guess what I found?

Only the second part was being sent to the browser (the stuff with the meta tags was being ignored). Bug? Feature? Beats me. I eventually had to go with something like:

REM {Here is a collection of variables used by JavaScript that are captured from Domino,};
REM {as well as necessary <meta> tags.};
"<meta http-equiv=\"Expires\" content=\"0\">" + @Char(13) +
"<meta http-equiv=\"Cache-Control\" content=\"must-revalidate\">" + @Char(13) +
"<meta http-equiv=\"Cache-Control\" content=\"no-cache\">" + @Char(13) +
"<meta http-equiv=\"Pragma\" content=\"no-cache\">" + @Char(13) +
"<script type=\"text/javascript\">" + @Char(13) +
" var webDbName = '" + @WebDbName + "';" + @Char(13) +
" var targetView = '" + @UrlQueryString("targetView") + "';" + @Char(13) +
" var canEditJournal = " + @If(@IsNotMember("[EditJournal]"; @UserRoles); "false"; "true") + ";" + @Char(13) +
" var canEditTask = " + @If(@IsNotMember("[EditTask]"; @UserRoles); "false"; "true") + ";" + @Char(13) +
" var isIncidentManager = " + @If(@IsNotMember("[IncidentManager]"; @UserRoles); "false"; "true") + ";" + @Char(13) +
" </script>"

Why it makes a difference is beyond me (of course, I'm fairly new to Domino), but now the entire thing is being sent to the browser.

U.S. shocked by Greece 101-95 in World semifinals

SI.com - NBA - U.S. shocked by Greece 101-95 in World semifinals - Friday September 1, 2006 7:37AM

You know, there used to be a time when US players would whoop anyone's ass if they dared step into a basketball stadium with them.

Apparently, thanks to the showboating and terrible work ethic present in the NBA today, those days are over.