Ok, pretty simple question, I have working an AJAX method, what it does is that it searches in the database for specific information with a query. I can see in the Console that the query is being made, I can even see the "Post" in the Chrome Developer Console, when I click it I can see the HTML that I want to show, but i have no effing idea on how to render ir in the page.
the :3000/ already has the html I want to show, but how do I update it??
The way I am showing it is this...
<%if not #itemsok.nil?
#itemsok.each do |searches|
%>
<table>
<tr>
<td style="width:100px;"><%= searches.first_item.description %> </td>
<td style="width:150px; font-size:30px;"><%= searches.first_item_grade %> </td>
<td style="width:150px;"><%= searches.second_item.description %> </td>
<td style="width:150px; font-size:30px;"><%= searches.second_item_grade %> </td>
<td style="width:150px; font-size:18px;">Show </td>
</tr>
</table>
#itemsok is the variable where I save the items from the query.
Thanks, I think I'm missing something very silly here.
Sorry for my terrible english.
UPDATE: The controller looks like this:
def index
size1 = params[:size1]
number1 = params[:number1]
number2 = params[:number2]
quiero = params[:quiero]
tengo = params[:tengo]
if (not number1.nil?) and (number1 != "")
item1 = Item.find(number1)
elsif not quiero.nil?
quiero.strip!
item1 = Item.find(:first, :conditions => ['lower(description) LIKE ?', "%#{quiero.downcase}%"])
end
if (not number2.nil?) and (number2 != "")
item2 = Item.find(number2)
elsif not tengo.nil?
tengo.strip!
item2 = Item.find(:first, :conditions => ['lower(description) LIKE ?', "%#{tengo.downcase}%"])
end
if (item1 and item2)
#itemsok = Contribution.where("first_item_id = ?",item1.id).where("second_item_id = ?",item2.id).where("second_item_grade = ?",size1)
respond_to do |format|
format.html
format.js
end
end
In your respond_to block put format.js above format.html.
Make sure you have index.js.erb in your view folder for the controller.
This index.js.erb(comes from the action name) should have a jQuery statement like the following if you're using rails 3.1+:
$('#DOMelementToPlaceContent').html(<%= escape_javascript(render :partial => "partial/location") %>);
This will replace the content of the DOM element with ID DOMelementToPlaceContent with the content in the specified partial.
Also, you should think about moving the logic for your search to a search action in the same controller in which case you'll need a search.js.erb file in the view folder for the controller.
Related
I'm putting together a combo box or called the same as a select in rails, I put everything together but it gives me an error that tells me that I have a problem with the map inside the select, I'm using simple_form_for and I'm doing a map inside the collection inside the selector or called in simple_for associatio.
I copy the view and the controller
This view
<h1>HistContact#index</h1>
<p>Find me in app/views/hist_contact/index.html.erb</p>
<%= simple_form_for #histcontact, url:hist_contact_index_path do |f| %>
<% f.association :contact, collection: #contacts.map{|cont| [cont.name , cont.id]}%>
<%f.submit "buscar"%>
<% end %>
<table id = "client_table" class="table table-striped table-sm">
<thead>
<tr>
<th>Id</th>
<th>fecha</th
</tr>
</thead>
<tbody>
<% #histcontacts.each do |c|%>
<tr>
<td> <%= c.id %> </td>
<td> <%= c.created_at %></td>
</tr>
<% end %>
</tbody>
</table>
the controller
class HistContactController < ApplicationController
before_action :authenticate_user!
def index
#histcontacts = HistContact.all
#contacts = Contact.all
end
def new
#histcontact = HistContact.new
#contacts = Contact.new
end
def create
#histcontact = HistContact.find(contact_id: params[:contact])
end
private
def contactID(current_user)
client_id = Client.where(user_id: current_user.id)
contact_id = Contact.where(client_id: client_id.ids[0])
return contact_id
end
end
Thank you
According to error, you are trying to map a single object instead of an array of objects. Based on your controller code, the view file you shared is probably new.html.erb. To solve this problem you need do it like this:
def new
#histcontact = HistContact.new
#contacts = Contact.all
end
I have a task in my Rails app that can update a gallery album. This is passed an id that corresponds with an album on my Flickr account, it deletes all the photos attached to the album locally in the app and pulls them afresh from Flickr and updates the album name and title if required. This is required because I am currently working my way through all my photos re-tagging them all and this task will help pull those tags from Flickr to my site for searching and linking purposes.
I built an admin page that lists all my albums and each has an "Update Album" button. That looks like:
gallery.html.erb
<table class="striped">
<tr>
<th>Collections</th>
<th>Albums</th>
<th>Photo count</th>
<th>Flickr ID</th>
<th>Options</th>
</tr>
<% #collections.each do |c| %>
<tr>
<td><%= c.title %></td>
<td></td>
<td></td>
<td><%= c.flickr_id %></td>
<td></td>
</tr>
<% if c.has_albums? %>
<% c.albums.each do |a| %>
<tr class="<%= a.title.parameterize %>">
<td>↳</td>
<td>
<%= a.title %>
</td>
<td>
<%= a.photos.count %>
</td>
<td>
<%= a.flickr_id %>
</td>
<td class="this-one">
<%= link_to "Update",
admin_update_album_path(
album_flickr_id:a.flickr_id,
row: a.title.parameterize
),
"am-button": '',
method: :post,
remote: true
%>
</td>
</tr>
<% end %>
<% end %>
<% end %>
</table>
Because the task of updating took a while I thought putting it as a background job would be a good idea. Here's my controller and job:
gallery_controller.rb
class Admin::GalleryController < AdminController
def update_album
UpdateAlbumJob.perform_later(params[:album_flickr_id], params[:row])
end
end
update_album_job.rb
class UpdateAlbumJob < ApplicationJob
queue_as :default
after_perform do |job|
album = Album.find_by(flickr_id: job.arguments.first)
album.update_attribute(:updating, false)
puts job.arguments
ActionCable.server.broadcast 'album_updates_channel', content: 'Update complete', row: job.arguments[1], status: 'complete'
end
def perform(album_flickr_id, row)
require 'flickraw'
FlickRaw.api_key=ENV["FLICKR_API_KEY"]
FlickRaw.shared_secret=ENV["FLICKR_API_SECRET"]
flickr.access_token=ENV["FLICKR_OAUTH_TOKEN"]
flickr.access_secret=ENV["FLICKR_OAUTH_SECRET"]
# album_flickr_id = params[:album_flickr_id] or raise "No Album Flickr ID specified"
album = Album.find_by(flickr_id: album_flickr_id)
album.update_attribute(:updating, true)
ActionCable.server.broadcast 'album_updates_channel', content: 'Updating…', row: row, status: 'in-progress'
# Album.find_by(flickr_id: album_flickr_id).destroy if Album.find_by(flickr_id: album_flickr_id)
# Get tags
#flickr_tags_list = flickr.tags.getListUserRaw user_id: ENV["FLICKR_USER_ID"]
#tags_key = {}
#flickr_tags_list['tags'].each do |t|
#tags_key[t['clean'].to_sym] = t['raw'].first
end
# ========
# Work out parent collection
# This needs to cater for when there is NO parent collection
#collections = flickr.collections.getTree user_id: ENV["FLICKR_USER_ID"]
#parent_id = nil
def search_for_set_id_of_collection(set_id, collection, empty)
if collection["collection"]
collection.collection.each_with_index do |c|
search_for_set_id_of_collection(set_id, c, #parent_id)
end
end
if collection["set"]
collection["set"].each do |set|
if set["id"] == set_id
#parent_id = collection["id"]
end
end
end
end
#collections.each do |c|
search_for_set_id_of_collection(album_flickr_id, c, #parent_id)
end
# ========
Photo.where(album_id: album.id).destroy_all
Album.add_set_from_flickr(album_flickr_id, #parent_id, ENV["FLICKR_USER_ID"], #tags_key, true)
end
end
albumupdates.js:
const ActionCable = require('actioncable-modules');
const dotenv = require('dotenv')
dotenv.config()
const actionCable = ActionCable.createConsumer(process.env.WEBSOCKET_SERVER)
actionCable.subscriptions.create("AlbumUpdatesChannel", {
received: function(data) {
console.log('Hello from Action Cable');
if (data.status == 'in-progress') {
$('.' + data['row'] + ' td.this-one [am-Button]').hide();
$('.' + data['row'] + ' td.this-one').append(data['content']);
} else {
$('.' + data['row'] + ' td.this-one [am-Button]').show();
$('.' + data['row'] + ' td.this-one p').hide();
}
}
})
Basically, this is the first time i've just background jobs and action cable. I'm not 100% sure whether i've done this correctly but i wanted to give them a try and then ask on here for comments and suggestions. It sort of works ok but I have some questions:
Is this the best way of updating the table of albums with the status of the job? eg, "Updating..." and "Update complete!". I'd love to show an "Update Complete!" message but somehow remove that once it's been seen so just the button is showing again but unsure what path to go down to achieve that.
How would the live page updates work if i start an album updating, go away from the page and come back?
Also i'm unsure if my albumupdates.js file is set up correctly?
Just some comments and improvements to my code would be very helpful!
Thanks.
I am working in a Rails application and using the deferLoading: true option on jQuery DataTables in order pass the loading of the first DataTables to the Rails controller.
I have the datatable loading how I want it, loading the initial table in the controller gets rid of the Ajax delay when the initial html loads, however, the Datatable info section won't display the pagination results.
Code and images are shown below.
Again everything works except the pagination at the bottom of the table, I just cant get it to apply the same details as the Ajax calls to the datatable. Any ideas or direction on this issue would be greatly appreciated!
index.html.erb:
<div class="row">
<div class="col-xs-12 table-wrapper">
<div class="inner-wrapper">
<p class="quick-app">
<a class="custom-btn accent-inverse-btn add-user" href="<%= calculator_path%>">Quick Application</a>
</p>
<table class="table table-striped table-scroll cms-table-width dataTable" id="customer_deals_datatable" data-source="<%= dealer_customer_deals_url(:include_archived => params[:include_archived].present?) %>" >
<div>
<thead>
<tr>
<th>ID/Calculator</th>
<th>Applicant/Co-Applicant</th>
<th>Year</th>
<th>Model</th>
<th>App Status</th>
<th>Tier Number</th>
<th>Docs Status</th>
<th>Submitted On</th>
<th>Days Remaining</th>
<th>Chrome Decision</th>
<th>Updated At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% #datatable.data.each do |datum| %>
<tr>
<% datum[0] = datum[0].join('') %>
<%= (datum.map {|content| "<td>#{content}</td>"}.join('')).html_safe %>
</tr>
<% end %>
</tbody>
</div>
</table>
</div>
</div> <!-- </div>#content -->
</div>
controller
def index
respond_to do |format|
format.html do
params.merge!({"iDisplayLength"=>"10","iSortCol_0"=>"10","sSortDir_0"=>"desc"})
#datatable = CustomerDeals::CustomerDealsDataTable.new(view_context, #dealer)
end
format.json { render json: CustomerDeals::CustomerDealsDataTable.new(view_context, #dealer) }
end
end
here is a portion of the code from the datatable class in the project:
module CustomerDeals
class CustomerDealsDataTable
def fetch_deal_searches
return #deal_searches if #deal_searches.present?
deal_searches = CustomerDeals::CustomerDealSearch.where(dealership_id: #dealer )
if is_submitted_on_sort?
deal_searches = deal_searches.where('deal_dated_calculator_value != ?', 'calculator')
end
if params[:sSearch].present?
deal_searches = deal_searches.containing(params[:sSearch])
end
deal_searches = deal_searches.order(order_query)
#deal_searches = deal_searches
end
def is_submitted_on_sort?
SORT_COLUMNS[params[:iSortCol_0].to_i] == 'deal_submitted_on'
end
def lookup_sort_column
SORT_COLUMNS[params[:iSortCol_0].to_i]
end
def order_query
"#{lookup_sort_column} #{params[:sSortDir_0]}"
end
def paged_deal_searches
fetch_deal_searches.page(current_page_number).per(params[:iDisplayLength])
end
def current_page_number
params[:iDisplayLength].to_i == 0 ? 1 : params[:iDisplayStart].to_i/params[:iDisplayLength].to_i + 1
end
end
end
You're on the right track, deferLoading also can be assigned integer or array of two integers to specify how many records there are in the table for pagination to work.
From the manual:
deferLoading is used to indicate that deferred loading is required, but it is also used to tell DataTables how many records there are in the full table (allowing the information element and pagination to be displayed correctly).
In the case where a filtering is applied to the table on initial load, this can be indicated by giving the parameter as an array, where the first element is the number of records available after filtering and the second element is the number of records without filtering (allowing the table information element to be shown correctly).
Examples:
57 records available in the table, no filtering applied:
$('#example').dataTable( {
"serverSide": true,
"ajax": "scripts/server_processing.php",
"deferLoading": 57
} );
57 records after filtering, 100 without filtering (an initial filter applied):
$('#example').dataTable( {
"serverSide": true,
"ajax": "scripts/server_processing.php",
"deferLoading": [ 57, 100 ],
"search": {
"search": "my_filter"
}
} );
Here's my controller
class ActivitiesController < ApplicationController
def exercises
if current_user.userprofile.present? #chef whether there is a userprofile object
#weeknum = current_user.userprofile.week
#dayly_activity = Activity.where(:week => 1, :day => 'Monday').first
end #end check userprofile
end
def updatexercises
respond_to do | format |
#dayly_activity = Activity.where(:week => 1, :day => 'Monday').first
#dayly_activity.update_attributes(params[:#dayly_activity])
#dayly_activity.save
format.html { render action: "exercises" }
end
end
end
And my template
<h1>WEEKLY EXERCICES</h1>
Day : <%= #dayly_activity.day %>
<%= form_for(#dayly_activity, :url => { :action => "updatexercises" }) do | f | %>
<table>
<tr>
<td>Jogging:</td>
<td>
<% list = (0..20).to_a %>
<%= f.select :jog, list %>
x 0.1 km
</td>
</tr>
<tr>
<td>Bicycling:</td>
<td>
<% list = (0..10).to_a %>
<%= f.select :bicycl, list %>
km
</td>
</tr>
<tr>
<td>Push ups:</td>
<td>
<% list = (0..20).to_a %>
<%= f.select :pushups, list %>
x 10 times
</td>
</tr>
<tr>
<td colspan = "2"><%= f.submit %></td>
</tr>
</table>
<% end %>
When I click the button, the Daily+activity object is not being saved. Am I missing some thing
EDIT
I've tried to hard code this way and it saving to the database.
#dayly_activity.jog = 17
#dayly_activity.pushups = 13
#dayly_activity.save
Obviously, the problem must be with the update_attributes
You need to use params[:dayly_activity] (drop the # sign).
Also, I would put these two lines :
#dayly_activity = Activity.where(:week => 1, :day => 'Monday').first
#dayly_activity.update_attributes(params[:dayly_activity])
Outside of your respond_to block (put them on top of it).
You can also drop the #dayly_activity.save, update_attributes do it automatically and will returns true/false if it works/fails.
You have error in [:#dayly_activity]
And in that code
#dayly_activity.update_attributes(params[:#dayly_activity])
#dayly_activity.save
save is useless. update_attributes saving the record.
It better to check result of update_attributes. So you can catch validation errors.
For example
if #dayly_activity.update_attributes(params[:dayly_activity])
redirect_to dayli_activity_path, :notice => "Updated"
else
render :edit
end
i just don't get it, where did i do wrong.
please highlight them for me.
Im testing a graph using gruff.
in ReportController
def mygruff
#gr = Hash.new
#gr["jan"] = 3
#gr["feb"] = 6
logger.info({##gr.keys})
end
in my log, i did get 'janfeb'
in mygruff view
<%if #gr.blank?%>
<%=No gruff%>
<%else%>
<%=#gr.keys%>
<%end%>
I will get No gruff on mygruff page.
But i get it in my log.
Ive tried
object.empty?
true
object.blank?
true
object.nil?
false
how to get the hash in my view?
please show me the way.thank you.
def stat2
#cus_t = Hash.new
a = Gruff::Bar.new('500x350')
a.theme = {
:colors => ['#138F6A','#330000','#0aaafd','#FF0000','#00CD00','#ff6602', '#3bb003', '#1e90af', '#efba30', '#0aaaac'],
:marker_color => '#aaa',
:background_colors => ['#eaeaea', '#fff']
}
a.hide_title = true
#customer = Customer.find(:all)
#customer.each do |custs|
#g_cus = Casedf.count(:all, :conditions=> "customer_id=" + custs.id.to_s)
a.data(custs.companyname, #g_cus)
##cus_t[custs.companyname] = #g_cus
#cus_t.store(custs.companyname,#g_cus)
end
a.write("#{RAILS_ROOT}/public/images/customer.png")
$logger.info("hash keys #{#cus_t.keys}")
end # end def
Here is what I did on my view:
<table>
<% if #cus_t.nil?%>
<tr>
<td colspan="6">No cus added so far<%=#cus_t.keys%>l</td>
</tr>
<%else%>
<tr>
<td><%=#cus_t.keys%></td>
</tr>
<%end%>
</table>
So when I browse to stat2's page, I get nothing, but in my logs, the keys are printed out. I'm stumped, please help.
Hi Do you have in your action
def mygruff
#gr = Hash.new
#gr["jan"] = 3
#gr["feb"] = 6
logger.info({##gr.keys})
end
it was not clear for me from comment
In Ruby, hashes don't have a blank? method. That method is added by Rails and there may be a bug with it. Please try this in your view:
<% if #gr.empty? %>
No gruff
<% end %>
<%= #gr.inspect %> <!-- print regardless to see if there is data there -->