Jarrett@Work

Sunday, December 20, 2009

Simple Format Live Preview

Inspired by Phil Haack of ASP.NET MVC fame, I decided to write my own live preview for the Ruby on Rails simple_format helper.

Since it’s for Rails, it’s written in Prototype, which is a departure from my usual work in jQuery. I actually worked with Prototype first, before switching to jQuery. I switched because I now work in a Microsoft shop and jQuery comes prepackaged with ASP.NET MVC.

The simple_format helper is pretty simple. It converts single newlines to break tags and double newlines to paragraphs. The live previews watches the keyup event on the textarea field and updates the contents of the preview div. The simple_format is just that: simple!

The source is hosted on GitHub. I’ve worked with Git and GitHub for a little while now, and I totally get what all of the fuss is about. I like the same things about Git that I like about RoR. You can tell that they have taken the best of many other tools and made it all easier!

<html>
<body>

<form id="my-form">
<textarea id="my-textarea"></textarea>
<div style="clear:both;"/>
<div id="my-live-preview"></div>
</form>

<script type="text/javascript" src="./path/to/prototype.js"></script>
<script type="text/javascript" src="./path/to/simple-format-preview.js"></script>
<script type="text/javascript">
new SimpleFormatPreview('my-textarea', 'my-live-preview');
</script>

</body>
</html>

Friday, December 18, 2009

Pick Your Battles

I’m probably not the best at picking my battles. To be more accurate, I probably pick battles that should never even start. Even more accurately, they’re probably not battles at all until I start them.

Let’s lay down a scenario. My boss asked two of his developers to implement some new feature. Nothing any client wanted; something he wanted. Although I don’t know if that would have mattered to me if a client would have wanted it. In short, I refused. This feature was more than a simple add-on. It would have embedded itself into a very base level of the application and touched just about every query from that point on. And, a lot of working code would need to be rewritten. I saw nothing but bad vibes coming from this idea.

My colleague, on the other hand, agreed to write the feature. Later on in this meeting, when prompted by my boss, my colleague agreed with me that it was a terrible idea but would have done it anyway because the boss was… well, he was the boss.

<Insert picture of shock on boss’ face.>

After my boss received the second opinion, he dropped the request. (Thank goodness!)

This is not the only time this has happened. I have been in multiple conversations with other coworkers where it is me on one side – it isn’t right based on principle and we know better – and one (or more) on the other – it’s what the customer wants. While I’m usually a firm believer that the customer is an expert in his or her domain of knowledge, the customer usually knows nothing about computers. Sometimes, we’re lucky. We get customers who know what they want, and they give us room to explore and design. They see some things. They like those things. They want more of those things.

Other times, the customer used to write mainframe applications in 1977 and the only experience they’ve had with a “modern” language is a “Teach Yourself Java in 24 Hours” book that they read in 1999. If you’re riding the edge of the .NET framework, then you’d know that programming has changed dramatically just last year, let alone how much it has changed in the past decade.

Enter Uncle Bob Martin’s latest post on Saying “No”. It references a comic about web design. The main Martin makes is all about being a professional. Professionals adhere to principles and standards. Laborers do what they are told. Professionals are in negotiation with their clients. Negotiators have the right to willingly walk away from the table. If one party cannot walk away from the table, then it isn’t a negotiation.

We are professionals. We know the right thing to do. When know when to do it. It is just as important to know when to not compromise as when it is to compromise.

Saturday, December 12, 2009

If Your Page Won’t Center in IE 8

It’s because you didn’t give it a DOCTYPE.

As I found out the very, very hard way, IE 8 will default to quirks mode. I’ve got a CSS block that says something along the lines of .container { margin: 0 auto; }, which centers my content in every browser. However, it wasn’t centering in IE, and I couldn’t figure out why for the life of me.

I added a DOCTYPE, and all was golden again.

Friday, December 11, 2009

Redirect without WWW in Rails

I don’t like www as the typical beginning to a web page. It’s 2009, almost 2010. Do we really need it? Do we really need to prefix our web pages with something that indicates that this particular fixture lives on the world wide web? WWW is for server administrators who need a way to distinguish which boxes sit on which side of the corporate firewall. WWW is not for real people. No matter what your point of view, the WWW has to work. Too many people use the WWW in their URLs and bookmarks. They’ll type http://www.google.com and http://www.rubyonrails.org.

Funny enough, if you type http://google.com, you’ll get redirected to http://www.google.com and if you type http://www.rubyonrails.org, you’ll get redirected to http://rubyonrails.org. So it looks like the debate over what to do with the WWW is still strong with us.

To get this to work, you need to know the 3 main parts of the URL.

  • Protocol – either the http:// or https:// that starts the web page, including the slashes.
  • Host – the domain root, something like www.example.com or just example.com.
  • Request URI – everything that comes after the first slash, including the first slash, path, and query string.
class ApplicationController < ActionController::Base
before_filter :redirect_without_www

def redirect_without_www
redirect_to "#{request.protocol}example.com#{request.request_uri}" if request.host =~ /^www/
end
end

Since we’re sticking making this method a before_filter on the ApplicationController, we’re sure to cover every request that hits our application.

Friday, December 4, 2009

Pretty User Messages In Rails

In a small effort to make user interfaces a little nicer, here’s the way I’m doing it in a current Ruby on Rails application. This is pretty standard stuff, but if it helps someone out, then all the better.

imageFirst, in our controller, we need to add some messages. This can really be anything in the application. For the example below, I’m showing a simple logon action.

def logon
if request.post?
credentials = Credentials.find_by_email(params[:email])
if credentials && credentials.valid_password?(params[:email])
flash.now[:notice] = "You have successfully logged on!"
credentials.last_login = DateTime.now
credentials.last_login_from_ip = request.remote_ip
credentials.save
set_up_session(credentials)
redirect_to :controller => :welcome
else
flash.now[:error] = "Invalid credentials"
end
else #not a post request
flash.now[:message] = "Please log on with your email address and password"
end
end

Next, we need a helper to get those messages. Add this to your application_helper.rb file.

def show_flash
keys = [:error, :message, :success, :warning]
keys.collect do |key|
content_tag(:div, flash[key], :class => "flash flash_#{key}") unless flash[key].blank?
end.join
end

When you’re ready to get those messages, presumably in your layout file, all you need is the following. If you’re reading this blog, and you’re not familiar with Rails, that’s really too bad. Because helpers are pretty much the best thing ever.

<%= show_flash %>

Here’s the CSS to make everything nice and presentable. My icons are all 24 x 24 PNG images.

.flash {
margin: 0.5em 0;
width: 836px;
padding: 14px 14px 14px 46px;
}

.flash_error {
border: 2px solid #cc0000;
background: #ffcccc url("../images/flash-error.png") 14px 10px no-repeat;
color: #cc0000;
}

.flash_message {
border: 2px solid #003399;
background: #ccccff url("../images/flash-message.png") 14px 10px no-repeat;
color: #003399;
}

.flash_success {
border: 2px solid #006600;
background: #ccffcc url("../images/flash-success.png") 14px 10px no-repeat;
color: #006600;

}

.flash_warning {
border: 2px solid #cc9900;
background: #ffffcc url("../images/flash-warning.png") 14px 10px no-repeat;
color: #cc9900;
}

Hooray! Funny, the more I work with CSS, the easier it gets.

Blogs I Follow...

My Posts