Yesterday I presented at the jQuery Boston Conference 2010. I’ve never attended a jQuery Conference before, so this was an awesome experience all around.
Each year, there is a jQuery UI Introduction talk and this year I was privileged to present the material.
Slides – The web presentation is best viewed with Google Chrome
In order to spice up the content some, I included some bacon demos using the draggable, droppable, and resize interactions. I hope to add more bacon slides in the near future ;)
If you were able to attend my talk, I would appreciate it if you could rate my presentation at SpeakerRate.
I use embedded jsFiddle in my examples to view and execute all of my code example. You can launch the full jsFiddle from within the slides to view, edit, run, and share the code.
I want to thank the jQuery Team for allowing me to speak this year and a special shout out to Leah Silber, Ralph Whitbeck, and the others that put tons of hours into putting this event together.
I've been working on a project recently where I'm appending the current date to the end of script files so that they won't be cached.
I'm surrounding the code with lots of Unit Tests and I was trying to figure out the best way I could test that the script was actually loaded with the appended timestamp.
How could a JavaScript file tell what URL requested itself? Could the script know what URL make itself load?
Initially I was thinking location.href, but that ends up being the URL of the page the script was loaded on, not the script URL itself. Someone else suggested document.referrer, but that turns out to be the URL that referred the current page.
After a little time passed and several tweets passed by my stream, the correct answer flowed by...
var scripts = document.getElementsByTagName( "script" ); var lastScript = scripts[scripts.length - 1]; alert( lastScript.src );
Since the script files execute in order, if you grab the scripts on the document while you are executing, then the last script listed should be the one you are currently in!
This question has been asked on stackoverflow as well ;)
As it turns out, the above technique only works for pages that have the <script> tag manually declared. If you dynamically inject your <script> tags programmatically, then the above technique doesn't work correctly. For my scenario to work, I had to tweak the solution a little bit.
Fortunately, I knew what file I was in, so I could do some partial matching to grab the script tag on the page to look at the src.
I first met the CEO (Mike Hostetler) and President (Jonathan Sharp) of appendTo back in January while I was at the launch of jQuery 1.4 in Washington DC.
After the unfortunate turn of events at my last job (raided by the FBI & IRS), I was forced to look for a new job opportunity.
One of the first places I thought of working for was appendTo. After several weeks of talks everything worked out and now I am an official employee!
Since I’ve started I’ve done some writing, did an architectural review of a client’s code, and most recently I’ve been diving deep in developing a JavaScript and jQuery library.
I am really excited about this opportunity. The group of people that I work alongside are top notch! I find it impressive that appendTo has 5 official jQuery Team members working for them.
It looks like I’ll be able to attend the Boston jQuery Conference this coming October 16-17, 2010. I hope to see you there! Sign up while tickets last.
By the way, thank all of you who sent me job leads, contacting me about working with you, or tweeted on my behalf while I was looking for a job. I appreciate all your efforts!
There are a lot of articles out there that show you how to integrate with the jQuery jqGrid Plugin from a listing, paging, sorting approach, but I haven’t seen many that show the integration with the add/edit/delete features that jqGrid offers.
It turns out that it isn’t very difficult to do, but it took quite a bit of digging in the jqGrid API documentation for me to find all the things I needed.
The following article will show how to customize the add/edit/delete modal experience inside of the jqGrid with ASP.NET MVC.
Contact ViewModel
First, you start off with your ViewModel. In this case the following is really bare bones. I haven’t annotated the properties with metadata because I actually do that manually in the jqGrid columns. That isn’t optimal, but it would be nice to have these automatically mapped. That sounds like another blog post ;)
public class ContactViewModel
{
public System.Guid ContactId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public DateTime DateOfBirth { get; set; }
public bool IsMarried { get; set; }
}
Contact View
The following code setups up the jqGrid to support add, edit, and delete.
The first function you’ll see is a custom validator that checks to see if the phone number has a length of 14. Yes, it isn’t bullet-proof validation by any stretch of the imagination, but its more of an example of what can be done.
Next you’ll see the updateDialog object literal defining the look and behavior of the add, edit, and delete dialog windows. The main property to define is the URL where the AJAX requests will post the data. You can also control whether the dialog closes immediately, if it’s a modal dialog, etc…
The next important thing to notice is the “key: true” property of the ContactId column. If you don’t set this property then the POST for the delete command only send the relative ID that jqGrid generates, not the ContactId that you need. So, this is important ;)
Note:You’ll see some code below setting global properties for the jqGrid such as the title of the dialogs, buttons, etc. If you don’t do this then you’ll get generic titles. I figured these customizations made the user experience a little nicer, but things will work just find without them.
The add/update/delete feature takes one URL where you can change the logic based on the operation type. The MVC Modal Binder will map the fields into your ViewModel in most cases. The exception is the “id” that is passed on the delete operation, but there is a way to get around that later in this post ;)
public ActionResult Update(ContactViewModel viewModel, FormCollection formCollection)
{
var operation = formCollection["oper"];
if (operation.Equals("add") || operation.Equals("edit"))
{
repository.SaveOrUpdate(new ContactViewModel
{
ContactId = viewModel.ContactId,
DateOfBirth = viewModel.DateOfBirth,
Email = viewModel.Email,
IsMarried = viewModel.IsMarried,
Name = viewModel.Name,
PhoneNumber = viewModel.PhoneNumber
});
}
else if (operation.Equals("del"))
{
repository.Delete(new ContactViewModel
{
ContactId = new Guid(formCollection["id"])
});
}
return Content(repository.HasErrors.ToString().ToLower());
}
What About Using Complex Keys?
Instead of having ContactId (“key: true”) as your key to delete, you might have a more complex key to identify which item to delete. As it turns out, you can bind to the onclickSubmit event of the add/edit/delete dialog and change what data is POST’ed to the controller.
A nice side effect of this is that you name your property such that the MVC Modal Binder works.
Updated Dialog Object Literal
var updateDialog = {
url: '<%= Url.Action("Update", "Contact") %>'
, closeAfterAdd: true
, closeAfterEdit: true
, afterShowForm: function (formId) {
$("#PhoneNumber").mask("(999) 999-9999");
$("#DateOfBirth").datepicker();
}
, afterclickPgButtons: function (whichbutton, formid, rowid) {
$("#PhoneNumber").mask("(999) 999-9999");
}
, modal: true
, onclickSubmit: function (params) {
var ajaxData = {};
var list = $("#list");
var selectedRow = list.getGridParam("selrow");
rowData = list.getRowData(selectedRow);
ajaxData = { ContactId: rowData.ContactId };
return ajaxData;
}
, width: "400"
};
I hope you found the above article of some use in your everyday coding. The jqGrid also provides an inline editing feature similar to what you might experience in an Excel grid. You might look into that if you are interested.
I saw an interesting tweet by Remy Sharp (@rem) the other day that sparked my interest.
So, I proceeded to research the Geolocation API and look up various web services that allowed me to utilize JSONP requests from jQuery.
Here is some pseudocode to describe what I came up with…
if (Your browser supports the GeoLocation API) {
if (Geolocation data contains address) {
Use address to populate form (Firefox)
} else {
Use Long/Lat to get address from web service & populate form (Chrome)
}
} else {
Use IP address to get address from web service & populate form (IE)
}
Note:You may notice depending on the browser not all of the fields are being filled out. This is because of the web services that I am utilizing are lacking one or more fields or vary depending on your location. If I find a better web service then I’ll update the script.
The goal of this blog post is to show how you can utilize some helpful techniques to easily Unit Test your Web Application. In this post I will focus on Unit Testing the Client-Side validation rules that ASP.NET MVC generates. You can apply the following techniques to pretty much any scenario, but since this is something I do, I thought I’d share.
Our sample applications is a Contact Manager. At this point we only have a toolbar with a “New Contact” button. When the button is clicked a “New Contact” dialog will appear with several input fields and a “Save” and “Cancel” button. All of the fields are required, so if the user clicks the “Save” button client-validation should verify that all fields have a value.
ASP.NET MVC Contact ViewModel
First lets take a look at our ViewModel which will drive the rules of our client-side validation.
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace jQueryUnitTestingFormValidation.Models
{
public class ContactViewModel
{
[HiddenInput(DisplayValue = false)]
public System.Guid Id { get; set; }
[Required(ErrorMessage = "Name Required")]
[DisplayName("Name")]
[StringLength(50, ErrorMessage = "Name must be less than or equal to 50 characters")]
public string Name { get; set; }
[Required(ErrorMessage = "Email Required")]
[DisplayName("E-mail")]
[StringLength(50, ErrorMessage = "Email must be less than or equal to 50 characters")]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"^([a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\s*;?\s*)+$", ErrorMessage = "Email must be valid")]
public string Email { get; set; }
[Required(ErrorMessage = "Phone Number Required")]
[DisplayName("Phone Number")]
[StringLength(50, ErrorMessage = "Phone must be less than or equal to 50 characters")]
public string PhoneNumber { get; set; }
[Required(ErrorMessage = "Date of Birth Required")]
[DisplayName("Date of Birth")]
public DateTime? DateOfBirth { get; set; }
[Required(ErrorMessage = "Required")]
[DisplayName("Is Married")]
public bool IsMarried { get; set; }
}
}
ASP.NET MVC Contact View
Our View is pretty simple. I decided for this sample to not modify the MasterPages that the Templated Helpers use. You’ll see that I’m call the LabelFor, EditorFor, and ValidationMessageFor and organizing them as I wish. If you are interested in a cleaner way to do this you can check out a previous blog entry I wrote entitled Opinionated ASP.NET MVC 2 Template Helpers.
The Contact Revealing Module contains the logic to initialize the button and dialog events, post the form to the Controller, etc…
Note: I am utilizing the Revealing Module Pattern for those of you who might not be aware of it. It is very helpful in splitting up your JavaScript code into testable and reusable modules.
var contactCreateModule = (function () {
var public = {},
dialogWidth = 800;
public.createDialog;
public.createPost;
public.init = function () {
public.createDialog = $("#createDialog");
public.createPost = $("#createPost");
public.initEventHandlers();
};
public.initEventHandlers = function () {
public.initToolbar();
public.initDialog();
};
public.initToolbar = function () {
$("#toolbar button").button();
$("#createContact").click(function () {
public.displayCreate();
});
};
public.initDialog = function () {
$(".datePicker").datepicker();
public.createDialog.dialog({
autoOpen: false
, width: dialogWidth
, modal: true
, open: validationModule.clearValidationMessages
, buttons: {
"Cancel": function () {
public.createDialog.dialog("close");
},
"Save": function () {
if (public.createPost.valid()) {
public.createDialog.dialog("close");
public.postContact();
}
}
}
});
};
public.displayCreate = function () {
public.createDialog
.dialog("open")
.find("input:first")
.focus();
};
public.postContact = function (callback) {
$.ajaxSettings.traditional = true;
$.ajax({
url: public.createPost.attr("action"),
data: public.createPost.serialize(),
type: "POST",
success: function (data, textStatus, xhr) {
public.postContactSuccess(data, textStatus, xhr);
callback(data && data.Success);
},
error: public.postContactError
});
};
public.postContactSuccess = function (data, textStatus, xhr) {
if (data && data.Success) {
notificationModule.displayMessage(true, "Your contact has been created!");
} else {
notificationModule.displayMessages(data.Success, data.Messages);
}
};
public.postContactError = function (xhr, textStatus, error) {
var errorMessage = exception ? exception : xhr.statusText;
notificationModule.displayMessage(false, "There was an error creating your contact: " + errorMessage);
};
return public;
} ());
Classic QUnit Style Tests
I initially started this blog post using standard QUnit syntax, but there was something about it that didn’t stand well with me. In particular, I didn’t like how I had a bunch of asserts all lumped together. Later in this article I switch out the classic QUnit-Style with a BDD-Style syntax.
The following are some screenshots from the Unit Tests…
The following is a slightly zoomed in view of the above image. You can see that all the asserts for one particular test are hidden beneath it. You can expand &| collapse the test to see each individual assert.
You can view the unit tests below that generated the above screen shots.
Since I don’t want the $.ajax call to actually occur in my Unit Tests, I swap out the default functionality with a stub function instead in the module setup (which is called before each test). In the module teardown (which is called after each test) I restore the default functionality in case any future test needs it.
var contactWasPosted = false;
module("Contact: Create", {
setup: function () {
contactWasPosted = false;
contactCreateModule.postContactBackup = contactCreateModule.postContact;
contactCreateModule.postContact = function (callback) {
contactWasPosted = true;
};
},
teardown: function () {
contactCreateModule.postContact = contactCreateModule.postContact;
contactCreateModule.createDialog.dialog('close');
}
});
test("When New Contact Button Clicked", function () {
//Arrange
//Act
$("#createContact").click();
//Assert
ok($("#createDialog:visible").length, "Dialog Should Display");
ok($("#Name_validationMessage:not(:visible)").length, "Name Validation Should Not Display");
ok($("#Email_validationMessage:not(:visible)").length, "Email Validation Should Not Display");
ok($("#PhoneNumber_validationMessage:not(:visible)").length, "PhoneNumber Validation Should Not Display");
ok($("#DateOfBirth_validationMessage:not(:visible)").length, "DateOfBirth Validation Should Not Display");
ok($("#IsMarried_validationMessage:not(:visible)").length, "IsMarried Validation Should Not Display");
});
test("When Click Save On an Empty Form", function () {
//Arrange
$("#createContact").click();
//Act
$(".ui-button-text:contains('Save')").parent().click();
//Assert
ok($("#Name_validationMessage:visible").length, "Name Validation Should Display");
ok($("#Email_validationMessage:visible").length, "Email Validation Should Display");
ok($("#PhoneNumber_validationMessage:visible").length, "PhoneNumber Validation Should Display");
ok($("#DateOfBirth_validationMessage:visible").length, "DateOfBirth Validation Should Display");
ok($("#IsMarried_validationMessage:visible").length, "IsMarried Validation Should Display");
ok($("#createDialog:visible").length, "Dialog Should Remain Displayed");
});
test("When Click Save On an Complete Form", function () {
//Arrange
$("#createContact").click();
$("#Name").val("xNamex");
$("#Email").val("tasty@bacon.com");
$("#PhoneNumber").val("xPhoneNumberx");
$("#DateOfBirth").val("xDateOfBirthx");
$("#IsMarried").attr("checked", true);
//Act
$(".ui-button-text:contains('Save')").parent().click();
//Assert
ok($("#Name_validationMessage:not(:visible)").length, "Name Validation Should Not Display");
ok($("#Email_validationMessage:not(:visible)").length, "Email Validation Should Not Display");
ok($("#PhoneNumber_validationMessage:not(:visible)").length, "PhoneNumber Validation Should Not Display");
ok($("#DateOfBirth_validationMessage:not(:visible)").length, "DateOfBirth Validation Should Not Display");
ok($("#IsMarried_validationMessage:not(:visible)").length, "IsMarried Validation Should Not Display");
ok(contactWasPosted, "Contact Should Post");
ok($("#createDialog:not(:visible)").length, "Dialog Should Be Closed");
});
BDD Style QUnit Tests
After talking more with Dan Mohl (@dmohl) I decided I wanted to try to find a Behavior Driven style of writing QUnit tests. I know there are several other BDD Client-Side Unit Test frameworks out there, but I wanted to keep to the QUnit runner for now.
So, during my research the author of Pavlov, Michael Monteleone (@namelessmike), let me know about his project, which ended up to be exactly what I was looking for.
The following is the output of my tests using QUnit and Pavlov…
Here is a slightly zoomed in view of the QUnit Pavlov test output…
The structure of the Unit Tests is dramatically different from the above classic Unit Tests.
The first thing you’ll notice is that I am extending the Assertion definitions to clean up some of the assert code that I had in my previous Unit Tests.
I still have the same logic in from the above Unit Tests that was in the setup and teardown methods, but now you can find those in the before and after methods.
The syntax of Pavlov is very readable from an English standpoint. You basically describe some scenario in words, and then split it out into code. It was very refreshing once I put it all together.
QUnit.specify.extendAssertions({
isNotDisplayed: function(actual, expected, message) {
ok(actual.is(":hidden") || actual.text().length == 0, message || "okay: isNotDisplayed");
},
isDisplayed: function (actual, expected, message) {
ok(actual.is(":visible") || actual.text().length > 0, message || "okay: isDisplayed");
}
});
QUnit.init({ moduleTestDelimeter: ", it " });
QUnit.specify.globalApi = true;
QUnit.specify("Contact", function () {
describe("Create", function () {
var contactWasPosted;
before(function () {
contactWasPosted = false;
contactCreateModule.postContactBackup = contactCreateModule.postContact;
contactCreateModule.postContact = function (callback) {
contactWasPosted = true;
};
$("#createContact").click();
});
after(function () {
contactCreateModule.postContact = contactCreateModule.postContact;
contactCreateModule.createDialog.dialog('close');
});
describe("When the contact button is clicked", function () {
it("should display the dialog", function () {
assert($("#createDialog:visible").length).isEqualTo(1);
});
it("should not display name validation", function () {
assert($("#Name_validationMessage:visible")).isNotDisplayed();
});
it("should not display email validation", function () {
assert($("#Email_validationMessage:visible")).isNotDisplayed();
});
it("should not display PhoneNumber validation", function () {
assert($("#PhoneNumber_validationMessage:visible")).isNotDisplayed();
});
it("should not display DateOfBirth validation", function () {
assert($("#DateOfBirth_validationMessage:visible")).isNotDisplayed();
});
it("should not display IsMarried validation", function () {
assert($("#IsMarried_validationMessage:visible")).isNotDisplayed();
});
});
describe("When clicking save on an empty form", function () {
before(function () {
$(".ui-button-text:contains('Save')").parent().click();
});
it("should keep the dialog displayed", function () {
assert($("#createDialog:visible").length).isEqualTo(1);
});
it("should display Name validation", function () {
assert($("#Name_validationMessage:visible")).isDisplayed();
});
it("should display Email validation", function () {
assert($("#Email_validationMessage:visible")).isDisplayed();
});
it("should display PhoneNumber validation", function () {
assert($("#PhoneNumber_validationMessage:visible")).isDisplayed();
});
it("should display DateOfBirth validation", function () {
assert($("#DateOfBirth_validationMessage:visible")).isDisplayed();
});
it("should display IsMarried validation", function () {
assert($("#IsMarried_validationMessage:visible")).isDisplayed();
});
});
describe("When clicking save on a completed form", function () {
before(function () {
$("#Name").val("xNamex");
$("#Email").val("tasty@bacon.com");
$("#PhoneNumber").val("xPhoneNumberx");
$("#DateOfBirth").val("xDateOfBirthx");
$("#IsMarried").attr("checked", true);
$(".ui-button-text:contains('Save')").parent().click();
});
it("should not display name validation", function () {
assert($("#Name_validationMessage:visible")).isNotDisplayed();
});
it("should not display email validation", function () {
assert($("#Email_validationMessage:visible")).isNotDisplayed();
});
it("should not display PhoneNumber validation", function () {
assert($("#PhoneNumber_validationMessage:visible")).isNotDisplayed();
});
it("should not display DateOfBirth validation", function () {
assert($("#DateOfBirth_validationMessage:visible")).isNotDisplayed();
});
it("should not display IsMarried validation", function () {
assert($("#IsMarried_validationMessage:visible")).isNotDisplayed();
});
it("should post contact", function () {
assert(contactWasPosted).isTrue();
});
it("should close the dialog", function () {
assert($("#createDialog:visible").length).isEqualTo(0);
});
});
});
});
Conclusion
The more and more I find myself creating highly dynamic websites, the more I find the need to Unit Test the browser interaction.
I hope you found the above example helpful. I would be interested to hear what tools you use to help Unit Test your client-side code. Please share… it makes us all better :)
You can find some other helpful client-side Unit Testing tools in the Script Junkie article I wrote entitled jQuery Test-Driven Development. In addition I wrote several other jQuery related articles that you can find on Script Junkie.
Note: It was not my intention to exhaustively Unit Test everything in the above example. There are other things I would Unit Test, but to make this example easy to understand in a bite-sized chuck, I limited myself to some simple examples.
Over the past 7 months or so I’ve written 7 articles that are now available on Script Junkie. I was honored to write these articles for the launch of the website. I hope this clues you into why the blog posts on this site have been lacking.
Recently I’ve been working on some highly dynamic User Interfaces and at one point in the project I found my first reflex on a certain task to use a switch statement in JavaScript.
Now, my previous training in studying the Design Patterns has told me that the switch statement is bad. The design pattern drilled into me to resolve the switch statement is the the Strategy Pattern, however, I’ve never used the Strategy Pattern in JavaScript before.
The following example is a simple demo application where I start with a switch statement and then refactor the code later in the blog post to use the Strategy Pattern.
A Simple Super Hero Demo Application
The sample application is a Super Hero creator. You provide a Super Hero name and then you select your Super Hero power. The power can be a variety of things ranging from Flying, Invisibility, to nothing at all. Some of the powers have additional questions (metadata) about that particular power.
Once the Super Hero is created, the application should build up a object with the appropriate power type and supporting metadata. For now, I’m just outputting the object in the Firebug Lite console using console.dir().
First Pass at a Switch Statement Solution
Here is the above application written using a switch statement to build up the Power type and metadata. The solution is fairly simple in nature. I am utilizing the Revealing Module Pattern.
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification
The switch solution violates the Open/Closed Principle in that every time a new Super Hero power is added to the list that the same piece of code will need to be modified. This is problematic in that new bugs can easily be introduced as new features are added or as defects are resolved.
Let’s look at a better way to solve the solution.
Refactoring Using the Strategy Pattern
A lof of the code will remain the same in the refactored solution. We mainly want to pull out the switch statement into something that is more maintainable and less error prone for future enhancment.
var superHeroModule = (function () {
var public = {};
public.init = function() {
$("input:radio[name='Power']").click(function() {
var selectedPower = this.value;
$("#powers .power").hide();
$("#powers ." + selectedPower).show();
});
$("#create").click(function() {
var superHero = public.scrapeSuperHero();
console.dir(superHero);
});
};
public.scrapeSuperHero = function() {
var superHero = {};
superHero.Name = $("#Name").val();
superHero.Power = public.scrapePower();
return superHero;
};
public.scrapePower = function() {
var power = {};
var selectedPower = $("input:radio[name='Power']:checked").val();
var scrapePowerFunction = "public.scrapePower" + selectedPower;
power = eval(scrapePowerFunction)();
return power;
};
public.scrapePowerFlying = function() {
var power = {};
power.type = "Flying";
power.speed = $("#flyingSpeed").val();
return power;
};
public.scrapePowerInvisibility = function() {
var power = {};
power.type = "Invisibility";
return power;
};
public.scrapePowerStrength = function() {
var power = {};
power.type = "Strength";
power.lift = $("#strengthLift").val();
power.strongerThan = $("#strengthStrongerThan").val();
return power;
};
public.scrapePowerVision = function() {
var power = {};
power.type = "Vision";
power.distance = $("#visionDistance").val();
power.seeInDark = $("#visionDark").is(":checked");
power.xrayVision = $("#visionXray").is(":checked");
return power;
};
return public;
} ());
superHeroModule.init();
Pros of this Solution
Abides by the Open/Closed Principle by opening the code for extension, but closing it for modification.
Cons of this Solution
The solution is more complex than the previous switch statement implementation
You might have noticed the use of the eval function. Douglas Crockford labeled the eval function as a Bad Part of JavaScript for some very good reasons, however, in this case I think the benefits it brings in this situation outweighs the risks. With every hard and fast rule, there comes a place and time to examine the benefits and risks.
Conclusion
I found that separating the switch statement logic into the above Strategy Pattern has made my current project much more maintainable and less error prone when adding new features.
How have you addressed similar situation? Have you implemented a different solution to the switch statement problem? Please share with me, I’d love to know!
I updated the Couch Potato bookmarklet to add the ability to expand and collapse the details of each document from the list page by clicking the “+” to the left of the document key.
You can also click the “Expand All Documents” action located in the right navigation column.
The Bookmarklet
To use the bookmarklet, drag the following link to your bookmark/favorites list:
We’ve been using CouchDB in our current project at work and I’ve been using the CouchDB Futon manager more and more lately to create, edit, or delete documents.
After a lot of test data gets into our document store, I end up needing to clear out the documents. I could Delete the whole database with a button, but I’d rather not remove the CouchDB design documents defining custom views.
In order to delete documents from Futon, you have to manually drill down into each document and then click the delete button. I found this very monotonous, so I decided to make a bookmarklet to help me out some.
The Solution
So, I created the CouchDB Potato Bookmarklet (because I’m lazy). The bookmarklet creates a new delete column and provides a “Delete Documents” link to delete all the checked documents. I also added a “Select All Documents” which only selects non-design documents (so that I don’t accidentally delete a CouchDB view). These links can be found in the right navigation column under the “Recent Databases” section.
The Bookmarklet
To use the bookmarklet, drag the following link to your bookmark/favorites list:
If you have used ASP.NET MVC any, then you are probably aware of the MVC Contrib project hosted on CodePlex. It is a helpful library that provides useful tools that ASP.NET MVC doesn’t give you out of the box.
Opinionated Input Builders
One of the pieces that I really like is the Opinionated Input Builders that Eric Hexter wrote. The builder allows you to provide one property at a time from your View Model and it will output the label, required indicator, the appropriate input control, and whatever else that it needs to display.
As it turns out, the ASP.NET MVC team took a similar approach when putting together the Template Helpers in ASP.NET MVC 2. I ended up switching to the Template Helpers.
With some CSS styling, the output of the EditorForModel is close to what the Opinionated Input Builder, but there are some problems as we’ll discuss in the next section.
ASP.NET MVC 2 EditorFor
The problem is that I usually don’t want to display or edit my entire model. I often times have things in my View Model that I don’t particularly want to display. I want to rather manually choose which properties I want to display or edit.
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) { %>
<%= Html.EditorFor(m => m.FirstName) %>
<%= Html.EditorFor(m => m.LastName)%>
<%-- Purposely Not Show the Email –%>
<p class="actions">
<input type="submit" value="Create" />
</p>
<% } %>
Using the above syntax doesn’t quite give the output I was looking for. Only the input controls are rendered (as seen in the following screenshot) instead of providing the scaffolding of label, input, and validation fields like the EditorForModel method provides.
You end up having to provides the layout of the controls and explicitly mention the label, input controls, and validation for each property.
Modify the Template Helpers MasterPage
I soon began to miss the simple syntax of rendering all the necessary code like I was used to when using the Opinionated Input Builders outputted from the MVC Contrib.
Well, a while back Brad Wilson (one of the ASP.NET MVC 2 developers), wrote an awesome series about Templated Helpers and the last post in the series, ASP.NET MVC 2 Templates, Part 5: Master Page Templates, he addressed this granular Opinionated Input Builder type syntax!
All you do, is to override the Master Page that the templates use internally. So, inside my Master Page I layout where I want the label, validation, and input controls to go and then ASP.NET MVC 2 does the rest by resolving which Template Helper to use!
I modified the Master Page some to suite my needs (I use divs instead of tables), but overall it is the same one that he lays out on his blog.
There are several other files that you’ll need. I’ve grabbed most of them from Brad’s blog post and have them in the demo application below that you can download.
Now we can try the above scenario one more time and get the output that we were expecting.
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) { %>
<%= Html.EditorFor(m => m.FirstName) %>
<%= Html.EditorFor(m => m.LastName)%>
<%-- Purposely Not Show the Email –%>
<p class="actions">
<input type="submit" value="Create" />
</p>
<% } %>
I’ve been using jsFiddle more and more to test and share JavaScript and jQuery code.
Although I love that jsFiddle shows the HTML, JavaScript, CSS, and Results window all at the same time, I also would love to somehow see the output of the console window in the User Interface. Depending on the browser someone views my jsFiddle projects, the console may or may not be defined. I really don’t like alert statements and sometimes it is just easier to console.log() than it is to write out messages to the DOM.
Firebug Lite
So, I’ve been finding myself adding Firebug Lite as a resource to jsFiddle and letting Firebug be part of the rendered output.
If you’ve tried this, then you may have noticed that Firebug auto-opens once jsFiddle is rendered. Seeing that the Rendered section isn’t very big this could be a big problem.
Thankfully, there are several options you can provide to Firebug Lite to customize it’s behavior.
I find myself setting the following three options on a regular basis.
<script type="text/javascript">
firebug.env.height = 200; //Set the initial height of the Firebug window
firebug.env.debug= false; //Set Firebug to be initially launched or minimized
firebug.env.detectFirebug = true; //If browser has Firebug, don’t interfere with it
</script>
I also like to use JsBin quite a bit and honestly switch between it and jsFiddle quite often depending on what I am doing.
Full Screen Option
One of the features that I really like in JsBin is that you can launch the session to Full Screen and not inside the editor. This is helpful if you want to interact with the DOM with your browser’s debugging tools, minimize any side-effects the editor might be creating, etc…
As it turns out, jsFiddle has this same feature, but you have to know how to get to it. You can just add “/show” to the end of your jsFiddle URL to show it without the editor. To swap back to the edit view you can simply remove the “/show” from the URL.
Now that we know we can swap back and forth between Full Screen and Edit mode, what I miss is the nice little JsBin link in the upper-right hand corner of the page allowing you to easily swap between the two environments.
As it turns out, I’ve recreated this in jsFiddle by adding the following code to my JavaScript window…
$("<a />", {
id : "show",
text : window.location.pathname.indexOf("show/light") > 0 ?
"View Full Screen" : "Edit using jsFiddle",
href : window.location.pathname.indexOf("show/light") > 0 ?
window.location.pathname.replace(/light\/$/gi, "") :
window.location.pathname.replace(/show\/$/gi, ""),
target : "_blank"
}).appendTo('body');
…and here is the supporting CSS that I put in the CSS window of the jsFiddle Editor.
In case you haven’t heard from the end of the Rey Bomb #2 Episode of The Official jQuery Podcast, I announced that after 21 episodes I am stepping down as my role of co-host.
Around the time I first joined the podcast I also started to become involved with some intense writing projects (as will become apparent in the near future), although I can’t say much about it right now :)
As a result, I haven’t had much margin in my life. I’ve been running on empty for quite some time and other more important things in my life have gotten the shaft! Unfortunately, one of those was my family and I intend to change that.
I don’t plan to fall off the face of the earth. I plan to refocus on blogging and tweeting. I would like to do some more speaking, but probably not for the rest of the year as baby #3 is coming in August.
I am honored to have been asked to join The Official jQuery Podcast and during my involvement I got to meet many great people that I hadn’t previously known. I am glad to have formed these relationships, and look forward to further investing in them.
I hope the future of The Official jQuery Podcast is bright and I encourage you to either start or continue to listen.
This year I was chosen by the community to speak at Mix10 as one of the Open Call sessions. I was honored to be selected and thoroughly enjoyed attending Mix10 and building relationships.
This seminar provides an overview of several in-depth concepts that developers need to learn to bring their jQuery development to the next level. We review six things that you should know, such as: "What Is This?", "Am I Referencing the jQuery Object or a DOM Element?", "Understanding Selectors", "Combine and Minify Your Scripts", "Different Ways of Storing Data", and "The Dos and Don'ts of Events". Along the way, we share several helpful websites and tools to make your job as a jQuery developer easier.
For each of the 6 points I started with beginning material and then progressed to intermediate then advanced concepts. When I moved to the next point the content would go back to beginner and then progress to advanced. In this way, I hoped to reach a wider audience with things tips they could take away from the session.
The video from my talk is now available from the Mix10 website. You can watch the video and also download my web-based presentation along with the code I showed.
Unfortunately, the main demo that I wanted to show didn’t work during the presentation. The demo worked the night before & it works now. My guess is that the Picasa Web API was temporarily down during my talk, which is unfortunate. I guess I should have expected something to go wrong. Anyway, overall I think it went well. I had several questions at the end and people stayed after to ask questions as well.
During the presentation I listed several resources that I recommended. I pulled those out and provided them below for quick access them. Some of them I demonstrated during the talk and others I just referred to as good resources you may want to check out.
If you were able to attend my session at Mix10 or watch the above video recording, I would appreciate if you could take a moment to rate my talk on speakerrate.com. Thank you again for voting my session into Mix10.
Note: Someone asked me what Visual Studio theme I was using to show the code near the end of the session. As it turns out, I was using JetBrains WebStorm IDE. Jeffrey Way did a great mini-screencast review of the new IDE on Nettuts.
Although I’ve switched to Google Chrome as my primary web browser, I still switch over Firefox every once in a while for one reason or another.
With the recent release of Firefox 3.6 you might find some of your favorite add-ons no longer in working because they haven’t yet been updated to support the new version number.
You can easily get around this limitation by installing the Nightly Tester Tools Firefox Add-on which allows you to override the maximum version the add-ons say they can support.
Keep in mind, even though you are forcing your add-ons to run with your current browser version it doesn’t mean they will work, but usually I find that they do work just fine.
I’m a sucker for running the latest and greatest build of Firefox so the Nightly Tester Tools Firefox Add-on is a must for me.
I tend to use the Portable Versions of Firefox so they are sandboxed in their own little folders. That way I can also have several versions on my box for testing.
As a total side-note, but related point I also like these following Portable Applications that you can find from the same site…