Rails ActiveAdmin offers native selectable_column element for batch action, and I found a plugin gem 'active_admin_scoped_collection_actions'
Both are excellent options for the INDEX page, but can I bring that functionality to the Show/View page, or a nested table_for on a tab?
Here's how I'm surfacing a child table as a grid:
forfeitures = ref_bond.forfeitures
renderer_forves = ActiveAdminExtensions::Renderer.new(resource: forfeitures, row: ->(field) { column field })
render_field_forves = ->(field) {
}
tab "Forfeitures" do
button :class => "btn_new_panel" do
link_to("New Forfeiture", new_admin_forf_path(bond_no: ref_bond.BONDNO, typ_inst: ref_bond.TYP_INST))
end
table_for forfeitures, class: "index_table" do
Forves.columns.each &render_field_forves
column :actions do |r|
text_node link_to "View", [:admin, r]
text_node " "
text_node link_to "Edit", [:edit, :admin, r]
end
end
end
So how can I get those Batch Actions here?
Related
I have this code that creates a table on the activeadmin Dashboard:
columns do
column do
panel "New Mentor's requests" do
table_for User.where(mentor_request: true) do |t|
t.column("Id") { |user| user.id }
t.column("Name") { |user| user.account.full_name }
t.column("Email") { |user| user.account.email }
t.column("Organization") { |user| user.organization.name }
end
end
end
end
Is there a way to add "actions" like on the rest of the resources? I mean like "new, edit, delete", but a custom one.
I tried putting the "actions" tag, but I get an undefined method.
table_for is used to render a collection of objects which may not necessarily be ActiveRecord objects, so the action methods aren't available like they are in an index action. However, you should be able to render your own actions with something like this:
column("View User") { |user| link_to "View", user_path(user) }
EDIT For multiple links you can wrap the link_tos use Arbre's span tag:
column("View User") do |user|
span link_to "View", "/mypath"
span link_to "Edit", "/mypath"
span link_to "Delete", "/mypath"
end
I'm using ActiveAdmin 1.0.0.pre2 w/ arbre 1.0.2, I haven't tried it on earlier versions.
You can also try this:
ActiveAdmin.register Foo do
actions :all
index do
column :name
actions defaults: true do |foo|
link_to "Custom ACTION", custom_action_path(foo.id)
end
end
end
It worked for me to have more options than the already defined ones: View, Edit, Delete
Source: https://github.com/activeadmin/activeadmin/issues/53
I am looking for some pointers on getting started with this feature; I would like a user to be able to preview what their post would look like if saved
ActiveAdmin.register Post do
permit_params :comments, :title, :category_id, :slug, :published
# Create Blog Post
form do |f|
inputs 'Blog' do
f.semantic_errors
f.input :title
f.input :category_id, as: :select, collection: Category.all
f.input :comments, as: :text, input_html: { rows: 10, cols: 10 }
f.input :published, as: :boolean
end
inputs 'Submit' do
f.actions
end
end
end
So looking at the active admin documentation I can see you can add custom action items
action_item :preview, only: :new, name: 'preview_button' do
# do stuff here
end
I can also add a custom controller action in the form of a collection_action which will also add a route for me
collection_action :preview, method: :post do
#post = Post.new(params[:post])
end
So now I have a custom action preview and a button that can pass data to the method (I have hard coded it for now, as unsure how to get the data from outside the form).
This is what I have so far:
action_item :preview, only: :new, name: 'preview_button' do
link_to 'Preview', preview_my_admin_panel_posts_path(post: { title: 'Test Title', comments: 'test comments', category_id: '1' })
end
# Add controller action
collection_action :preview, method: :get do
#post = Post.new(params[:post_params])
end
My view gets rendered but nothing gets outputted, how do I then show the data?
Is this the correct approach?
Update
Can now show the hardcoded data with
collection_action :preview, method: :get do
#post = Post.new(permitted_params[:post])
end
The difference being in the active admin docs
The permit_params call creates a method called permitted_params. You should use this method when overriding create or update actions:
Now I just need to grab the form data outside the form and pass it through my link_to and then be able to keep the form populated with the same data if I go back to the form.
Ideally I would like to have the preview button within the f.actions as then I would have access to the #post object.
I want to add three fields that will be used as counters to the top of the screen on my app. The following code does actually work, HOWEVER, if you put the page in edit mode and then click the "Save" button, the three counter fields disappear and stay that way until you refresh the browser. I am a Haml newbie, and there isn't much documentation out there, and what little there is did not help me.
Here is the relevant Haml code to render the page in question:
- form_for [#application, #item_collection], :html => { 'data-remote' => 'json', :id => 'edit_item_collection', :class => 'show_progress inline_edit' } do |f|
= render 'edit_fields', :f => f
.submit.editing_only
%button.default_action{ :type => 'submit',:id => 'Save'} Save`
And here is the Haml code for the actual page:
.field.large
= f.label :name, nil, 'data-help-id' => 'page_name'
= f.text_field :name, disabled_if_unauthorized(#item_collection, :maxlength => 255, :title => "Edit Page")
= f.error_message_on(:name, :css_class => 'error_message')
.field
= f.label :path, nil, 'data-help-id' => 'page_path'
= f.text_field :path, disabled_if_unauthorized(#item_collection, { :maxlength => 255, :class => 'extra_margin', :title => "Edit Page" })
= f.error_message_on(:path, :css_class => 'error_message')
.field.info
= f.label 'Info'
%ul.elements_count
%li.elements_in_use{ :id => 'elements_in_use' }
%li.unused_elements{ :id => 'unused_elements'}
%li.undefined_elements{ :id => 'undefined_elements'}
When I click "Save," the elements_count unordered list disappears (but reappears if I refresh the browser). I know that the problem is that I need to put "= f." in front of these elements, but I don't see how to do that for lists.
Here is my JavaScript for populating the li elements:
function getElementCount() {
var usage_element_total = $('.usage').size();
var unused_element_total = $('.unused').size();
var undefined_element_total = $('.undefined').size();
$('#elements_in_use').html(usage_element_total + " Elements in use,");
if (unused_element_total < 1) {
$('#unused_elements').html(" 0 unused Elements,");
} else {
$('#unused_elements').html((unused_element_total-1) + " unused Elements,");
}
$('#undefined_elements').html(undefined_element_total + " undefined Elements");
}
Any help would be vastly appreciated. Thanks!
You need to trigger the Javascript that populates the element counts whenever the form is updated. Presumably you’re calling getElementCount when the page loads, you could trigger it when the form is rendered:
$("form").bind("ajax:complete", getElementCount);
But I’m guessing a bit as to how things are wired together and maybe that won’t work for your situation.
I have dropdown list using select_tag and I have button near it.
I have following requirements:
1) on click of submit button it should go to books#show action
2) Then in show action I retrieve the selected book from dropdown list
3) The show method should show details of book that I would retrieve from database
i.e,the same page should update with this book details.
However,I am unable to perform none of this.
In my view:
<%= form_tag books_path do |f|%>
<%= label_tag "select book" %>
<%= select_tag "selectbook", options_from_collection_for_select(#bid,"book_id","book_id"), :prompt => "Select book",:class => 'cmbbook' %>
<%= submit_tag "view ...", :disable_with => "Please wait." ,:action => "show"%>
<%end%>
In my controller
if(params[:selectbook])
#books = Book.where("book_id = ?",params[:selectbook])
else
#books = Book.all
end
#bid= Books.select("book_id").uniq;
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #books }
format.json { render json: #books }
end
The submit method calling action create instead of show and I also wish the page autoupdate with new book data.
First of all, you should specify controller and action for the form, like this
form_tag( {:controller => 'your_controller', :action => "show"} )
For autoupdating page you should read rails doc
I have found what to do:
I have to write a method in javascript that calls getJson() method to appropriate controller and action and again update view using javascript.Thus,using ajax javascript problem is solved.However,I wish I can do same with pure ruby code.
I've got a nested model called categories and I have created a nested form to allow creation of a category and sub categories in one form.
This works fine if you pre-build the children in your new method like so:
class CategoriesController < InheritedResources::Base
def new
#category = Category.new
#category.children.build
end
end
The problem starts to happen when you want to dynamically add new children in the form using AJAX.
Here is my form:
%table
= form_for #category do |f|
%tr
%td= f.label :name
%td= f.text_field :name
%tr
%td(colspan=2)
%b Sub categories
- #category.children.each do |sub|
= f.fields_for :children, sub do |child|
= render "child_fields", :f => child
%tr
%td= link_to_add_fields "Add sub category", f, :children
%tr
%td= f.submit 'Save'
Here is my helper method for link_to_add_fields (as per Ryans Railscast):
module ApplicationHelper
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(:partial => association.to_s.singularize + "_fields", :locals => { :f => builder})
end
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
end
end
And here is the Javascript which over
function add_fields(link, association, content) {
// Generate new unique index, so base this off the current time.
var new_id = new Date().getTime();
var regexp = new RegExp("new_" + association, "g")
// Replace new_association with the current time.
$(link).closest("tr").before(content.replace(regexp, new_id));
}
I noticed that on the pre-built children the rendered output is like this:
<input type="text" size="30" name="category[children_attributes][0][name]" id="category_children_attributes_0_name">
Where as the AJAX generated fields are:
<input type="text" size="30" name="category[children_attributes][1308801890744][name]" id="category_children_attributes_1308801890744_name">
This looks correct but when I go to click create only the pre-built children are saved.
Update1
If I put a debugger line in my def create and type params I only see my pre-built category not the extra one I dynamically added.
(rdb:4) params
{"utf8"=>"✓", "authenticity_token"=>"iwq1Vx3jOZZsjd79Nj+qKNXxOwWP40c8XDFS8ooGMdg=", "category"=>{"name"=>"1", "children_attributes"=>{"0"=>{"name"=>"2"}}}, "commit"=>"Save", "action"=>"create", "controller"=>"categories"}
This is a result of browsers (at least Firefox) behaving weirdly when a form is inside of a table. The easiest/quickest fix is to put the table inside the form. It's a one-line change to your views/categories/new.haml file:
= form_for #category do |f|
%table
%tr
How I debugged it, in case it helps:
I first checked request.raw_post; the parameters weren't there which meant rails was never even seeing the correct request. That pointed to a browser rendering issue.
I was able to debug the issue via firebug by noticing that the form closed out awkwardly when rendering your original haml. Moving the form out of the table seemed to fix it in firefox.
I'd suggest sticking to divs, mainly because it avoids a lot of weird browser issues.