In my index.html.erb I have a button like:
<%= button_to 'Test', question_path, :remote => true, :class => "btn btn-primary btn-large" %>
This triggers a method in my controller, which asks a server for a simple string value, and the method succesfully gets an answer back. This was verified by puts question.gets.
I want to pass that answer back to index.html.erb and show it in a <div>.
create an app/views/questions/show.js.erb and add the js code you need here.
# controller
def show
#question = ... # fetch question
end
# show.js.erb
$('#div_id').text('<%= escape_javascript #question.gets %>');
Related
I'm trying to create an order confirmation page for my Rails 6 app. The idea is that user will see a preview of the item they are creating before submitting and the object being saved in the database. Below desired flow:
User visits /cash_transactions/withdrawals/new
User enters data and clicks submit
User is redirected to /cash_transactions/withdrawals/confirm which
displays the entry
User clicks confirm to save object to db or cancel
Object is saved
I followed two main threads that describe this type of action, but they are quite old - 11 and 12 years old. Nevertheless based on that I've created below code:
# controllers/cash_transactions/withdrawals_controller.tb
module CashTransactions
class WithdrawalsController < CashTransactions::BaseController
(...)
def confirm
#cash_transaction = CashTransaction.new(cash_transaction_params)
render 'cash_transactions/_confirm'
end
end
end
# routes.rb
namespace :cash_transactions do
resources :withdrawals, only: %i[new create] do
collection do
post :confirm
end
end
end
With corresponding views:
# app/views/cash_transactions/new.html.erb
<%= render 'cash_transactions/form', cash_transaction: #cash_transaction %>
# views/cash_transactions/_form
# the form is rendered for cash_transaction create action
<%= simple_form_for cash_transaction, url: { action: :confirm } do |f| %>
<%= f.input :amount %>
<%= f.button :submit, 'Submit' %>
<% end %>
# confirmation page under views/cash_transactions/_confirm.html.erb
<div>
Total of withdrawal: <%= #cash_transaction.amount.to_i %>
</div>
<%= link_to 'Confim', cash_transactions_withdrawals_path(#cash_transaction), method: :post %>
<%= link_to 'Cancel', cash_transactions_path %>
And everything works until the user clicks confirm button in views/cash_transactions/_confirm.html.erb - instead of creating a record an error appears:
param is missing or the value is empty: cash_transaction
Did you mean?
authenticity_token
action
controller
_method
where did I go wrong? or there is a completely different way to do so?
tl/dr: You need to add parameters to your create request.
Why this is happening
The /confirm view is being rendered with an (unsaved) #cash_transaction object, however that object is not being used and so the information is being lost when the page is rendered.
The line:
<%= link_to 'Confim', cash_transactions_withdrawals_path(#cash_transaction), method: :post %>
Will submit a POST request with no parameters to the /cash_transactions/withdrawals#create (because you've given it no parameters to post). It doesn't know to include the params from the previous request.
There are a few options to fix this... you can add params as URL parameters in link_to like this, however I wouldn't recommend posting with params in the URL.
You can use button_to instead, and pass in the cash_transaction arguments from the previous request in the params: option (or pull them out of the unsaved #cash_transaction object).
Approach #1 - reuse create params
# Get them from the params sent in the previous request. In the controller...
def create
#cash_transaction = CashTransaction.create!(cash_transaction_params)
# etc...
end
#...
protected
def cash_transaction_params
params[:cash_transaction].permit(:amount, :whatever)
end
helper_method :cash_transaction_params
# In the view
<%= button_to 'Confirm', {action: 'create', params: cash_transaction_params}
Approach #2 - Access attributes from the model you built
<%= button_to 'Confirm', {action: 'create', params: #cash_transaction.attributes.slice('amount', 'other_attribute') }
Or you could do something like render the form again but hidden and have the "confirm" button submit the hidden form (with { action: :create } instead of { action: :confirm}). This last solution is probably the easiest to understand.
We have a link_to sending an ajax post, and are wondering if there's a way to change the content of the sending tag.
We basically want to update the database, then change the icon in the link_to block.
<%= link_to add_favorite_path({type: type, id: id}),
type:"button", disable_with: '...', :method => :post,
:remote => true, class: 'btn btn-default btn-sm', id: "#{type}-#{id}" do %>
<i class="fa fa-plus"></i>
<% end %>
Here's the favorites contoller:
class FavoritesController < ApplicationController
respond_to :js
def add
#type = params[:type]
#id = params[:id]
#selector = "#{#type}-#{#id}"
end
end
EDIT: add.js.erb:
var link = $("a#<%= #selector %>");
link.html('<i class="fa fa-check"></i>');
Found Solution:
Could not alter the item html when using the disable_with: option. Removed it and it works.
You can just make sure the appropriate controller reponds to JS
respond_to :js, :html
Then create the view file add.js.erb to add the appropriate JS to render the new icon.
I would like to see more code but something like this
$("#id_of_link").html("<i class='fa fa-check'></i>");
Although, I usually create partials and escape_javascript to render the new partial in the JS
I currently have a couple of forms that I'm trying to change the button that submits it based if I'm on the edit or new action. I had two forms created but this smelt bad, and am now just using a single form partial.
At the end of my partial, I have something like this at the end of my forms:
<p>
<% if controller.action_name == 'new' %>
<%= f.submit "Create", :class => "pink_button"%> or
<% elsif controller.action_name == 'edit' %>
<%= f.submit "Update", :class => "pink_button"%> or
<% end %>
<%= link_to "cancel", :back %>
</p>
That way, if I'm creating some new, the button reads "Create", and if it's an update that a user is trying to complete, the button reads "Update". This works great, until the form is submitted and validation fails.
In my controller, I'm catching things that do fail like so:
def update
#list = current_user.lists.find(params[:id])
if #list.update_attributes(params[:list])
redirect_to list_path(#list), :notice => "List '#{#list.name}' updated."
else
render :action => 'edit'
end
end
So the form is simply re-rendered. The problem is, I'm no longer on the edit path. This means, my form button does not show up any longer.
Is there a convention to what I'm trying to do?
Thanks
Yes, this is handled in Rails with i18n by default. The translations are in ActionView, and look like this:
en:
helpers:
select:
# Default value for :prompt => true in FormOptionsHelper
prompt: "Please select"
# Default translation keys for submit FormHelper
submit:
create: 'Create %{model}'
update: 'Update %{model}'
submit: 'Save %{model}'
All you need to do is f.submit (without passing "Create" or "Edit", etc) and the translations will do the rest. You can overwrite these by dropping the above yaml into your local locales.
If you need to set the class you can pass nil, e.g. f.submit nil, :class => 'whatev'
The Rails way is to check if the record is new or not:
#list.new_record? ? "Create" : "Update"
Rails has a method persisted? to determine if an object has persisted.
If you're using erb, do
<%= f.submit (#list.persisted? ? 'Create' : 'Update) %>
If you're using haml, use
= f.submit (#list.persisted? ? 'Create' : 'Update')
For more, see http://apidock.com/rails/ActiveRecord/Persistence/persisted%3F
I have an erb file named index that has a form in it. As a simple example:
<% form_for #foo, :url => {:action => 'bar'} do |f| %>
<%= f.submit "BAR!" %>
<%end%>
When I click the BAR! button it preforms the actions I expect and it forwards me onto the bar.erb file, displaying the expected output. What I would like to be able to do, however, is to take the generated html from this page and stuff it into the innerHTML of a div on the index page. I assume there is a way but I must ask, is there a way to achieve this? Are there any examples available that would be helpful? Thanks!
You should be able to pass the id of the div to update like so:
<% remote_form_for #foo, :url => {:action => 'bar'}, :update => 'id-of-div-to-update' do |f| %>
<%= f.submit "BAR!" %>
<%end%>
In the controller:
def bar
# your code here
respond_to do |format|
format.html { redirect_to(xxx) }
format.js
end
end
Rails will look for a template named bar.js and will render it and return it's content to the browser without a redirect.
in js.rjs file i am shwoing prompt with textbox like
page << "var name = prompt('Enter name:'); "
i want to add the value name to the table names
is it possible to do from rjs
if so please guide me how to do it..
You shouldn't do this back and forwarding with rjs. You're returning javascript to be executed by the client, and you can't get the value back directly unless you embed another AJAX call into the javascript your return.
A better way to do this would be to use a single AJAX call. Use a remote_form_for with a text_field for the user to enter their name into, then POST it to your controller action and store it in the database in the normal fashion.
Something like:
# In your view
<% remote_form_for :user, :url => { :controller => :users, :action => :create } do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
# In your controller
def create
#user = User.new(params[:user])
#user.save
render :update do |page|
# Return whatever javascript you want here
page << "alert('Created user')"
end
end