I found many posts with this problem, but it's seems like none of them solves my problem. I got this code which i want to render from string:
<%= button_to "/admin/#{contr_name}/#{obj.id}", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>
I have tried this:
template += "<div class='col-sm-4'>"
template += "<%= button_to \"/admin/#{contr_name}/#{obj.id}\", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>"
template += "</div>"
ERB.new(template).result(binding)
but i get syntax errors.
How i can fix this?
I would suggest to use partials instead.
First, define the partial at, for example, views/shared/_delete_button.html.erb:
<%= button_to "/admin/#{contr_name}/#{obj.id}", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>
Then, you can render the partial with the wanted parameters:
render 'shared/delete_button', contr_name: [contr_name], obj: [obj]
Replacing [contr_name] and [obj] with whatever you want those variables to be assigned to.
Or, even better, allow the partial to extract the controller's name from predefined variables, like this:
<%= button_to "/admin/#{controller.controller_name}/#{obj.id}", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>
Now you only need to supply the obj when rendering it.
render 'shared/delete_button', obj: [obj]
You could also use named routes, and do [route_name]_path(obj) instead of manually constructing the path.
Related
I am trying to implement a delete button for each newsletter signup on my Users Show view in an admin section.
What I'm trying now:
<% #news_subs&.each do |news| %>
<div class="vert-flip bot-drop">
<div class="wellington bot-drop sub-well flip-card-inner">
<div class="flip-card-front">
<p class="align-left left hype"><%= news.name %></p>
<p class="align-right right"><%= news.verified %></p>
<div style="clear: both;"></div>
</div>
<div class="flip-card-back">
<p class="newsletter-email"><%= news.email %></p>
<%= link_to "Remove", news, method: :delete,
data: { confirm: "Are you sure you want to..." },
class: "btn btn-xs btn-danger newsletter-remove" %>
</div>
</div>
</div>
<% end %>
But I am getting the following error:
Routing Error
No route matches [DELETE] "/newsletter.2"
I have tried using: <%= link_to "Remove", Newsletter.find(params[:id]), method: :delete, but that just throws the same error as well.
How can I delete the individual news_sub and not navigate away from the page?
Using Ruby 3 and Rails 6.1
Update:
Rails Routes:
newsletter_index GET /newsletter(.:format) newsletter#index
POST /newsletter(.:format) newsletter#create
new_newsletter GET /newsletter/new(.:format) newsletter#new
edit_newsletter GET /newsletter/:id/edit(.:format) newsletter#edit
GET /newsletter/:id(.:format) newsletter#show
PATCH /newsletter/:id(.:format) newsletter#update
PUT /newsletter/:id(.:format) newsletter#update
DELETE /newsletter/:id(.:format) newsletter#destroy
edit_news_verification GET /news_verification/:id/edit(.:format) news_verification#edit
Routes.rb:
get 'newsletter', to: 'newsletter#newsWelcome', as: 'newsWelcome'
post 'newsletter', to: 'newsletter#create'
...
resources :newsletter
resources :news_verification, only: [:edit]
You can fix this by specifying the route rather than just passing the object to your link_to method. Instead of passing news specify the path you need, eg news_sub_path(news).
This should work:
<%= link_to "Remove", news_sub_path(news), method: :delete,
data: { confirm: "Are you sure you want to..." },
class: "btn btn-xs btn-danger newsletter-remove" %>
I have a link class like
link_to( class: 'btn_download<%= index %>')
from a .each_with_index model call
Model.each_with_index do |m, index|
but it throws an error
and when i try with #{index} it just adds #{index} to the class name instead of dynamically adding 'index'
As I noticed there are some issues in your code. Please find below the code snippet example I wrote similar to your case which will help you to fix your issue
<% User.all.each_with_index do |m, index| %>
<%= link_to users_path, class: "btn_download#{index}" do %>
<span class="fa fa-sign-out"></span>
Download
<% end %>
<% end %>
So instead of using 'btn_download <%= index %>' try "btn_download#{index}".
Also, Use double quotes
class: "btn btn-primary btn-sm download_btn#{index}"
instead
class: 'btn btn-primary btn-sm download_btn#{index}'
Please let me know if you have any confusion in this.
If you want to wrap your link around an icon, use the following syntax:
<%= link_to ..._path(...) do %>
<i class="fa fa-spin fa spinner"></i>
<% end %>
You have to append a do onto the link to and then close the block with an end. And just put whatever inbetween (icon or image or div).
Sometimes in my Rails views, I have some duplicated code, because I have to set the parameters of a Rails helper method according to some conditions. Like:
<% if something %>
<%= link_to "Target", #target, class: "target-a" %>
<% else %>
<%= link_to "Target", #target, class: "target-b" %>
<% end %>
or another example:
<% if tooltip == false %>
<%= image_tag picture.url(size), class: "img-responsive #{css_class}" %>
<% else %>
<%= image_tag picture.url(size), class: "img-responsive #{css_class}", data: { toggle: "tooltip", placement: "bottom" }, title: "#{picture.name}" %>
<% end %>
Is there a way of writing this in a more elegant way (without repeating the whole helper)?
Thanks
You can isolate the differences in the options hash and merge just the differences into a shared base options hash:
<%
link_options =
if something
{}
else
{ data: { toggle: "tooltip", placement: "bottom" }, title: "#{picture.name}" }
end
%>
<%= image_tag picture.url(size),
link_options.merge(class: "img-responsive #{css_class}") %>
Or, better yet, you could do the same sort of thing but in your own, custom helper method. Using a helper method is preferable because then you have a method that can be tested, re-used, named (in a self-documenting manner), etc.
I am getting this error:
NoMethodError - undefined method `stringify_keys' for "/posts/7/up-vote":String:
This is my code:
<% if policy(Vote.new).create? %>
<div class="vote-arrows pull-left">
<div if vote = current_user.vote(post) %>
<%= link_to [post, Vote.new], post_up_vote_path(post), class: 'btn btn-primary', method: :up_vote do %>
<i class = "glyphicon glyphicon-chevron-up #{(current_user.voted(post) && current_user.voted(post).up_vote?) ? 'voted' : '' }" ></i> Upvote
<strong><%= post.points %></strong>
<% end %>
<% else %>
<%= link_to [post, vote], post_down_vote_path(post), class: 'btn btn-danger', method: :down_vote do %> <i class = "glyphicon glyphicon-chevron-down #{(current_user.voted(post) && current_user.voted(post).down_vote?) ? 'voted' : '' }"></i>;nbsp; Downvote
<% end %>
</div>
<% end %>
I am getting the error on this line:
<%= link_to [post, Vote.new], post_up_vote_path(post), class: 'btn btn-primary', method: :up_vote do %>
<i class = "glyphicon glyphicon-chevron-up #{(current_user.voted(post) && current_user.voted(post).up_vote?) ? 'voted' : '' }" ></i> Upvote
Any help would be greatly appreciated...
Try going through the code you've posted line-by-line and look for errors. Here's some to check for:
<!-- Mixing HTML and Ruby on this line -->
<div if vote = current_user.vote(post) %>
The link_to links need some love. Read the docs carefully and note in particular:
Valid HTTP verb values for :method
The path only needs to be specified once
link_to docs here: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
You may want to spend some time getting the indentation right for the if/else/ends as this will make it easier for you to spot syntax errors.
The format of a link_to call is:
link_to "The text in the link", the_path, hash_of_options
That the first argument must be text is what Sergio meant by "link_to must accept label as its first parameter". So, something like:
<%= link_to "Up-vote the post" , post_up_vote_path(post), class: 'btn btn-primary', method: :up_vote do %>
You're giving it a path (or an array that could be converted to a path) as both main arguments.
Check out the docs for the method: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
Note that your link contains an icon, which should probably take the place of the "label", so your label could just be an empty string.
I am working through the Agile Web Development with Rails book but I have been using Twitter Bootstrap instead of the custom styling from the book. I am having trouble adding an icon through GLyphonics to the button_to method. My code looks like this:
<%= button_to <i class="icon-search icon-white">Add To Cart</i>,
line_items_path(product_id: product),
class: "btn btn-success" %>
I have tried quite a few variations but can't seem to get it to work correctly.
I'm not sure how the OP got this to work, but Rails button_to generates an <input type='submit' /> element, which does not allow for HTML in the value field.
See also: input type="submit" Vs button tag are they interchangeable?
The best alternative in this situation is to force link_to to PUT (or POST):
<%= link_to raw("<i class=\"icon-search icon-white\">Add To Cart</i>"),
line_items_path(product_id: product),
class: "btn btn-success",
method: :put %>
You can add the icon as a child element:
<%= button_to button_path, method: :delete do %>
<span class="glyphicon glyphicon-search"></span>
<% end %>
It looks like you have an issue with your quotes:
<%= button_to raw("<i class=\"icon-search icon-white\">Add To Cart</i>"),
line_items_path(product_id: product),
class: "btn btn-success" %>
Enclose the label of the button in double quotes, escape the double quotes in your i tag, and finally, wrap everything into a raw() call to ensure the HTML is properly displayed.
Alternatively you can use html_safe:
<%= button_to "<i class=\"icon-search icon-white\">Add To Cart</i>".html_safe,
line_items_path(product_id: product),
class: "btn btn-success" %>
good point from #jordanpg: you can't have HTML in the value of a button, so his solution is more appropriate and should get the approved status.
the html_safepart remains valid though.
Using raw() or #html_safe still did not work for me.
I am using a helper method to create a button_to flag content. Ended up using the following in my helper method (path is defined beforehand):
form_tag path, :method => :post do
button_tag do
content_tag :i, 'Flag as inappropriate', :class => 'icon-flag flag_content'
end
end
I used this one and it works fine for me :
<%= link_to(line_items_path(product_id: product),
method: :put,
class: 'btn btn-success') do %>
<%= content_tag('i', nil, class: 'icon-search icon-white') %> Add To Cart
<% end %>
Hope this helps
I am using this helper:
module ApplicationHelper
def glyph(*names)
content_tag :i, nil, class: names.map{|name| "icon-#{name.to_s.gsub('_','-')}" }
end
end
Example:
glyph(:share_alt)
=> <i class="icon-share-alt"></i>
and
glyph(:lock, :white)
=> <i class="icon-lock icon-white"></i>
Using Rails 4 and Bootstrap 3, here's how to create a delete button using link_to or button_to.
Note that I'm using Haml instead of Erb.
In your view:
- #users.each do |user|
= link_to content_tag(:i, ' Delete', class: "glyphicon glyphicon-trash"),
users_path(user),
class: "btn btn-danger",
method: :delete,
data: { confirm: "Delete user #{user.username}?" }
You can also replace the content_tag part with
raw('<i class="glyphicon glyphicon-trash"> Delete</i>'),
This work for me, (and with confirm message)
<%= button_to "/home/delete?cardId="+card.id.to_s, data: { confirm:'Are you sure you want to delete?' } do %>
<i class="fa fa-times"></i>
<% end%>
this generate
<form class="button_to" method="post" action="/home/delete?cardId=15">
<button data-confirm="Are you sure you want to delete?" type="submit">
<i class="fa fa-times"></i>
</button>
</form>