Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 JQuery page.insert_html and TypeError: Element.insert is not a function

I replaced Prototype with JQuery for Rails 3. I am now trying to do the following:


  #photo
    =render 'shared/photo'
  = link_to_function "Add a Photo" do |page| |
      page.insert_html :bottom, 'photo', :partial => 'shared/photo', :object => Photo.new |
    end |

So the Javascript generated is:



try {
    Element.insert("photo", {
        bottom: "Data\n\n"
    });
} catch (e) {
    alert('RJS error:\n\n' + e.toString());
    alert('Element.insert(\"photo\", { bottom: \"Data\\n\\n\" });');
    throw e
};
return false;

In the rails docs insert_html is a Prototype helper, but I thought that replacing Rails.js with the https://github.com/rails/jquery-ujs would replace this helpers for JQuery helpers. I get a TypeError.ElementInsert is not a function.

Am I doing something wrong ? Or am I going to do this myself without the helpers ?

like image 384
daniel Avatar asked Jan 27 '11 19:01

daniel


2 Answers

Someone just sent this question to me, maybe I can help. I'm on the jquery-ujs/jquery-rails team.

Unlike prototype-ujs for rails, jquery-ujs does not come bundled with rjs support. There is a separate gem that provides that functionality called jrails.

We've talked about merging the two projects, but decided to keep them separate, as it's more flexible that way.

like image 162
jangosteve Avatar answered Oct 30 '22 16:10

jangosteve


I have a fairly rudimentary workaround. In my case I've run page.insert_html(:top ,'content', render('form')).

The error is caused by the generated .js.rjs code trying to run Element.insert(), which is a prototype function. I don't know enough about rails to do anything very productive, however adding the following to my application.js has worked form me:

//Check if the function exists
if (typeof Element.insert !== "function") {
  //If not, hook it onto the $().append method.
  Element.insert = function (elem, ins) {
    $("#" + elem).append(ins.top);
  };
}

Obviously, this is basic and will only work with :top, so adjust to your needs. There must be a better way...

like image 34
kdoole Avatar answered Oct 30 '22 15:10

kdoole