I am using Rails CoffeeScript to call an action in my controller, which is fine, but I can not get the response to work.
I have a form with a list of budget lines. I want to allow the use to add a new line using CoffeeScript so I don't need to reload the question.
I have got the following in CoffeeScript:
$("button[id^='new_budget_line']").on 'click', (event) ->
category_id = $(this).attr('name')
child_economy_id = $('#child_economy_id').val()
$('#form_id').submit ->
valuesToSubmit = $(this).serialize()
$.ajax
type: 'POST'
url: $(this).attr('action')
data: valuesToSubmit
dataType: 'JSON'
$.ajax({
type: 'GET'
url: '../child_economy_lines/create_line'
data:
child_economy_id: child_economy_id
category_id: category_id
cost_type: 'direct'
dataType: JSON
}).done (response) ->
alert "Hey"
$('#test_append').html("Hey you now!!")
And the following in my controller
def create_line
logger.debug "Hejsa fra create line - category id #{params[:category_id]}"
#child_economy_line = #child_economy.child_economy_lines.build(:child_economy_category_id => params[:category_id], :cost_type => params[:cost_type])
if #child_economy_line.save
respond_to do |format|
format.js {render nothing: true}
format.json {render :json => "test"}
end
end
end
The action in the controller i called fine, and the new line is created, but I can not the actions after the ajax call to work. The part from .done ...
Can anybody help me identify where it is going wrong?
Related
I have an app where a user has a portfolio that has many positions and each position has many movements. So the url for an associated movement index page for a particular position looks like: portfolio_position_movements. I have an index page with and the controller action looks like
def index
#movements = #position.movements.all
respond_to do |format|
format.html
format.json { render json: #movements}
end
end
My ajax call in my movements.js file is this:
var loadData = function(){
$.ajax({
type: 'GET',
contentType: 'application/json; charset=utf-8',
url: ?,
dataType: 'json',
success: function(data){
drawBarPlot(data);
},
failure: function(result){
error();
}
});
};
How can I pass in a dynamic route path so this will work with the movement index on any position object?
You can use erb tags in js files, for me i did it as the following:
#edit.js.erb
$modal = $('.modal'),
$modalBody = $('.modal .modal-body'),
$modalHeading = $('.modal .modal-heading');
$modalHeading.html("Edit <%= #student.full_name.titleize %>'s information");
$modalBody.html("<%= escape_javascript(render 'edit_student') %>");
$modal.modal();
Note: the file extension is .js.erb so rails can process it. I was calling a modal form and the edit method in students_controller.rb was:
def edit
#student = Student.find(params[:id])
respond_to do |format|
format.html # edit.html.erb
format.js # edit.js.erb
format.json { render json: #student }
end
end
Edit:
You can embed the JS code inside html.erb and use rails routes like:
<script>
var loadData = function(){
$.ajax({
type: 'GET',
contentType: 'application/json; charset=utf-8',
url: <%= my_ajax_path %>,
dataType: 'json',
success: function(data){
drawBarPlot(data);
},
failure: function(result){
error();
}
});
};
</script>
What is my_ajax_path?
Is a rails route defined in routes.rb for example i need a list of all available sections that students can apply to using ajax so i did the following:
1- defined a method in students_controllers.rb like this one:
def available_sections
batch_id = (params[:batch_id].nil? || params[:batch_id].empty?) ? 0 : params[:batch_id].to_i
if batch_id == 0
#sections = [].insert(0, "Select Section")
else
batch = Batch.find(params[:batch_id])
# map to name and id for use in our options_for_select
#sections = batch.sections.map{|a| [a.section_name, a.id]}
end
end
2- added a route to it in routes.rb
resources :students do
collection do
get :available_sections
post :create_multiple
end
end
3- Inside new.html.erb:
<script type="text/javascript">
$(document).ready(function() {
$('.student_section_id').hide();
$('#student_batch').change(function() {
$.ajax({
url: "/students/available_sections",
data: {
batch_id : $('#student_batch').val()
},
dataType: "script",
success: function () {
if (+$('#student_batch').val() > 0)
{
$('.student_section_id').fadeIn();
}
else
{
$('.student_section_id').fadeOut();
}
}
});
});
});
</script>
Forget about that messy code :D as it was my first steps but you get the point, and for this line url: "/students/available_sections" it should be using rails routes you can get it by calling rails routes from the command line to get a list of all your application routes
$.ajax
url: "/models"
type: "POST"
dataType: 'json'
data: {model: {name: "name", x: "x", y: "y"}}
Is there any way to check if my server eccepted this request and saved new element without making server request again?
Oh .. I figured it out.
Every time when ajax request is triggered it waits till server respond with some data. (in my example it is data in json format)
My ajax request in coffescript looks like this now:
$.ajax
url: "/models"
type: "POST"
dataType: 'json'
data: {model: {name: "name", x: "x", y: "y"}}
success: (data) ->
alert "Request was send to the server and server axcepted what I wanted to say … but I don't know if he do what I've told to him"
error: (data) ->
alert "The server says that he couldn't do what I've told him becouse of error number: #{JSON.stringify(data['status'])}"
And the most important in this case is to make server actually respond with some value of an expecting error.
So … some changes needs to be done in Controller.
I wanted to create some element so action "create" looks like this:
def create
#model = Model.new(model_params)
respond_to do |format|
if #model.save
format.html { render :nothing => true }
format.json { render :json => #model, :status => :ok}
else
format.html { ender :nothing => true }
format.json { render json: #model.errors, status: :unprocessable_entity }
end
end
end
:unprocessable_entity sends error #422
I need to set session variable on ajax call on rails. I have following ajax code:
$.ajax({
url: '/dashboard/set_session',
type: 'GET',
data: {
site_id: site_id
},
dataType : 'json'
}).done(function(data){
console.log(data);
});
And on rails end:
def set_session
puts params[:site_id]
session[:site_id] = params[:site_id]
puts session[:site_id]
respond_to do |format|
format.json { render json: 'success'}
end
end
The first and second puts print same value. That means the session is set. But when I navigate to other pages or reload the page, the session value of site_id is cleared.
How to fix this issue?
on change of a dropdown value i am trying to populate other dropdown list value.
Here i have added my new action in routes.rb :
resources :appointments do
collection do
get :getdata
end
end
This is my js code :
$("#appointment_department_id").change(function(){
//on change of department dropdown.
$.ajax({
url: "/appointment/getdata",
type: "GET",
data: {department_id: $(this).val()},
success: function(data){
alert(data);
}
error: function(data){
alert(data);
}
});
});
here is my action in controller file :
def getdata
#dept_id = params[:department_id]
department_name = #dept_id
#all_doctors = User.all; #will write my custom query later.
end
But on call to this action, it's returning error:
"NetworkError: 404 Not Found - http://localhost:3000/appointment/getdata?department_id=5"
(checked in firebug)
the error is in the ajax url, in the ajax request you are using 'appointment/getdata', but in routes you have defined appointments,
so use
$("#appointment_department_id").change(function(){
//on change of department dropdown.
$.ajax({
**url: "/appointments/getdata",**
type: "GET",
data: {department_id: $(this).val()},
success: function(data){
alert(data);
}
error: function(data){
alert(data);
}
});
});
Where's your respond_to in your controller?
If you're sending an Ajax request, you'll have to either define respond_to "JS" or "JSON" like this:
def getdata
respond_to do |format|
format.js
end
end
You could also do it like this:
Class Controller
respond_to :html,:js, :json
def getdata
respond_with(#custom_vars)
end
end
i think you forget "s" of "appointment" word in url: "/appointment/getdata", so try to add "s" like this :
$.ajax({
url: "/appointments/getdata",
...
...
I would like to change a Workorder.wostatus_id based on data in html.
In my index html, I have the wostatus.id stored like this:
<span id="woid">4</span>
I would like to update the workorder.wostatus_id = 4
This is in the workorders.js.coffee - but, it's not working:
$.ajax
type: 'POST'
url: 'http://localhost:5000/workorders'
data:
workorder:
wostatus_id: $("#woid").val()
Maybe I'm not getting to the right workorder record?
Even doing this didn't update the workorder.wostatus_id
$.ajax
type: 'POST'
url: "http://localhost:5000/workorders"
data:
workorder:
wostatus_id: '3'
This didn't work either:
$.ajax
type: 'POST'
url: "http://localhost:5000/workorder/17"
data:
wostatus_id: '7'
I'm missing something big time.
Does the ajax POST execute this code in the workorder controller????
# PUT /workorders/1
# PUT /workorders/1.json
def update
#workorder = Workorder.find(params[:id])
respond_to do |format|
if #workorder.update_attributes(params[:workorder])
format.html { redirect_to #workorder, notice: 'Workorder was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #workorder.errors, status: :unprocessable_entity }
end
end
UPDATE:
I added this to the workorder controller:
def changestatus
#workorder = Workorder.find(params[:id])
#workorder.update_attribute :wostatus_id, '4'
render nothing: true
end
I added this to the routes:
resources :workorders do
member { put :changestatus }
end
This is currently in the js.coffee:
$.ajax
type: 'PUT'
url: "http://localhost:5000/workorders/11/changestatus"
data:
wostatus_id: 4
(I'm hard coding things until I get the next step working.)
SO - this works, workorder 11 gets wostatus_id changed to 4.
But, now I'm having trouble getting the right information from the html.
The html contains 2 data fields I need - one for which workorder and the other is what the wostatus_id is.
Here is the html for the update url:
<div class="false" data-change-url="http://localhost:5000/workorders/16/changestatus">
I thought this would get that url - but, it doesn't work:
$(this).data('change-url')
If I understand correctly, then I think your sending a single value while your controller expects an array, and you're using different param names (wostatus_id on client, workorder on server).
Perhaps what you want is this:
$.ajax
type: 'POST'
url: $('#sort2').data('update-url')
data:
workorder: $('#sort2 span').map((i, el) ->
el.text()
) // Change the selector to the elements that holds the ID
Found out I didn't need any new controller code - I could just use update.
This is for jquery-ui sortable.
receive: (event, ui) ->
str_id = $(ui.item).attr('id')
woid = str_id.split('_')[1]
$.update "/workorders/" + woid,
workorder:
wostatus_id: $(this).data('wostatus-id')
Thanks for the help - you got me going in the right direction.