Home > other >  Render partial after ajax request
Render partial after ajax request

Time:08-26

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.

  • Related