2 Jun

Textile Editor Helper v0.2

June 2nd, 2007 — 8:04 pm Chris

We’ve just recently rolled out v0.2 of our Textile Editor Helper plugin, so I wanted to give a brief overview of the changes/additions.

Refactored

First, the structure of the Javascript has been reworked and organized to be more object-oriented. The main goal was to eliminate cluttering the system with a number of slightly obscure functions such as edToolbar and edButton. Now, these are, respectively TextileEditor.initialize and TextileEditorButton. Of course, this should be transparent to most since the inteface (helper methods) have not changed.

Restyled

This again should be transparent, but it’s worth noting: the way the buttons are styled has changed slightly. Previously, every button had an ID and that was used in the CSS to provide a background image. In v0.2, however, the image is directly added as a child to the button element. The main reason for this was to allow the new feature: custom buttons.

Custom buttons

It is now possible to add custom buttons to the toolbar. A new textile_editor_button helper facilitates this. Note that, currently, you can only add buttons to the end. The helper takes two arguments: the first being the text or HTML to put inside the button, and the second argument is an options hash. The options supported are the same as those for the Rails content_tag helper.

Examples

Here are a few examples of adding custom buttons:

# this will add a separator line
<% textile_editor_button :separator %>

# custom button with custom action
<% textile_editor_button image_tag('textile-editor/bold.png') + ' Greetings', 
  :onclick => "alert('Hello!')" 
%>

# custom button that implements the textile '@' tag
<% textile_editor_button 'Code',
  :onclick => "TextileEditor.insertTag(this, '@', '@');" 
%>

# custom button that implements the textile 'h5' tag
<% textile_editor_button 'H5',
  :onclick => "TextileEditor.insertTag(this, 'h5');" 
%>

# custom button that implements a custom tag
<% textile_editor_button 'Ruby',
  :onclick => "TextileEditor.insertTag(this, '[code.ruby]', '[/code.ruby]');" 
%>
*
#1: Matt said on Jun 4 at 9:33 pm

Hi all!

First off, great plugin, I’ve been playing around with it and really like it. However, I do have a problem:
I have multiple text forms on my page (it’s a long story), each one is its own form, however the form is identical (/foo/_form.rhtml over and over and over…).

If I set it up like such:

<= textile_editor_initialize unless !%w(create edit show).include?(@controller.action_name) – >

then later on in my form:
<=form stuff>



<= textile_editor ‘reply’ , ‘body’ – >

... repeated a few times

I get no textile editors on the form. When I look at the head-generated javascript I see that it is trying to load the ‘reply_body’ element over and over and over… so I figured I needed to make them unique somehow. This is somewhat less than optimal but I was able to do this:
<form_unique_id = some magic here – >
<=form_stuff>



<= textile_editor ‘reply’ , ‘body_’ + form_unique_id – >

Now, each textile editor appears - yay! Unfortunately, though, when I click any one of the icons it submits the form – without inserting the textilized info. Any ideas?? Thanks!!!


Matt

#2: Chris said on Jun 5 at 11:21 am

I haven’t really tested TEH with multiple instances before, but I just tried and I did encounter a bug. I’ve updated SVN with a fix, but I don’t know if it will correct the problem you are describing.

What browser are you using? If you just include a single textile editor, does it work? Also, are you using the new version (0.2)? (Note that you may need to run rake textile_editor_helper:install to update the relevant files).

#3: Matt said on Jun 7 at 12:22 pm

Verified fixed: multiple forms do not submit when clicking a button.

Browser: FireFox 2.0.0.4 Mac

Works just fine now. My only other issue is that the onLoad event does not use any sort of scoping for the form box and so appears to fail if you have separate forms with the same form field names, e.g.
(simplified html)
<form>

</form>

<form>

</form>

the onload tries to TextileEditor.initialize(‘body_text’, ‘extended’); twice and it stacks up in strange fashions—it causes two textile editor bars to appear on the first form but nothing shows up on the second. I can get around that if I change the form field to be unique somehow, e.g.
<form>

</form>

but then it becomes tedious to get them out after I hit submit. Any ideas?

Thanks again,


Matt

#4: Chris said on Jun 7 at 4:40 pm

You could use normal text areas and assign them unique DOM IDs, and then pass those as arguments to the textile_editor_initialze

For example, if you have the IDs article_body_1 and article_body_2, you should be able to do this:

<%= textile_editor_initialize 'article_body_1', 'article_body_2' %>

#5: Chris said on Jun 7 at 4:45 pm

Another solution: if you simply assign a custom DOM ID as a option to textile_editor, that ID will be used instead of the default (based on the object and field).

So…

<%= textile_editor 'article', 'body', :id => 'article_body_1' %>
<%= textile_editor 'article', 'body', :id => 'article_body_2' %>
<%= textile_editor_initialize %>

#6: Matt said on Jun 7 at 6:06 pm

Chris,

Phenomenal! That worked great.

Thanks again,


Matt

#7: baker said on Jun 15 at 5:24 pm

hi, i really like this plugin and would be a great addition to my application. however, i cant seem to get it working if i use rjs, or if i try to render my edit form using partial, or even a template. the only way i can get the toolbar to render is by rendering the edit form normally with an action. i notice that the textile editor helper div appears with my text area inside, however, when rendering via rjs, that div is missing?

thanks for any help!

#8: Chris said on Jun 15 at 6:56 pm

I just updated TEH to support AJAX-based initialization, so try updating your local copy of TEH. Open up the lib/textile_editor_helper.rb and see the comments for the textile_editor_helper() method for information on how it works.

Hope that helps!

#9: Jamie Hoover said on Jun 23 at 2:59 am

Thanks so much for the AJAX support! I don’t get how to get this working, though. I’ve got my textile_editor and textile_editor_initialize inside a partial.

Would you please provide us with an example?

#10: Chris said on Jun 25 at 11:03 pm

I may upload an example at some point, but the basic idea is like this: in the main view file (whatever will be rendered from a standard HTTP request) should have textile_editor_initialize called somewhere inside of it – it’s necessary to have it here because it will load in the required JS and CSS files. (Alternatively, you could use textile_editor_support to simply load add in these support files).

Then, in the AJAX response template, textile_editor_initialize should be called in order to activate any new editors defined in the response. When textile_editor_initialize is used in the response of an AJAX request, the output is slightly different: it simply adds direct calls to initialize the editors. This is different from the standard result, which is to add the JS and CSS, and register an Event observer.

#11: Ray said on Jul 12 at 2:57 pm

I posted an example at my blog

#12: Ray said on Jul 12 at 3:00 pm

Getting TEH over Ajax does work. However, any customized buttons are added each time the TEH is sent to the browser through Ajax. As a result, identical buttons are added if <% textile_editor_button ‘H5’, :onclick => “TextileEditor.insertTag(this, ‘h5’);” > is added after <= textile_editor … %>.

#13: Claudio said on Sep 3 at 5:20 pm

/>textile-editor.js:76:
’s’ should be ‘simple’

Wonderful job you’ve done guys!!!! (I’m not using it with rails, that is why I found this inconsistency, had to go and see what you were doing! :P)

~Claudio

#14: Matt King said on Oct 19 at 5:45 pm

I added in support for simple Textile links, pasted below are diffs to textile-editor.js and textile-editor-config.js, respectively:

561,564c561
<         if (button.id == 'ed_link') { // set tagEnd to add URL (Added by matt@mattking.org 10/19/2007)
<           url = prompt('Enter URL:');
<           button.tagEnd = '":' + url;
<         }
---
> 
594c591
<       button.tagEnd = '":'; // reset tagEnd to strip URL (Added by matt@mattking.org 10/19/2007)
---
>
21c21
< teButtons.push(new TextileEditorButton('ed_link',             'link.png',       '"',  '":', 'l', 'Link'));
---
> 

#15: Dave O. said on Oct 20 at 6:01 pm

I’m going to post your code here for everyone just so they can implement it if they want. I’ll be honest, it most likely won’t make it to TEH core. Chris and I have been looking at how to modularize what we have right now for the snippet editor and make it available to everyone. I think it’s a bit of a slicker implementation and more usable. It also may make it easier for folks to add their own custom functions in that style.

We’ve been a bit remiss in getting it out the door though.

#16: Charlie said on Apr 4 at 4:15 pm

Hi – I’m experiencing the problem where clicking on any of the icons results in the form being submitted.

I’m using a straight-up implementation with edit.rhtml and _form.rhtml. Prototype version 1.6.0.

Any suggestions? From searching the web it seems that some people have had this problem before, but I could not find a clear solution to it.

Any help would be greatly appreciated.

Add comment

You are adding a new comment