I am trying to achieve a button_to which looks like a link (class="btn btn-link") and which has as its text (input) value a semantic-ui icon. I need the button to display in-line as a link. I am using the semantic-ui-rails gem. My button-to is formatted as below:
<%= button_to semantic_icon('lightbulb outline'),
votes_path,
options: {
params: {
voter_id: current_user.id,
target_type: "Comment",
target_id: comment.id,
value: 1
}
},
class: "btn btn-link",
remote: true
%>
However, the button displays on my screen as
<i class="lightbulb outline icon"></i>
Instead of rendering the lightbulb-outline icon itself.
What must I change to get the value of the input tag of the button-to form to render properly?
try
<%= button_to votes_path, class: "btn btn-link", remote: true, params: {
voter_id: current_user.id,
target_type: "Comment",
target_id: comment.id,
value: 1
} do %>
<%= semantic_icon('lightbulb outline') %>
<% end %>
Related
My last chance is some last living developer in RoR
Nothing in the darkest corners of the internet works for:
<%= link_to 'some-link', '#', data: { confirm:'Are You Sure?') %>;
it generate this:
<a data-confirm="Are you sure?" href="#">some link</a>
but there is no confirm dialog box.
I try everything - turbo_confirm, try to add controller with class for stimulus ... and still nothing.
Right now I remove turbo-rails, stimulus etc. - but still nothing.
data-turbo-confirm presents a confirm dialog with the given value. Can
be used on form elements or links with data-turbo-method.
https://turbo.hotwired.dev/reference/attributes
Examples that work
<%= link_to "GET turbo link", "/",
data: {
turbo_method: :get,
turbo_confirm: "Sure?"
}
%>
<%= link_to "POST turbo link", "/",
data: {
turbo_method: :post,
turbo_confirm: "Sure?"
}
%>
<%= button_to "Button", "/",
data: { turbo_confirm: "Sure?" }
%>
<%= form_with url: "/",
data: { turbo_confirm: "Sure?" } do |f| %>
<%= f.submit "Submit" %>
<% end %>
Doesn't work
<%= link_to "GET link", "/",
data: { turbo_confirm: "Sure?" }
%>
Fix by adding turbo_method: :get.
Really doesn't work
<%= link_to "UJS link", "/",
data: { confirm: "Sure?" }
%>
But easy to fix:
// app/javascript/application.js
document.addEventListener("click", event => {
const element = event.target.closest("[data-confirm]")
if (element && !confirm(element.dataset.confirm)) {
event.preventDefault()
}
})
data-disable-with
This one is a bit more involved, but it's all the same pattern, listen for event, check for data attribute, if else, do something.
// app/javascript/application.js
// on form submit
// set `value` if `input`
// set `innerHTML` if `button`
document.addEventListener("turbo:submit-start", event => {
const element = event.detail.formSubmission.submitter
if (element.hasAttribute("data-disable-with")) {
// element.disabled = true // this is done by turbo by default
if (element instanceof HTMLInputElement) {
element.value = element.dataset.disableWith
} else {
element.innerHTML = element.dataset.disableWith
}
}
})
<%= form_with url: "/" do |f| %>
# <button>
<%= f.button "Submit", data: { disable_with: "..." } %>
# <input>
<%= f.submit "Submit", data: { disable_with: "..." } %>
<% end %>
I currently have a simpleForm in a HAML/RoR program:
= simple_form_for(#client, url: {action: "update" }, html: { method: :put }) do |f|
BLAH BLAH BLAH
= f.submit "Update Password", id: "submit", class: "btn btn-primary"
It functions. But on submit, it doesn't go where I want it to go.
When I change it to:
= simple_form_for(#client, url: admin_client_path(#client), html: { method: :put }) do |f|
It goes to the right place if I reload the form page, but the original place otherwise... It appears to actually change the password in both cases, at least...
I am having 2 button fields which are redirected to same html page,
= link_to url_for(params.merge(action: 'my_report', format: :html)), class: 'button on-dark right', data: { toggle: 'modal', placement: 'left' } do
= t('reports.pdf_export')
= link_to url_for(params.merge(action: 'show', format: :pdf)), class: 'button on-dark right' do
= t('reports.all_pdf_export')
In that html I want to add extra stuff when we click on all_pdf_export button, can we add this by name or any flag to be added?
Please help me.
controller method:
def customer_report
#x = params[:x]
#y = params[:y]
#details = Detail.by_account(current_account).active.includes(:company, :primary_contact)
respond_to do |format|
format.html{ render layout: "modal" }
end
end
Button view:
= link_to url_for(params.merge(action: 'my_report', format: :html)), class: 'button on-dark right', data: { toggle: 'modal', placement: 'left' } do
= t('reports.pdf_export')
= button_to t('reports.all_pdf_export'), url_for(params.merge(action: 'customer_report', format: :html)), class: 'button on-dark right', params: { x: "value", y: "value" }, data: { toggle: 'modal', placement: 'left' } do
common view for both the links:
<div>
<%= #account.name %> <br/>
<%= #account.description %><br/>
<% if #x? %>
<%= #account.details %>
<% end %>
</div>
You'll probably be best using button_to, which creates a small form, allowing you the luxury of passing params through it:
= button_to t('reports.all_pdf_export'), url_for(params.merge(action: 'show', format: :pdf)), class: 'button on-dark right', params: { x: "value", y: "value" }
(button_to) generates a form containing a single button that submits to the URL created by the set of options. This is the safest method to ensure links that cause changes to your data are not triggered by search bots or accelerators.
If using the above, you'll be able to access the parameters in your controller as follows:
#app/controllers/your_controller.rb
class YourController < ApplicationController
def show
#x = params[:x]
#y = params[:y]
end
end
Update
You must remember to evaluate against the variable you set:
<%= #account.name %> <br/>
<%= #account.description %><br/>
<%= #account.details if #x == "value" %>
I've got this bunch of code
<%= link_to admin_conference_statuses_path(conference_id: #conference.id), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Comm invoiced out Venue</span>
<% end %>
<%= link_to admin_conference_statuses_path(conference_id: #conference.id), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Cross charged to Client</span>
<% end %>
And I have this in my controller
def create
conference_id = params[:conference_id] #Keep the same
#conference_status = ConferenceStatus.find_by_conference_id(conference_id)#Keep the same
#conference_status = ConferenceStatus.new unless #conference_status#Keep the same
#conference_status.conference_id = params[:conference_id]
#conference_status.invoiced_out_user_id = current_user.id
#conference_status.invoiced_out_datetime = DateTime.now
if #conference_status.save
# Success
else
# Failure
end
end
Now, when one button is pressed it grabs the id and puts it into a database.
How would I go about adding it so that when button 2 (opposed to button 1) is pressed it puts current user id into a column called "cross_charged_user_id"
If you have the answer could you post it and explain what it does, so I know for next time?
Thanks
Sam
You can pass one extra parameter to second link. Then depending on this extra parameter you can assign the current user as cross_charged_user.
The html code look like:
<%= link_to admin_conference_statuses_path(#conference), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Comm invoiced out Venue</span>
<% end %>
<%= link_to admin_conference_statuses_path(#conference, cross_site_to_client: true), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Cross charged to Client</span>
<% end %>
And the controller just check the params[:cross_site_to_client] and assign the current user
if params[:cross_site_to_client].present?
#conference_status.cross_site_to_client_id = current_user.id
end
Even You can cleanup your code as well
#conference_status = ConferenceStatus.find_or_create_by_conference_id(params[:conference_id])
if params[:cross_site_to_client].present?
#conference_status.cross_site_to_client = current_user
else
#conference_status.invoiced_out_user = current_user
end
#conference_status.invoiced_out_datetime = DateTime.now
#conference_status.save
In my app users have lists and list_items (list_items link the products they add to their appropriate list). I have a product search modal that returns a list of products each with a product_id attribute. I would like to conditionally display a button (either ADD or ADDED) based on whether the user already has the product in their list or not.
The issue is using {raw-product_id} variable that is passed in from the search with the ActiveRecord object lookup. If I manually input an integer, it works fine, but the variable that is used looks like it's a string, and even with to_i appended, doesn't work when using: - if current_user.list_items.where(product_id: '{raw-product_id}'.to_i).exists? Relevant lines of code near the bottom.
code:
-# = form_tag main_app.products_path(), method: :post do
= form_tag main_app.list_items_path, data: { passthru: current_user.nil?, remote: true } do |f|
= hidden_field_tag :success, 'back'
= hidden_field_tag :list_id, args[:list].try(:id) || '0'
.product_picker_inner
.product_picker_body
.product_picker_details
.product_picker_details_default
= hidden_field_tag :product_id, '{raw-product_id}'
= hidden_field_tag :added_from, 'search'
%h4.text-center
{escaped-title}
.text-center.product_picker_category
%span
{escaped-category}
.product_picker_content
.row
.col-xs-12.col-md-6.product_picker_avatar6
%img.img.img-responsive.center-block{ src: '#{raw-avatar}' }
-# .rectangle-avatar.contain-image{ style: 'background-image: url("{encoded-avatar}")' }
.col-xs-12.col-md-6.product_picker_description
{escaped-description}
.col-xs-12.col-md-6
.text-center{ style: 'margin:1em 2em 0.3em 0' }
price:
%b
{raw-price_formatted}
.row{ style: 'padding: 1em 0 0 0;' }
.col-xs-12
.fancy-span{ style: 'font-size: 0.8em' }
%span Tell us about this product
= text_area_tag :comment, '', class: 'form-control'
.text-center.product_picker_controlls
- if current_user.list_items.where(product_id: '{raw-product_id}'.to_i).exists?
= button_tag 'ADDED', type: 'submit', class: 'btn btn-danger btn-lg t03e', id: 'product-{raw-product_id}'
-# %a.btn.btn-primary.btn-lg.t03e{ href: "#{products_path( list_id: args[:list].try(:id) || '0', success: 'back' )}&u={raw-id}", data: { method: :post } }
ADDED
- else
= button_tag 'ADD', type: 'submit', class: 'btn btn-primary btn-lg t03e', id: 'product-{raw-product_id}'
-# %a.btn.btn-primary.btn-lg.t03e{ href: "#{products_path( list_id: args[:list].try(:id) || '0', success: 'back' )}&u={raw-id}", data: { method: :post } }
ADD
.product_picker_loading_overlay
%div{ style: 'position: absolute;top: 50%;left: 0;line-height: 1.1em;right: 0;text-align: center;font-size: 40px;margin: -20px 0 0 0;' }
%i.fa.fa-circle-o-notch.fa-spin
.text-center{ style: '' }
%a{ href: '#', 'data-dismiss' => 'modal' }
CLOSE
In more closely examining the code, I found that there was a javascript file that replaced all instances of {raw-attribute} with the proper values, so this DOM manipulation was not reaching the ERB itself. My solution was to add the button text and button class directly to the JSON itself, and then add those attributes in the HAML.
new json in the jbuilder file:
json.in_list #list.list_items.where(product_id: product[:product_retailer].try(:product_id)).exists? ? 'ADDED' : 'ADD'
json.button_class #list.list_items.where(product_id: product[:product_retailer].try(:product_id)).exists? ? 'btn-danger' : 'btn-primary'
new haml:
.text-center.product_picker_controlls
= button_tag '{raw-in_list}', type: 'submit', class: 'btn btn-lg t03e {raw-button_class}', id: 'product-{raw-product_id}'
-# %a.btn.btn-primary.btn-lg.t03e{ href: "#{products_path( list_id: args[:list].try(:id) || '0', success: 'back' )}&u={raw-id}", data: { method: :post } }
'{raw-in_list}'