Bit of a short post from me this week (a longer one coming next week, I promise). Just wanted to cover a little bit of jQuery I discovered that helped me a lot with a particular problem I couldn't seem to beat.
I had a contentEditable area that showed a little admin toolbar above it when you focused on the element, and I needed to remove it as soon as the user clicked away from the area. Unfortunately, the "blur()" implementation for contentEditable areas is a little bit all over the place and a user can get around it occasionally. It doesn't seem to fire, for example, when you immediately highlight some other text rather than just clicking away.
So, I came up with this snippet:
$(document).mousedown(function (e) {
if (!$(e.target).is('.editable, .editable *')) {
$('.top-bar').remove();
$('div.active').removeClass('active');
}
});
This basically fires a mousedown event whenever you click anywhere on the document. It checks whether the target is within the editable area and if it's not, it removes the admin toolbar and associated CSS class.
Visual Studio 11 Developer Preview is now available (actually, it was released a little while ago) and I only just got around to giving it a go. Although it doesn't seem a whole lot different to VS2010, there are a number of improvements and additions:
- async and await keywords
These keywords allow for some impressive asynchronous functionality to be handled (I briefly covered this in a previous blog post)
- Built-in bundling and minification of client scripts
This allows you to bundle up JavaScript and CSS into single files, to remove unnecessarily large numbers of requests and save on file size.
- Integrated Anti-XSS encoding routines
These anti cross site scripting features were available previously as an external DLL, but are now part of the core functionality.
- Support for HTML5 form types
Types such as email, tel, url and search are now handled appropriately.
There's more, but you can check out the full details here.
In addition to this, you can also check out the MVC 4.0 Developer Preview (I discussed this in a previous post) and the ASP.NET Web Pages 2.0 Developer Preview.
This week I was trying to replicate "hyperlink" functionality using a ContentEditable area, rather than a <textarea>. Stupidly, I thought the process of finding a user's currently selected text and surrounding it with a link would be fairly easy... it turned out to be fairly tough.
My function would use the window.getSelection() to get the user's current selection, and then call getRangeAt(0).cloneRange() to create a copy of the "Range" object for that selection. The range object tells the browser where the selection starts and where the selection ends.
I would pull the selected text out into a string object by calling .toString() on the Range object itself. Then I could modify that string to include an <a> tag surrounding it, with the appropriate link. The next step was the most difficult to figure out, the process is as follows:
- Create a new text node, using document.createTextNode and passing in the modified string.
- Call "insertNode" on my range object, passing the text node as a parameter.
- Call "removeAllRanges()" on the selection object, to remove any existing ranges.
- Call "addRange" on the selection object, passing in my modified range object.
This resulted in the selected text being replaced with my linked version in every browser except... Firefox. Bit of a strange one, really, and Googling the issue didn't seem to shed much light. My next step is to find a Firefox friendly fallback for if the normal method fails.
I thought I’d write a blog around a piece of interesting functionality I developed for a new blog engine that I am currently involved with.
The requirement was to take a flat list of posts and output a dynamic, magazine style layout with was broken down into multiple rows, with each row having a varying number of posts. This needed to be a random arrangement, so that each time the blog was visited, the layout would be different and make for a more interesting user experience.
This was going to be using MVC3, so the first step was to create a database table called BlogRow. This contained all of the row variations that existed within the system, the two most important columns being “ViewName” (which stored the name of the partial view instance for that particular row type) and “NumberOfPosts” (which stored the number of posts this row required to display).
When the page began rendering, you’d start with a flat list of 24 posts, retrieved in reverse chronological order from the database. Then you’d follow this process:
- Get a random BlogRow instance from the database (where NumberOfPosts for that row is higher than the remaining posts in the flat list)
- Slice the required NumberOfPosts out of the flat list (so slicing 4 would leave you with 20 in the flat list)
- Create a model for that particular partial view, consisting of a List of Post objects and the name of the partial view for that Blog Row
- This process continues until you have no posts remaining in the flat list of posts, at which post, a model which consists of a List of Lists of Posts (confusing, right?) is sent to the main View for the front of the blog
There were a couple of pieces of extra logic around this (for example, a row consisting of a single post is only used if there’s only one post left in the list at the end), but I won’t go into all of those now. The page also stored it’s layout in the user session, preventing the layout from changing constantly for a single user every time they refreshed the page.
I couldn’t find many instances of people using a dynamic number of Partial Views/Partial View Models within a single view, so it took a bit of planning to put something together, but I ended up with a pretty effective solution.
I've been getting to grips with nHibernate recently, having mostly used Entity Framework as my ORM of choice in the past. With nHibernate being the more mature framework, and after hearing things from other developers about how much better nHibernate is, I decided to check it out. To get used to using it, I decided to build a basic MVC website using nHibernate. First of all, I tried using XML mapping, but after having a little bit of trouble getting that up and running, I switched to Fluent nHibnerate (because it also looked cooler).
Rather than using XML, Fluent nHibernate maps directly in class files, with code something like this:
public class PostMap : ClassMap<Post>
{
public PostMap()
{
Id(x => x.Id);
Map(x => x.Title);
Map(x => x.Content);
Map(x => x.CreatedDate);
Map(x => x.ModifiedDate);
References(x => x.User);
}
}
However, when I started actually querying data, I came across the problem that if you had a class that referenced another class (for example, a blog post references a blogger) then when you tried to actually access information about the referenced class (the blogger) on the view side, you'd run into problems. It was because nHibernate 3 uses Lazy Loading by default, which means it only loads information about the blogger when it is specifically requested. The problem in this case was that once the model had been passed to the view, the nHibernate Session that connected it to the database was closed, this meant that you ended up with an error when you tried to do something like this.Model.User.Username, as it was trying to lazy load information on the user but discovering that it couldn't get to the database anymore.
I discovered two solutions after a bit of Googling:
- In the mapping class, specify that the reference should not be lazy loaded. This looks like: "References(x => x.User).Not.LazyLoad().
- When running a query against the open session, you request the object be explicitly loaded in by using the "Fetch" method. This looks like: "session.Query<Post>().Fetch(p => p.User)".
The second solution is preferable, because it doesn't make the explicit lazy loading system-wide and allows you to handle it on a per query basis.
I realise my post this week was particularly tech heavy, and I'm planning to do a more basic introduction to nHibernate, but I wanted to get this solution out there for anyone who ends up with the same problem!
ASP.NET MVC uses what is called a "View Engine" to render content to the user's browser. There are a growing number of view engines available, so I'm just going to cover what seem to be the three most popular.
Standard (.aspx)
Not going to cover this one, as this is more a post about the alternatives that are out there. I may refer to the differences between the alternative engines and the original engine as I go along, but I'm going to leave out the Standard engine for now.
Razor
The Razor view engine is sort of Microsoft's official "advanced" view engine, which comes packaged with MVC3. Scott Guthrie, the Vice President of the Microsoft Developer Division has blogged about the details of the engine here.
Razor is definitely my favourite of the view engines, so this blog post might descend a little bit into a discussion of why the other view engines aren't quite as good as Razor.
I'm just going to cover some of the basics:
Razor essentially allows you to seamlessly introduce code elements into markup without having to surround code blocks with "<%" as in the standard view engine. Using the "@" character, the view engine is parsed intelligently by the runtime to determine what is a presentation element and what is a code element.
For example, the code:
<h1>Hello <%=name %>, the year is <%= DateTime.Now.Year %></h1>
<ul>
<% foreach(var p in products) { %>
<li><%=p.Name %> (£<%=p.Price%>)</li>
<% } %>
</ul>
would become a much more readable:
<h1>Hello @name, the year is @DateTime.Now.Year</h1>
<ul>
@foreach(var p in products) {
<li>@p.Name (£@p.Price)</li>
}
</ul>
But both would result in exactly the same thing being rendered. This allows a developer to write a much neater, more concise and compact view when they are developing a page and allows front-end developers to alter markup without getting a headache.
nHaml
I'll be honest... I don't really get nHaml. I don't know what it brings to the table. It's slightly less verbose than the standard view engine, but it implements its own replacement for HTML markup and ends up looking pretty unattractive.
Here is the example from Razor, translated to nHaml:
%h1
Hello
= name
, the year is
= DateTime.Now.Year
%ul
- foreach(var p in products)
%li= p.Name + "(£" + p.Price + ")"
I don't know why anyone would want to write views like that... but apparently people do!
Spark
Spark is probably a bit of a step up from nHaml, but again, I think the markup comes out looking quite unattractive and definitely doesn't lend itself well to separation of concerns, as all of the code is essentially just written using XML tags.
Again, the same example from Razor, translated to Spark:
<h1>Hello ${name}, the year is ${DateTime.Now.Year}</h1>
<ul>
<for each="var p in products">
<li>${p.Name} (£${p.Price})</li>
</for>
</ul>
While I think this is slightly more readable than the nHaml variation, it's still somewhere close to a front-end developer's nightmare. It adds in all sorts of non-existent tags and attributes, and is likely to end up cluttered.
Maybe I'm wrong about the benefits of the alternative view engines, but Razor seems miles ahead of any of the others in terms of maximizing the developer's ability to mix code with markup, while avoiding frustrating front-end developers.
If you are interested in the other MVC view engines out there, there's a good compilation here.
ASP.NET MVC 4 is being talked about now, as it's been over a year since MVC3 came out. Microsoft has released the ASP.NET MVC 4 Roadmap, which gives some hints as to the functionality to come in the newest version. It's obviously not concrete, as things can change during development (as we all know) but it's a pretty good indication of what to expect.
Microsoft are integrating heavily with HTML5, Mobile devices and the cloud, as well as making everything and little bit more efficient and a little bit smoother. That seems to be the summary of their plans for ASP.NET MVC 4.
I'm just going to walk through some of the features that are mentioned:
Recipes
This sounds pretty interesting. It basically sounds a lot like jQuery plugins, but for .NET MVC. In a normal situation, this isn't particularly easy to do. Things like AJAX grids, for example, often involve some front-end markup, some back-end code (including data binding and data access). What recipes do is give you a nice, simple way of adding a "plugin" to your project. It automatically generates all the required code for you. This could potentially be a very interesting development, as it would allow easy creation/exchange of MVC "plugins" that you could use to quickly implement complex functionality with minimal work.
Default Template changes/New mobile template
Mainly to do with mobile support, from the looks of it. Detection for mobile devices will be added for the default "MVC site" template to avoid all of the awkward zooming in/out that you need to do to navigate the default site at the moment. It gives you a nice base to build from. Also mentioned is a new "Mobile Application" template, which will integrate with jQuery Mobile and allow you to optimize for mobile and tablet devices. MVC may also implement "mobile-specific views", which the application itself would handle, ensuring that mobile users get a more specifically designed experience.
Integrated CSS and JavaScript bundling
This functionality will allow the application to consolidate multiple CSS stylesheets and JavaScript files into single files, and reduce the size of the final file by removing whitespace and comments and so on. There's already ways of doing this at the moment, but this would come as standard, so you wouldn't even need to worry about it. Could be a nice feature.
All in all, sounds pretty cool, and I'm looking forward to messing about with some of the new features when it's released.
This is the start of a bit of an experiment for me. TDD is something I've heard a lot about, but never actually sat down and worked out, so I'll start this series of posts just with a little introduction to what Test Driven Development is, how it differs from normal development and why it's useful.
TDD is pretty much exactly what it sounds like. When developing an application, you'd normally design a bit of functionality, develop it and then write a unit test, using a unit testing framework such as nUnit, to... (surprise) test it. With TDD, you write a test for your functionality, run it and let it fail, then you develop until your test passes. Probably your first question would be: what's the point? Why write things that way round?
The advantages are pretty clear:
-
You set out what the functionality needs to do before you start writing it, almost like a specification within the code itself
-
The code becomes easier to understand in the context of the tests. You can see all the things that the code is meant to do by reading through the unit tests
-
You end up with a large number of automated tests that you can run, massively reducing debugging time
I've heard it said that once people start developing in this way, they find it very difficult to go back to the old ways. So, over the next few weeks, I'm going to find out how true that is.
I’ve had the idea in the back of my mind for a while to develop some drag and drop, intuitive editing/reordering type functionality as part of a front-end interface for a CMS. The basic setup is pretty straightforward, by using jQuery, jQuery UI and the HTML "contenteditable" attribute, I was able to set up a multiple column layout that allowed you to edit content on-screen and drag and drop to reorder items.
The first real issue I had to tackle was persisting those changes. In order to do that, I needed to somehow link my reorderable items up to a database. The page would load in the items (including which column they are in and their display order) from the database, then the user could drag and drop to reorder, then those changes would be automatically saved back in to the database.
This is where HTML data attributes and the jQuery .data() method came in handy. HTML5 data attributes allow you to have custom attributes against your HTML elements as long as they are prefixed with “data-“. So, I decided to use “data-arearef” for the column reference and “data-itemref” for an item reference. Using jQuery, I can then keep track of those data attributes.
In order to save changes back in to the database, I get all the areas on the page that have a HTML5 data attribute, then I create a list of the “data-itemref” attributes' values for each item within that area. That means that I can drag and drop to reorder my items, and those changes will be tracked using HTML5 data attributes and the jQuery .data() method, sent back to my .NET app using a jQuery AJAX call and like magic (and some C#, that also helps), it’s all saved!
Read more on HTML5 data attributes, or jQuery data.
We have managed to bring together the League of Extraordinary Gentlemen for a Movember photo shoot.
Let’s get behind the team, raise some money and have a little fun along the way...
An ode to Creative Fur!!!
Martyn has started the Movember race
Dax is edging ahead with plenty of fur on his face
Rob may be struggling to grow a full mane
Paul is showing ginger and starting to complain
Frazer was unsure but is having a go
Alex's growth is visible and beginning to show
Nat looks mighty snug with the growth on his face
Jason's attempt is so weak and is not looking that ace
Liggi is another one that's running ahead
Simons face is looking as cool as the hair on his head
Evan is trying and having a good go
Lyle's dark shadow is looking smooth protecting his nose
Craig takes the biscuit with growth dark and curly
We all should protest as he's making us all look girlie!!!!
The lone ranger is James he’s not here again
He will not escape, there’s no avoiding Movember my friend
Calling all Mo Bro’s and Mo Sista’s, join the official page and get behind our furry friends!!!
http://uk.movember.com/mospace/962034/