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
Related
Is it possible to render a javascript file inside a js.erb file? I have a modal that's being render in my new.js.haml file. However I have some javascript code that needs to run only when that modal gets called.
new.js.haml
$('.modal-content').html("#{ j(render partial: 'new') }");
I want to be able to call this file or render this file when new.js.haml is called upload.js
$ ->
files = [];
$("#upload_button").click ->
$("#file_input").trigger "click";
$("#file_input").change (event) ->
file = event.target.files[0];
files.push(file);
uploadfile files.length - 1, file;
uploadfile = (index, file) ->
formData = new FormData();
formData.append "file", file;
fileitem = "
<li class='file-item success'>
<div class='active'>
<span class='remove'>×</span>
<span>#{file.name}</span>
</div>
<div class='lds-ellipsis'><div></div><div></div><div></div><div></div></div>
</li>
";
$('#filelist').append fileitem;
setRemove();
setRemove = ->
$(".remove").unbind();
$(".remove").click ->
index = $(#).parent().parent().index();
files.splice index, 1;
$('.file-item').eq(index).remove();
Here is my form file that gets rendered but the upload.js file doesn't get called because it's already loaded on the main page. When the the new form button gets clicked it renders this form in a modal.
- #ticket.errors.full_messages.each do |message|
.error= message
= render 'layouts/standard_flash'
%ZenTicketForm{ title: 'Submit Help Request', :multipart => true, data: { remote: true } }
.col-xs-12.col-sm-12.col-md-12.col-lg-12{style: 'padding:0;'}
.col-xs-12.col-sm-12.col-md-12.col-lg-6
%dl.dl-horizontal
%dt Type
%dd.show-more-container
%ZenSelect#ticket_type{options: ['Questions', 'Incidents', 'Problems', 'Tasks'],
class: 'select2',
placeholder: t('activerecord.placeholders.zen_support/ticket.ticket_type') }
.col-xs-12.col-sm-12.col-md-12.col-lg-12
%dl.dl-horizontal
%dt Subject
%dd.show-more-container
%input.form-control{ type: 'text',
name: 'zen_support_ticket[subject]',
placeholder: t('activerecord.placeholders.zen_support/ticket.subject') }
.col-xs-12.col-sm-12.col-md-12.col-lg-6
%dl.dl-horizontal
%dt Priority
%dd.show-more-container
%ZenSelect#priority{ options: ['Low', 'Normal', 'High', 'Urgent'],
data: { placeholder: "activerecord.placeholders.zen_support/ticket.priority" },
class: 'select2' }
.col-xs-12.col-sm-12.col-md-12.col-lg-12
%dl.dl-horizontal
%dt Comment
%dd.show-more-container
%ZenTextArea#comment{ placeholder: t('activerecord.placeholders.zen_support/ticket.comment'),
error: #zendesk_ticket.errors&.dig(:comment) }
%dl.dl-horizontal
.new-show-less
%button.fileUpload.btn.btn-default#upload_button{type: "button"}
Attach File
%input.upload#file_input{:name => "attachments[]", multiple: true, :type => "file"}
%ul#filelist
You can put the JS code directly inside the js.erb file and it'll only be executed when that partial is rendered.
See more:
https://guides.rubyonrails.org/working_with_javascript_in_rails.html
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...
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
I ve used the fullcalendar assets gem for listing out all the events in the calendar, i have tried to modify the calendar as per my needs but for this scenario i am getting confused.
Ive used https://github.com/bokmann/rails3_fullcalendar
Scenario:
I have to filtered out all the appointments in the calendar for a particular worker. so in my appointments controller ive listed all the appointments in this way.
#appointments = #client.appointments
and it is listing all the appointments of a client, so now i ve to again filter out the appointments based on the selection of drop down button where i am listing all the workers of the client. so based on the worker selected, it will show the appointments of that particular selected worker.
Code tried
1. Rails Way
First i ve tried in the rails way that i needed to pass the id of the worker from the drop down to the controller, the code for drop down i ve used:
<%= form_tag appointments_path do %>
<%= select_tag(:worker_id, options_from_collection_for_select(#client.workers, :id, :alias), :include_blank =>true)%>
<%=submit_tag "Display"%>
<% end %>
But i dont know what to pass in the controller for fetching the records.
2. JS way
<%= select_tag(:worker_id, options_from_collection_for_select(#client.workers, :id, :alias), :include_blank =>true),:onchange => 'a(this.value)'%>
calendar.js
function a(pointer){
var intWorkerId = pointer;
alert(intWorkerId);
$.ajax({
url:'/appointments',
dataType: "json",
data:({
id:intWorkerId
}),
type:'get',
success:function(result){
alert(result);
$('#content').html(result);
console.log(1);
}
});
}
Some how the id of a worker i am getting in the controller as i ve tried to print the value and tried also to print the values from that id and it is correct but i dont know how to proceed.
Appointment.rb
def as_json(options = {})
{
:id => self.id,
:title => self.title,
:description => self.description || "",
:start => appointment_start_time.rfc822,
:end => appointment_end_time.rfc822,
:allDay => self.all_day,
:recurring => false,
:url => Rails.application.routes.url_helpers.appointment_path(id)
#:color => "red"
}
Appointment_controller.rb
if params[:id]
##appointments = #client.workers.params[:id].appointments
#p "*********id values****#{params[:id]}"
#worker = Worker.find(params[:id])
#p"***** #{worker.alias}"
##appointments = worker.appointments
#p "******* #{#appointments.count}"
p "*******hello id is here*******"
else
#appointments = "hello"
p "*******hello id is not here*******"
end
I ve tried every possible combination but not able to get results. Please help me.
Thanks
If appointments is an association on Worker you can get the clients worker like this:
#worker = #client.workers.find(params[:id])
The get that worker's appointments:
#appointments = #worker.appointments
This is assuming that in your Appointment class you have:
class Appointment < ActiveRecord::Base
belongs_to :worker
end
And your Worker:
class Worker < ActiveRecord::Base
has_many :appointments
end
In your controller you also need to get the #client. How are you currently doing that? Is it current_user? If not you need to pass in the client id in your form:
<%= form_tag appointments_path do %>
<%= select_tag(:worker_id, options_from_collection_for_select(#client.workers, :id, :alias), :include_blank =>true)%>
<%= hidden_field_tag :client_id, session[:client_id] # or wherever you store this
<%=submit_tag "Display"%>
<% end %>
Now you can find the client in your controller:
#client = Client.find(params[:client_id])
Also note that in the example form you provided you're passing the id of the worker as :worker_id, so you need to use params[:worker_id] in your controller. The JS example you provided uses :id so I'm assuming that's the approach you're going with since you use params[:id] in your controller example.
Finally, return the appointments as a JSON array:
class AppointmentsController < ApplicationController
def index
if params[:id]
#appointments = #client.workers.find(params[:id])
render json: #appointments.map(&:as_json)
else
#appointments = "hello"
p "*******hello id is not here*******"
end
I found the solution by re-rendering the calendar once again in the same js file
function RenderCalendar(eId) {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'agendaWeek',
aspectRatio: 1.5,
slotMinutes: 30,
slotEventOverlap: true,
editable: true,
timeFormat: 'h:mm t{ - h:mm t} ',
titleFormat: {
month: 'MMMM yyyy', // September 2009
week: "| MMM d[ yyyy] { '—' MMM d | yyyy}", // |Sep 7 - Sep 13|, 2009
day: 'dddd, MMM d, yyyy' // Tuesday, Sep 8, 2009
},
events: {
url: '/appointments',
cache: true,
type: 'GET',
data: {
id: eId
},
error: function () {
alert('there was an error while fetching events!');
},
},
I'm having trouble displaying the Uservoice widget on my page. I copied the javascript code from the Uservoice admin, converted it to HAML then pasted on to my app:
layouts/_uservoice.html.haml
:javascript
(function(){
var uv=document.createElement('script');
uv.type='text/javascript';uv.async=true;
uv.src='//widget.uservoice.com/Qho4ZF2W4O43bJ8Opc65g.js';
var s=document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(uv,s)
})()
:javascript
UserVoice = window.UserVoice || [];
UserVoice.push(['showTab', 'classic_widget', {
mode: 'full',
primary_color: '#cc6d00',
link_color: '#007dbf',
default_mode: 'support',
forum_id: 216289,
tab_label: 'Feedback & Support',
tab_color: '#cc6d00',
tab_position: 'middle-right',
tab_inverted: false
}]);
and my home view:
<doctype html>
%html
%head
= render 'shared/meta'
= favicon_link_tag 'tgnd_favicon.png'
%body
= render 'shared/fb'
#main{:role => "main"}
= render 'shared/header'
= render 'shared/sub_header'
.content_wrap.container
.content.box_normal
= render 'layouts/messages'
= yield
/ ! end of .container
.push
= render 'layouts/uservoice'
= render 'shared/footer'
= render 'shared/dialogs'