In the Phoenix framework, if I create a delete button (using the link helper function) then it generates a form element.
However, if I put this code inside a Bootstrap drop down, then it's not rendered as a menu item.
I tried using the :form parameter to remove the "button" class, like so:
<ul class="dropdown-menu" aria-labelledby="dLabel">
<li>Insert above</li>
<li>Insert below</li>
<li role="separator" class="divider" />
<li><%= link "Delete", to: log_path(#conn, :delete, log), method: :delete, data: [confirm: "Are you sure?"], form: [class: ""] %></li>
</ul>
This didn't help much. When I inspected the element using Chrome, it seems that Bootstrap menus are looking for the css selection - .dropdown-menu>li>a
Is there another class I could take advantage of for the form? What's the best way to address this with Bootstrap?
Related
(my first SO question, so please be kind!)
Each Schedule has only one System;
Each System has many Applications;
Each Application has many Users and Documents.
What I want to do to create a Schedule entry:
Generate a form that first shows multiple System names that can be clicked. When a System is clicked, it opens a partial that lists Applications associated with that System. Then, when clicking particular Applications, yet another partial opens that contains Users and Documents associated with that particular Application.
When editing this entry later, I want to be able to see everything I had entered before, with the correct System, Application(s), User(s), and Document(s) already pre-selected.
My question here is how to make a form element for choosing a System that will open another partial -- and, later, will be pre-selected when I view and/or edit the entry.
What kinda works right now is a <%= link_to %>, styled with Bootstrap, which opens its associated Applications partial when it's clicked. However, I'm not able to save the System from it, and I can't figure out whether it can display as already-selected later, such as in an Edit form.
We're trying to use radio buttons instead (because you can't pre-select a link_to, right?), so I've been throwing pasta at the wall with f.collection_radio_buttons, or iterating over f.radio_button, or a tag of <input type="radio">. However, I can't figure out how to make a radio button open a partial.
Since first posting this question, I've narrowed down to using f.radio_button within a loop. It shows as correctly "checked" when viewed while Editing the entry later, but it still doesn't open the partial.
Here's a snippet from /_schedule_form.html.erb:
<%= form_for #schedule do |f| %>
<% System.all.each do |a| %>
<!-- This link_to makes the Applications partial appear, but that's all it does -->
<%= link_to a.system_nm, system_applications_path(:system_id => a.id,
:schedule_id => params['id']), :title => 'Click to choose system',
:class -> 'btn btn-default btn-flat active', data: {:remote => true,
'data-target' => '#applicationList'} %>
</a> <!-- closes the link_to tag, I believe -->
<% end %>
<div id="applicationList">
<!-- the Applications partial renders here -->
</div>
<% end %>
Here's the system_applications.js.erb file that opens the _system_applications.html.erb partial:
$("#applicationList").html("<%= escape_javascript(render
'system_applications', locals: {applications: #applications,
schedule_applications_array: #schedule_applications_array})%>");
Here's an update with possible clue:
I'm now using this embedded Ruby code:
<% System.all.each do |rt| %>
<label>
<%= f.radio_button :system_id, rt.id, data:{:remote => true, 'data-target' =>
'#applicationList'}, href: system_applications_path(:system_id => rt.id,
:schedule_id => params['id']), class: 'remote-input', onclick:
"#applicationsList" %>
</label>
<% end %>
And, when I click on that radio button, I'm getting a JS error in the browser console Uncaught SyntaxError: Invalid or Unexpected Token which points to the rendered HTML, and specifically the > at the end of the line:
<input data-remote="true" data-data-target="#applicationList" href="/schedules/system_applications/24?schedule_id=122" class="remote-input" onclick="#applicationList" type="radio" value="24" checked="checked" name="schedule[system_id]" id="schedule_system_id_24" />
Just to make it more complicated:
When creating a NEW entry, and when I hover over one of the link_to buttons, I get a clean-looking path like /schedules/system_applications/24, and that's what gets sent to the server when clicked (which then reads the params as {"system_id"=>"24"}. But hovering over the f.radio_button labels shows no path, and clicking it sends "/schedules/new?schedule%5Bsystem_id%5D=24" with the params {"schedule"=>{"system_id"=>"24"}}. This triggers a 500 (Internal Server Error) (which makes sense, because there's no path for that URL). Do the params need to be the same? If so, how am I screwing it up?
Also, clicking the radio button sends the request to SchedulesController#new, while clicking the link_to sends it to SchedulesController#system_applications. I don't understand how I'm telling the radio button to send it to #new.
Where I'm stuck now is, the f.radio_button renders as "checked", which is correct; but it doesn't open the partial. The link_to version opens the partial, but I don't think it can render as "checked" later on.
Let me know if I'm asking clearly enough, too.
I think we made it work. One key change was to use url instead of href to use the system_applications_path to the controller, as shown here:
<% #systems.each do |a|
<label class="btn btn-sm btn-default">
<%= f.radio_button :system_id, a.id, :data => {url:system_applications_path(:system_id
=> a.id, :schedule_id => params['id']), 'data-target' => '#applicationList'+a.id.to_s,
:remote => true} %>
<%= a.system_nm %>
</label>
<% end %>
Now, when I click the radio button, it opens the correct partial, and it shows as selected later when I go to edit the entry. The Bootstrap styling (btn btn-sm btn-default) helps to show how much clickable area there is, but it's not required for basic functionality.
I suppose some of that [in]famous Rails Magic has radio_buttons treating href: differently than url. But it's "magic" only because I don't understand it (yet -- growth mindset!). What's the explanation behind it?
This is a portion of my groups view. I have a list of partials that I render with a collection of objects:
<div id="container">
<ul>
<li id="form"></li>
<li id="partials">
<%= render :partial => 'groups/partial-list-row', :collection => #allpartials, :as => :f %>
</li>
</ul>
</div>
In the list item with id "form" there is a ruby on rails form that is a form_for #newpartial which is defined in the Partial controller as #newpartial = Partial.new(). I have successfully used jquery to toggle the show and hide of the two list items on a "New Partial" button click, and upon completing a finished form, a new partial object is definitely created. What I'm looking for here is the collection of partials that reappears after the form submission includes the newly created partial object. What is the best way to do this? My form which sits inside the list item with id "form" looks like this:
<%= form_for #newpartial, :html => {:multipart => true, :class => 'custom'}, remote: true do |f| %>
<% if #newpartial.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#newpartial.errors.count, 'error') %> prohibited this partial from being saved:</h2>
<ul>
<% #newpartial.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render :partial => 'partials/form-partial', :locals => { :f => f } %>
<div class="actions">
<%= f.submit 'Launch', :class => 'large success button radius new_browser_tab' %>
<a class="cancel_campaign_new">Cancel</a>
</div>
<% end %>
I also have successfully created a function that is bounded to the "ajax:success" event of this form after the DOM is fully loaded. I just don't know if this is a right approach, and if it is, I don't know what the body of this event handler should consist of. I have created other questions relating to this same issue (I haven't found a solution to this for quite some time now). Here are the questions if you want additional context:
SO question 1
SO question 2
What I was failing to realize is that applying the remote: true on the form indicates that the controller's action method will respond with the models "action".js.erb file. After creating that file and performing the jquery I had always intended, I was able to fix a few kinks and got that part working.
The difference between putting the jquery to render the new partial in your client side javascript and your "action".js.erb file is that the "action".js.erb file is able to make the required request to the server, whereas your client side javascript is not.
Can someone read this and let me know if the above statements are accurate? I'd really like to provide an answer that is accurate as possible for anyone that comes across this...
There are some really good tutorials at CodeSchool.com which has some free courses to take that include video lectures, slides, and exercises that I used to finally give me enough guidance on this. Also worth mentioning that if you intend to learn this stuff quickly and plan on spending a lot of time developing your web development abilities, paying the 20 dollars a month for access to all the courses is well worth it (you can cancel at any time, so learn what you need to learn and move on!).
I want to have a search widget/filter feature on a custom page using active admin to provide a look-up feature. Using the action_items I have my own action and form that renders the search page. On the search page the 'filters' that I need to show include text fields of the 'Parent' resource and a drop down list of the Parent's Parent. The association is as follows
Class MyChildResource
belongs_to :myParentResource
Class MyParentResource
attr_accessible :name, :close_to_place, :date
has_many :myChildResources
belongs_to :myGrandParentResource
class MyGrandParentResource
has_many :myParentResources
In the active admin Resource
ActiveAdmin.register MyChildResource do
action_item :only=>:index do
link_to("Look Up Availability", search_admin_myChildResources_path)
end
collection_action :search do
# do something here similar to the 'filter' feature like filter on myparentresource.date as date
filter on myGrandParentResource as drop down
filter on myParentResource.close_to_place as string
end
end
Do I have to write my own custom meta_search features? I would be fine even if I have to write own search queries, based on the input that the user gives, but my problem is that how do I display the drop down values from the parent's parent model and/or leverage the power of active admin filters.
I read something similar in this question,How to add a filter to Active Admin dashboard? , but it's a hack and it definitely does not answer the question of displaying a list
I haven't found any DRY way of doing this, so I've ended up creating my own search form which uses the active admin css for the 'sidebar' and 'panel' as mentioned in the link above and for each element of drop down, text field , date and buttons. So I get a widget which looks like the sidebar.
For the search result, I am running my own queries and searching based on the user input.
The Search Form looks like this:
Search For <br>
<div id="search_filter_partial" class="panel_contents">
<%= form_tag(search_path,:remote=>true,:class=>"filter_form", :name=>"search_filters") do %>
<div class="filter_form_field filter_string">
<%= label_tag(:author, "Author",:class=>" label") %>
<%= text_field_tag (:author) %>
</div>
<div class="filter_form_field filter_select">
<%= label_tag(:book, "Book",:class=>" label") %>
<%= select("book","book_id", #books.map {|u| [u.name,u.id]}) %>
</div>
<div class="filter_form_field filter_string">
<%= label_tag(:published_date, "Published Date",:class=>"label")%>
<%= date_select :book,:published_date %>
</div>
<div class="buttons">
<%= submit_tag('Find It', :onclick => "validateForm();") %>
<a class="clear_filters_btn" href="#">Clear</a>
<input id="order" type="hidden" value="id_desc" name="order">
<input id="scope" type="hidden" name="scope">
</div>
<%end%></div>
Doesn't look too good, but that's the best I have been able to come up with since I want to stay consistent with the look and feel of Active Admin
I have my Ajax working, builtin Rails javascript, with the submit button. However, I would like it to submit when I change the value of the dropdown box and eliminate the button. In my research I found what looks like the correct solution but I get no request to the server. Here is my dropdown form code, note it still has the submit button that worked before I added :onchange:
<% form_tag('switch_car', :method => :put, :remote => true) do %>
<div class="field">
<label>Car Name:</label>
<%= select_tag(:id, options_from_collection_for_select(active_cars, "id", "name"),
:onchange => ("$('switch_car').submit()"))%><%= submit_tag "Switch Car" %>
</div>
<% end %>
Here is the HTML generated:
<form accept-charset="UTF-8" action="switch_car" data-remote="true" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="_method" type="hidden" value="put" />
<input name="authenticity_token" type="hidden" value="PEbdqAoiik37lcoP4+v+dakpYxdpMkSm7Ub8eZpdF9I=" />
</div>
<div class="field">
<label>Car Name:</label>
<select id="id" name="id" onchange="$('switch_car').submit()">
<option value="9">Truck</option>
<option value="10">Car</option>
</select>
<input name="commit" type="submit" value="Switch Car" />
</div>
Thanks in advance for any help.
Replace your onchange with this,
onchange: "this.form.submit();"
this.form.submit() will not work if form is remote: true and rails-ujs is in use. In that case, a regular submit will occur instead of XHR.
Instead you should:
onchange: 'Rails.fire(this.form, "submit")'
You can read here for more details.
This is what I was able to do to get it to work. I named the form switch_car by using :name => "switch_car" and used the following javascript.
:onchange => ("javascript: document.switch_car.submit();")
I am still looking for a better answer so I will updated if I find something. This doesn't use submit .js for some reason. It processes it as HTML unlike the submit button which uses AJAX to update only the changing page elements. But this is the best I have been able to find so far.
Depending on the js library you are using:
Prototype: :onchange => ("$('switch_car').submit()")
Jquery: :onchange => ("$('#switch_car').submit()")
If you are using the defaults and your rails version is below 3.1, then prototype is the default library.
This is an old question, but none of the above answers work for me. They all result in a text/html request.
The following works, e.g. (the hide class sets css display: none):
<%= form.radio_button :tier_id, tier.id, onchange: "$('#submit-button-id').click();" %>
together with:
<%= form.submit "Save changes", id: 'submit-button-id', class: 'hide' %>
A more general solution using jQuery (I don't need to know the name of the form) is:
onchange: "$(this).parent('form').submit();"
This seems to have been around for a while but, I'll post my findings anyway since I haven't found this explanation anywhere yet.
I came across this article which describes quite well what's the problem when triggering a ajax request via the submit() method (with or without jQuery or Handler). The author then recommends to form your own AJAX request. That is not required and shouldn't be done to make use of the logic within rails.js (jquery-jus gem).
Problems with triggering submit() manually occur since rails.js binds and listens to an event that is namespaced submit.rails. To manually trigger a submission use
onchange: 'javascript: $( this ).trigger("submit.rails")'
on the element or the form.
For a select_tag, just add:
{:onchange => "myHandler();" }
where your handler will be:
this.form.submit();
Also, if onchange doesn't work you might want to try onChage with a capital C.
Finally, make sure NOT TO CONFUSE a select_tag with a form select.
See my answer to a similar question, only regarding a form select
Adding An Onchange Event To A Form Select
Time at 2021, with Rails 6
make a hidden submit then use js click() function:
<%= form_with(modle: #user, local: false) do |f| %>
<%= f.select :menu1, ["option1","option2"], {}, onchange: "javascript:this.form.commit.click();" %>
<%= f.submit 'save', class: "hidden" %>
<% end>
reference: https://stackoverflow.com/a/8690633/15461540
If you want to learn rails way ajax submit on fields change here is the code.
<%= select_tag(:id, options_from_collection_for_select(active_cars, "id", "name"),
data: { remote: true, url: your_ajax_route_path }%><%= submit_tag "Switch Car" %>
data: { remote: true, url: your_ajax_route_path }
will automatically submit your input to your_ajax_route_path. If you are using a form builder then you should use with input_html
input_html: { data: { remote: true, url: your_ajax_route_path } }
like this. I hope it'll be useful for you
None of the solutions was working for me so I used the given below solution.
$("#q_dimension_id_eq").on("change", function (e) {
$(this).closest("form").submit();
});
I'm using rails 4.2.1 with jquery_ujs and it works for me:
onchange: 'jQuery(this).parent().trigger("submit")'
OBS.: It assumes the element is immediately child from form. You must adjust parent() according your DOM tree.
I see it being escaped, and in this case want to avoid that for a certain link. Or is the only way to build the link with HTML and ERB?
link_to("#{image_tag(#image.image.mini.url)} Next", #image.next_image, :class => "scroll next") if #image.next_image
EDIT: realising it may be my string-building that causes the problem, added my code to illustrate.
This?
= link_to #image.next_image do
<span> hey ya'll i'm some html! </span>
Use .html_safe.
link_to("#{image_tag(#image.image.mini.url)} Next".html_safe, #image.next_image, :class => "scroll next") if #image.next_image