Tuesday, April 29, 2008

Posting HTML Code in a Blog

If you've ever tried posting in a blog then you know that it doesn't work very well. This is because the browser gets confused and tries to interpret the code rather than display it literally.

A simple tool to correct the problem can be found here. It's not perfect in that indentation is lost but other than that it's quite effective.

JavaScript Background Image Swapper

I'm working on a project that involves displaying a world map on one page. I thought it would be neat to display a nighttime map when the user's local time was between 6pm to 6am. I first tried doing this with server-side C# code but it never really worked correctly so I revisited the problem and instead did the whole thing very simply with JavaScript.


Here's the ASP.Net control I was looking to alter:

<asp:Image ID="imageWorldMap" runat="server" Width="100%" Height="100%" />

And here's the JavaScript that gets called when the page loads:

<script type="text/javascript">
// Set the background according to what time of the day it is on the user's computer.
function SetBackground()
{
var now = new Date();
var hr = now.getHours();
var img;

if (hr >= 6 && hr < 18)
{
img = "Images/worldMap.jpg";
}
else
{
img = "Images/worldMapNight.jpg";
}

document.getElementById('<%=imageWorldMap.ClientID%>').src = img;
}
</script>

Monday, April 28, 2008

Warning the User About Prematurely Leaving a Web Page

I'm relatively new to website development. Up until now I've never had occasion to warn the user about leaving a web page. I knew it was possible though, as I'd seen it on some websites before.

I'm now working on a data editor that looks like this:

Essentially, the user can pick one of several bottom-level nodes in the treeview on the left and then the data associated with it will be displayed in the controls on the right. He might just view this data or may alter it. He can also add & delete & move nodes, each of which is connected with a data record.

A novice user wouldn't understand that all changes are handled locally and not updated in the database until 'Save' is pressed. So letting them enter a bunch of data and then close the browser or navigate to another page simply wasn't acceptable.

I found this article by well known ASP.Net guru, Scott Mitchell. It's actually the third in a trilogy of articles on the subject. I followed the basics of what he wrote and added this code to my ASPX page:

var needToConfirmExit = false; // Initialize

function ConfirmExit()
{
needToConfirmExit = Boolean(document.getElementById('<%= needToSaveData.ClientID %>').value);
if (needToConfirmExit)
return "You have made changes that have not yet been saved back to the database. If you leave now, all of those changes will be lost. Are you absolutely sure you want to do this?";
}

window.onbeforeunload = ConfirmExit;


The more advanced part of his article dealt with implementing an extensive client-side mechanism that kept track of which controls had their values changed. As my web page was AJAX enabled, partial page updates were occurring whenever any control's value was altered. So intuitively I knew there must be a simpler way

In the server-side code I already had a property called 'IsDirty' :

public bool IsDirty
{
get
{
return (bool)ViewState["IsDirty"]; // Note: If null then returns as false
}
set
{
ViewState["IsDirty"] = value;
ChangeButtonState(Constants.CommandButtons.Save, value);
needToSaveData.Value = value.ToString().ToLower();
}
}

'needToSaveData' is a hidden field that I placed inside the UpdatePanel. The beauty of this solution is that as soon as a control is updated, the 'ConfirmExit' JavaScript function is ready to go in case the user tries to prematurely leave the web page.

Sunday, April 27, 2008

Modal Popup Extender, StreamWriter

I've made a small, but useful enhancement to the Waikiki condo rental site I built. The owners of the condo have reservations well in advance so only need to find new people a few times a year. As such, they don't want people constantly writing them, saying such things as, "Hey, can I rent it next week?" This is a waste of time for the writer and for the condo owners.

One way to solve this would be for them to keep me updated about when it was available. But that would mean that I'd have to constantly update the site every few months. Sorry, not interested.

So I built a mechanism whereby they can customize a special message that appears when the user clicks on the Contact page. You can view the current message here:

What you're seeing is an effect provided by the ASP.Net AJAX Control Toolkit. It's called the Modal Popup Extender. It lets you display a Panel (ASP.Net's equivalent of a "Div") that contains whatever controls you want in it. In the example, there are only 3 objects:
  1. The panel, which displays a background image
  2. A label, whose text is customized
  3. An "OK" button
The "disabled" background effect behind the popup panel is caused by the extender referring to this simple CSS entry:

.modalBackground
{
background-color:Gray;
filter:alpha(opacity=70); /* For IE */
opacity:0.7; /* For Firefox */
}

There's a new Admin page that I added, that is accessed via a link at the bottom of the page, followed by a required password. I could have implemented a full Login mechanism but thought it overkill for this simple application that will forever be used by only 2 people. With that said, I did not embed the password directly in the code for all code files get compiled into a DLL, which is normally accessible by a hacker via the ASP.net "bin" folder. So instead, I embedded the password in the very secure "web.config" file like this:Arriving on the Admin page, one can only add/edit text and press "Submit" :
Implementing all of this was very simple. For example, the code that writes the text out to a file is this:

if (File.Exists(srcFile))
{
StreamReader streamReader;
string txt;
streamReader = File.OpenText(srcFile);
txt = streamReader.ReadToEnd();
streamReader.Close();

if (txt != "")
textBox1.Text = txt;
}

In my local test environment it worked perfectly. But intuitively I knew it wouldn't work right away on my GoDaddy hosted web server. Why? Three words: File write permissions

The text file in question resides in its own folder. This keeps it separate from the code and markup files. What I had to do was go into the GoDaddy File Manager, select this folder, and alter its Permissions so that Write was enabled and not just Read. Without doing that, the file is forever locked from any changes, short of FTP'ing in a new file.

Just some simple techniques here but together they allow for a nice and useful web application!

Friday, April 25, 2008

An Example of an ASP.Net Website

Earlier this year I was fortunate enough to find a privately owned suite to stay in during my stay in Waikiki. The owners, Irene & Wes, are incredibly nice people and I promised to build them a website to better advertise their suite. It's now done and live.

I must confess that I went well beyond what I had originally intended to do but I'm very pleased with the end result.

On the technical front, I still have a long way to go to be a "CSS Master". I find lining up side-by-side columns especially tricky. I tried to you DIVs as much as possible, rather than tables, but the latter sometimes prove invaluable.

The content of the site is presented in pretty basic ways, but there are two interesting highlights I'd like to draw your attention to:
  1. Maps - These are just embedded Google maps but I think it's incredible what they've done to make it so easy to incorporate sophisticated maps like these into anyone's website. Back in 1995, when the web first dramatically expanded to the general public, did anyone foresee that such information would be available so readily?

  2. Photos + Videos - Photography has been a passion of mine since I was a kid. Now, in the age of digital photography, it's incredible what images one can capture. Beginning with this trip I started using a Canon G9. It's a 12.1 MegaPixel gem that is reportedly "as good as it gets before short of getting an SLR". It's also very good at capturing videos, though I've found that even my 2GB memory card gets quickly filled when doing that!

    Anyhow, in times past, when I wanted to display hundreds of images, I would typically construct a traditional menu of hyperlink buttons like this one. But for this Waikiki site I wanted something different. So I decided to try out the accordion control. I think it worked super well! With so many photos, having companion thumbnails was a must. There is a bit of a delay loading the thumbnails into the cache the first time but it's not insurmountable, at least not with my high-speed connection.
Incidentally, for image manipulation, my current set of tools are these:

Monday, April 21, 2008

"Does not exist in the current context"

The fun & games with Visual Studio continue! I generally love the package but sometimes it frustrates me to no end.

So there I was testing a simple web page, adjusting this & that. Suddenly, when I tried to recompile it I got this message:

labelTagLine does not exist in the current context

This control resides in the header on the Master Page of my project. There's nothing fancy or special about it. I did a comprehensive search and found lots of others who had encountered similar problems with controls suddenly not being recognized. I tried all of their solutions but to no avail.

So eventually I copied main.Master and main.Master.cs outside of the project folder and deleted these two files within the project. Then I created a new, blank version of them. Slowly, I started copying the markup code and C# code back into their respective files, being sure to perform a "Rebuild Website" every so often. Lo and behold, when every last line of code was back, it worked! Something internally must have changed but nothing in my code files did. Another 2 hours wasted. :-(

Melodyne: Sophisticated Music Editing Software

I have zero musical talent but find this an extremely cool piece of software:
You can find out more about Melodyne here.

Debugging with Visual Studio 2005 in Windows Vista

What a Microsoft level headache I encountered this evening. That's my code for, "it should work but it doesn't because of something Microsoft didn't take care of properly".

I wanted to do something similar: Debug a simple ASP.net 2.0 web page in Visual Studio 2005, running on my Windows Vista Ultimate 64-bit machine. I added a Debug.WriteLine statement in the Page_Load event handler of default.aspx.cs and sit it as a breakpoint - as I'd done thousands of times before with Windows XP.

I pressed F5 and looked at the code screen, naturally expecting the app to stop on the designated line. And . . . it didn't! I tried again, but still no go. So I shut down VS2005 and cleared all the DLL files from the bin folder and all the files from the obj folder. I restarted it, recompiled, and tried again. Still didn't stop!

Then I did a ton of research and via Scott Gu's [excellent] blog was taken to this page. There are a LOT of steps. After following the instructions in the last one I tried again but it still didn't work! So then I examined this series of articles by Mike Volodarsky. I followed the VS2005 link and carefully went through the steps needed to get debugging working. I didn't actually go as far as running the app through IIS7 as I intuitively couldn't believe that the internal web server in VS2005 wouldn't debug properly in Vista.

I did some more research and came across this ASP.net forum posting. Note that the second fellow, from Lahore, Pakistan insisted to check the web.config file and be sure that debug is enabled. "Of course it must be", I thought. But when I checked, it was not! So I changed it to:



I hit F5 again and ... it worked!! I don't know for sure whether all those other steps were necessary though I think that installing the hotfix was probably a good idea.

In conclusion, I must say that situations like this are all too common with Microsoft development products. This should have been a "5 minute" thing to fix, but I wasted 90 minutes of my time on it. I simply don't accept that such things should be happening from a paid for product built by a multi-billion dollar company.

Though with the introduction of this blog, I hope to help others save countless time in the future by documenting situations like this and having it picked up shortly by the search engines.

Sunday, April 20, 2008

The Semantic Web

I've been reading about the future of the Internet, which is being promoted under the moniker of "Web 3.0" or "The Semantic Web". We're no where near there yet and some say we'll never achieve it but it's an interesting subject to discuss.

Here's a primer and here's a more detailed article.