How to select multiple items to delete (via checkbox) in Rails 6 - ruby-on-rails

I created a column of checkboxes where in users can select multiple items to delete on a table. Something like this but only a button "Bulk Delete":
Here's my code:
<%= render "shared/nav_dashboard" %>
<%= render "shared/header_dashboard" %>
<section>
<div class="container-fluid">
<!-- Page Header-->
<header>
<h1 class="h3 display">Pages</h1>
</header>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>List of Pages</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th><%= link_to "Bulk Delete", page_path(page), method: :delete, data: { confirm: "Are you sure?" }%></th>
<th>Id</th>
<th>Title</th>
<th>Summary</th>
<th>Date Created</th>
<th colspan="3">Action</th>
</tr>
</thead>
<tbody>
<% #pages.each do |page| %>
<tr>
<td><input type="checkbox" value="false"> </td>
<td scope="row"><%= page.id %></td>
<td><%= page.title %></td>
<td><%= page.body.truncate(60) %></td>
<td> <%= page.created_at.strftime("%B %d, %Y") %> </td>
<td><%= link_to "Show", page_path(page)%></td>
<td><%= link_to "Edit", edit_page_path(page)%></td>
<td><%= link_to "Delete", page_path(page), method: :delete, data: { confirm: "Are you sure?" }%></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
<%= render "shared/footer_dashboard" %>
I am wondering why it did not work?
How can I do this functionality step by step?

You could to use a form. It'll look something like this (I'm using simpleform, but this will work for every your preferred form-tag helper):
In routes.rb:
resources :pages do
collection do
delete :bulk_destroy
end
end
In your view:
<%= simple_form_for :pages, url: "/pages/bulk_destroy", method: :delete do |f| %>
<ul>
<% #pages.each do |page| %>
<li> <%= page.name %> <input type="checkbox" name="collection_ids[]" value="<%= page.id %>" /> </li>
<% end %>
</ul>
<%= f.submit %>
<% end %>
In your controller:
class PagesController < ApplicationController
def bulk_destroy
Page.where(id: params[:collection_ids]).destroy_all
end
end
Heavy-lifting taken care for you: https://github.com/joshmn/active_action or check out the bare-minimum proof of concept at https://github.com/joshmn/bulk_actions_poc

if you don't prefer to write other separate method then you can try like below, you just need to be sure that when multiple ids are selected it should send as params[:ids] rather then params[:id]
def destroy
ids = params[:ids].present? ? params[:ids] : [parmas[:id]]
Pages.where(id: ids).destroy
end

you might need to change syntax based on you jquery version
$('#bulk_delete').on('click', function(e){
var selectedIds = [];
$("input[type='checkbox']:checked").each(function(e){
ids.push($(this).data('id'))
})
$.ajax({url: 'your action url',type: 'DELETE', data: {ids: selectedIds}})
})

Related

the Ransack gem does not find the result

I am using the Ransack gem, I have a patient model, I am following the documentation, and I cannot get it to work.
I have also seen many blogs about it but nothing is working for me. Hope someone can help me
I show the code of the view and the controller
my controller:
def index
#q = Patient.ransack(params[:q])
#Patients = #q.result(distinct: true)
#pagy, #patients = pagy(current_user.patients.order(apellido: :asc), items:20)
end
my view:
<%= search_form_for #q do |f| %>
<%= f.text_field :apellido_cont, class: 'form-control' %>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
<div class="row">
<div class="col-xl-3">
<h3>Mis pacientes</h3>
</div>
<div class="col-xl-6">
<div class="form-group has-search">
<span class="fa fa-search form-control-feedback"></span>
<input type="text" class="form-control" placeholder="Buscar">
</div>
</div>
<div class="col-xl-3">
<%= link_to new_patient_path, class:'nuevo' do %>
<i class="fas fa-plus"></i> NUEVO PACIENTE
<% end %>
</div>
</div>
<div class="alertas">
<% if flash[:notice] %>
<div class="alert alert-success" role="alert"><%= flash[:notice] %></div>
<% end %>
</div>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Nombre</th>
<th scope="col">Contacto</th>
<th scope="col">Edad</th>
</tr>
</thead>
<% if #patients.each do |patient| %>
<tbody>
<tr>
<td class="datos"><%= patient.apellido %> <%= patient.nombre %></td>
<td><i class="fas fa-mobile-alt"></i> <span><% if patient.telmovil.blank? %>No hay dato<% else %><%= patient.telmovil %><% end %></span></td>
<td><%= patient.age %></td>
<td><%= link_to patient_path(patient), class:'ver' do %>
<i class="far fa-eye"></i>
<% end %></td>
</tr>
<% end.empty? %>
<h5 class="titulo">No tienes ningun paciente.</h5>
<% end %>
</tbody>
</table>
<div class="paginacion mt-3">
<%== pagy_bootstrap_nav(#pagy) if #pagy.pages > 1 %>
</div>
</div>
so I'm happy I came across this post. I have been using kaminari for years and had no idea about pagy and now I'm excited to try it!
My experience is with kaminari, so I had to google usage with pagy. It looks like to me you need to pass the entire query to the pagy method.
ie:
#pagy, #patients = pagy(Patient.ransack(params[:q]).result(distinct: true))
Hopefully that works!

Rails search table clickable link

I have a keyword search page for which the results are presented in a table. One of the fields in this table is a url which I want to display as a clickable link when the field has one in it but I can't get this working, when the link is clicked it instead queries the search again. I think the problem is due to the def within the searches controller dealing with the keywordsearch view. Can anybody help?
Below is the keywordsearch view which contains the results table:
<!-- Index of all Courses -->
<% provide(:title, "Courses Page") %>
<!--Breadcrumbs -->
<br>
<%= link_to "Back", :back %><br><br>
<!--Page Contents -->
<div class ="row">
<h1>Degrees Offered</h1>
<%= image_tag "line.png" , :alt => "line break"%>
</div>
<div class ="row">
<!-- Form for Keyword Search, to query database for University courses. It is hidden so as to not appear as a search on the page -->
<div class = "hidden">
<%= form_tag(keywordsearch_path, :method => "get", id: "search-data") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search course" %>
<%= submit_tag "Search" %>
<% end %>
</div>
<% if #search_degree != nil %>
<% end %>
<% if #search_degree != nil %>
<table border="1" class="table">
<thead>
<tr>
<th>University Name</th>
<th>Course Name</th>
<th>Duration</th>
<th>Qualification</th>
<th>Entry Requirements</th>
<th>Course Page</th>
</tr>
</thead>
<tbody>
<% #search_degree.each do |degree| %>
<tr>
<td><%= degree.uname %></td>
<td><%= degree.cname %></td>
<td><%= degree.duration %></td>
<td><%= degree.qualification %></td>
<td><%= degree.entry %></td>
<td> <a href=<% degree.url %>>View course page on University Website</a></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
Below is portion of the search controller in which keyword search is defined:
def keywordsearch
#search = Degree.all.select(:uname, :cname, :ucas, :duration, :qualification, :entry).distinct.order(id: :ASC)
if params[:search]
#search_degree = Degree.search(params[:search]).order('uname ASC')
end
end
The link from all of this is clickable but rather than taking me to the correct url it redoes the search.
try this instead of hardcoding the <a> tag:
<%= link_to 'View course page on University Website', degree.url %>
Can you also post a sample of url? Be sure to include the protocol (e.g, http://...)

how to center all columns with bootstrap-sass relative to screen size

The entire Rails app can be viewed on GitHub
and the app is hosted on heroku
Update: I have roughly centered the columns (take a look at the link), but I would like to center them in relation to the Contacts title. Is this possible?
Edit: Bonus points: each contact has links to Show Edit and Destroy. These are currently sort of smooshed together as ShowEditDestroy, and I would love to know how to put some padding in between them so they don't look so smooshed.
I am trying to center all columns within my view. I have done this previously using zurb-foundation, but I am having trouble doing it with bootstrap-sass. Here is an example of a previous site that I have built with zurb-foundation, that I am trying to mimic using bootstrap-sass: my portfolio
I just want all the guts in my view to organize themselves neatly within columns in botstrap, but to stay centered relative to the middle of the page, while keeping text right centered at all time.
Here is my current index.html.erb view:
<div id="main-container" class="container" style="text-align: left">
<div class="row">
<p id="notice"><%= notice %></p>
<h1 class="text-center">Listing Contacts</h1>
<table>
<thead>
<tr>
<div id="content" class="col-xs-3">
<th>First name</th>
</div>
<div id="content" class="col-xs-4">
<th>Last name</th>
</div>
<div id="content" class="col-xs-5">
<th>Email address</th>
</div>
<div id="content" class="col-xs-6">
<th>Company Name</th>
</div>
<div id="content" class="col-xs-7">
<th>Phone Number</th>
</div>
<div id="content" class="col-xs-8">
<th colspan="3"></th>
</div>
</tr>
</thead>
<tbody>
<% #contacts.each do |contact| %>
<tr>
<td><%= contact.first_name %></td>
<td><%= contact.last_name %></td>
<td><%= contact.email_address %></td>
<td><%= contact.company_name %></td>
<td><%= contact.phone_number %></td>
<td><%= link_to 'Show', contact %></td>
<td><%= link_to 'Edit', edit_contact_path(contact) %></td>
<td><%= link_to 'Destroy', contact, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Contact', new_contact_path %>
<h2>Import Contacts</h2>
<%= form_tag import_contacts_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
</div>
</div>
</div>
As you can see, i'm just building an online contact list, by following railscast 396. I just want to make everything purdy.
Bootstrap-sass does have a few mixins that you can use, one of these is a centered block. You can use it like this (once you have boostrap-sass up and running)
#import "bootstrap";
.centered {
#include center-block();
}

Undefined method `javascript_link_tag'

Im sure this is simple to fix but i've been on the problem for 2 hours now.
All im trying to do is load my User Index View which has a boostrap table. In the view i have it loading some JS files.
When i try to try to access it through my broswer i receive this error.
Anyone have any clues how to fix it and have the JS files load?
undefined method `javascript_link_tag'
Here is my User Index View
<%= javascript_link_tag 'dataTables.bootstrap.js' %>
<%= javascript_link_tag 'jquery.dataTables.min.js' %>
<%= javascript_link_tag 'jquery-1.11.1.min.js' %>
<div class="page-header">
<h1><%= #user.username %> <small>Edit Items</small></h1>
</div>
<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Image</th>
<th>Title</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% #item.each do |item| %>
<tr>
<td><div class ="small_fifty_image"><%= image_tag item.image.url(:thumb) %></div></td>
<td><h4><%= link_to item.title, item_url(item.id) %></h4></td>
<td>$<%=item.price %></td>
<td>
<button type="button" class="btn btn-default btn-sm"><%= link_to "Edit Items", edit_item_path(item) %></button>
<button type="button" class="btn btn-default btn-sm"><%= link_to "Delete", item, method: :delete, data: { confirm: "You sure?" } %></button>
</td>
</tr>
<% end %>
</tbody>
</table>
There are no such method javascript_link_tag. According to the documentation you should use javascript_include_tag. This method allow you to generate link tag for the individual scripts in your assets path as well.
Also, please note that files provided by gems usually don't include version in the file name and they aren't minimized.
Add in application.html.erb:
<%= javascript_include_tag "application" %>
<%= yield :javascript_includes %>
In top of your View.html.erb:
<% content_for :javascript_includes do %>
<%= javascript_include_tag "dataTables.bootstrap.js" %>
<%= javascript_include_tag "jquery.dataTables.min.js" %>
<%= javascript_include_tag "jquery-1.11.1.min.js" %>
<% end %>
Everything in the content_for block will be loaded at yield :javascript_includes.
try
<%= javascript_include_tag 'dataTables.bootstrap.js' %>
<%= javascript_include_tag 'jquery.dataTables.min.js' %>
<%= javascript_include_tag 'jquery-1.11.1.min.js' %>
instead.

Using partials, how do I render `striped` table rows in a DRY way?

So I have some view code that looks like this:
<div class="box-content">
<table class="table table-properties">
<tbody>
<%= render :partial => 'property', collection: #search.listings, as: :listing %>
</tbody>
</table>
</div>
In that _property.html.erb, I have this:
<tr>
<td class="span2">
<%= link_to listing_path(listing), :class => "thumbnail thumb2" do %>
<%= image_tag "room_1.jpg", :alt => "Lucas" %>
<% end %>
</td>
<td>
<h2><%= link_to listing.headline, listing_path(listing) %></h2>
<h5><%= listing.listing_type.name if listing.listing_type "#{listing.neighborhood.name.capitalize}" %></h5>
<h5>Maintenance <%= number_to_currency(listing.maintenance) %></h5>
</td>
<td class="span1">
<h2 class="price"><%= number_to_currency(listing.price)%></h2>
<h5><%= "#{listing.num_bedrooms} bed, #{listing.num_bathrooms} bath" %></h5>
</td>
</tr>
Basically, I want to generate that above code exactly, for each row, the only difference is I want every 2nd row (i.e. all even numbered rows) to have the class=striped..i.e. <tr class=striped>.
Thoughts on how to do this in a DRY way?
Have you tried using cycle and current_cycle ?
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-cycle
<tr class="<%= cycle('odd', 'even') -%>">
<!-- etc -->
</tr>
This alternates your classes with odd and even and IMHO should also work when render a collection. If you need the value of the actual cycle multiple times, you get it with current_cycle (because calling cycle multiple times would mess up your cycles, unless you want that).
Won't it be better just to use :nth-child() css selector? http://www.w3schools.com/cssref/sel_nth-child.asp
You can try something like this:
<tr class="<%=cycle("odd", "even") %>">
<td class="span2">
<%= link_to listing_path(listing), :class => "thumbnail thumb2" do %>
<%= image_tag "room_1.jpg", :alt => "Lucas" %>
<% end %>
</td>
<td>
<h2><%= link_to listing.headline, listing_path(listing) %></h2>
<h5><%= listing.listing_type.name if listing.listing_type "#{listing.neighborhood.name.capitalize}" %></h5>
<h5>Maintenance <%= number_to_currency(listing.maintenance) %></h5>
</td>
<td class="span1">
<h2 class="price"><%= number_to_currency(listing.price)%></h2>
<h5><%= "#{listing.num_bedrooms} bed, #{listing.num_bathrooms} bath" %></h5>
</td>
</tr>
Do it with jquery:
$(document).ready(function(){
$("table.table-properties > tbody > tr:odd").addClass("odd");
$("table.table-properties > tbody > tr:not(.odd)").addClass("even");
});

Resources