Split Index Results Over Several Pages - javascript

I'd like to generate a list of all the characters in my Character table, but split them so that the page isn't extremely long. I'd like for the default to be 15 characters, then you'll be presented with a "Next" button, to view the next 15 results. Is this possible to do in rails?
Here is a copy of my index.html.erb (I've taken out all the .CSS information):
<table class="table">
<tr>
<th><strong>Name</strong></th>
<th><strong>Race</strong></th>
<th><strong>Class</strong></th>
<th><strong>Alignment</strong></th>
</tr>
<% #characters.each do |character| %>
<% if character.user_id == current_user.id %>
<tr onclick="location.href= '<%= character_path(id: "#{character.id}") %>'">
<td><%= character.name%></td>
<td><%= character.race %></td>
<td><%= character.class_ %></td>
<td><%= character.alignment %></td>
</tr>
<% else %>
<tr>
<td><%= character.name%></td>
<td><%= character.race %></td>
<td><%= character.class_ %></td>
<td><%= character.alignment %></td>
</tr>
<% end %>
<% end %>
</table>
If need be, I am open to using JavaScript or Jquery to get this done.

What you're describing is called pagination. There are many ways to do it, but the kaminari gem is the most popular. Here's a guide to using it in your Rails app: http://railscasts.com/episodes/254-pagination-with-kaminari
In short, your controller should be responsible for setting #characters to only the particular page you want to return (with Kaminari, that's #characters = Character.page(params[:page].to_i)). Then, provide links on your view to go to the previous and next pages (making sure to handle the first and last page properly).

Related

Rails 4: dynamically added checkboxes are not submitting

I started to learn Rails and try to apply AJAX with some records that are added dynamically in a listing. Then I want to delete multiple records that are selected via checkboxes directly in the listing.
It works fine but not when I create a new Record and want to delete it without refreshing the page. The header's response is : "ActiveRecord::RecordNotFound in AccountsController#destroym". It acts as if I click the button without checking my checkboxes.
Thanks for your help :)
accounts_controller.rb
def destroym
Account.destroy(params[:delete])
respond_to do |format|
format.html {redirect_to accounts_path}
format.js #render accounts/destroym.js.erb
end
end
_row.html.erb
<% #data = Account.find(id) %>
<tr id='tr<%= #data.id %>'>
<td><%= #data.id %></td>
<td><%= #data.login %></td>
<td><%= check_box_tag 'delete[]', #data.id %></td>
</tr>
index.html.erb
<table class="table table-striped table-hover " id="accountsListing">
<%= form_tag destroym_accounts_path, method: :DELETE, remote: true, id: "deleteForm" do %>
<thead>
<tr>
<th>#</th>
<th>Username</th>
<th>Password</th>
<th>Website</th>
<th>Date</th>
<th>Editer</th>
<th><%= submit_tag "delete" %>
<%= link_to "Delete", '', :onclick => "$('#deleteForm').submit()", id: "removePwd", class: "text-danger", remote: true, method: :DELETE %> </th>
</tr>
</thead>
<tbody>
<% #accounts.each do |account| %>
<%= render 'row', id: account.id %>
<% end %>
</tbody>
<% end %>
</table>
destroym.js.erb
$("#accountsListing input:checked").closest("tr").remove();
create.js.erb
$("#accountsListing tr:first").after("<%= escape_javascript (render 'row', id:#account.id) %>");
The problem in this case is that you're replacing your whole page's HTML... So, all the DOM events bound to your elements are also destroyed.
When you replace your html (the .js.erb file), Rails will provide some special attributes to your elements (Rails calls that "unobstrusive JavaScript", because there's no JS code directly in your elements).
The issue here, of course, is that the JS code that Rails uses (see my link) are only applied when the page launches.
You have several choices:
1) your destroy.js.erb can only remove the exact row you just deleted (instead of replacing all the rows).
2) you can call rails-ujs' code by yourself. This is a hack and should not seriously be considered.
3) you can reload the page "automatically" (you lose the benefit of AJaX).
4) you can write your own JS code to send the AJaX request.
My solution to handle checkboxes created dynamically. The on function is mandatory if you want to handle events on elements added dynamically.
JS code
$("#deleteBtn").on("click", function() {
var ids = [];
$('#accountsListing :checkbox:checked').each(function(){
ids.push($(this).val());
});
$.ajax({
url: '/accounts/destroym',
type: 'POST',
data: {
"_method":"DELETE",
"authenticity_token": window._token,
"delete[]": ids
},
});
});

How to asynchronously send JS variable to Rails

Simple HTML form in a view. I need the user selected value of the form to pass into the active record query when the user switches it. (Probably not params because then it won't be asynchronous?)
In the example below I need the business_id to be the value of the form. New to rails, so if you could provide some in page javascript, I'll deal with refactoring it to the resources later...
<select name="clients">
<option value="1">Tesla</option>
<option value="4">Chevy</option>
</select>
<table>
<% #clients.where(month_year:'2015-02',business_id:'NEED VALUE OF HTML FORM HERE').find_each do |client| %>
<tr>
<td><%= client.month_year %></td>
<td><%= client.business_id %></td>
<td><%= client.bill_charge %></td>
</tr>
<% end %>
</table>
To expound on other answers, here's a (perhaps) overly simplified mock up.
Client view
Here you need to call render that points to a partial. This partial will contain the table data (so it's resuable later). You also need to give your select statement a class that jquery can easily grab to do the async fetch of your client data.
# app/views/clients/index.html.erb
<%= select_tag "business", options_from_collection_for_select(Business.all, "id", "name"), class: "car-select" %>
<div class="clients-table">
<%= render "table_list" %>
</div>
Table Partial
With the table you just cut out of the index view, you'll need to paste into a partial
# app/views/clients/_table_list.html.erb
<table>
<thead>
<tr>
<th>Month year</th>
<th>Business</th>
<th>Bill charge</th>
</tr>
</thead>
<tbody>
<% #clients.each do |client| %>
<tr>
<td><%= client.month_year %></td>
<td><%= client.business.try(:name) %></td>
<td><%= client.bill_charge %></td>
</tr>
<% end %>
</tbody>
</table>
AJAX script
This need to watch for changes to the select and submit a request for client data
# app/assets/javascripts/clients.coffee
ready = ->
$('.car-select').on 'change', ->
bid = $(this).val()
$.ajax
url: '/businesses/' + bid
dataType: 'script'
return
return
$(document).ready(ready)
$(document).on('page:load', ready)
# this is turbolinks-friendly
Businesses Controller processes request
In your ajax request you are calling to a URL like, "http://yourapp.com/businesses/23", which really hits the show action of your businesses controller. You want to do it this way because it's completely RESTful and you don't have to change any routes. But you will need to edit the action to provide an instance variable for clients.
# app/controllers/businesses_controller.rb
def show
#business = Business.find(params[:id])
#clients = #business.clients (this assumes that you already have a proper has_many / belongs_to relationship between business and client)
respond_to do |format|
format.html
format.js
end
end
UJS View
The last piece of the puzzle is the UJS view. This is javascript that is only called when the js request type is sent to a particular controller action. In this case, the show action of the businesses controller. This is going to take the newly created #clients and replace the existing table with the partial and new data.
#app/views/businesses/show.js.erb
$(".clients-table").html("<%= escape_javascript(render( '/clients/table_list', client: #clients)) %>");
If you still have questions, or want to do more complicated things, you should go research a little on UJS templates and callbacks.
put your result table into a partial.
fire a ajax request on the on change event of the select
render the table based on the value of the select which you pass as request variable (`#clients')

Call javascript function inside erb tag

I'm trying to add rows to a table as shown in the below code snippet from my view.html.erb file:
<% #res.each do |r| %>
<tr>
<td class="alt" id="resName"><%= r.name %></td>
<td class="norm" id="startDate"><%= r.startDate %></td>
<td class="norm" id="endDate" ><%= r.endDate %></td>
</tr>
<% end %>
The problem that I am encountering is that the startDate and endDate values are being displayed with the format: Thu May 01 2014 08:00:00 GMT-0400 (EDT) where I want to display them with the format 05/01/2014.
I have a javascript function, formatDate, which will make the formatting change, but I can't figure out a way to call it from within the erb tags.
I've tried a few things, but can't seem to get it to work. Is it not possible, or am I just doing something wrong? Can anyone offer any help/advice? Thank you in advance!
<td><%= r.startDate.strftime("%-m/%-d/%Y)" %></td>
I prefer very light views; I'd use a decorator:
<td><%= r.start_date_formatter %></td>
Or at least a helper:
<td><%= view_date(r.start_date) %></td>
(Unrelated markup elided for clarity; consider doing the same in future questions. If it's not directly related to the question, it's just noise :)

Static HTML, want to use ruby on rails

I have an app that hosts a static HTML webpage with text and some images. I want to use ruby on rails to learn about it more.
I have a simple ror app. I went to app/views/home.html.erb, and pasted the HTML I have there. This is not the best approach.
Is there a better approach to port this Static HTML to ror?
Where do javascript files go in ror?
You should checkout high_voltage, which is a gem for static pages.
1) You have helpers in RoR ERB to help you with HTML, especially if you connect to a DB, for example from their help:
<table>
<tr>
<th>Title</th>
<th>Summary</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #books.each do |book| %>
<tr>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to "Show", book %></td>
<td><%= link_to "Edit", edit_book_path(book) %></td>
<td><%= link_to "Remove", book, method: :delete, data: { confirm: "Are you sure?" } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to "New book", new_book_path %>
Everything between <%= .... %> are RoR helpers, so it's really up to your application if RoR will help you with your static HTML or not (maybe since you say it's static, i.e. not dynamic at all, the best approach would just be to leave it as is.
2) Javascript files are placed under app/assets, and you should definitely read about the asset pipeline

How to replace an empty selector inside the underscorejs template

I have 2 backbone nested views that render a table of products for a shopping cart.
Every view has its own underscore template. When the cart is empty only the main view will render replacing the empty div with: "cart is empty". Unfortunately the following solution didn't work:
<div class="container">
<div class="twelve columns">
<table class="standard-table">
<thead>
<tr>
<th>Remove</th>
<th>Product code</th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody class="cart-table-body">
<% if (typeof(product_id)=="undefined") { %>
<tr>
<td>cart is empty</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
The nested template
<td><i class="icon-remove-sign"></i></td>
<td><%= product_id %></td>
<td><%= product_name %></td>
<td><%= price %></td>
<td><%= quantity %></td>
<td><%= price*quantity %></td>
I think, you never pass product_id into the first template, meaning it always shows cart is empty. You should pass there some flag variable like products_length or empty_cart so the template could check if cart is empty.
Also with this approach you need a way to check whether you add first product and in that case replace existing innards of cart-table-body (cart is empty message) with a first added product view element. Then append views of following elements.

Categories