RoR, Javascript - how to automatically update charts from table? - javascript

I'm using Highcharts to make graphical representation of my data in my tables. I can get the data to be show on the charts but to do so I find myself having to code each record one by one like this:
Model:
def self.subject_analysis(subject_type)
Note.where(:subject_type => English).count if subject_type == :English
Note.where(:subject_type => Geography_Class_C).count if subject_type == :Geography_Class_C
Note.where(:subject_type => Maths_Class_B).count if subject_type == :Maths_Class_B
Highcharts js
...
},
series: [{
name: 'Number of notes By Class Module',
data: [<%= Note.where(:subject_type => 'English').count %>, <%= Note.where(:subject_type => 'Geography Class C').count %>, <%= Note.where(:subject_type => 'Maths Class B').count %>]
}]
});
This works but obviously this is far from ideal and not what I need. I would just like the charts to update from the table automatically when the table changes because a new record has been added.
Would appreciate any guidance. Thanks.

you can make use data attributes
define #my_var in controller
#my_var = Note.where(:subject_type => English).count
on view <div id='english' data-note='<%= #my_var %>'>
than in your js file
eng = $('#english').data('note')
and pass it to highcharts code

Related

Dynamic button values from javascript?

I have a page that does a search, using javascript, and I want to take the list of users that it comes up with, and send that as a submit to the next page. What I have, is:
.search_client_users
= form_tag admin_clients_path, method: "get" , class: "search_form" do
= label_tag 'search_term', 'Old domain name:'
= text_field_tag 'search_term', nil, autocomplete: "off", size: "50"
.main_form.client_emails
= simple_form_for(:domainNameSwap, url: { action: "update" }, html: { method: :put }) do |f|
.input-row
= f.hidden_field :users, value: #clients
.submit-row
.row
.col-xs-5
.submit
= f.submit "Update domains", id: "submit", :class => "btn btn-primary submit"
.client_list
- content_for :javascript do
= javascript_include_tag 'admin/search_client_users'
[some of the formatting may not be quite right due to cut and paste, sorry]
The admin/search_client_users creates an #clients, I'm pretty sure, at least, with:
class App.ClientUserList
constructor: ->
#incrementalSearchAttempts = 0
search: (searchTerm, completeCallback) =>
handleResponseWithOrderAwareness = (attemptNumber, response) =>
if attemptNumber >= #incrementalSearchAttempts
completeCallback(response)
#incrementalSearchAttempts++
onComplete = _.partial(handleResponseWithOrderAwareness, #incrementalSearchAttempts)
$.get('/admin/manage_clients/client_list', { search_term: searchTerm }).complete(onComplete)
class App.Views.SearchClientUsers extends Backbone.View
events:
"keyup input[name='search_term']": "search",
"click .profile_attribute": "showClientUserProfile"
initialize: =>
#clientUserList = new App.ClientUserList()
search: =>
searchTerm = $('.search_form input[name=search_term]').val()
#clientUserList.search(searchTerm, #render)
showClientUserProfile: (event) =>
window.location = $(event.currentTarget).closest('tr').data('client-path')
render: (response) =>
#$el.find('.client_list').html(response.responseText)
$ ->
new App.Views.SearchClientUsers(el: $('.search_client_users')).search()
so, I'm trying to take the list of clients, and send it to the update method in the controller. However, due to when javascript and ruby take place, it doesn't seem to be working... is there a way to do this? or do I have to figure out how to do this in Ajax?
ETA: An alternative idea is, I suppose to just turn the initial text_field into a form, so that the text field is used both for the javascript, and THEN submitted to the form, and then the update can re-do the search... My dataset is small enough that doing the search twice is not a huge problem I suppose...
But I'm not quite sure exactly how to merge the two forms...

Move chart.js function from partial to assets folder in .coffee file

I have text block in main page, it located in _about.html.haml partial. When I click the link, text replaces by radar chart via AJAX (I use 'chart-js-rails' gem). Now the js function located in _my-chart.html.haml partial (which replaces first one) & I think it's not good enough.
So the question is: how to move this function code to assets folder in .coffee file or something like that?
P.S. I already try to move it to 'chart.js' file & use = javascript_include_tag 'chart.js' but it's not working graph doesn't render & I have empty canvas element.
views/welcome/_about.html.haml
%div{id: 'about'}
%h2 About
%p Some text
= link_to 'View chart', welcome_chart_path, remote: true
views/welcome/chart.js.haml
$('#about').replaceWith('#{j render(partial: 'welcome/my-chart')}');
views/welcome/_my-chart.html.haml
%div
%h2 Chart
%canvas{id: 'my-chart', width: '400', height: '400'}
:javascript
$(function() {
var ctx = $('#my-chart');
var data = {
labels: [a, b, c],
datasets: [
{data: [1, 2, 3]}
]
};
var my_chart = new Chart(ctx, {
type: 'radar',
data: data
})
});
controllers/welcome_controller.rb
class WelcomeController < ApplicationController
respond_to :js, only: [:chart]
...
def chart; end
end

undefined local variable or method

I am trying to implement a highchart that sums hours for a specified week. What it is currently doing is looking at my 'efforts' table and summing all records in that table. However I am trying to sum hours for a particular week, for the current user. I have the following snippet from my highcharts.html.erb.
series: [{
name: 'Hours',
data: [<% #efforts.each do |effort| %>
[Date.UTC(<%= effort.week_commencing.strftime("%Y,%m-1,%d") %>),<%= Effort.sum(:hours).
where(:week_commencing => week_commencing, :user_id => current_user.id)%>],<% end %>]
}]
});
});
I have the full code available on pastebin http://pastebin.com/ifbQfR0i
Is there a way around this?
Updated: Error message
NameError in Statistics#range
Showing /home/Project/app/views/statistics/range.html.erb where line
115 raised:
undefined local variable or method `week_commencing' for #<#:0x9fdadc8> Extracted source (around line #115):
name: 'Hours',
data: [<% #efforts.each do |effort| %>
[Date.UTC(<%= effort.week_commencing.strftime("%Y,%m-1,%d")
%>),<%= Effort.sum(:hours).
where(:week_commencing =>
week_commencing, :user_id => current_user.id)%>],<% end %>]
}] }); });
Efforts.rb
== Schema Information
Table name: efforts
id :integer(4) not null, primary key
project_task_id :integer(4)
user_id :integer(4)
week_commencing :date
hours :float
created_at :datetime
updated_at :datetime
I'm not quite sure, but shouldn't it be:
%>),<%= Effort.sum(:hours). where(:week_commencing => effort.week_commencing, :user_id => current_user.id)%>],<% end %>] }] }); });
instead of
%>),<%= Effort.sum(:hours). where(:week_commencing => week_commencing, :user_id => current_user.id)%>],<% end %>] }] }); });

Changing from observe_field to JQuery in Rails 3

Prior to Rails 3, I used this code to observe a field dynamically and pass the data in that field to a controller:
<%= observe_field :transaction_borrower_netid,
:url => { :controller => :live_validations, :action => :validate_borrower_netid },
:frequency => 0.5,
:update => :borrower_netid_message,
:with => "borrower_netid" %>
I'm trying to update that code to work with Jquery and Rails 3, but I can't get it to work. I updated my routes.rb to include
match "/live_validations/validate_borrower_netid" => "live_validations#validate_borrower_netid", :as => "validate_borrower"
and I'm trying to observe the field and make the necessary calls with:
jQuery(function($) {
// when the #transaction_borrower_netid field changes
$("#transaction_borrower_netid").change(function() {
// make a POST call and update the borrower_netid_message with borrower_netid
$.post(<%= validate_borrower_path %>, this.value, function(html) {
$("#borrower_netid_message").html(html);
});
});
})
but it's not working. My Javascript and Jquery skills are severely lacking, so any help anyone could provide would be much appreciated. Thanks!
You need to wrap your <%= validate_borrower_path %> in quotes:
$.post("<%= validate_borrower_path %>", this.value, function(html) {
I ended up using the following:
$('#transaction_borrower_netid').live('change', function() {
// when the #transaction_borrower_netid field changes
// make a POST call and replace the content
var netID = $('#transaction_borrower_netid').val();
$.post("/live_validations/validate_borrower_netid", { borrower_netid: $('#transaction_borrower_netid').val() }, function(html) {
$("#borrower_netid_message").html(html);
});
})

Rails, javascript and updating forms

I have a form that allows the user to choose a country. Depending on which country is selected, I need to change the State/Province drop-down to include either a list of states or a list of provinces. I was going about this using the observe_field tag, but that was depreciated in rails 3...
So.., how should one go about this now? I am using select_tag to populate the drop-downs, and the arrays used in the options_for_select are all stored server-side and made accessible in the controller action, so I can't access them from javascript..
Using the Carmen gem: https://github.com/jim/carmen.
I did the following some times ago (AJAX).
HTML:
<p>
<label>Country <span>*</span></label>
<%= profile_form.select(:country,Carmen.countries, {:include_blank => 'Select a Country'}, :id => "profile_country") %>
</p>
<p>
<label>State <span>*</span></label>
<%= profile_form.select(:state, "" , {:include_blank => 'Select a Country first'}, :id => "profile_state") %>
</p>
Controller:
def states
begin
render :json => Carmen::states(CGI::unescape(params[:country]))
rescue
render :json => {"content" => "None"}.to_json
end
end
Javascript with jQuery:
$('#profile_country').change(function() {
if ($(this).val() == '')
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>No state provided for your country</option>'));
}
else {
$.ajax({
type: "GET",
url: "/remote/get_states/" + encodeURIComponent($(this).attr('value')),
success: function(data){
if (data.content == 'None')
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>No state provided for your country</option>'));
}
//handle the case where no state related to country selected
else
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>Select your State</option>'));
jQuery.each(data,function(i, v) {
$('#profile_state').append( $('<option value="'+ data[i][1] +'">'+data[i][0] +'</option>'));
});
}
}
});
}
});

Categories

Resources