How to set the locale inside an Ajax call in Ruby on Rails? - ruby-on-rails

I have this Ajax function inside my application.js file:
$("#project_person_id").change(function() {
$.ajax({
url: '/projects/get_invoice_types',
data: 'person_id=' + this.value,
dataType: 'script'
})
});
Is it possible to use a locale inside that function?
When I change line 3 to this:
url: '/de/projects/get_invoice_types',
I get the desired outcome (i. e. the output in German).
But of course I would like to set this dynamically. How can this be done?
Thanks for any help.

you can set it dynamically wherever you like, i.e
var locale = "de"; // set it dynamically
and the use it as a global, like this
$("#project_person_id").change(function() {
$.ajax({
url: "/"+locale+'/projects/get_invoice_types', // use it
data: 'person_id=' + this.value,
dataType: 'script'
})
});
a more elegant why would be to set it as a data attribute to the body tag <body data-locale="de"> or to the HTML head <html lang="de">, and pull it using a function
function locale() { return $("body").data("locale") } or
function locale() { return $("html").attr("lang") } and then retrieve it like this:
$("#project_person_id").change(function() {
$.ajax({
url: "/"+locale()+'/projects/get_invoice_types', // use it
data: 'person_id=' + this.value,
dataType: 'script'
})
});
there are other options of course, these seem straightforward.

I solved this issue modifying $.get and $.post jQuery's functions.
I my case the locale is a parameter in the url, but it can be injected as Sagish did too
(function ($) {
var oPost = jQuery.post;
var oGet = jQuery.get;
jQuery.post=function(url , data , success , dataType ){
if (typeof data === "undefined") {
data={};
}
data=add_locale_to_url(data);
return oPost.apply(this,[url , data , success , dataType]);
}
jQuery.get=function(url , data , success , dataType ){
if (typeof data === "undefined") {
data={};
}
data=add_locale_to_url(data);
return oGet.apply(this,[url , data , success , dataType]);
}
})(jQuery);
And when I call $.get or $.post the locale is automatically added to the URL:
...
var remote_search=$.get("/expenses/search_users/"+$(this).val());
remote_search(function( data ) {
$("#processing").hide();
alert( "Usuari inexistent");
obj_error.val("");
});
...

I solved this issue by adding data attributes to my erb template.
<button type="button" class="btn btn-success" id="save-job-position-btn" data-locale="<%= params[:locale] %>"><%= t("save") %></button>
$( "#save-job-position-btn" ).click(function() {
var locale = $(this).data("locale");
}

Related

<function> is not defined at HTMLButtonElement.onclick

Good day,
I have a button
<button id="4" onclick="UpdateStatus(this.id)" class="btn btn-default" type="button">update</button>
that is calling an ajax function
<script>
$(document).ready(function () {
function UpdateStatus(Id) {
$.ajax({
type: "Post",//or POST
url: '/myController/UpdateSomething?Id=' + Id,
// (or whatever your url is)
data: { data1: var1 },
success: function (responsedata) {
// process on data
alert("got response as " + "'" + responsedata + "'");
}
});
}
}
</script>
My problem is that I receive an error in my view:
UpdateStatus is not defined at HTMLButtonElement.onclick
what am I doing wrong? thanks
Update
When I try to run this code
#section scripts
{
<script>
$(document).ready(function () {
//Carga datos del curso
console.log("asdf");
});</script>}
I do not get the message in my console.
The problem is, You are defining your method definition inside the document.ready event of jQuery. When the button markup was parsed and rendered, the JavaScript method was not defined, hence you are getting the error.
The jquery ready method gets executed a little later when the document is ready (parsing and rendering of the HTML is already done, DOM is safe to be accessed). By this point, the HTML has been already rendered.
Define it outside it.
<script>
function UpdateStatus(Id) {
alert('UpdateStatus called');
}
$(function () {
});
</script>
Another option is to use unobutrusive JavaScript. So instead of wiring up a click event handler to the button markup, you will wire up later, when document ready is fired.
<button id="4" class="btn btn-default" type="button">update</button>
and wire up the click event
$(function () {
$("#4").click(function (e) {
e.preventDefault();
alert('User clicked');
});
});
<script>
function F(user_id) {
var user_id = user_id;
$.ajax({
type:"GET",
url:"http://127.0.0.1:8000/preference",
data: {'user_id':user_id},
async: false,
success: function (result) {
console.log(result)
}
});
}
</script>
the first line is automatically not to display. It is the script's type and src attributes. I used the "text/javascript" and "http://code.jquery.com/jquery-latest.js".
This question I found 2 solutions. One is as the above. To divide the script into two parts. Second is to move the function to under the button tag.
It is really a scope question. But I didn't find the solution's logic. But I solve it.
This is definitely a scoping issue, because UpdateStatus defined within the scope of document.ready() function. You can declare UpdateStatus as variable outside document.ready() block and declare a function inside it:
var UpdateStatus;
$(document).ready(function () {
UpdateStatus = function () {
var buttonId = $('#4').attr('id');
$.ajax({
type: "POST",
url: '/myController/UpdateSomething',
data: { Id: buttonId, ... }, // setting parameters
success: function (responsedata) {
// process on data
alert("got response as '" + responsedata + "'");
}
});
}
});
Additionally, based from standard event registration model and separation of concerns, I suggest you to use unobtrusive JavaScript by retrieving button ID like this:
$(document).ready(function () {
$('#4').click(function() {
var buttonId = $(this).attr('id');
$.ajax({
type: "POST",
url: '/myController/UpdateSomething',
data: { Id: buttonId, ... }, // setting parameters
success: function (responsedata) {
// process on data
alert("got response as '" + responsedata + "'");
}
});
});
});
Because you're using AJAX POST, no need to use query string parameters in URL like url: '/myController/UpdateSomething?Id=' + Id.
Related issues:
Uncaught ReferenceError: (function) is not defined at HTMLButtonElement.onclick
Why is inline event handler attributes a bad idea in modern semantic HTML?

Passing "data-" to controller

I have the following code...
HTML:
<button type="button" class="btn btn-primary" id="filterData"
data-filterString="#Model.LastName">Filter</button>
TypeScript:
$("button[id='filterData']").click(() => {
var dataList = [];
var filter = $(this).data("filterString");
$("input[class='personRecord']").each(function() {
dataList.push($(this).val());
});
var parameters = JSON.stringify({ "filterString": filter, "dataList":paymentList });
$.ajax({
url: "/Employee/FilterName",
data: parameters,
type: "POST",
contentType: "application/json; charset=utf-8",
success: function () {
alert("Success");
}
});
});
Controller:
[HttpPost]
public void SendAll(string filterString, List<string> dataList) {
...
}
However, the variable filter keeps returning "undefined". How do you pass custom data items, data-filterString in this case?
In your jQuery, you can only use lower case values for the data method, even if your attributes are upper/mixed case. So you should write:
var filter = $(this).data("filterstring");
If you do use mixed case in your key, jQuery converts that to a dashed variable, so when you search for filterString, your attribute should be called data-filter-string.
$(function() {
console.log($('#test').data('filterstring'));
console.log($('#test').data('filterString'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="test" data-filterString="value1" data-filter-string="value2"></div>

How to use ajax in mvc?

I am a very beginner to mvc and ajax both.
I have tried many examples on net but I don't understand how ajax is used practically?
I have a controller named members which has GetAllMembers Method.
GetAllMembers returns a List<Members>
Now I want to use JQuery and ajax something like :
$(document).click(function () {
$.ajax({
url: "Members/GetAllMembers",
success: function () {
},
error: function () {
alert("Failed to get the members");
}
});
});
Is my URL right?
Upon success I want to display that List in a ListBox.
How can I get it? Can anyone give me a start?
$.ajax({
type: "POST",
url: "Members/GetAllMembers", //Your required php page
data: "id="+ data, //pass your required data here
success: function(response){ //You obtain the response that you echo from your controller
$('#Listbox').html(response); //The response is being printed inside the Listbox div that should have in your html page.
},
error: function () {
alert("Failed to get the members");
}
});
Hope this will help you.. :)
$(document).click(function () {
$.ajax({
url: "Members/GetAllMembers",
success: function (result) {
// do your code here
},
error: function () {
alert("Failed to get the members");
}
});
});
So your request give response in "result" variable. So you have to easily manage result variable value in foreach loop and set value in ListBox HTML.
Follow this example:
suppose you have this html:
<p>List Box - Single Select<br>
<select id="listBox" name="listbox">
</select>
</p>
So we have this js:
var template = '<option value="$value">$name</option>';
var getAllMembers = function() {
$.ajax({
url: 'Members/GetAllMembers',
dataType: 'json', //Assuming Members/GetAllMembers returns a json
success: function(response) {
$.each(response, function(index){
var option = template.replace(/\$value/g, this.value)
.replace(/\$name/g, this.name);
$('#listBox').append(option);
});
}
});
};
EDIT: Now you only need to call getAllMembers(); function.
Hope this help.
Pablo.

Dynamically added link action produces 'This request has been blocked...' error

When I add category in controller action I return JSON object:
return Json(new { categoryName = category.Name, isPrimary = isPrim ? "1" : "-1", categoryId = categoryId }, JsonRequestBehavior.AllowGet);
In JS handler function I add item on page:
...
var totalLink = "<li style='color: #bbbbbb;'>" + result.categoryName + "<a class='removeCategoryButton' href='#lnk#'>remove</a></li>";
var lnk = '#Url.Action("RemoveCategoryFromLocation", "Location", new{locationId = Model.Location.TicketId, categoryId=-1})';
totalLink = totalLink.replace('#lnk#', lnk);
totalLink = totalLink.replace('-1', result.categoryId);
$('#otherCategories').append(totalLink);
...
When I click on remove link I call the following function:
$(function () {
$('.removeCategoryButton').click(function (event) {
event.preventDefault();
$.ajax({
url: this.href,
type: 'POST',
context: this,
success: function (result) {
if(result.categoryName == 1) {
$(this).closest('li').remove();
}
}
});
return false;
});
});
But I get the following error:
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
This error happens only when I add item and want to remove it as soon after add on page. If I refresh page and click on remove link it works without problem.
Just to note when I get the error from above category is removed, so call works it just from some reason pop this error.
You seem to be adding the remove links dynamically and yet you have subscribed to the .click event handler only once when the DOM is ready. So make sure you do it in a lively manner. But since the .live() method is deprecated, depending on the jQuery version that you are using you should use either .delegate() or the .on() methods.
So with the latest version of jQuery it is recommended to use .on():
$(document).on(events, selector, data, handler);
$(document).on('click', '.removeCategoryButton', function () {
$.ajax({
url: this.href,
type: 'POST',
context: this,
success: function (result) {
if(result.categoryName == 1) {
$(this).closest('li').remove();
}
}
});
return false;
});
Notice that you no longer need to wrap this in a document.ready callback.

JQUERY GET operation not working

I'm having trouble with the following JQuery script
$('#extra_data').append('<div id="tabs-' + (tab_length + 1) + '"></div>');
$.get(url, function(data) {
$('#tabs-' + (tab_length + 1)).html(data);
});
My trouble is that the $.get(..) operation doesn't return any results - although when using firebug it shows the ajax call as expected.
Any clues?
Thanks.
Controller
<HttpPost()> _
Function GetPartialView() As ActionResult
If (Request.IsAjaxRequest()) Then
Return View("PVTest")
Else
Return View()
End If
End Function
I've filtered the request if it is Ajax. You can even pass an object to your partial view.
jQuery
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: 'POST',
url: 'Home/GetPartialView',
data: {},
dataType: 'json',
beforeSend: function(XMLHttpRequest) {
},
complete: function(XMLHttpRequest, textStatus) {
$('#extra_data').append(XMLHttpRequest.responseText);
}
});
});
</script>
Partial View (PVTest.ascx)
<%# Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl" %>
<div id="01">
Hello World
</div>
Try load method:
$('#extra_data').append('');
$('#tabs-' + (tab_length + 1)).load(url)
I think you need to use Post and [HttpPost] in ASP.NET MVC, I think there is a security
issue related to GET.
I only seem to use Post operations and remember seeing something about security.
Will see if I can verify that...
ADDED:
see: ASP.NET MVC 2.0 JsonRequestBehavior Global Setting
I would use a POST, as Mark suggested:
$.ajax({
type: 'POST',
url: url,
data: { },
dataType: 'json',
beforeSend: function(XMLHttpRequest) {
},
complete: function(XMLHttpRequest, textStatus) {
var Response = $.parseJSON(XMLHttpRequest.responseText);
}
});
the Response should contain the JSON stream. You can append it to your element.
The controller should do something like this:
<HttpPost()> _
Function DoSomething() As ActionResult
Return (Json(myObject, JsonRequestBehavior.DenyGet))
End Function

Resources