Reputation: 21
I'm trying to use ajax for displaying searching results in a Ruby on rails app. However, after I submit the search form, it shows ActionController::UnknownFormat error at the line where it says respond_to respond_to do |format|. It does not allow me render partial and I'm not sure why. Using Rails 6.0.2.2
availabilities/_searchform.html.erb
<form>
<%= simple_form_for(:search, :url => search_rides_path, :remote => true, :method => :get) do |f| %>
<div class="form-row">
<div class="form-group col-md-2">
<%= f.input :start_city, label: 'Start City', class: "form-control", error: 'Start address is mandatory, please specify one' %>
</div>
<div class="form-group col-md-4">
<%= f.input :start_street_address, label: 'Start Street Address', class: "form-control" %>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<%= f.input :end_city, label: 'Destination City', class: "form-control" %>
</div>
<div class="form-group col-md-4">
<%= f.input :end_street_address, label: 'Destionation Street Address', class: "form-control" %>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<%= f.input :trip_date, as: :date, html5: true, inline_label: 'Yes, remember me', class: "form-control" %>
</div>
<div class="form-group col-md-2">
<%= f.input :trip_time, as: :time, html5: true, inline_label: 'Yes, remember me', class: "form-control" %>
</div>
<div class="form-group col-md-2">
<%= f.input :lowest_acceptable_price, label: 'Expected Price', class: "form-control" %>
</div>
</div>
<%= f.submit "Search", class: "btn btn-primary" %>
<% end %>
</form>
part of avilabilities_controller.rb
class AvailabilitiesController < ApplicationController
before_action :set_availability, only: [:show, :edit, :update, :destroy]
# respond_to :html, :json, :js
# GET /availabilities
# GET /availabilities.json
def index
@availabilities = Availability.unmatched
end
def search
if params[:search]
@availabilities = Availability.unmatched.search(params[:search])
if @availabilities
respond_to do |format|
format.js { render partial: 'availabilities/result.html'}
end
else
respond_to do |format|
flash.now[:alert] = "Could not find an availability"
format.js { render partial: 'availabilities/result.html'}
end
end
else
@availabilities = Availability.unmatched
end
end
end
availabilities/search.html.erb
<p id="notice"><%= notice %></p>
<%= render 'searchform' %>
<div id="results">
</div>
availabilities/_result.html.erb
<% if @availabilities %>
<%@availabilities.each do |availability|%>
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Ride</h5>
<strong>Start city: </strong> <%= availability.start_city %><br>
<strong>Start street address: </strong><%= availability.start_street_address %><br>
<strong>End city: </strong><%= availability.end_city %><br>
<strong>End street address: </strong><%= availability.end_street_address %><br>
<strong>Trip Time: </strong><%= availability.trip_time %><br>
<strong>Price Requested: </strong><%= availability.lowest_acceptable_price %><br>
<br>
<a href="#" class="btn btn-primary">View Details</a>
<a href="#" class="btn btn-primary">Request Ride</a>
</div>
</div>
<% end %>
</div>
<% else %>
<h1> No results have been found </h1>
<% end %>
availabilities/_result.js.erb
alert("hello world!")
Upvotes: 0
Views: 2609
Reputation: 102443
You have fundamentally misunderstood how Rails UJS works. When you use remote: true
Rails UJS sends an XHR request to Rails with a application/javascript
content type. Rails renders some JavaScript (or what should have been js) and then sends it back to the client.
Rails UJS takes the response and essentially pops it into a script tag to eval it. If the response is a bunch of HTML this will just cause a parser error.
What you want to do is:
class AvailabilitiesController < ApplicationController
before_action :set_availability, only: [:show, :edit, :update, :destroy]
# respond_to :html, :json, :js
# GET /availabilities
# GET /availabilities.json
def index
@availabilities = Availability.unmatched
end
def search
if params[:search]
@availabilities = Availability.unmatched.search(params[:search])
respond_to do |format|
flash.now[:alert] = "Could not find an availability" unless @availabilities.any?
format.js { render :result }
end
else
@availabilities = Availability.unmatched
end
end
end
Then create a js.erb
view containing JavaScript that alters the existing DOM:
// app/views/availabilites/results.js.erb
document.getElementById("results")
.innerHTML = "<%= j render(partial: 'results.html.erb') %>";
Upvotes: 1