1

My problem

I realize that there are a ton of questions about using remote: true and having the server process the request as HTML instead of javascript so that you get a MissingTemplate Error on SO already.

So far none of them answer my question. To prove that:

  1. I know that I have included / bundled etc jquery, jquery-ujs etc because this link used to work. Also I can see them getting included on the rendered page and also as mentioned in the question, I'm getting the server to successfully process the request as JS in many places.

  2. I know that I'm not having a precompiled assets issue because I don't have any precompiled assets (deleted the public/assets folder myself just to make sure).

If I put the following on my index page right at the top

<%= link_to "Test", "/create_tags_dialog", :remote => true %>

It renders the html perfectly:

<a data-remote="true" href="/create_tags_dialog">Test</a>

and correctly calls the remote script, no TemplateMissing Error because the request is processed as JS.

Just to be sure I even copied the rendered HTML back onto the index and they both work as expected:

<a data-remote="true" href="/create_tags_dialog">Test2</a>

(i.e. the server processes the request as JS and I get no TemplateMissing Error)

Now for the problem

If I put the same link_to line into a bootstrap dropdown <ul> the request gets processed as HTML and I get a MissingTemplate Error. I checked and the rendered html is identical! Again, just to check, I put the raw html in as well <a data-remote="true" href="/create_tags_dialog">Test</a>

The only difference between identical uses of this anchor tag is that the second use (the broken one) is inside of a bootstrap dropdown which gets rendered as a partial on page load.

Could it be the partial? Please let me know if I can include any outputs, error logs, screenshots etc to help clarify things.

Note

I see a few solutions like this one

Which recommend ensuring this line is in the index

<%= javascript_include_tag "jquery", "jquery_ujs" %>

I don't have that line exactly, mine is

<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>

and my application.js is

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require bootstrap.min
//= require turbolinks
//= require jquery-readyselector
//= require fastclick
//= require_tree .

Also the link is working in a different div of the same page at the same time, but just in case I thought I'd mention this. . .

Update

Thanks to AmShaegar I discovered the change in my code that causes this to break. I added a stopPropagation() to my dropdowns because I want them to stay open after click like this:

$('#tags-filter-dropdown').click (e) ->
  e.stopPropagation()

If I comment this out, my remote-link goes back to working. Any suggestions for how I can both keep that dropdown from closing and activate a remote link? I tried implementing AmShaegar's solution of giving the link a class and preventing propagation / default on the link specifically but it just killed the link (unresponsive). Is there a middle ground?

Community
  • 1
  • 1
KCE
  • 1,159
  • 8
  • 25
  • I think that bootstrap dropdowns work with onclick event handlers, taking the href and redirecting to it. When doing this, your remote request is cancelled due to redirection. Can't tell you how to solve though :-( – AmShaegar Dec 03 '14 at 19:33

1 Answers1

1

Based on this question and my comment above:

It may help if you disable bootstraps onclick handler for your remote link. You need to give your link a special class and then write your own onclick handler.

link_to "Test", "/create_tags_dialog", :remote => true, { class: 'no_bootstrap' }

$(".no_bootstrap").click(function(e) {
    e.stopPropagation();
    e.preventDefault();
    // You may still want to close the drop down manually here.
    // See bootstrap documentation for this.
});​

Update

Looks like you need to trigger the remote click event manually after you stopped propagation. Therefor you need to know how rails does it internally.

From viewing the source code I would say this could work like this:

$(".no_bootstrap").click(function(e) {
    e.stopPropagation();
    e.preventDefault();
    $(e.target).trigger('click.rails');
});​
Community
  • 1
  • 1
AmShaegar
  • 1,491
  • 9
  • 18
  • 1
    Oh I see! I implemented what you have and the dropdown-link now does nothing (so still broken). But you helped me figure out what change I made that broke this. Please see my updated question now that I know what's causing the break. – KCE Dec 03 '14 at 19:53
  • Well stupid me... Of course, this will also disable Rails' remote link functionality. – AmShaegar Dec 03 '14 at 19:55
  • I think you need to change the order of events. You must register your click event after rails so that you will only stop bootstrap's event. Where is your click event defined? – AmShaegar Dec 03 '14 at 20:05
  • 1
    On this page, my document body has classes corresponding to its route (to see why check out [this post](http://brandonhilkert.com/blog/page-specific-javascript-in-rails/)) and I call this function with some others in a function called initializeTable like so `$(".sessions.index").ready(initializeTable)`. – KCE Dec 03 '14 at 20:12
  • $(".sessions.index").ready(...) means as soon as the element is rendered. I guess both, rails and bootstrap are waiting for the full document to be ready. So you are blocking everything else from being executed. I think, what you need to do is this: Trigger Rails' event manually. I will update my answer accordingly. – AmShaegar Dec 03 '14 at 20:17
  • Ooh, interesting! It does both now! I added the 'click.rails' trigger as you suggested (and dropped the no_bootstrap.click) and now it briefly brings up the modal (which the remote JS goes to) and then fails (for the same reason as before, no html template available). In the logs, I only see one call to `GET "/create_tags_dialog"` as HTML, I sorta expected two, with the first being as JS. Also, in case it helps, I should probably clarify that the exact error I get is `ActionController::UnknownFormat` because I'm using `respond_to{|format| format.js}` with no html option. – KCE Dec 03 '14 at 20:37
  • You need to drop your ``$('#tags-filter-dropdown').click`` and use only my second example with the link having .no_bootstrap class, I think. – AmShaegar Dec 03 '14 at 20:40
  • All right! Thank you for the detailed help and digging into the source code! One last question, I'd like to update my question title and body so that other users with the same problem can find this better, but it would be sorta rewriting history. Can you comment on best practice? Should I open a new question and answer it myself to distill this conversation into something more useful to others? – KCE Dec 03 '14 at 20:46
  • I had the same 'problem' with my answer. I don't know how it's handled generally but I would just leave it like that. It's just one answer. Whoever is interested in how this all comes together will read the comments. – AmShaegar Dec 03 '14 at 20:51