TinyMCE and Ajax 9

Posted by Hubert Sun, 02 Mar 2008 12:12:00 GMT

TinyMCE is a visual XHTML editor that you can put on your web app, to convert textareas into Word-like editors. This way you can make it possible for your clients edit pages more easily, saving you lots of trouble explaining them basics of HTML or even easier formatting languages. TinyMCE doesn’t play well with AJAX calls, however it’s easy to fix it. I will use TinyMCE with Ruby on Rails, version 2.0.2.

Let’s start with creating new application:

     [hubert@swarog ~]$ rails tiny_mce_ajax
       create
       create  app/controllers
       create  app/helpers
       ...........................
       create  log/development.log
      create  log/test.log
     [hubert@swarog ~]$ cd tiny_mce_ajax/
     [hubert@swarog tiny_mce_ajax]$ ls
     README    app     db   lib  public  test  vendor
     Rakefile  config  doc  log  script  tmp

Now, let’s install tiny_mce plugin:

     [hubert@swarog tiny_mce_ajax]$ ruby script/plugin install http://secure.near-time.com/svn/plugins/trunk/tiny_mce
     [hubert@swarog tiny_mce_ajax]$ rake tiny_mce:scripts:install

TinyMCE plugin used to work right after you do it, however something has changed either in Rails or the editor plugin that requires us to make a little hack here:

First, open this file with your favorite editor:

     vendor/plugins/tiny_mce/lib/tiny_mce.rb

and put these two lines at top of the file:

     require 'tiny_mce_helper'
     include TinyMCEHelper

We’re ready to go. First, let’s create a RESTful controller:

     [hubert@swarog tiny_mce_ajax]$  ./script/generate scaffold note body:text
     [hubert@swarog tiny_mce_ajax]$  rake db:migrate

An add TinyMCE and Prototype script links to HEAD section of our layout file:

     <script src="/javascripts/tiny_mce/tiny_mce.js" type="text/javascript"></script>
     <%= tiny_mce %>
     <%= javascript_include_tag :defaults %>

At this point, we have TinyMCE installed in our application, that will be used on all textareas. However, this will not work if we add another textarea using JavaScript and/or AJAX calls.

To make it work, let’s add partial to our application:

file: app/views/notes/_new.html.erb

     <% form_remote_for :note, @note, :update => { :success => "notes" }, :position => :bottom,     :url => { :controller => "notes", :action => "create" }, :after => "$('new_note').innerHTML = ''; "      do |f| %>
             <%= f.text_area 'body', :colls => 100, :rows => 10 %><br/>
        <%= submit_tag "Save", :onclick=>"javascript: tinyMCE.triggerSave(); tinyMCE.execCommand('mceRemoveControl', false, 'note_body'); " %>
     <% end %>

     <script type="text/javascript">
        tinyMCE.execCommand('mceAddControl', false, 'note_body');
     </scrip>

And modify our “index” view:

 Listing notes
     <table id="notes">
             <%= render :partial => "note", :collection => @notes %>
     </table>

     <br />

     <%= link_to_remote "New note", :url => { :action => "new" }, :update => { :success => "new_note" } %>

     <div id="new_note">

     </div>

Add partial for single note: _note.html.erb

     <tr>
         <td><%=h note.body %></td>
         <td><%= link_to 'Show', note %></td>
         <td><%= link_to 'Edit', edit_note_path(note) %></td>
         <td><%= link_to 'Destroy', note, :confirm => 'Are you sure?', :method => :delete %></td>
     </tr>

And modify “new” and “create” actions in our controller: notes_controller.rb

      def new
        @note = Note.new

        if request.xhr?
               render :partial => "new"
        else
        respond_to do |format|
          format.html # new.html.erb
          format.xml  { render :xml => @note }
        end
        end
      end

      def create
        @note = Note.new(params[:note])

       respond_to do |format|
          if @note.save
            if request.xhr?
                    render :partial => @note
                    return
            end
            flash[:notice] = 'Note was successfully created.'
            format.html { redirect_to(@note) }
            format.xml  { render :xml => @note, :status => :created, :location => @note }
          else
            format.html { render :action => "new" }
            format.xml  { render :xml => @note.errors, :status => :unprocessable_entity }
          end
        end
      end

Download full source code example

Social networking Social networking Social networking
Comments

Leave a response

  1. Ken Schroeder 14 days later:

    Thanks for the tutorial was able to get this running on Rails 2.0 quickly. I’m trying to use this for a blog application and can get it to work for one post or comment but subsequent new comments or posts generates Java errors Error: this.getDoc() has no properties Source File: http://localhost:3000/javascripts/tinymce/tinymce.js?1205614249 Line: 1

    Any ideas on this? I imagine its cuz I need to id my textareas or something but wasn’t clear on the parameters being used in the tinymce initializaiton

  2. Ken Schroeder 14 days later:

    Oh there is an error on your _new.html.erb code with your end tag

  3. Hubert 14 days later:

    Thanks for pointing this out Ken, I hope code is somehow helpful. Anyway, I can’t find a bug in _new.html.erb, I would be really, really thankful if you could explain the right solution, so I can update the code.

  4. Ken Schroeder 14 days later:

    sorry looks like the post commented out your end script tag is scrip. yes this has been very helpful thanks. I fixed my initial problem, do you know how to change from the default simple layout. I’ve looked at their wiki but not sure where to tweak the init parameters with the plugin. Thanks –ken

  5. Ken Schroeder 14 days later:

    BTW, Seem to be getting a lot of Proxy Errors to your site.

  6. Hubert 15 days later:

    Ken,

    it’s easy to set up TinyMCE options in your controllers. I think this should work even in application_controller.rb because of inheritance, but you must check this yourself. I do it like this:

         uses_tiny_mce :options => {:theme => 'advanced',
                       :browsers => %w{msie gecko safari},
                       :plugins => %w{contextmenu paste spellchecker},
                       :theme_advanced_toolbar_location => "top",
                       :theme_advanced_toolbar_align => "left",
                       :theme_advanced_resizing => true,
                       :theme_advanced_resize_horizontal => true,
                       :paste_auto_cleanup_on_paste => true,
                       :theme_advanced_buttons1 => %w{formatselect bold italic underline strikethrough separator justifyleft justifycenter justifyright indent outdent separator bullist numlist forecolor backcolor separator link unlink image undo redo},
                       :theme_advanced_buttons2 => [],
                       :theme_advanced_buttons3 => [],
                       :editor_selector => "tinymce",
                       :content_css => "/stylesheets/content_in_editor.css"
                        }

    So, you can specify lots of options here like buttons you want, where to put the editor bar etc. I found :content_css option really, really useful - you can make content in editor using exacly how it will appear on the web site by using the same CSS file.

    A nice post on using it can be found on John Wulff’s blog.

    And yes, my hosting is cheap, and it looks like I’m having some problems with mongrel… ugh.

  7. Don French about 1 month later:

    The mistake on the show code is the “t” is missing from the last script tag in _new.html.erb on the page as scrip. Works fine after adding that.

  8. Mike about 1 month later:

    Big thanks for this, most handy,

    Mike

  9. online casinos 2 months later:

    That odd free casino online gawked on account of the ethnic relationship. Job forsook that table. I read once, the loud experience brusquely clenched apart from a dark blackjack online. That material is blindly atomic. One golden product went a slot machines online merrily. Definite sir is this real lot. Some proud home glowered one online free casinos enchantingly. Specific information is one stiff blackjack online…

Comments