rolando.cl
Better text areas in enki (or any other rails app for that matter)
When creating my site, I realized that I might be typing a lot of code snippets into this blog, and since usually pressing “tab” changes focus on input fields and not actually inserts a tab in the text I’m editing, I realized I had to “fix” that, here’s my solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# context: enki blog (http://www.enkiblog.com/)
# file: app/views/admin/posts/_form.html.erb
<% content_for(:head) do -%>
<%= javascript_include_tag 'admin/edit-preview' %>
<% end -%>
<%= form.inputs do -%>
<%= form.input :title -%>
<%= form.input :body,
:hint => "<a href='http://textile.thresholdstate.com/'>Textile enabled</a>. Use Ctrl+E to switch between preview and edit mode.".html_safe -%>
<%= form.input :tag_list, :as => 'string', :required => false, :hint => 'Comma separated: ruby, rails…'.html_safe -%>
<% end -%>
<%= form.inputs do -%>
<%= form.input :published_at_natural, :label => 'Published at', :as => 'string', :hint => 'Example: now, yesterday, 1 hour from now, '.html_safe + link_to("more…".html_safe, "http://chronic.rubyforge.org/") -%>
<%= form.input :slug, :hint => "Leave blank for an auto-generated slug based on the title." -%>
<%= form.input :minor_edit, :as => 'boolean', :hint => 'Minor edits will not show up as refreshed in feed readers. Use this to fix spelling mistakes and the like.' unless @post.new_record? -%>
<% end -%>
<script type="text/javascript">
$(document).ready(function () {
$("#post_body").css("font-family", "Menlo").css("font-size", "8pt");
var has_focus = false;
var lastKey = 0;
$("#post_body").bind('blur', function () {
if (lastKey == 9) {
// if selection is nothing, then insert a "tab"
if (this.selectionStart - this.selectionEnd == 0) {
var val = $(this).val();
var a = val.substring(0, this.selectionStart);
var b = val.substring(this.selectionStart, val.length);
$(this).val(a + "\t" + b);
// now set the selection
this.selectionStart += 1;
}
$(this).focus();
return false;
}
return true;
}, true);
$("#post_body").keydown(function (event) {
lastKey = event.keyCode;
});
});
</script>
|
It goes like this:
when post_body looses focus (the body text area for the post) and if last key pressed was actually a tab (you can loose focus by clicking somewhere else), then insert a tab where the selection pointer was, and move the selection pointer.
Oh, I also added some nice css styles for the textarea, like the lovely Menlo font and a specific font size.
It’s not the best solution, but it works.
Some wild ideas to implement:
- context-aware tab (like if you’re inside a ruby snippet, then insert two blanks instead of a “\t”
- be able to shift-up/down indentation levels
But… if you start doing all that, you end up with something more like a text editor than just a simple post creator in your blog app. So… this small change is what will work best for me now.