1

I have a working Ruby on Rails form that currently posts my results and redirects the user to another view and posts the results. The flow is:

views/tools/index.html.erb -> views/tools/ping.html.erb

Since I have it working now, I'd like to convert it to AJAX and keep the user on the views/tools/index.html.erb view, getting rid of the redirect to enhance the user experience. However, I'm unsure of how to proceed based on the way that my Tools controller is currently setup, and my incredibly lacking knowledge of AJAX.

So, here's what I currently have:

views/tools/index.html.erb (added 'remote: true' to form)

<h1> Tools </h1>

<h3> Ping </h3>

<%= form_tag ping_tool_path(1), method: "post", remote: true do %>
  <%= text_field_tag :ip, params[:ip] %>
  <%= submit_tag "Ping", name: nil %>
<% end %>

<!-- this is where I'd like to put the results via AJAX -->
<div id="output"></div>

controllers/tools_controller.rb

class ToolsController < ApplicationController

  def index
    
  end

  def ping
    ping_host(params[:ip])
    save_host(params[:ip])

    # Adds based on recommendations
    respond_to do |format|
     format.html { redirect_to tools_path }
     format.js
    end
  end


  protected

    def ping_host(host)
      f = IO.popen("ping -c 3 #{host}")
      @output = f.readlines

      tool_type = "ping"
      tool = Tool.find_by(tool_type: tool_type)
      tool.increment(:tool_hit_count, by = 1)
      tool.save

      @results = "<pre>#{@output.join}</pre>".html_safe
    end

    def save_host(host)
      host = Host.find_or_create_by(host_ip: host)
      host.increment(:host_hitcount, by = 1)
      host.save
    end
end

views/tools/ping.html.erb

<%= @results %>

views/tools/ping.js.erb (New file based on suggestion)

$("#output").html("<%= @results %>");

routes.rb

Rails.application.routes.draw do
  root 'tools#index'

  resources :tools do
    member do
      post 'ping'
    end
  end
end

This is what I see on the Network tab in Google Chrome after submitting the form: Network Tab of Google Chrome

So, what I know at this point is that I'll need to add remote: true to my form in views/tools/index.html.erb, and this is where I get lost.

It seems that I have an issue ATM with the fact that I've abstracted the form to use my ping method in the Tools controller, whereas all of the tutorials (and railscasts) I've gone through are doing AJAX on CRUD methods and a given model, not something like what I've build here so far. Please help me understand AJAX!

2
  • What happens when you do <%= form_tag ping_tool_path(1), method: "post", remote: true do %> Commented Dec 1, 2015 at 21:28
  • @MattW. From the backend, both my tool_hit_count and host_hitcount are updated, however, my view stays on index.html.erb. So, from the UI perspective, nothing happens. Commented Dec 1, 2015 at 21:30

1 Answer 1

2

You're on the right track, now you need to modify the def ping action with a respond_to block.

def ping
  ping_host(params[:ip])
  save_host(params[:ip])

  respond_to do |format|
    format.html { redirect_to tools_path } ## if you still want to have html
    format.js
  end
end

and create a file called view/tools/ping.js.erb where you have javascript that will be run and returned asynchronously

$("#output").html("<%= j @results %>"); 

The <%= %> block will be evaluated first and replaced with the output of that ruby code. Then this will be inserted into the #output div.

Sign up to request clarification or add additional context in comments.

7 Comments

Well, at least I wasn't far off! Ok, I made the change, I see that in console log that Rendered tools/ping.js.erb (0.6ms) did happen, however nothing is displayed in the <div id="output"></div> area yet.
@Godzilla74 if you're on Google Chrome you can open up the inspect element -> then click the Network tab, it should show you what is being called on the network and what response is being sent back.
@Godzilla74 my response does require you to have jQuery. That could be it.
I added a screenshot of what the Network Tab shows after the form submit. I don't see a reference to the ping
I do have the jquery-rails gem installed
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.