Following the directions here (and correcting for the tag issues in the code sample) I am attempting to implement a pie chart in my app. I load the initial page but the pie chart does not load on the partial (I make it into the html.erb file). A lot of things are hard coded right now so for instance Chart Type, etc do not get passed back to the controller yet.
Can someone help point out where I went awry?
Controller:
def dynamic_chart
#chart_types = ChartType.all
#user_visible_models = ["Asset","Asset Manufacturer","Asset Model", "Map","Campus","Tag","Room", "Room Monitor"]
#date_ranges = ["Day", "Week", "Month"]
end
def gen_chart
#rooms = Array.new
Room.all.each do |room|
#rooms << [room.name, room.asset_count]
end
#chart = LazyHighCharts::HighChart.new('pie') do |f|
f.chart({:defaultSeriesType=>"pie" , :margin=> [50, 200, 60, 170]} )
series = {
:type=> 'pie',
:name=> 'Asset by Rooms',
:data=> #rooms
}
f.series(series)
f.options[:title][:text] = "THA PIE"
f.legend(:layout=> 'vertical',:style=> {:left=> 'auto', :bottom=> 'auto',:right=> '50px',:top=> '100px'})
f.plot_options(:pie=>{
:allowPointSelect=>true,
:cursor=>"pointer" ,
:dataLabels=>{
:enabled=>true,
:color=>"white",
:style=>{
:font=>"13px Trebuchet MS, Verdana, sans-serif"
}
}
})
end
dynamic_chart.html.erb
<% javascript 'dynamic_chart' %>
<div id="graph_controls">
<%= form_tag('activate_reports/dynamic_chart', :class => "well form-inline") do %>
<%= text_field_tag(:name, nil, :class => "input-small", :placeholder => "Report Name") %>
<%= collection_select(:activate_report, :chart_type_id, #chart_types, :id, :name, :prompt => "Select chart") %>
<%= label_tag :x_axis, "X:", :class => "control-label" %>
<%= select :x_axis, nil, #user_visible_models, :prompt => true %>
<%= label_tag :y_axis, "Y:", :class => "control-label" %>
<%= select :y_axis, nil, #user_visible_models, :prompt => true %>
<%= select :date_range, nil, #date_ranges, :prompt => "Select a day" %>
<%= link_to("Chart!", "#", :remote => true, :class => "btn", :onclick => 'gen_chart()') %>
<% end %>
</div>
<div id="chart_area"></div>
_gen_chart.html.erb Partial:
<%= high_chart("chart_area", #chart) %>
gen_chart js function used to initiate the new chart
function gen_chart(){
jQuery.ajax({
url: "/activate_reports/gen_chart",
type: "GET",
data: {},
dataType: "html"
});
}
Related
I have an application that has hundreds of products. I created a simple filter search bar and it works great for a single parameter, but I would like to add multiple parameters and return any product that contains one of the search parameters.
Here is my working code for a single parameter; I would show what I've tried to add multiple params, but I am a bit out of my depth.
products_controller.rb
def index
#products = Product.all.order('LOWER(name)')
if params[:q]
#products = Product.where('name ILIKE ?', "%#{params[:q]}%").all.order('LOWER(name)')
end
end
_searchbar.html.erb
<div class="form-inline">
<%= form_tag(products_path, :method => "get", id: 'search-form', :html => {class: 'form'}) do %>
<div class="form-group">
<%= text_field_tag :q, params[:q], placeholder: 'Product Name', class: 'form-control' %>
</div>
<%= submit_tag 'Search', class: 'btn btn-primary' %>
<% end %>
</div>
We should know the operation behind. The sql query must be like this:
select * from products where name ilike '%name1%' or name ilike '%name2%';
According you code:
select * from products where name ilike '%name1,name2%'
That's incorrect.
Try to the following:
# :query need to be an array
# Eg:
# "Product name 1, Product name 2, Product name 3" => params[:q].split(', ')
# => ["Product name 1", "Product name 3", "Product name 3"]
search_string = []
query.each { |q| search_string << "name ILIKE ?" }
search_string = search_string.join(' OR ')
Product.where(search_string, *query)
You can do that using following steps like if you need to use input field then form look like this
<div class="form-inline">
<%= form_tag(products_path, :method => "get", id: 'search-form', :html => {class: 'form'}) do %>
<div class="form-group">
<%= text_field_tag :x, params[:x], placeholder: 'Product Name1', class: 'form-control' %>
</div>
<div class="form-group">
<%= text_field_tag :y, params[:y], placeholder: 'Product Name2', class: 'form-control' %>
</div>
<div class="form-group">
<%= text_field_tag :z, params[:z], placeholder: 'Product Name3', class: 'form-control' %>
</div>
<%= submit_tag 'Search', class: 'btn btn-primary' %>
<% end %>
</div>
Or you need this filtering key is in the checkbox then form look like this
<%= form_tag(products_path, :method => "get", id: 'search-form', :html => {class: 'form'}) do %>
<%= check_box_tag("x[]", "x") %> Xname
<%= check_box_tag("y[]", "y") %> Yname
<%= check_box_tag("z[]", "z") %> Zname
<%= submit_tag 'Search', class: 'btn btn-primary' %>
<% end %>
Now update the controller look like this
if params[:x] || params[:y] || params[:z]
#products = Product.where('true')
#products = #products.where('name ILIKE ?', "%#{params[:x]}%") unless params[:x].blank?
#products = #products.where('name ILIKE ?', "%#{params[:y]}%") unless params[:y].blank?
#products = #products.where('name ILIKE ?', "%#{params[:z]}%") unless params[:z].blank?
#products = #products.order('LOWER(name)')
else
#products = Product.all.order('LOWER(name)')
end
Hope it helps
I have this nasty if/else statement in a rails view:
<% if question.field_type == "text_area" %>
<%= f.text_area :content, :class=>"form-control question-field", :data => {:question => question.id, :filter=> #filter}, :value=> question.answer(#assessment).try(:content) %>
<% elsif question.field_type == "date" %>
<%= f.date_select :content, { :order => [:year, :month, :day], :prompt => { :day => 'day', :month => 'month', :year=> "year" }, :end_year=> Date.today.year, :start_year => Date.today.year - 2 }, {:class => "question-field", :data => {:question => question.id, :filter=> #filter}, :value=> question.answer(#assessment).try(:content)} %>
<% elsif question.field_type == "text_field" %>
<%= f.text_field :content, :class=>"form-control question-field", :value=> question.answer(#assessment).try(:content), :data => {:question => question.id, :filter=> #filter} %>
<% elsif question.field_type == "dropdown" %>
<%= f.select :content, options_for_select(question.options), { :prompt => "Choose One..." }, :class=>"form-control question-field", :value=> question.answer(#assessment).try(:content), :data => {:question => question.id, :filter=> #filter} %>
<% elsif question.field_type == "number" %>
<%= f.select :content, options_for_select(1..10), {:include_blank=> true}, :class=>"form-control question-field", :value=> question.answer(#assessment).try(:content), :data => {:question => question.id, :filter=> #filter} %>
<% elsif question.field_type == "percentage" %>
<h2>100%</h2>
<%= f.range_field :content, :value=> get_percentage(question), :class=> "question-field percentage", :data => {:question => question.id, :filter=> #filter}, :step => 25, :in => 0..100 %>
<% end %>
Is there a good way to refactor this to make it nicer? This piece of code is in every field:
:class=>"form-control question-field", :value=> question.answer(#assessment).try(:content), :data => {:question => question.id, :filter=> #filter}
Do I refactor into a helper method or a partial?
Sometimes templates are just messy and you can only clean up detail. Refactoring into a parameterized partial will help. For goodness sake, use a case. And consider switching to HAML. It eliminates a lot of the visual clutter.
<%= render 'question_field', f: f, type: question.field_type %>
Then in _question_field.erb,
<%= case type %>
<% when 'text_area' %>
<% f.text_area :content, class: 'form-control question-field', %>
<% data: { question: question.id, filter: #filter }, %>
<% value: question.answer(#assessment).try(:content) %>
<% when ... %>
<% end %>
Note common industrial practice is to pick a max line length and stick to it: 100 and 120 are pretty common. Also, use the new symbol key notation for hashes. The old hook-and-arrow is too noisy.
In HAML:
= case type
- when 'text_area'
- f.text_area :content, class: 'form-control question-field',
data: { question: question.id, filter: #filter },
value: question.answer(#assessment).try(:content)
- when ...
I would get rid of if's and when's altogether by creating seperate partial for every possibility, then you just end up with:
<%= render question.field_type, locals: {question: question} %>
Or to make it even cleaner for view make helper method and call only
<%= question_field(question) %>
and this method would look little bit like
def question_field(question)
return render question.field_type, locals: {question: question}
# raise when no partial found, or do something elese
end
Hi i am using ransack + kalendae_assets gem for searching records in between start date and end date
for this i am using ransack PREDICATES by referring
https://github.com/ernie/ransack/blob/master/lib/ransack/constants.rb
here is my code
<%= search_form_for #search, url: guest_search_rooms_path, html: {:method =>:post} do |f| %>
<%= f.label :start_date_eq , "Start Date"%>
<%= f.text_field :start_date_eq, class: 'release_date' %>
<%=f.label :end_date_eq, "End Date" %>
<%= f.text_field :end_date_lteq, class: 'release_date' %>
<%= f.submit "search" %>
<% end %>
rooms.controller
def guest_search
#search = Room.search(params[:q])
#roome = #search.result(:distinct => true)
#room= #roome.where("status IS ?", true).order("room_type_id desc")
##room = #search.result(:distinct => true)
end
but when i enters start and end date it not searches how can i do this
With https://github.com/dangrossman/bootstrap-daterangepicker you can do date range search with:
= search_form_for q, url: orders_path, builder: SimpleForm::FormBuilder do |f|
= f.input :daterange , input_html: {value: "#{q.date_gteq.to_s} - #{q.date_lteq.to_s}"}
= f.input :date_gteq, as: :hidden
= f.input :date_lteq, as: :hidden
:coffee
$ ->
$('#q_daterange').daterangepicker
format: "YYYY-MM-DD"
startDate: $('#q_date_gteq').val()
endDate: $('#q_date_lteq').val()
ranges:
'This Week': [moment().startOf('week'), moment().endOf('week')],
'Next Week': [moment().add('week', 1).startOf('week'), moment().add('week', 1).endOf('week')]
, (start, end, label) ->
$('#q_date_gteq').val start.format("YYYY-MM-DD")
$('#q_date_lteq').val end.format("YYYY-MM-DD")
.on 'apply.daterangepicker', -> $('#order_search').submit()
You could make a custom predicate.
In my view I have a ransack search field like
= f.text_field :request_date_between, class: 'daterange'
That will send a date to the controller like
'2015-10-01 to 2015-10-31'
then in my down and dirty ransack.rb initializer I have;
Ransack.configure do |config|
config.add_predicate 'between',
arel_predicate: 'between',
formatter: proc { |v| v.split(' to ') },
type: :string
end
module Arel
module Predications
def between other
gteq(other[0]).and(lt(other[1]))
end
end
end
to make between predicate recognize local timezone, in ransack.rb initializer...
Ransack.configure do |config|
config.add_predicate 'between',
arel_predicate: 'between',
formatter: proc { |v| Range.new(*v.split(' to ').map { |s| Time.zone.parse(s) }) },
type: :string
end
No need to overwrite Arel::Predications#between.
(This works only on datetime column type.)
You can use range with starting date and end date. Then you can get search result between the dates. Here is the sample code in your search form:
<div class="control-group">
<%= f.label :scrap_date_cont, "Scrap Date", class: 'control-label' %>
<div class="controls">
<% if q.scrap_date_cont.blank? %>
<%= f.text_field :scrap_date_cont, include_blank: true, default: nil, :class => 'datepicker3', :style=>"width:100px;" %>
<% elsif !q.scrap_date_cont.blank? %>
<%= f.text_field :scrap_date_cont, :value => "#{change_date_format_for_edit_page(q.scrap_date_cont)}", :class => 'datepicker3', :style=>"width:100px;" %>
<% end %> <%= link_to "Select Range", "#", :id => 'dates' %>
</div>
</div>
<div class="control-group" id="range" style="display:none" >
<%= f.label :scrap_date_gteq, "Range", class: 'control-label' %>
<div class="controls">
<% if q.scrap_date_gteq.blank? %>
<%= f.text_field :scrap_date_gteq, include_blank: true, default: nil, :class => 'datepicker1', :style=>"width:100px;" %>
<% elsif !q.scrap_date_gteq.blank? %>
<%= f.text_field :scrap_date_gteq, :value => "#{change_date_format_for_edit_page(q.scrap_date_gteq)}", :class => 'datepicker1', :style=>"width:100px;" %>
<% end %>
<% if q.scrap_date_lteq.blank? %>
<%= f.text_field :scrap_date_lteq, include_blank: true, default: nil, :class => 'datepicker2', :style=>"width:100px;" %>
<% elsif !q.scrap_date_lteq.blank? %>
<%= f.text_field :scrap_date_lteq, :value => "#{change_date_format_for_edit_page(q.scrap_date_lteq)}", :class => 'datepicker2', :style=>"width:100px;" %>
<% end %>
</div>
</div>
And Here is the controller code:
params[:q][:scrap_date_cont] = change_date_format(params[:q][:scrap_date_cont]) if !(params[:q][:scrap_date_cont]).blank?
params[:q][:scrap_date_cont] = params[:q][:scrap_date_cont].to_date.strftime("%d/%Y/%m") if !(params[:q][:scrap_date_cont]).blank?
params[:q][:scrap_date_gteq] = change_date_format(params[:q][:scrap_date_gteq]) if !(params[:q][:scrap_date_gteq]).blank?
params[:q][:scrap_date_gteq] = params[:q][:scrap_date_gteq].to_date.strftime("%d/%Y/%m") if !(params[:q][:scrap_date_gteq]).blank?
params[:q][:scrap_date_lteq] = change_date_format(params[:q][:scrap_date_lteq]) if !(params[:q][:scrap_date_lteq]).blank?
params[:q][:scrap_date_lteq] = params[:q][:scrap_date_lteq].to_date.strftime("%d/%Y/%m") if !(params[:q][:scrap_date_lteq]).blank?
Helper code:
#Change date format in edit time
def change_date_format_for_edit_page(date)
new_date = date.strftime("%m/%d/%Y")
puts new_date.inspect
return new_date
end
Script :
$("#dates").click(function () {
var $that = $(this);
$("#range").toggle("slow", function() {
$that.toggleClass("toggled-off");
});
});
I think it might help you...
In my case, I did like this:
Just pass a single date, and it will search from beginning `til end of that date.
initializers/ransack.rb
Ransack.configure do |config|
config.add_predicate 'between_begin_and_end',
arel_predicate: 'between_begin_and_end',
formatter: proc { |v| v.to_date },
validator: proc { |v| v.present? },
type: :string
end
module Arel
module Predications
def between_begin_and_end date
gteq(date.to_date.beginning_of_day).and(lt(date.end_of_day))
end
end
end
view
<%= f.text_field :date_field_here_between_begin_and_end, class: 'datepicker', placeholder: 'yyyy/mm/dd' %>
Here's a solution with a dropdown to choose the date range. We'll add a between predicate and pass it a datetime range formatted as a string, like below:
(5.days.ago..5.days.from_now).to_s
=> "2021-05-30 15:21:05 +0200..2021-06-09 15:21:05 +0200"
First add a Ransack between predicate, relying on the native between Arel predicate. The formatter takes that string value and splits it on '..', converts the start/end dates as DateTime and builds a range.
# config/initializers/ransack.rb
Ransack.configure do |config|
config.add_predicate 'between',
arel_predicate: 'between',
formatter: proc { |v| Range.new(*v.split('..').map{ |s| DateTime.parse(s) }) },
validator: proc { |v| v.present? },
type: :string
end
In a model or view model or helper or else, define the options for the select:
# app/helpers/rooms_helper.rb
module RoomsHelper
def rooms_search_ranges
now = Time.current
next_month = 1.month.from_now
{
"This month" => now.beginning_of_month..now.end_of_month,
"Next month" => next_month.beginning_of_month..next_month.end_of_month
}
end
end
And in your form, assuming your model has an booked_at attribute:
<%= search_form_for #search, url: guest_search_rooms_path, html: {:method =>:post} do |f| %>
<%= f.select :booked_at_between, rooms_search_ranges %>
<%= f.submit "search" %>
<% end %>
I have following controller:
def personalization
#title = t "generic.forms.personalization"
end
def update_personalization
begin
#user.user_data.birthdate = Date.civil(params[:user_data][:"birthdate(1i)"].to_i,params[:user_data][:"birthdate(2i)"].to_i,params[:user_data][:"birthdate(3i)"].to_i)
rescue
wrong_data = 1
end
if #user.user_data.update_attributes(params[:user_data])
if wrong_data
flash[:Error] = t "generic.messages.error.wrong_data"
redirect_to :back and return
end
flash[:Success] = t "generic.messages.success.account_updated"
redirect_to :back
else
flash[:Error] = #user.user_data.errors.full_messages.join(".<br>")
redirect_to :back
end
end
and following view:
<div id="ProfileEditForm" class="ContentBorders">
<h1 class="FormsHeading"><%= t #title %></h1>
<div class="FormsSpacing">
<%= form_for(#user.user_data, :html => { :id => "UpdateUserForm", :class => "EditForms"}, :url => {:action => 'update_personalization'}) do |f| %>
<% flash.each do |key, value| %>
<div class="FormsMargins <%= key %>"><%=raw value + "." %></div>
<% end %>
<div class="Field"><div class="LabelInline"><%= t "generic.site.first_name" %>:</div>
<%= f.text_field :first_name, :id => "EditFirstName", :class => "Rounded5", :maxlength => "30" %></div>
<div class="Field"><div class="LabelInline"><%= t "generic.site.last_name" %>:</div>
<%= f.text_field :last_name, :id => "EditLastName", :class => "Rounded5", :maxlength => "30" %></div>
<div class="Field DateSelection"><div class="LabelInline"><%= t "generic.site.birthdate" %>:</div>
<%= date_select("user_data", "birthdate", :start_year => 1901, :end_year => 2011, :include_blank => true) %>
</div>
<div class="Field GenderSelection"><div class="LabelInline"><%= t "generic.site.gender" %>:</div>
<%= f.radio_button :gender, "0", :id => "EditGenderMale" %> <span><%= t "generic.site.male" %></span>
<%= f.radio_button :gender, "1", :id => "EditGenderFemale" %> <span><%= t "generic.site.female" %></span>
</div>
<div class="Field EducationSelection"><div class="LabelInline"><%= t "generic.site.educational_level" %>:</div>
<%= f.select :education_level, options_for_select({
" " => 0, (t "generic.site.education_levels.first") => 1, (t "generic.site.education_levels.second") => 2,
(t "generic.site.education_levels.third") => 3, (t "generic.site.education_levels.fourth") => 4,
(t "generic.site.education_levels.fifth") => 5, (t "generic.site.education_levels.sixth") => 6,
(t "generic.site.education_levels.seventh") => 7 }, #user.user_data.education_level) %>
</div>
<div class="Action"><%= f.submit (t "generic.forms.update_data"), :id => "EditSubmit", :class => "ProfileEditAction Shadow1 Rounded5 AcceptButtonsBorder" %></div>
<% end %>
</div>
</div>
<%= render :partial => 'profile_panel' %>
Now. The problem is with date_select method. Each of form field works properly (data from database fills them up), except that which was generated from data_select.
If I select some proper data, and click update button, then it saves that proper data to the db. Problem comes with the moment, when it is generated, and it doesn't come with any values (it's always empty when loaded).
Any ideas, how can that be fixed?
maybe...
you have:
<%= date_select("user_data", "birthdate", :start_year => 1901, :end_year => 2011, :include_blank => true) %>
you need:
<%= f.date_select("user_data", "birthdate", :start_year => 1901, :end_year => 2011, :include_blank => true) %>
just put the "f"
<%= f.date_select ...
I'm trying to pass a string with a link_to_remote call as the :id, and the string should be collected from an input field with and id of "movie_title".
<div id="search_list">Nothing here yet</div>
<br />
<% semantic_form_for #movie do |f| %>
<% f.inputs do -%>
<%= f.input :title, :class => "movie_title" %> <%= link_to_remote( 'Search...', { :url => { :action => :imdb_search, :id => "'+$('\#movie_title').value+'" } }, { :title => "Search for this movie", :class => "imdb_search" } ) -%>
[...removed text that does not matter...]
<% end -%>
<%= f.buttons %>
<% end %>
I keep getting an javascript error, and if I remove the # from the jquery in the link, it returns "Undefined".
The link I get is:
<a class="imdb_search" href="#" onclick="jQuery.ajax({data:'authenticity_token=' + encodeURIComponent('yHPHYTZsPTQLi9JYSauUYcoie/pqPPk2uHBTN0PzNsQ='), dataType:'script', type:'post', url:'/movies/imdb_search/'+$('%23movie_title').value+''}); return false;" title="Search for this movie">Search...</a>
So I want the link updated with the contents of movie_title.
How do I do that?
I'd try something like
<%= link_to_remote( 'Search...', {
:url => { :action => :imdb_search},
:with => "'id=' + $('movie_title').value",
{:title => "Search for this movie", :class => "imdb_search"}
)
Fixed it
Used:
$('movie_title').val()
Insted of
$('movie_title').value