I am creating a form where if the user enters in an URL, my code will return an image url. When the result is successful, I want to update the partial that displays the image without reloading the page
in my controller
def receive_url
img_path = ProcessUrl.new.parse_url(params[:submitted_url])
end
in my view
<div>
<%= form_tag({controller: "get_url", action: "receive_url"}, method: :post, remote: true) do %>
<%= label_tag "Enter Url" %>
<%= text_field_tag "submitted_url", nil, placeholder: 'Enter search url...'%>
<%= button_tag "Publish", class: 'button', data: { disable_with: "Please wait.." } %>
<% end %>
</div>
<%= render :partial => 'image', locals: { stored_url: @stored_url } %>
in my partial _image.html.erb
<div>
<% if @stored_url != nil %>
<a href="<%= @stored_url %>" >
<div id="background_image" style="height: 300px; width: auto; background-image: url(<%= @stored_url %>); background-repeat: no-repeat"></div>
</a>
<% end %>
</div>
what do I need to do in my controller to pass in @stored_url
CodePudding user response:
For this answer, I'm assuming your routes are correctly set. I'm also assuming you have jquery. If not, i'll adapt the answer to plain javascript syntax.
<%= render :partial => 'image', locals: { stored_url: @stored_url } %>
The line above in your view will only render on page load. To have it update after submitting a link to the receive_url
endpoint, we'll have to use some javascript. In traditional rails way, this is handled by a *.js.erb
file.
Before we do that, lets adjust the view and partial slightly:
index.html.erb:
<div>
<%= form_tag({controller: "get_url", action: "receive_url"}, method: :post, remote: true) do %>
<%= label_tag "Enter Url" %>
<%= text_field_tag "submitted_url", nil, placeholder: 'Enter search url...'%>
<%= button_tag "Publish", class: 'button', data: { disable_with: "Please wait.." } %>
<% end %>
</div>
<div id="image_section">
<%= render :partial => 'image', locals: { stored_url: @stored_url } %>
</div>
The view is updated so we have a div
with and id
. We can use that id as a reference for our js.erb
file where to update the view.
_image.html.erb:
<% if @stored_url != nil %>
<a href="<%= @stored_url %>" >
<div id="background_image" style="height: 300px; width: auto; background-image: url(<%= @stored_url %>); background-repeat: no-repeat"></div>
</a>
<% end %>
In the partial, we just got rid of the div
tag, since it is now present in the view.
Our controller also needs to be adjusted. we want to tell rails we'll answer the call with some javascript (js.erb
), and we want to have the variable @stored_url
available in our partial:
controller:
def receive_url
img_path = ProcessUrl.new.parse_url(params[:submitted_url])
#fill in our stored_url
@stored_url = <YOUR LOGIC TO GET THE URL>
#tell rails we would like to respond with js
respond_to do |format|
format.js
end
end
Finally, we need to create a receive_url.js.erb
file in our view map.
This javascript function will be called after our request to receive_url
is processed. Notice that the name of this file is the same as our endpoint.
receive_url.js.erb:
$("#partial_image_section").html("<%= j (render 'image') %>");
It does the following: First, it searches for an element with id
equal to partial_image_section
. Secondly, it replaces its inner html with render 'image'
. The render
function will rerender our partial, resulting in a new image.