Inserting data-remote form via JavaScript in a Rails App, ujs not catching remote
Asked Answered
C

4

7

I have a simple form that is being appended to a container:

<form action="/something" data-remote="true" method="post">
  <input type="submit" />
</form>

My understanding was that rails_ujs.js captures all submit events, so I wouldn't need to reattach any events when inserting new forms. However, this form is not being picked up as a remote form. Even when I put a debugger in rails_ujs.js on the general submit event this form is not firing that event. All forms rendered server-side trigger it no problem.

Did I miss something about having to attach an event to dynamically inserted form?

Christoper answered 17/5, 2013 at 16:10 Comment(0)
C
11

It turns out I was rendering a form within a form and that was causing the issue. I'm an idiot :p

Christoper answered 17/5, 2013 at 18:47 Comment(2)
Five years later (and nearly a day of beating my head against this), I'm an idiot as well.Outhouse
Thanks for that! I checked my code, and my code closed my form, but a lack of a trailing div tag prevented Chrome from seeing it, so Chrome didn't close my form until later! Thanks for the help!Indies
A
1

after injecting the for, you need to attach the event to the dom using jQuery's live & the rails_ujs's handleRemote() event to the form submit

$(function(){
    $("body")
        .live('ajax:complete', function(){
             $("form[data-remote]").live('submit', function(e){
                  $.rails.handleRemote($("form[data-remote]"));
                  e.preventDefault();
             });
        });
});

Currently, this looks for all the forms in the page, you might want to make it more specific to improve performance.

PS: if you are using latest jQuery(jQuery 1.7 or later), you might want to know that in recent versions of jQuery, live() has been deprecated in favour of on(). here is a nice explanation of on() vs live()

At answered 17/5, 2013 at 17:13 Comment(2)
Is that supposed to be necessary? github.com/rails/jquery-ujs/blob/master/src/rails.js#L326 shows that rails_ujs is using event delegation on the document which should capture all submit eventsChristoper
^^^Should Not be needed but hey, currently its not working. so try it, it may or may not work. But there is no harm in trying. Incase, it doesn't work do post back with a sample app on github which reproduces this issue, so we can help further :)At
S
0

I'm not sure how rails_ujs.js works, but I think your problems lies with the fact that html content that you add on the client side does not respond to events that have already been binded. The solution is that, whenever you add a new HTML element on the client side you also have to bind any event to it.

Consider the following example:

<html>
<head>
    <title>My Page</title>
    <script src="jquery.js"></script>
</head>
<body>
    <div id="content">
        <a href="#" class="link">Click me</a>
    </div>
    <a href="#" class="add_link">Add link</a>
    <script type="text/javascript">
    $(document).ready(function(){
        $('.link').click(function(){
            alert('Click me');
        });

        $('.add_link').click(function(){
            $("#content").append("<a href='#' class='link'>Click me no alert...</a>");
        });
    });
    </script>
</body>
</html>

When you click on the 'Add link' link it will add a link that says click me and that has the class 'link'. However if you click this link it will not display an alert, that is the event click event does not fire, it only fires for server-side generated content.

The solution is described in more detail in this question: In jQuery, how to attach events to dynamic html elements?

However I'm not sure how to apply it to rails_ujs, you probably have to do some modifications there.

Shinberg answered 17/5, 2013 at 16:30 Comment(0)
D
0

rails_ujs does use document delegation, not bindings to specific elements onload, so it should pick up your form.

Could it be that there is no hidden auth_token field in your form, and so inserting the csrf token is failing? Or it's going to the server and then fails an authenticity check?

And then, the dumb question: are you sure your debugged version of rails_ujs is present on the page? Is rails_ujs loaded? console.log($.rails) to check.

Damoiselle answered 17/5, 2013 at 16:52 Comment(1)
That's what I thought, which makes this really frustrating to figure out. My actual code is injecting the csrf token and setting the form for utf-8.Christoper

© 2022 - 2024 — McMap. All rights reserved.