Archive for February, 2009

Developer Features in Safari 4 0

There are some developer features hidden in the new beta of Safari. They are a bit hidden, which is fine since most people browsing the web don’t care to inspect the elements of the page they’re browsing, but as a developer, this is a must.

Turn on the develop menu item in the advanced settings.

image

Show the menu bar. I haven’t found a way to get to it without the menu, but I haven’t really looked into it yet.

image

And now you have all the tools you would expect to see and then some!

image

They look eerily familiar don’t they?

Update: The presence of the Develop menu is not new with Safari 4, but there are several updated and additional features in the beta.

Animating Partial Postbacks and UpdatePanels with jQuery 4

Update panels make it really easy to do pseudo ajaxish stuff with little or no extra effort. Wrap your controls in a an UpdatePanel, pay for the entire page to post back and go through its life-cycle and you’re pretty much there. I’ve already written a bit on the extra steps you’ll need if you’re doing some jQuery magic inside that UpdatePanel. It’s not difficult and easy enough to either delegate up the chain to something outside the UpdatePanel (e.g. event delegation) or rinse and repeat the jQuery after the partial post back is complete (e.g. add_endRequest).

What would be really slick-o-matic is if we could do some animation to transition the partial postback so it wouldn’t just explode with new content in our face. Now granted, that may be an overstatement. The content changes usually aren’t drastic or very distracting to but let’s add a bit of polish.

Keep in mind this is a first draft, done in about 30 minutes after an idea landed in my head at 3am. It still needs some polishing, but the major hurdles are taken care of.

For our example, we’ll have a simple Div that will be worked upon in a partial postback. Our goal will be to gently transition the display of that work to the user. Something like this.

Original Video – More videos at TinyPic

We’ll start off with some basic styles to help illustrate the change. We’ll change the content of the Div and also the class.

	#mydiv{ width:200px; border:solid 1px black; font-size:xx-large; }
	.myclass0 { height:200px; background-color:Blue; }
	.myclass1 { height:100px; background-color:Red; }
	.myclass2 { height:150px; background-color:Lime; }
	.myclass3 { height:50px; background-color:Purple; color:White; }

Nothing too exciting, but our partial postback will give us some new dimensions and style. It’ll get the point across.

Next we need some HTML.

<form id="form1" runat="server">
	<asp:ScriptManager ID="ScriptManager1" runat="server">
	</asp:ScriptManager>
	<div>
		Original time: <%= DateTime.Now.ToLongTimeString() %> 
		<asp:UpdatePanel ID="UpdatePanel1" runat="server">
			<ContentTemplate>
				<asp:Button runat="server" Text="Button" ID="MyButton"
						OnClick="MyButtonClick"
					OnClientClick="return ClientClick(this,'#mydiv'); " />
				<div id="mydiv" runat="server">
					<asp:Label runat="server" Text="Label"
                                           ID="MyLabel"></asp:Label>
				</div>
			</ContentTemplate>
		</asp:UpdatePanel>
	</div>
</form>

The magic is going to live in the ClientClick event handler, but forget about that for now. The server side OnClick event will do some trivial work.

 protected void MyButtonClick(object sender, EventArgs e)
 {
	 MyLabel.Text = DateTime.Now.ToLongTimeString();
	 var c = "myclass" + DateTime.Now.Millisecond % 4;
	 mydiv.Attributes.Add("class",c);
 }

This could just as easily toggled a view from edit mode to read-only, expanded a detailed area, etc. Here, we are just picking one of four css classese to use on the div and also giving a label the current time. Like I said this isn’t the cool part.

The final steps are to do the following:

  • Get the jQuery animation to happen on the click of the button.
  • Get the partial postback to wait until the animation is done.
  • Get the DOM to appear in the pre-animation state when it comes back from the partial postback.
  • Get the animation to happen once we have the new page ready to go.

The function needs to know what needs to be animated upon. I’ve been using slide transitions, but the animation is something I think can very easily be abstracted out. We make some quick tests to see if we are in the process of animating or if the animation has been completed. I struggled with how to delay the button click’s post back from happening until the animation is complete and finally decided to just let it happen a second time, but to flag the second click to allow it to continue posting back. I’m using the jQuery data feature to keep some state about the button.

If we are currently sliding, then there is nothing left to do, and if we are done sliding then we can skip the other steps and continue the postback.

if (d.data("isSliding")) return false;
if (d.data("doneSliding")) return true;

If we don’t meet those conditions, we need to slide. We set our flag, wire up the end request handler and the callback to the slide method and kick off the slide.

The slide method is the simplest.

d.slideUp(500,
	function() {
		d.data("isSliding", false);
		d.data("doneSliding", true);
		$(sender).click();
	});

Slide our control up, and when we’re done, set some flags and kick off the click a second time. With the flags set, we’ll fire off the postback. Nothing really fancy here either. Notice we can still reference d here. We don’t need to find it again.

The endRequest handler looks a bit more involved.

var prm = Sys.WebForms.PageRequestManager.getInstance();

var f = function(s, e) {
	d = $(whatToSlideDown);
	d.css("display", "none");
	d.slideUp(0);
	d.slideDown(500);
	prm.remove_endRequest(f);
}

prm.add_endRequest(f);

Here, inside the function we do need to ask jQuery to find what we want again. The DOM has been changed and the old d we created from $(whatToSlideUp) probably isn’t there anymore. In addition, we need to set the element in the state we left the old element. In this case, we want the display to be set to “none”. This allows the slideDown to work just like we would expect following a slideUp.

This is part of the setup that I don’t like. I’ve tried quickly running a slideUp(0) on the the new elements, but I was seeing a flash of the default state before getting the slide up. This is something that I would like to factor out. The animation, including this default state should be a parameter to the function.

Here is a look at the function as a whole. It’s a stupid function name I know, but that is easily changed.

function ClientClick(sender,whatToSlideUp,whatToSlideDown) {

	if (!whatToSlideDown)
		whatToSlideDown = whatToSlideUp;

	var d = $(whatToSlideUp);

	if (d.data("isSliding")) return false;
	if (d.data("doneSliding")) return true;

	d.data("isSliding", true);

	var prm = Sys.WebForms.PageRequestManager.getInstance();

	var f = function(s, e) {
		d = $(whatToSlideDown);
		d.css("display", "none");
		d.slideUp(0);
		d.slideDown(500);
		prm.remove_endRequest(f);
	}

	prm.add_endRequest(f);

	d.slideUp(500,
		function() {
			d.data("isSliding", false);
			d.data("doneSliding", true);
			$(sender).click();
		});
	return false;
}

That’s it. There is definitely room to polish this up and make it more flexible. I’ll post back when I get it up and running in a real application so it looks more useful.

TFS, Team Build and a Build Confirmation 0

We recently wanted to add a manual verification to our TFS builds. We didn’t want someone accidentally clicking the build to production when they meant to build to development. They are right next to one another and look very similar.

I didn’t want to spend a lot of time on it, so I came up with this. It’ll work for now and ensure we manually interact with the queue build dialog.

<Target Name="BeforeEndToEndIteration" Condition="'$(C***)' != 'suck'" >
    <Error Text=
"You did not state your feelings for the C***. Please state this by submitting
 the parameter /p:C***='suck' in the queue build dialog."/>
</Target>

The parameter name realy isn’t “C***”, but I didn’t want to offend any followers of the team with the longest championship drought of any professional sports team. Actually, I bet it is safe to extend that to individual performers too.

Asp.Net and forcing password change after PasswordRecovery 0

Like many websites, we implemented a feature that will let our users self recover lost or forgottton passwords.  Asp.Net provides this right out of the box with the PasswordRecovery control.  It took us 90% of the way to where we want to be. It verifies the account exists, generates a random password and mails it to user.  The last step we wanted was to force the user to change their password after they’ve requested a new on from the PasswordRecovery control. Turns out, it wasn’t that bad.

We created a new profile property for our user to track if we were requiring a password change on the next login.

 <profile>
   <properties>
     <add name="RequirePasswordChange" type="System.Boolean" allowAnonymous="false"/>
   </properties>
 </profile>

We already had our ForgotPassword.aspx page with our PasswordRecovery control on it. We just needed to write up one more event.

<asp:PasswordRecovery ID="PasswordRecovery1" runat="server"
     OnSendingMail="SendingMail" >
 </asp:PasswordRecovery>

In the new event we’ll set that flag so we know the next time they successfully log in, we’ll make them change their password. I didn’t really see any other event that was more appropriate than SendingMail, but since we only send the e-mail when we pass all the challenges we’ve setup, it works well enough.

Also, since we’re not logged in, we have to ask for the profile by name, and then make the change.

protected void SendingMail(object sender, MailMessageEventArgs e)
{
    var p = Profile.GetProfile(PasswordRecovery1.UserName);
    p.RequirePasswordChange = true;
    p.Save();
}

The login page has some code added after we login.

<asp:Login ID="Login1" runat="server" OnLoggedIn="LoggedIn">
</asp:Login>

If we require the password change, then redirect to the new page.

protected void LoggedIn(object sender, EventArgs e)
{
    if (Profile.GetProfile(Login1.UserName).RequirePasswordChange)
        Response.Redirect("ChangePassword.aspx");
}

Lastly, ChangePassword.aspx resets the flag on successful login.

<asp:ChangePassword ID="ChangePassword1" runat="server"
    OnChangedPassword="ChangedPassword">
</asp:ChangePassword>
protected void ChangedPassword(object sender, EventArgs e)
{
    Profile.RequirePasswordChange = false;
    Profile.Save();
}

That’s it.

Two bugs for the price of none 0

We recently pushed a feature into production that had a pretty serious flaw. If gone unfound it could have caused headaches with billing the wrong customer the wrong amount and all kinds of other potentially damning effects. Luckily for us, we also had a second bug. The feature that was to send the notification e-mail that data was ready to be corrupted by our bug was misconfigured when it moved to the production environment. Lucky for us, no one was being told they should go execute our buggy code, so no one did and we found it, fixed it and all those actions items that queued up ran through without a hitch.

Now lucky for us or not, we did fail to find two serious bugs. It highlights the need for thorough acceptance testing. Thorough being the key word there.

The first bug existed if action items queued up and were acted upon in a certain order. Testing was done in this area, but the items never fell in the order where we found the bug. Would acceptance tests go so far to say:

  • Act on the first item in the list and verify the actions were taken correctly.
  • Act on the second item in the list…
  • Act on a list with a single item…
  • Act on a list with two items…
  • Act on a list with n items…

How detailed do you get? 

The first bug was a pretty lame mistake, although I feel SQL should have been alerted when we attempted to do an udate  a single from a statement that returned multiples. I don’t know how it makes sense to choose the first row and go about your business. 

As for the second, testing the production configuration is hard. We do have some junk data laying around in the production DB that we can manipulate, and probably should have to verify the e-mails were sending. Config changes between the two are difficult to manage. Keeping the e-mail address, servers, roles, etc in sync to the correct environment is made simpler by branches, but verification isn’t.

Git Extensions and Visual Studio 6

With the Git extensions you get some nice Visual Studio integration. You get a nice menu and toolbar to work some of your Git magic right from the IDE.
ss-20090215112020

Personal Branches with Git 2

Quite often I find myself wanting to experiment with something with whatever I’m working on. I want to roll back to the point I’m at now if it doesn’t workout, but I don’t want to commit what I’ve started to the shared source repository for everyone else to see just yet. So what is one to do? Comment out a whole heck of code and manually rollback if I need to? That’s a bummer.

If we’re using TFS (we currently are) you can create a shelveset of the current point and unshelve it later if you need to. That isn’t a terrible option, but I would really like to be able to check in often and compare between my current point and previous versions.

Enter Git. I’ve been hearing a lot of hype about Git, but never really found a need to have the entire repository on my local box…until I thought about what a personal branch would need. It would need exactly that. Anyway, this is not a novel idea. You can search the Google for exactly this and there are ton of articles describing how to make it work.

What I was most amazed with was how easy it was to get Git setup and how fast the operations were. It’s amazing how fast operations can be if you are smart about what you’re doing and don’t rely on the server to do everything. (TFS, please take that as an insult.)

So skipping the install of msysgit, you can have your repository setup in no time. It is really as simple as:

cd \my\source\dir
git init

You have files in that directory you want to track

git add .

Ready to check in your changes?

git commit -m "some message"

OK. Now you’ve made changes and want to rollback?

git checkout .

Now you want to try out a new branch for a while?

git branch newbranch
git checkout newbranch

Ready to go back to the main branch?

git checkout master

Pretty amazing huh? It is really that easy. I’ve included a screencast of a similar set of steps to those so you can see it really is that easy. It’s nothing flashy, but it really shows how easy it is to get setup.


Original Video – More videos at TinyPic

There is a GUI tool that gets installed and some extensions to make things a little easier.

Just remember if you ever need help from the command line, help is right around the corner.

git help checkout

Scoping JavaScript with Module Pattern 0

I’ve entered the world of actually writing JavaScript. In the past, usability was really a secondary concern. I need to do a postback to make a button visible, no problem. The screen will flash, but who cares. It’s not like the user is going to stop using my application to do the stack of work on their desk. They have to use it. It’s their only option.

Now that isn’t entirely true. We attempted to make it as usable as possible, but anything that even close to using jQuery was probably just, according to the powers that be, the developers just playing around with cool toys. I’m not sure the value of the user experience fell nicely into a quantifiable metric. I’m beginning to rant, so back to the point.

In my new adventures with jQuery, I’ve been writing a lot of JavaScript. The biggest complaint I’ve had with my JavaScript is that everything is global and can potentially be overwritten by subsequent JavaScript, or I might be overwriting someone else’s functions or variables. My JavaScript files looked like the following.

var foo = "berry";
function doWork(s){
	alert(s+foo);
}

$(function(){doWork("foo")});

I just cross my fingers that no one else has a doWork function or foo variable. There has to be a way to scope this stuff.

Luckily, I found and article that explains exactly that. It explains the Module Pattern and how to use it to limit the scope of JavaScript.

I’ll let you read the article for a more complete description that I could put together, but ultimately, my JavaScript ends up looking like this.

myScript = function(){
  return {
	init:function(){doWork("foo");}
  }
  var foo = "berry";
  function doWork(s){
	alert(s+foo);
  }
}();
$(myScript.init);

In this case, init is the only method that gets exposed. You can’t invoke doWork. Also, by adding the scope of myScript, you can have greater confidence your methods and variables aren’t getting overwritten.

My practice thus far is to have one JavaScript file for each page and user control. The scope of each page’s file is the name of the page, or control. So you could see Login.aspx.js with a scope of MyApp_Login.

So far so good. We’ll see how it goes.

Finding parent elements with jQuery 1.3 0


magnifying monkey man.

I was recently writing a little javascript function that would traverse up the object graph and apply jQuery selectors to pick the correct parent that I needed. It was a pretty basic function, but I had that gut feeling that this is something that I shouldn’t be writing. It has to be already written by someome. 

Luckily, with jQuery 1.3, it’s part of the core library. New in this version is the closest method which will find the closest parent that matches the selector you pass.

ASP.Net Ajax payload size compared to jQuery 0

Let me start off by saying this isn’t scientific, or possibly even accurate, but was pretty shocking at first glance. I wanted to take a look at what the true size of our pages were, so I brought up Chrome’s nice resource inspector and refreshed and average page from our intranet application. It was a bit shocking at first.

image

All that orange is javascript! Now, I know the browser is probably caching that, when it goes through IIS – Cassini won’t cache it—, butit still seems like a pretty big chunk, but it’s probably all the jQuery and jQuery plugins we’re using right?

image

Without the rest of the files, it’s hard to put that into perspective, but trust me ,that is pretty small. What about the plugins?

image

Those are pretty small too. All that javascript has to be somewhere right? What about ASP.Net Ajax?

image

I had to scale the image so it would fit, but there is a lot there. You may have noticed that we are using the min version of the jQuery file. Is the ASP.Net Ajax minified?

NOPE!

I haven’t really looked to see if it is possible to shrink that JS somehow, we’ll see about doing that soon.