user13541811
user13541811

Reputation:

Using ajax to change the state of a button in Ruby on Rails views

I have a setting in which I would like to dynamically change a buttons disabled state. Currently the logic I have looks as follows:

<% if @has_attachment_file_sent %>
   <% if current_user.id != @offer.user_id %>                     
      <%= link_to send_signature_requests_path, remote: true, method: :post,
          data: { confirm: "Are you sure?" },
          id: "signature_request_button",
          class: "button is-info is-fullwidth  m-t-10 m-b-10"  do %>
          <span>Send request</span>
      <% end %>
   <% end %>
<% else %>
   <button class="button is-info is-fullwidth  m-t-10 m-b-10" disabled>Send request</button>
<% end %>

However, the problem with this method is that this only changes the state of the button when you refresh the page. Is there a way to do this kind of Ajax with RoR or what should I do here?

Also tried using javascript as follows:

<script>
    $(document).ready(function() {
        var has_attachment_file_sent = <%= @has_attachment_file_sent %>
        console.log(has_attachment_file_sent);
        if(has_attachment_file_sent) {
           $('#signature_request_button').attr('disabled', true);
        }        
    })
</script>

but this doesn't seem to be doing anything.

Also here's my controller

def show
    @offer = Offer.find(params[:id])
    @has_attachment_file_sent = Comment.where(user_id: @offer.user_id).any? {|obj| obj.attachment_file.attached?}
    respond_to do |format|
        format.html
        format.js { render layout: false, content_type: 'text/javascript' }
    end
end

Upvotes: 0

Views: 402

Answers (3)

Matt Ray
Matt Ray

Reputation: 71

Oh yeah, how annoying, forgot about that

Maybe something like this inside js.erb

It should work, hacks but I’m sure there is another solution I’m going blank on

# render partial line here
<% if @disabled %>
  $(‘#button-id’).prop(“disabled”, true);
<% else %>

$(‘#button-id’).removeAttr(“disabled”)

<% end %>

Upvotes: 0

Taoufik
Taoufik

Reputation: 296

First place your html in a partial and wrap the content in div, assume that the partial's name is 'buttons.html.erb'

_buttons.html.erb

<% if @has_attachment_file_sent %>
   <% if current_user.id != @offer.user_id %>                     
      <%= link_to send_signature_requests_path, remote: true, method: :post,
          data: { confirm: "Are you sure?" },
          id: "signature_request_button",
          class: "button is-info is-fullwidth  m-t-10 m-b-10"  do %>
          <span>Send request</span>
      <% end %>
   <% end %>
<% else %>
   <button class="button is-info is-fullwidth  m-t-10 m-b-10" disabled>Send request</button>
<% end %>
<div id="buttons">
  <%= render partial: 'buttons' %>
</div>

Add button in view

<%= link_to 'Refresh', show_page_path(id: @offer.id), id: 'btn_call_ajax', remote: true %>

you should adapt show_page_path with your route

def show
    @offer = Offer.find(params[:id])
    @has_attachment_file_sent = Comment.where(user_id: @offer.user_id).any? {|obj| obj.attachment_file.attached?}
    respond_to do |format|
        format.html
        format.js
    end
end

Then you should create a file named show.js.erb that contain the following code:

$('#buttons').html('')
$('#buttons').append("<%= escape_javascript render(:partial => 'buttons') %>");

Upvotes: 0

Matt Ray
Matt Ray

Reputation: 71

create the file show.js.erb and in your controller just leave it as format.js without curly braces.

create a partial with

<button class="button is-info is-fullwidth  m-t-10 m-b-10" disabled="<%= disabled ? “disabled” : “”  %>”>Send request</button>

And add a div in original file, wrap rendering of the partial above

<div id=“woohoo”>
<%= render partial: “file_above”, locals: {disabled: true} %>
</div>

Then in that .js.erb file add this $(‘#div-around-button’).html(“<%= j render(‘show’, disabled: @disabled_variable_from_controller) %>”) and it will basically refresh that button with new value that you got from controller 🙂

P.S. I wrote this all on my iPhone so I might have missed small things like syntax

Upvotes: 0

Related Questions