Can I change the instance variable using ajax in rails? - javascript

I have used ajax to get the object from controller.
$('#city').on('change',function(){
$.ajax({
url: "/courses/index",
type: "GET",
data: {city: $('#city').val() },
success: function(responseData) {
alert(responseData);
}
});
So the responseData is the json format collection of the courses.
Currently, I have a html code: <%= #courses.first.name %>
How to modify the #courses instance which the result is the responseData of ajax.
Thanks.

You can't change the instance variable, because that belongs to the instance of the Ruby class you're using.
Using ajax invokes a new instance of your respective classes (on the server); javascript only works with the front-end view (HTML code / DOM), so you have to populate that with the response:
$(document).on('change', '#city', function(){
$.ajax({
url: "/courses/index",
type: "GET",
data: {city: $('#city').val() },
success: function(responseData) {
course = JSON.parse(responseData);
$(".element").html(course.name);
}
});
});
Without knowing which data you're expecting back etc, it's kind of tough to know how to "parse" your data. However, the important thing to note is that you should not be trying to change the ERB, instead identify the html and replace it with the JSON you receive back.
Also, you'll need to use something like JSON.parse to create a workable object in your javascript (which you can then use to populate your page with).

Sounds like you want to POST the information back to the rails application via Ajax.

Related

In Javascript array there are items, but when I pass an array to an MVC Controller, list/array is empty

I'm using ajax POST method
to send objects stored in an array to Mvc Controller to save them to a database, but list in my controller is allways empty
while in Javascript there are items in an array.
here is my code with Console.Log.
My controller is called a ProductController, ActionMethod is called Print, so I written:
"Product/Print"
Console.Log showed this:
So there are 3 items!
var print = function () {
console.log(productList);
$.ajax({
type: "POST",
url: "Product/Print",
traditional: true,
data: { productList: JSON.stringify(productList) }
});}
And when Method in my controller is called list is empty as image shows:
Obliviously something is wrong, and I don't know what, I'm trying to figure it out but It's kinda hard, because I thought everything is allright,
I'm new to javascript so probably this is not best approach?
Thanks guys
Cheers
When sending complex data over ajax, you need to send the json stringified version of the js object while specifying the contentType as "application/json". With the Content-Type header, the model binder will be able to read the data from the right place (in this case, the request body) and map to your parameter.
Also you do not need to specify the parameter name in your data(which will create a json string like productList=yourArraySuff and model binder won't be able to deserialize that to your parameter type). Just send the stringified version of your array.
This should work
var productList = [{ code: 'abc' }, { code: 'def' }];
var url = "Product/Print";
$.ajax({
type: "POST",
url: url,
contentType:"application/json",
data: JSON.stringify(productList)
}).done(function(res) {
console.log('result from the call ',res);
}).fail(function(x, a, e) {
alert(e);
});
If your js code is inside the razor view, you can also leverage the Url.Action helper method to generate the correct relative url to the action method.
var url = "#Url.Action("Print","Product)";

Ajax request not passing parameter to ASP.NET MVC controller

Tried looking in stackoverflow because this looked so trivial. Found many similar questions and read through them. Found no solution using these examples. Here is my code, can anyone help?
function testAjax() {
return $.ajax({
type: "GET",
url: '#Url.Action("Nodes","Competence", new { userId = Sven });',
contentType: "application/json;charset=utf-8",
dataType: "json"
});
}
var promise = testAjax();
promise.success(function (data) {
var dataConverted = JSON.stringify(data);
$('#tree').treeview({ data: dataConverted, multiSelect: true });
});
ASP.NET MVC method
public JsonResult Nodes(string userId)
{
var temp = userId;
var list = new List<Node>();
list.Add(new Node("Test1"));
list.Add(new Node("Test2"));
list.Add(new Node("Test3"));
return Json(list, JsonRequestBehavior.AllowGet);
}
EDIT:
Just before I was about to turn crazy on Halloween night, i figured out to try in a new session. Turns out it was just a caching problem..Thanks for the help everyone
Since your server may not expecting a request with JSON content, try removing the contentType parameter on your ajax call. Its default value is "application/x-www-form-urlencoded; charset=UTF-8" and is fine for most cases.
It's type should be "POST"
return $.ajax({
type: "POST",
url: '#Url.Action("Nodes","Competence")',
data: { userId: "Test" },
contentType: "application/json;charset=utf-8",
dataType: "json"
});
As it's a GET verb, it'll be easiest to pass this in as a querystring value. This also conforms better with a RESTful design.
For example replace #Url.Action("Nodes","Competence")
with
#Url.Action("Nodes","Competence", new { userId = id });
Then you can delete the data property. This will append ?userId=valueOfId into your url and then it should be mapped correctly to your action with the userId correctly populated.
Update
As #freedomn-m stated:
This will generate the url when the view is built server-side. If the
parameters never change, then fine - but it's relatively unlikely that
the parameters won't change, in which case you should add the url
parameters at runtime if you want them on querystring.
This is completely accurate. Without knowing your exact implementation I can only make assumptions. But technically you could wrap your ajax call in a function and then you could either pass in the userId and generate the url within that function or pass in the url, performing the url generation outside of the function.
This would mean that you only need one function that performs the ajax request and you can have another function that gets the userId (and possibly generates the url) and then passes that into the ajax function. How you store the userId is entirely up to you, but one thing I would suggest is investigating data attributes which is a fairly well defined way for storing data on html elements.

Correct jQuery syntax for doing a $.post with a header (ASP.NET MVC)

I'm working on a ASP.NET MVC project that uses some jQuery on the client side. I have a jQuery call like this, which works correctly:
$.post($('form').attr("action"), $('form').serialize(), function(data){
// Deal with the data that came back from the ASP.NET MVC controller
}
I want to do the exact same call, except I also want to send in a custom header. I am able to successfully create and send a custom header like this:
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers['__RequestVerificationToken'] = token;
$.ajax({
url: "/report_observation/" + submitType,
cache: false,
type: "POST",
data: {
'viewModel': $('form').serialize(),
},
headers: headers,
success: function (data) {
// Deal with the data that came back from the ASP.NET MVC controller
},
error: function (response) {
alert("Error: " + response);
}
});
There are two problems with this second bit of code. One is that I have to make a custom url to go to the correct controller, and I don't know of a way to simply use $('form').attr("action") to automatically go to the correct place.
The second -- and bigger -- problem is that I'm not able to pass over the form data with $('form').serialize() as I could in the one liner $.post example. Doing a #Html.Raw(Json.Encode(Model)) in my Razor cshtml file doesn't send over the model for the whole form, presumably because this code is within a partial view that doesn't know the state of the models in the other partial views that make up this form.
Anyway, I'm thinking there must be an easy way to take this code...
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers['__RequestVerificationToken'] = token;
...and incorporate the headers property into this bit of code:
$.post($('form').attr("action"), $('form').serialize(), function(data){
// Deal with the data that came back from the ASP.NET MVC controller
}
However, I can't figure out the correct syntax. Any ideas?
OK, I figured it out. The second example can indeed work if the data field looks like this:
data: $("form").serialize(),
In other words, I had to NOT assign it to the viewModel parameter.
yes, for the second problem use that dev5000 says, and, for the URL, simply get the value for the attribute action fo the form and use it:
var url = $("from").attr("action");
$.ajax({
url: url,
...
})

How to load new content to DIV without refreshing [duplicate]

This question already has answers here:
how to reload DIV content without refreshing whole page
(8 answers)
Closed 9 years ago.
I want to load new content from the server to the DIV without refreshing the whole page.
I tried the following
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/result/?age="+ ageData +"&occasion="+
occasionData +"&relationship="+ forData +"#",
success: function (response) {
$("#testDIV").html(response);
}
});
But the problem is the whole page is loading in <DIV id="testDIV">. I want to replace the old DIV with New DIV content returned from the server not with the whole page.
You can keep your same process sense you are interested in using AJAX directly and want to manage your done function (instead of success because .done() will replace it). Here is how...
.done(function(data) {
...
}
Inside of that done function, you can filter the page content to what you want. Simply request what you want to filter with jquery like this...
var $response = $(data);
var response_title = $response.filter(".title").html(); //I'm assuming you are trying to pull just the title (perhaps an < h1 > tag, in this little example, from the entire external page!
THEN!...
$("#testDIV").html(response_title);
With the done function, based on jQuery's API, you can use this format...
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
So your final code may look something like this...
$.ajax({
type: "GET",
url: "ht.tp://127.0.0.1:8000/result/?age="+ ageData +"&occasion="+ occasionData +"&relationship="+ forData +"#"})
.done(function(response) {
var $response = $(response);
var response_title = $response.filter(".title").html();
$("#testDIV").html(response_title);
});
I like the answer by blackhawk. It uses the existing code with slight modification.
I would just condense it to a one line change like this:
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/result/?age="+ ageData +"&occasion="+
occasionData+"&relationship="+ forData +"#",
success: function (response) {
$("testDIV").html($(data).filter(".title").html());
}
});
The code you are displaying is actually correct.
The problem comes from what your server is providing.
What you are doing here is GETing a whole page via an AJAX call, and replacing the content of One div with that whole page.
Your server should not render the whole page for that call, but only the content of the div you wish to replace. If you are using framework like rails or symfony, they often provide an easy way to detect if the query is a normal GET request, or an AJAX call.
Basically you have 4 strategies at your disposal :
Make the requests to a specific endpoint that is used only for the ajax call and that returns the content of the div you wish to replace. And not the whole page.
Make the request to the same page, and detect if the request is a normal HTTP request or an AJAX call. Based on that, return the whole page or just the content of the div. You'll probably have to look for the helpers in your framework / toolbox documentation.
Make the AJAX request but ask for a JSON object. Transform your JSON in HTML on the client side to replace the content of the div. This is the "my app is just an API" approach. This is my personal favorite as this JSON endpoint can be used for other purposes (eg: a mobile app) since it carries only content, and not presentation. This also tends to be the fastest way in terms of performance since a significant part of the computation is done on the client side. On the con side, this requires you to write more JS.
Always render the whole page, and filter only what you need on the client side. This is balchawk approach. Benefit is that you don't have to modify your server, but you will waste processing time and bandwidth by returning a whole page, when only a subset is necessary.
$(function(){
$('.classloader.').on('click', function(e){
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/result/?age="+ ageData +"&occasion="+
occasionData +"&relationship="+ forData +"#",
beforeSend: function() {
$("#testDIV").hide();
$('div#loading').show();
},
success: function(html){
$("#testDIV").html($(html).filter("#mainContent").html()).show();
$('div#loading').hide();
}
});
return false;
});
})

Saving elements to database with $.ajax()

I'm trying to save dynamically created elements in my application.js file to the database. Would the code look something like this?:
$.ajax({
type: "POST",
data: { title: 'oembed.title', thumbnail_url: 'oembed.thumbnail_url'}
});
Is there anything I'm missing? Assume that oembed.title and oembed.thubnail_url hold the values I want to save, and that title and thumbnail are the database columns.
First problem I see is your data is strings. Get rid of the ' quotes
$.ajax({
type: "POST",
data: { title: oembed.title, thumbnail_url: oembed.thumbnail_url}
});
I'm going to assume you need to incorporate some user-supplied data into the new DB object - otherwise, it would be way easier to just create it from Rails.
If you're using entirely user-supplied data, you can use the serialize() method (use hidden fields for server-generated stuff):
jQuery.ajax({
url: '/path/to/whatever',
data: $('#MyForm').serialize(),
type: 'POST'
});
Or you could use the jQuery Form Plugin - it'll let you easily combine user-supplied data with server-generated data. For example:
$('#MyForm').ajaxForm({
//Hardcoded/server-generated stuff goes in here
//(and will be added to the data from the form inputs):
data: {title: oembed.title},
type: 'POST'
});
The ajaxForm() function will set up the form and its defaults, and sends an AJAX call when the user hits the submit button (see also: ajaxSubmit()).
On the Rails side, everything should work exactly the same as if the user had submitted the form normally (though you might want to just respond with a status code/message - no call for a redirect or page render).
Hope this helps!
PS: From your example, it looks like you might be able to use data: oembed in your AJAX calls. This will submit all oembed's attributes...

Categories

Resources