Here’s some of my own checkbox implementation.
// Generate Form (used for submitting check-boxes)
jQuery(function($) { $.extend({
form: function(url, data, method) {
if (method == null) method = 'POST';
if (data == null) data = {};
var form = $('<form>').attr({
method: method,
action: url
}).css({
display: 'none'
});
var addData = function(name, data) {
if ($.isArray(data)) {
for (var i = 0; i < data.length; i++) {
var value = data[i];
addData(name + '[]', value);
}
} else if (typeof data === 'object') {
for (var key in data) {
if (data.hasOwnProperty(key)) {
addData(name + '[' + key + ']', data[key]);
}
}
} else if (data != null) {
form.append($('<input>').attr({
type: 'hidden',
name: String(name),
value: String(data)
}));
}
};
for (var key in data) {
if (data.hasOwnProperty(key)) {
addData(key, data[key]);
}
}
return form.appendTo('body');
}
}); });
// Filter Submissions
function filterCheckboxes(route, thing, cmd) {
var formSend = new Object;
formSend["utf8"] = "✓";
formSend["_method"] = "patch";
var csrfName = $("meta[name='csrf-param']").attr('content');
formSend[csrfName] = $("meta[name='csrf-token']").attr('content');
formSend[thing] = new Object;
formSend[thing]["command"] = cmd;
formSend[thing][thing + "_ids"] = $("." + thing + "-check:checked").map(
function () {
return this.value;
}
).get();
$.form(route, formSend, 'POST').submit();
}
// Will check all items that have the same class name as the link/button
function checkByClass(source) {
var aInputs = document.getElementsByTagName('input');
for (var i=0;i<aInputs.length;i++) {
if (aInputs[i] != source && aInputs[i].className == source.className) {
aInputs[i].checked = source.checked;
}
}
}
And in the view header
<div class="row filters">
<div class="form-inline">
<input type="checkbox" class='profile-check' onchange='checkByClass(this)' />
<%= content_tag 'span', 'delete', class: 'filter-delete', onclick: "filterCheckboxes('#{profile_ids_profiles_path}', 'profile','delete')", style: 'cursor:pointer;' %>
</div>
</div>
Above the first input is a checkbox at the top of the page that will select or unselect every checkbox that has the profile-check
class on it via the checkByClass
Javascript method I wrote. The line below that submits a list of all checkboxes selected to the profile route I have for handling multiple ids and depending on what the command is executes it for the current user.
And the individual checkbox item looks like
<%= hidden_field_tag "profile[profile_ids][]", '' %>
<%= check_box_tag "profile[profile_ids][]", profile.id, nil, class: "profile-check" %>
At the moment that controller only has delete as an option
def profile_ids
current_user.profiles.where(id: params["profile"]["profile_ids"]).destroy_all if params["profile"]["command"]["delete"]
redirect_to(profiles_path, notice: "#{params['profile']['command'].capitalize} completed.") and return unless params['profile']["command"].empty?
redirect_to profiels_path
end
The route is just
resources :profiles do
collection do
patch 'profile_ids'
end
end
You can use this example and just change both the Javascript .submit()
method to the rails UJS hook for submitting in rails and the controller to return a UJS response. The UJS hook for that can be done like: $('form#myForm').trigger('submit.rails');
- (source origin). Just use the CSS selector and jQuery trigger()
in the filterCheckboxes
Javascript. And you can add an onclick
action to each checkbox to run the UJS through filterCheckboxes
.