Rails Unobtrusive JavaScript (UJS) does not seem to be connecting the data-remote

Version of Rails: 3.2.1

Version of Ruby: 1.9.3p125

Browser Used: Chrome 18.0.1025.162

Developers Operating System: Mac OS/X Lion

Server's Operating System: CentOS 5

I am attempting to utilize :remote in my link_to call in order to request HTML content via AJAX and then populate a specific section of the page with the retrieved content.

It seems that Rails is not correctly setting up the link. The browser interprets the link as a regular link tag and does not execute any of the Rails UJS click event handlers.

A link with a data-confirm connected to it works, which suggests that UJS is covering some essential wireups.

I am adding other click event listeners to the same link to show/hide a section of the page where the returned HTML from the AJAX call would be displayed.

If this issue has been discussed elsewhere, I apologize. I have been searching for several days but have not found a solution addressing this precise problem. Although there are related articles, they all presume that the AJAX call is being initiated, and there may be a Rails render flow or routing issue. In my case, there doesn't seem to be any setup happening at all.

The following is some code:

The link in the View:

<%= link_to image_tag("icons/24x24/attachment.png"), task_notes_path(task), :class => "section-link task-notes-link", :title => "View recent notes", :remote => true, 'data-section' => "task-notes" %>

Ruby on Rails-generated output:

<a href="/tasks/7/notes" class="section-link task-notes-link" data-remote="true" data-section="task-notes" title="View recent notes"><img alt="Attachment" src="/assets/icons/24x24/attachment.png"></a>

Controller code for /task/:task_id/notes:

def index
store_return_to

@project = nil
@tasks = nil

if (params.has_key?(:project_id))
  @project = Project::find(params[:project_id])

  sort = [
    { :field => 'status', :direction => 'asc'},
    { :field => 'priority', :direction => 'asc' }
  ]

  filter = { :status => Task::STATUS_ACTIVE.to_s }

  @tasks = Task::filter_sort(:project => @project, :sort => sort, :filter => filter, :per_page => 0)
else
  @task_sort = params.has_key?(:task_sort) ? params[:task_sort] : { :field => 'priority', :direction => 'asc'}
  @task_filter = params.has_key?(:task_filter) ? params[:task_filter] : { :status => Task::STATUS_ACTIVE.to_s }
  @task_search = params.has_key?(:task_search) ? params[:task_search] : ""

  @tasks = Task::filter_sort(:search => params[:task_search], :sort => @task_sort, :filter => @task_filter, :page => params[:tasks_page], :per_page => 15)      
end

respond_to do |format|
  format.html # index.html.erb
  format.js
  format.json { render json: @tasks }
end
end

Lastly, the code in the index.js.erb file:

<% if (<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="99b8d9e9ebf6f3fcfaedb7f7f0f5">[email protected]</a>?) %>
    $('#project-<%<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="023f4272706d686761762c6b66">[email protected]</a>%>-tasks').html('<%= escape_javascript(render(@tasks)) %>');
<% else %>
    $('#project-tasks').html('<%= escape_javascript(render(@tasks)) %>');
<% end %>

Answer №1

After some investigation, I finally managed to solve the issue.

I carefully analyzed the HTML code related to the :remote links:

<div class="list-item-row">
<div class="list-item-expander action-icon">
  <a href="#" title="Show/hide content pane">
    <%= image_tag "icons/24x24/plus.png", :class => "expander-image closed" %>
    <%= image_tag "icons/24x24/minus.png", :class => "expander-image opened" %>
  </a>
</div><div class="action-icon">
  <a href="#" data-section="task-description" class="section-link" title="Show details"><%= image_tag "icons/24x24/page.png" %></a>
</div><div class="action-icon">
  <%= link_to image_tag("icons/24x24/attachment.png"), task_notes_path(task), :class => "section-link task-notes-link", :title => "View recent notes", :remote => true, 'data-section' => "task-notes" %>
</div><div class="action-icon">
  <%=task_image_tag(task, 24)%>
</div><div class="action-icon">
  <div class="task-priority task-priority-<%=task.priority_str.downcase%>" title="<%=task.priority_str%> Priority"></div>
</div><div class="action-icon">
  <% unless (task.assigned_developer.nil?) %><%= link_to image_tag(task.assigned_developer.avatar.icon.url), developer_path(task.assigned_developer), :title => "Assigned to: " + task.assigned_developer.full_name %><%end%>
</div><div style="width:280px;">
  <%=link_to truncate(task.name, :length => 40, :omission => "..."), task_path(task), :title => task.name, :class => "item-show-link" %>
</div><div style="width:300px;font-size:10px;color:#777;">
  <%=truncate(task.description, :length => 50, :omission => "...")%>
</div><div style="width:90px;float:right;text-align:center;">
  <%=task.status_str%>
</div></div>

The :remote links can be found inside a DIV with the id "list-item-expander". This specific row had an onclick event that would expand the details of the current item beneath it. Below is the JavaScript code responsible for this interaction:

elem.find(".list-item .list-item-row").click(function(evt) {
    evt.stopPropagation();
    $.tf.listItem.showHideItem($(this));
});

It turns out that the evt.stopPropation() function was preventing the click event of the :remote link from propagating high enough in the event chain to be handled by UJS. To fix this issue, I filtered out the srcElements associated with the :remote link. Here's the modified code:

elem.find(".list-item .list-item-row").click(function(evt) {
    if ($(evt.srcElement).not('a').not('img').size() > 0) {
        evt.stopPropagation();
        $.tf.listItem.showHideItem($(this));
    }
});

By implementing this filter on srcElements, clicks on images and links are now allowed to propagate correctly.

Answer №2

Have you included your rails.js in the application.js / application.coffee javascript asset packager? If not, make sure to do so. Otherwise, you may need to write event handlers in JavaScript/CoffeeScript on your own.

It seems like the code could use some cleaning up. Your index.js.erb code should probably be wrapped in $(document).ready(function(){ /HERE/ });

Your index action in the notes controller is handling display, search, and filtering - more than I would have expected :)

For information on ajax/remote things in Rails 3.2, check out http://guides.rubyonrails.org/ajax_on_rails.html

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for correctly loading all elements on an HTML page before making CSS modifications

This question has been asked several times in the past. I am asking because when I used the on ready callback in jQuery, it did not change the placeholder text of my element "search_input". $( document ).ready(function() { $("#search_input").attr(' ...

How to launch a new window for a popup

How can I make IE8 open new windows as pop-ups without changing browser settings? I want to use JavaScript's window.open() function. Firefox opens new windows correctly, but IE8 opens them in tabs instead of pop-up windows. Any suggestions on how to a ...

How to Use Jquery to Track Mouse Movement Over a PNG Image

Need help with this issue Link to Example The first image is a puzzle, The second image is of earth. I can rotate, drag, and resize the earth image, but it appears behind the puzzle image. While I can interact with the puzzle image, I cannot move or ro ...

Get JSON or partial HTML responses from ASP.NET MVC controller actions

Is there a recommended method for creating controller actions that can return either JSON or partial HTML based on a specified parameter? I'm looking for the optimal way to asynchronously retrieve the results in an MVC page. ...

Encountering difficulty in reading a session variable when accessing it through Ajax, however, the variable is successfully retrievable when called from the controller in ASP.Net

I have implemented a method within the controller to retrieve the value of a session variable. However, when I attempt to call this method from Ajax jQuery, I am unable to obtain the value. Interestingly, if I try to read the session value from another met ...

Error: JQuery Ajax Success Handler cannot locate class method

There is a javascript Class in my code that successfully posts data, but encounters an issue when trying to access a specific function within a success handler. Although the function is found during the construction of the class and can be called from othe ...

Element sticking on scroll down and sticking on scroll up movements

I am currently working on a sticky sidebar that catches and stays fixed at a certain scroll point using JavaScript. However, I am facing an issue where I need the sidebar to catch when scrolling back up and not go further than its initial starting point. ...

What steps need to be taken to implement a structured autocomplete feature?

Let me break down the workflow for you: The user inputs something in a text field. Upon keypress, the frontend communicates with our backend script to retrieve and select a specific value. Once the value is selected, on leaving the input field, we query ...

The test() function in JavaScript alters the output value

I created a simple form validation, and I encountered an issue where the test() method returns true when called initially and false upon subsequent calls without changing the input value. This pattern repeats with alternating true and false results. The H ...

How can jQuery be used to display the size and type of linked files in title attributes?

For instance: Prior to <a target="_blank" href="http://www.adobe.com/devnet/acrobat/pdfs/reader_overview.pdf"> Adobe Reader JavaScript specification </a> As the file is in PDF format, the title should read title="PDF, 93KB, opens in a new ...

What is the best way to determine the ideal scrollTop value?

When loading content through ajax into #list, I am determining the necessary scroll based on the height of #list, but I want to reduce it by 200px. After the ajax call is complete, I execute: var pos = jQuery("#list").innerHeight() - 200; Once the height ...

Displaying dropdown options based on the previous selection made by the user

Can I link the data in my second dropdown to the selection made in the first dropdown? I tried a similar solution from stackoverflow without success. You can find the reference here. The code works when directly copied and pasted but not within my system. ...

What are the best ways to stop jQuery events from propagating to ancestor elements?

I have a collection of nested UL's that follow this structure: <ul class="categorySelect" id=""> <li class="selected">Root<span class='catID'>1</span> <ul class="" id=""> <li>First Cat<span ...

What could be causing the malfunction of Bootstrap Multiselect functionality?

I have been attempting to set up Bootstrap Multiselect but it simply refuses to work. Despite trying various solutions, I am unable to pinpoint the issue. My index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

The jQuery Deferred feature on Ajax is failing to properly pass the array in the data option as an array, instead converting

I am facing an issue in my application where I want to use jQuery deferred to handle Ajax success and error uniformly from a central location. It works perfectly fine when I pass strings in the data option, but when I try to pass an array, it gets sent as ...

Having trouble getting Yii2, Select2, and Optgroup to work together with Ajax

I am currently utilizing Yii2 along with Select 2. I have attempted to implement examples involving optgroup that are loaded through ajax. The browser sends requests, but unfortunately nothing is displayed when I attempt to print the results. Below is the ...

Extract Data from JSON Array using Jquery

I am working with a JSON array retrieved from a web API, and I need to extract specific values from it. For instance, how can I retrieve all the rides in the first place and access rides[1]. UserID or Images? { "Status":1, "Rides& ...

Incorporate data into the input value rather than the div using Ajax technology

This ajax function is working perfectly, but I would like to modify the location where the result should appear. <script type="text/javascript"> function submitForm1() { var form1 = document.myform1; var dataString1 = $(form1).serialize(); $.ajax ...

Show a dynamic highchart graph displaying linear data retrieved from the database

I am attempting to present data retrieved from a database in a linear highchart format. Here is the JSON response from my database: [{"protocol":"tcp","date":"01/02/20","time":"00:10:20","total":281}, {"protocol":"udp","date":"01/02/20","time":"00:10:30", ...

Is there a way to determine if my cursor is within a specific zone?

Is there a way to check, using a .hover function, if my cursor pointer is inside or outside a specific zone? You can find an example here. HTML <ul class="menuLeft"> <li>1</li> <li>2</li> <li>3 ...