31 August 2006

Arggh!!

I just don't get it. On my web-based JavaScript view loader that I've created, there's three views that just.won't.farking.work on my supervisor's computer, but on mine they work fine! What the hell, eh?

I thought that I had recreated this bug once, but I guess I was wrong. Time to go back to the drawing board.

The only difference that I can see between the views that don't work and the ones that do is the fact that the ones that do work have a @Now() function in one of the columns... Why that would make a difference is beyond me, because everything that I'd been taught to believe says that @Now() functions are a bad idea to put in views!

30 August 2006

Cookies Can Hurt

mdm-adph: Cookie Functions: Revealed!

Remember my post about my custom cookie functions? They were great, and that's the truth. However...

There were a couple of things I could've done better, and one in particular that was just pure sloppiness. -_-'

For one thing, you can't set how long you want the expiry date to be -- I just hard-coded it at an hour for my purposes. It's an easy fix, however, and I'll probably change that in the future.

The second (and biggest) thing was my lack of a path attribute! (It comes right after the ";expires=" part of the cookie.) Yep... and you just know it would come back and bite me in the ass.

As I've found out, make sure and at least hard-code a ";path=/" after the expiry attribute, or else cookies you create with new documents in Domino (which are usually referenced in the URL field of your browser with their actual form names) will not be accessible to already-created documents (which are referenced by their UNID's). Ouch! Took me half an hour to figure this out, and it was staring me in the face the whole time.

The tweaked code:
// Set the cookie
document.cookie = name + "=" + escape(data) + ";expires=" + exDate + ";path=/";

Slimming photos with HP digital cameras










Slimming photos with HP digital cameras

Wow -- does anyone else find something like this totally creepy? (Besides, it's something that William Gibson wrote about almost 20 years ago in his novel Mona Lisa Overdrive. Or was it Count Zero?)

Not to mention the fact that the people in these pictures who are being "slimmed" by HP's software don't even have weight problems at all... Notice how subtle the effect is? If you're actually overweight and worried about how you look in pictures, this software isn't going to do crap for you.

Technology gone awry? A band-aid fix of a terrible problem with obesity that America has? You be the judge.

29 August 2006

Last-minute Changes

Having to do some last minute changes to the project that I submitted about a week or two ago because of the tropical storm bearing down on Florida. Here's to hoping that I get it to work!

Wired News: Is Ubuntu Linux for You, Too?

Wired News: Is Ubuntu Linux for You, Too?

Just a neat article on Wired.com about the new Linux distribution that's taking the world by storm. I run it on both physical machines and by virtualization.

...Speaking of virtualization, you just have to check out something called VMWare -- download the player, and then get the Browser Appliance. This will be especially amazing if you're doing this on a Windows box. Just try it out -- trust me.

28 August 2006

Fiddler HTTP Debugger - Fiddler

Fiddler HTTP Debugger - Fiddler

A very neat tool that I learned about in my recent Lotus Notes Training class (the instructor was kind of a hacker and wasn't ashamed about it). I still haven't learned out how to use it (I've only had it five minutes), but I'm going to learn!

21 August 2006

Blimp Cell Service Idea Floated

Blimp Cell Service Idea Floated: Wired.com

This sounds like a very good idea, and, just to me, it sounds a lot more possible than trying to get an internet-providing satellite to stay in a Low Earth Orbit.

The makers of the $100 Laptop need to partner up with this guy -- this could provide the internet access to those third-world countries they're trying to supply with the laptops.

18 August 2006

Client Programming and NAB Lookups

I've actually been programming in the Client for the past couple of days, so I haven't even really had a browser open (hence my lack of posting).

Anyway, I've been wrangling with a problem that I've just gotten fixed this morning -- how to do @DBLookup()'s of the NAB: turns out that when you do, you can't directly lookup the "People" view, you have to lookup the "(@Users)" View...

Examples:

Incorrect
@DbLookup(""; "":"names.nsf"; "People"; @UserName; "OfficePhoneNumber" )

Correct
@DbLookup(""; "":"names.nsf"; "($Users)"; @UserName; "OfficePhoneNumber" );

Makes all the difference in the world.

16 August 2006

New Utility Function

I've added a new function to my little list of utility functions that I like using:

// Updates the status bar with a chosen message,
// clearing it after a certain number of seconds
function updateStatusBar(message, timeout)
{
// Initially, set the message bar's text
window.status = message;

// Then, if timeout has been set, clear out the message bar
// after the chosen number of seconds
if (timeout)
{
setTimeout('window.status = ""', timeout * 1000);
}
}

As you can see, nothing too fancy, just a little function that will display a message in the status bar window and then automatically clear it out after a certain number of seconds. Useful for displaying prompts that you don't want to bother clearing out.

Oddly enough, it isn't working in my copy of Firefox, even though w3schools.com says it does...

15 August 2006

JSON Revisited

Okay, after reading up on it a little bit, I've noticed that JSON has one difference that I quite like -- it apparently doesn't differentiate between "attributes" and text-data. Here, let me show you:

JSON DATA STRUCTURE

{
"window":
{
"title": "Sample Konfabulator Widget",
"name": "main_window",
"width": 500,
"height": 500
}
}

(JSON advocates please correct me if I'm wrong in my syntax -- I'm new to this.)

XML Data Structure

<window title="Sample Konfabulator Widget">
<name>main_window</name>
<width>500</width>
<height>500</height>
</window>

See the difference? The attributes in XML tags are represented the same way as the text data (I think it's called CDATA) is represented -- trust me, I can definitely see the advantages of this. One of my main things that pissed me off when I was creating my first XML parsers was having to handle the data within the tags in a different way from the data within the attributes within the tags -- just thinking about it now pisses me off.

Why? Because I'm lazy and it's an extra step of parsing. :p

Introducing JSON

Introducing JSON

Well -- so that's what JSON is. Seriously, though -- I don't get it. Was XML too easy to understand or something? :p

JSON-lovers fear not -- I keed, I keed. I, too, can see the need for a more object-orientated form of data storage for programmers used to C++ or PHP -- hey, if it makes people happy, go for it. And, I must admit, there were one or two examples where the JSON data storage version was quite a bit shorter than the XML version.

That being said, I just bloody learned XML, so I'm sticking to that for a while. So there.

14 August 2006

OpenDNS

Lotus Geek | Another tool you should be using: OpenDNS

OpenDNS.com

Wow -- I didn't even know this kind of service existed. That being said, there's just something about this whole idea that makes me kind of... wary. Just seems too good to be true. I admit, maybe I just don't know enough right now about the entire DNS universe -- who knows, I might actually be able to benefit from this, especially if it somehow lets me surf more anonymously. Maybe I'll give it a try.

Using AJAX as a Web Edit-Protection Device

IBM Lotus Advisor :: Use AJAX as an Effective Web Edit-Protection Device for IBM Lotus Domino

Phew! Just got done implementing this into the application I'm working on now, and it works great!

For all of you who can't access the article (it's for subscribers only, and my Dept. luckily had a group one we all use), it's an article about creating a type of "edit checking" for Domino web documents, since no such thing exists for such a stateless medium as the web by default... It's a combination of an agent and some very creative ajax commands that update "lock stubs" for documents that are currently being edited. If a document is being edited by a certain user, any other user who tries to edit the document will get a little alert box telling them so. The lock stubs are updated every n seconds (your choice) whilst a document is being edited, and after a user is done editing, the lock stubs are no longer updated, allowing any other user to edit it. (You just use the same updating agent to check and see how long it's been since the lock stub has been updated.)

Make sense? Trust me, it's easy. Here, let me show you the agent:

Sub Initialize
'**********************************************
' Checks to see if a document is currently being edited
' by checking the status of a lock stub belonging to a certain UNID
'
' Original idea from Scott Good of Lotus Advisor Magazine
'**********************************************

'Create variables
Dim Session As New NotesSession
Dim Doc As NotesDocument
Dim queryString, UNID, remoteUser
Dim allowEdit As Integer
Dim timeInterval As Integer

'Assign values to variables
Set Doc = Session.DocumentContext
allowEdit = True

'Set "timeInterval" to how long, in seconds,
'you want to lock a document
timeInterval = 90

'Grab UNID and remoteUser from the URL Query String
queryString = Doc.Query_String(0)
UNID = Evaluate(|@Middle("| + queryString + |" + "&"; "&UNID="; "&")|, Doc)
remoteUser = Evaluate(|@Middle("| + queryString + |" + "&"; "&remoteUser="; "&")|, Doc)

'If the UNID was successfully grabbed
If (UNID(0) <> "") Then
' The current document has been saved at least once
' and has a document unique ID
Dim DB As NotesDatabase
Dim LockView As NotesView
Dim LockDoc As NotesDocument
Set DB = Session.CurrentDatabase
Set LockView = DB.GetView("LockStubs")
Set LockDoc = LockView.GetDocumentByKey(UNID(0), True)
If (LockDoc Is Nothing) Then
' No lock document was found, so create one
Set LockDoc = DB.CreateDocument
LockDoc.Form = "LockStub"
LockDoc.ParentUNID = UNID(0)
LockDoc.UpdateTime = Now
LockDoc.User = remoteUser(0)
Call LockDoc.Save(True, False)
Else
' A lock document WAS found
If (LockDoc.User(0) <> remoteUser(0)) Then
' The current editor is not the prior editor--
' Create and set variables
Dim nowVal As NotesDateTime
Dim lastUpdate As NotesDateTime
Dim timeDiff As Double
Set nowVal = New NotesDateTime(Now)
Set lastUpdate = New NotesDateTime(LockDoc.UpdateTime(0))

' "timeDiff" is the number of seconds
' between now and the last edit
timeDiff = nowVal.TimeDifferenceDouble(lastUpdate)

' Block editing if less than two minutes have passed
If (timeDiff < timeInterval) Then
allowEdit = False
End If
End If
End If
End If

' It's somebody who's allowed to edit--
' Update the lock doc
If (allowEdit) Then
LockDoc.UpdateTime = Now
LockDoc.User = remoteUser(0)
Call LockDoc.Save(True, False)
End If

' Return XML information dealing with this edit request
Print "Content-type: text/xml"
Print "<editrequest>"
Print "<unid>" + UNID(0) + "</unid>"
If allowEdit Then
Print "<allowedit>Yes</allowedit>"
Print "<currenteditor />"
Else
Print "<allowedit>No</allowedit>"
Print "<currenteditor>" + LockDoc.User(0) + "</currenteditor>"
End If
Print "</editrequest>"
End Sub

You call the agent with an URL command composed of:

../UpdateEditAgent?OpenAgent&randNum=[randomnumber]&UNID=[docUNID]&remoteUser=[Remote_User]

Everything in brackets is dynamic data:
  • "randNum" is a random number you have to generate and pass along with the URL command -- this is necessary to subtly change the ajax command since XML data just so happens to usually be cached locally on the client's machine...

  • "UNID" is the UNID of the document that you're wanting to check the locking stub of...

  • And "remoteUser" is the remote user who is currently trying to edit the document in question.

Why did I use "Remote_User" and not "Session.EffectiveUserName?" Well, on the app that I'm working on, regular users are allowed to edit documents, however, they're not allowed to create any... I've encountered certain difficulties with this, you see, and have to run all my web agents in my apps as myself. It's actually not too difficult, and it allows me to keep things a LOT more secure.

Well, just run the agent when you try and open the document, and it either returns positive XML or negative XML. It's really as simply as that, and it only took a couple of hours to implement.

11 August 2006

Test01.com

第一考试网 IT认证,学历考试,资格考试,外语考试,各类论文资.务类范文 >> 站点首页

Yeah... your guess is as good as mine. I was trying to access our internal testing server (which happens to be called "test01") and then IE brought me out here...

Looks like a fun place, though!

Moo.fx and XHTML 1.0 Strict

I've been playing around with the Moo.fx JavaScript effects library today -- mostly, just trying to get the hang of it. It's not too hard, but that's the thing -- if you're used to programming everything you use by yourself, then it's hard to just start using someone else's library...

But, I've got the hang of it now. The only snag is the fact that (apparently) Domino forms can only be rendered in HTML 4.0.... ugh. No wonder my code has been acting funny for all these months -- I had forgotten just how different the two doctypes are. Fortunately, Domino static pages can be rendered in whatever I want them to be (just change the document treating to "HTML" instead of "Notes"), so I'm now happily coding away in XHTML 1.0 Strict!

(It really helps out Moo.fx's "accordion" effect, something that just absolutely farking refuses to work in IE running HTML 4.0.)

10 August 2006

Dynamic JavaScript/CSS "Popup" Windows

These bits of code are nothing new (I've included cites about where they're from), but I'm using them together in new and interesting ways, and sometimes that's what creating code can be all about!

These four functions, when used together, create a system for displaying pseudo-popups on your website -- for example, for alert boxes and preferences boxes. The calling function "drawCSSMessageBox()" will toggle the visibility of the box and its "screen" -- a large white <div> in the background, dimmed a bit, to cover and protect the rest of the page and to force the user to attend to the message box.

"getPageSize()" is a very neat function my wife helped me find that calculates the extent of whatever page the user is on -- it works in many different browsers and OS's, and helps make your "CSSMessageBoxScreen" function cover the entire page.

It's set up right now to toggle itself and its screen every time it's called, so try and not include too many fancy long-winded formulas in the "data" parameter, or strange things may happen. (I'm actually using a revised version of this that detects whether or not it's already open on my apps , but this way is much simpler.) You can customize it very easily, and it has an optional CSS class called "messagebox" that can be applied to the box's appearance.

It works exactly the same in Mozilla and IE, so you won't have to change a thing to get it to work in either browser.

Well, have fun, and make sure and grab the CSS at the end!

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

// Gets the dimensions of the user's window for many different browsers--
// Returns an array of pageWidth, pageHeight, windowWidth, and windowHeight
// By Lokesh Dhakar of http://www.huddletogether.com
function getPageSize()
{
var xScroll, yScroll;

if (window.innerHeight && window.scrollMaxY)
{
xScroll = document.body.scrollWidth;
yScroll = window.innerHeight + window.scrollMaxY;
}
else if (document.body.scrollHeight > document.body.offsetHeight)
// all but Explorer Mac
{
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
}
else
// Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
{
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}

var windowWidth, windowHeight;

if (self.innerHeight)
// all except Explorer
{
windowWidth = self.innerWidth;
windowHeight = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight)
// Explorer 6 Strict Mode
{
windowWidth = document.documentElement.clientWidth;
windowHeight = document.documentElement.clientHeight;
}
else if (document.body)
// other Explorers
{
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}

// for small pages with total height less then height of the viewport
if (yScroll < windowHeight)
pageHeight = windowHeight;
else
pageHeight = yScroll;

// for small pages with total width less then width of the viewport
if (xScroll < windowWidth)
pageWidth = windowWidth;
else
pageWidth = xScroll;

arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
return arrayPageSize;
}

// Inspiration from nsftools.com (http://www.nsftools.com/tips/NotesTips.htm#datepicker)
function drawCSSMessageBox(data, x, y, width, height)
{
// Toggle fading of the background the background
toggleMessageBoxScreen();

// Create CSSMessageBox if it doesn't already exist
if (!byId('CSSMessageBox'))
{
// don't use innerHTML to update the body, because it can cause global variables
// that are currently pointing to objects on the page to have bad references
// document.body.innerHTML += "
"; var newNode = document.createElement("div"); newNode.setAttribute("id", 'CSSMessageBox'); newNode.setAttribute("style", "visibility: hidden;"); document.body.appendChild(newNode); } // move the CSSMessageBox div to the proper x,y coordinate and toggle the visiblity var CSSMessageBox = byId('CSSMessageBox'); CSSMessageBox.style.position = "absolute"; CSSMessageBox.className = "messagebox"; CSSMessageBox.style.left = x + "px"; CSSMessageBox.style.top = y + "px"; CSSMessageBox.style.width = width + "px"; CSSMessageBox.style.height = height + "px"; CSSMessageBox.style.zIndex = 10000; CSSMessageBox.innerHTML = data; // toggle the visibility of CSSMessageBoxScreen and CSSMessageBox CSSMessageBox.style.visibility = (CSSMessageBox.style.visibility == "visible" ? "hidden" : "visible"); CSSMessageBox.style.display = (CSSMessageBox.style.display == "block" ? "none" : "block"); } function toggleMessageBoxScreen() { // Create MessageBoxScreen if it doesn't already exist if (!byId('MessageBoxScreen')) { var newNode = document.createElement("div"); newNode.setAttribute("id", 'MessageBoxScreen'); newNode.setAttribute("style", "visibility: hidden;"); document.body.appendChild(newNode); } // move CSSMessageBoxScreen to cover the entire page with its dim-ness-ocity var MessageBoxScreen = byId('MessageBoxScreen'); MessageBoxScreen.style.position = "absolute"; MessageBoxScreen.style.left = "1px"; MessageBoxScreen.style.top = "1px"; MessageBoxScreen.style.width = getPageSize()[0] + "px"; MessageBoxScreen.style.height = getPageSize()[1] + "px"; MessageBoxScreen.className = "trans75"; MessageBoxScreen.style.backgroundColor = "#ffffff"; MessageBoxScreen.style.zIndex = 9999; // toggle the visibility MessageBoxScreen.style.visibility = (MessageBoxScreen.style.visibility == "visible" ? "hidden" : "visible"); MessageBoxScreen.style.display = (MessageBoxScreen.style.display == "block" ? "none" : "block"); }


/*  NECESSARY CSS */

.trans100 {opacity: 1.0; filter:alpha(opacity=100); -moz-opacity: 1.0;  }
.trans90 {opacity: .90; filter:alpha(opacity=90); -moz-opacity: 0.90;  }
.trans50 {opacity: .50; filter:alpha(opacity=50); -moz-opacity: 0.50; }
.trans25 {opacity: .25; filter:alpha(opacity=50); -moz-opacity: 0.25; }
.trans75 {opacity: .75; filter:alpha(opacity=50); -moz-opacity: 0.75; }

Intel's Trust

The lawsuit that's Intel's worst nightmare - August 21, 2006

"So what's keeping [AMD] CEO Hector Ruiz up at night? Despite all the good news, he still sees one crucial - and worrisome-piece of unfinished business standing in his way. 'What can still hurt us the most, frankly, is Intel's antitrust practices,' he says. 'That's the largest obstacle for us to get where we need to go.'

Ruiz and his colleagues believe Intel's (Charts) monopolistic foul play is what sank AMD's (Charts) last bid for parity. That was in 2001, when the company had also gained share for five years straight. But once its unit share hit 21.8%-right around where it is today - the bottom suddenly fell out of its markets, Mercury Research data show. The contraction was especially severe in Japan, where AMD's unit share slid from 25% in mid-2002 to 9% in mid-2004, according to Gartner Dataquest.

The downright suspicious part, as AMD execs see it, was what happened to AMD's share with particular Japanese customers. Its portion of Sony's (Charts) business dropped from 23% in 2002 to zero by 2004, AMD says.

Its consumer desktop business with NEC (Charts) plummeted from 84% to almost nothing over the same period, while its total share of NEC business sank from close to 40% to less than 15%. AMD's Toshiba business flat-lined-dropping from about 15% in 2000 to zero in 2001 and ever since, AMD alleges."

No matter what way you look at it -- whether you're used to looking for corporate conspiracies or not -- you'd have to be absolutely blind not to see that something suspicious happened to AMD's market share around mid-2002. What makes it even more of a damn shame is the fact that a lot of people (myself included) consider AMD chips to be the superior product in terms of price, speed, and efficiency.

The Daedalus Project: Faces of Role-Playing

The Daedalus Project: Faces of Role-Playing (Page 7)

Not to spoil a surprise or anything, but I think I know who wrote one of the testimonials on this page... ^_~

09 August 2006

JavaScript "onkeypress" Event

JavaScript onkeypress Event

Not quite Mr. W3Schools! As to when it started working, I don't know, but "event.keyCode" works fine in both IE and Firefox, as I've just found out. Mozilla purists may scoff, of course, but this is making many programmer's lives (such as my own) a lot easier. (And if it makes more users able to adapt Firefox as their browser choice, even better!)

Elusive Bug

So, after coming back to work after a day off, I was able to recreate the bug! I can't find it, just yet, but at least I was able to recreate it. That's half the battle done.

It has something to do with my dynamic AJAX view memory (a script that remembers a view's appearance so that the next time the user visits it will look the same) -- as it appears, if a view is "slow" (has @Now in column titles, etc.), the script is loading it fine, but if the view is efficient and quick, the script gets hung. Weird...

For now, I've just turned off the view memory -- it's gotten rid of the bug, but now my app has lost a feature.

To the debugger!

07 August 2006

Dojo DOM Function

Well, I haven't found the bug yet, but I did find the neatest little DOM Reference function while perusing the Dojo JavaScript toolkit:

function byId(id)
{
return document.getElementById(id);
}

You should be able to instantly see what this does, and how it can be nearly indispensable. It's removed dozens of instances of:

var [variablename] = document.getElementById("[DOMobject]");

from my code, that's for sure!

Uh-oh

Oops! I've goofed up somewhere.

I submitted my application for testing today, and there's a small bug that keeps popping up on my supervisor's computer but not on mine, and nothing I'm doing on my own PC is replicating it...

Wish me luck!

Cookie Functions: Revealed!

Just a preliminary display of my custom cookie functions. Some of you may think they're a bit too specialized, and that they could be compressed, but I'm lazy, and like ease of use more than anything. So, here you go.

// Retrieves a cookie and returns its data
function getCookie(c_name)
{
// Set variables
var returnedData = null;

// Check the length of this page's cookies -- if cookies exist, continue execution
if (document.cookie.length > 0)
{
// Get index of cookie data dealing with this cookie
var c_start = document.cookie.indexOf(c_name + "=");

if (c_start != -1)
// If cookie information was found
{
// Perform string operations to get the actual data that was sent to the cookie
c_start = c_start + c_name.length + 1;
var c_end = document.cookie.indexOf(";", c_start)
if (c_end == -1)
c_end = document.cookie.length;

// Grab and decode the data that was wanted
returnedData = unescape(document.cookie.substring(c_start, c_end))
}
}
return returnedData;
}

// Sets a cookie with the data passed to it
function setCookie(name, data)
{
// Create a date object for the cookie that is one hour into the future
var exDate = new Date();
exDate.setHours(exDate.getHours()+1);

// Set the cookie
document.cookie = name + "=" + escape(data) + ";expires=" + exDate;
}

// Deletes a cookie
function deleteCookie(name)
{
// Remove the cookie by setting its expiry to a date in the past
if (getCookie(name))
document.cookie = name + "=" + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

// Removes a certain value from a cookie's delimited data
function removeDataFromCookie(name, data, delimiter)
{
// Grab the cookie's data and, if not null, continue processing
var cookieData = getCookie(name);
if (cookieData)
{
// split() the cookie's data into an array
var cookieDataArray = cookieData.split(delimiter);

// Iterate through the array, and when the data is found, splice() it out
for (var x = 0; x < cookieDataArray.length; x++)
if (cookieDataArray[x] == data)
{
cookieDataArray.splice(x, 1);
break;
}

// Re-set the cookie's data with the joined remains of the array
setCookie(name, cookieDataArray.join(delimiter));
}
}

// Removes any values containing a certain value from a cookie's delimited data
// and returns the values in an array (if none are found, an empty array is returned)
function removeSimilarFromCookie(name, data, delimiter)
{
// Create array of values that are removed
var removedValues = new Array();

// Grab the cookie's data and, if not null, continue processing
var cookieData = getCookie(name);
if (cookieData)
{
// split() the cookie's data into an array
var cookieDataArray = cookieData.split(delimiter);

// Iterate through the array, and when similar data is found, record it and splice() it out
for (var x = 0; x < cookieDataArray.length; x++)
if (cookieDataArray[x].indexOf(data) != -1)
{
removedValues.push(cookieDataArray[x]);
cookieDataArray.splice(x, 1);
x--;
}

// Re-set the cookie's data with the joined remains of the array
setCookie(name, cookieDataArray.join(delimiter));
}

// Return the removed data
return removedValues;
}

// Checks to see if a value is stored within a delimited cookie
// Returns true or false
function checkDataInCookie(name, data, delimiter)
{
// Grab the cookie's data
var cookieData = getCookie(name);

// Return false if the cookie does not exist
if (cookieData == null)
return false;
else
{
// split() the cookie's data into an array
var cookieDataArray = cookieData.split(delimiter);

// Iterate through the array, and when the data is found, return true
for (var x = 0; x < cookieDataArray.length; x++)
if (cookieDataArray[x] == data)
return true

// Return false if the data is not found betwixt the boundaries of this cookie
return false;
}
}

// Adds a certain value to a cookie's delimited data--
// Can check for duplicates if required
function addDataToCookie(name, data, delimiter, ignoreDuplicates)
{
// Grab the cookie's data
var cookieData = getCookie(name);

// If cookie does not exist, just create cookie with data supplied--
// If cookie existed and either the data is new or ignoreDuplicates is true,
// add data to cookie's data list
if (cookieData == null)
setCookie(name, data);
else if ( (ignoreDuplicates) || (!checkDataInCookie(name, data, delimiter)) )
setCookie(name, cookieData + delimiter + data);
}

04 August 2006

"Cleaning Up Cookie Crumbs" and Other Hits

Not really doing much today, besides cleaning up some cookie functions (and adding some more) before posting them here.

I'm also working on some nice "floating <div>" message boxes for the web application I'm working on. The biggest thing I'm trying to get right is making sure to "dim" the background to remove it from the viewer's focus (and control). I've accomplished this not by dimming the background (which would still leave the user able to edit it), but actually by creating an enormous <div> element, painting it white, making it semi-transparent, and setting its z-index to be above everything (except for the message box, of course). Pretty neat, huh?

It works like a charm, though the dimensions of the box are a little off in IE (like everything else).

Why is it that when you specify "width: 100%" and "height: 100%" in IE that whatever you're bloody well changing the size of doesn't end up as 100% wide and 100% high? Anybody know what the coders for IE are smoking?

03 August 2006

Working with Opacity via CSS

Mandarin Design: CSS Opacity and Transparency

I have been farking around with this bloody code for 2 goddamn hours now and have just now got it to work!

The problem? (It's something that the site doesn't exactly address.) Why in the hell do elements that you want to change the opacity of have to have a damn "width" or "float" attribute in Internet Explorer? Well, for whatever reason, they do!

This tutorial started off by declaring that elements you want to change the opacity of need a "float" attribute in the style, but that turned out not to be the case (at least in Firefox) -- one of their own freakin' examples changes the opacity without a "float" attribute! And IE doesn't exactly need one -- it seems to work just fine with only a "width" attribute.

I could have made dual code for both browsers, of course, but I absolutely loathe doing that... Call me crazy if you want to, but I've always made perfectly fine web sites that work in all browsers using just one set of code, and I don't intend to change that now!

02 August 2006

Toned Down Code

I've had to actually tone down some of the Ajax I'm working on now (sometimes there's just too much going on ). I'm now working on a deadline, and that means no more funny business -- it's time to release a finished product.

I've decided to forego the entire "dynamic deletion of documents" and just go with a "pseudo-refresh." Why the prefix? Because even though the user will think the view is being refreshed, it really won't be... I'll just be redoing the individual Ajax commands until there's all new data.

Sadly enough, stuff just doesn't work on the web as quick as it does in notes, but I'm sure people will understand that -- it's one thing to be accessing Domino through the Notes client (where everything works perfectly); it's another to be accessing it through a stateless browser that leaves Domino with absolutely no idea about what the user's currently doing!

Programming = Art

To all my fellow programmers: ever wonder why you just can't leave something alone if it works fine and dandy? Ever wonder why you have to keep continuously screwing with things, trying to make them better, until you eventually break them? What am I saying -- of course you do.

That's why I think programming is like art -- just like an artist painting a picture, a programmer designing an app can eventually try and put too much detail (whether this detail be layers of paint or lines of code) into his creation, resulting in nothing but a giant mess that looks like shit (or in the case of a program, a giant mess that doesn't work).

I'm pretty sure I narrowly avoided one of those situations this morning... here's to hoping!

01 August 2006

Back Down to Business

On the current application I'm working on, I'm done with making it look pretty (read: fixing HTML markup) and am ready to get back down to the nitty-gritty details. I had taken a break of about a week or so to fix some appearance issues, but now it's time to get back down to the underlying code.

I've been working on an ajax-powered deletion engine for a Notes application that's viewed on the web -- coupled with an ajax-powered (I love that term) view-displaying engine, it should emulate almost perfectly the behavior inherent to Notes' Apps when viewed in the client.

I've got it working almost perfectly -- the only issue is the views' redrawing after the delete has commenced. I'm torn between wanting it to happen dynamically (right in front of the user's eyes) and wanting to redraw the entire page (to avoid little bugs that seem to be popping up here and there).