trestle
trestle copied to clipboard
Any plans for batch editing?
Apologies if this is the wrong place, but we've actually been looking to either change off our backend framework or create our own. One of the key features we need is the ability to mass-select and edit all items to set multiple many-to-many associations.
Would this feature be something planned or that would fit in this framework?
Batch actions, both built-in (i.e. delete) and custom, are definitely on the roadmap, and probably fairly close to the top of the list. There's actually a small part of it already implemented (the selectable column -- not quite enough to be useful) but something had to give in order to put out an initial release.
I'll keep this issue open for any additional comments and requests in relation to this feature.
@spohlenz Awesome. I'll keep an eye out for developments. Looking good so far.
A few years late, but:
add app/views/trestle/resource/_scopes.html.erb
:
<%= content_tag(:dl, class: admin.scopes.classes) do %>
<div class="d-flex">
<div class="mr-1">
<a class="scope dropdown-toggle <%= 'disabled' unless admin.batch_actions.any? %>" type="button" id="batchActionsDropdown" data-toggle="dropdown" aria-expanded="false">
Batch actions
</a>
<div class="dropdown-menu" aria-labelledby="batchActionsDropdown">
<% admin.batch_actions.each do |_, action| %>
<%= button_to action.label, admin.path("batch_#{action.name}"), form_class: "batch-action-form ", remote: true, data: {method: :post, confirm: "Are you sure?" }, class: "dropdown-item" %>
<% end %>
</div>
</div>
<% admin.scopes.grouped.each do |group, scopes| %>
<%= content_tag(:dt, group, class: ["scope-group", ("scope-group-empty" if group.blank?)]) if admin.scopes.grouped? %>
<dd>
<ul class="scope-list">
<% scopes.each do |scope| %>
<li>
<%= link_to persistent_params.merge(scope: (scope unless scope.active?(params))), class: ["scope", ("active" if scope.active?(params))] do %>
<strong><%= scope.label %></strong>
(<%= number_with_delimiter(scope.count(admin.collection(params))) %>)
<% end %>
</li>
<% end %>
</ul>
</dd>
<% end %>
</div>
<% end %>
mod trestle a bit:
class Trestle::Admin
class << self
def batch_actions
@batch_actions ||= {}
end
end
end
class Trestle::Resource::Builder
class BatchAction
attr_reader :name, :options, :block
def initialize(name, options = {}, &block)
@name = name
@options = options
@block = block
end
def label
@options[:label] || "#{@name}"
end
end
def batch_action(name, options = {}, &block)
admin.batch_actions[name] = BatchAction.new(name, options, &block)
controller do
define_method "batch_#{name}" do
instance_exec &block
end
end
routes do
post "batch_#{name}", on: :collection
end
end
end
some custom js which i'm not proud of:
$("form.batch-action-form").each(function(i, form) {
form.addEventListener('submit', function (e) {
const idElements = $('input[name="selected[]"]:checked');
$(form).find('input[name="ids[]"]').remove()
idElements.each(function(_, el) {
$(form).append(`<input type="hidden" name="ids[]" value="${el.value}" />`)
})
return true;
})
})
and in your admin file:
Trestle.resource(:appointments, model: Appointment) do
batch_action :destroy, label: "Destroy selected?" do
appointments = Appointment.where(id: params[:ids])
appointments.destroy_all
flash[:message] = "Destroyed!"
redirect_to admin.path(:index)
end
end