Send data via post to action create Jquery and Ruby on Rails - ruby-on-rails

I am using Jquery. I have created a array javasript called #provinces in localhost:3000/provinces/new. I need pass that array to localhost/provinces through the POST method, I mean to the create action
I created a special button for that called Send data via post
<html>
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$provinces=new Array();
$(".add").click(function(e) {
$("body").append("<label class='label1'>Add Province</label>");
$("body").append("<input type='text' class='value'/>")
$(".add").prop('disabled', true);
$("body").append("<input type='button' id='save' value='Save'>")
});
$("body").on("click","#save", function(){
$provinces.push($(".value").val());
$(".label1").remove();
$(".value").remove();
$(".add").prop('disabled', false);
$(this).remove();
});
$("body").on("click",".show", function(){
$cadena="";
for($i=0;$i<$provinces.length;$i++){
$cadena=$cadena+"\n"+$provinces[$i];
}
alert($cadena);
});
$("body").on("click",".send", function(){
});
});
</script>
</head>
<body>
<h1>New province</h1>
<button class="add">Add Province</button>
<button class="show">Show array</button>
<button class="send">SendData via post</button>
<br/><br/>
</body>
</html>

Examine this line:
$provinces=new Array();
1) In js, the $ sign has no special meaning when used like that. In fact, the $ sign is sometimes used in jQuery to indicate that a variable has been assigned a wrapped set, and your array is not a wrapped set, so the $ sign is misleading.
2) new Array() is equivalent to [], so you can simply write:
var provinces = [];
You cannot pass arrays between javascript and ruby code(or vice versa). However, you can use javascript to send a request that contains a string to a ruby program on the server.
1) You can convert your array to a string using:
JSON.stringify()
2) You can send a string to a ruby program on the server using jQuery's .ajax() function:
$.ajax({
url: '/provinces/create',
type: 'POST',
contentType: 'application/json',
data: json_str
})
.success(function(resp_data, text_status) {
console.log('resp: ' + resp_data);
console.log('status: ' + text_status);
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log('status: ' + textStatus);
console.log('error: ' + errorThrown);
})
3) On the server side, if a request has a Content-Type equal to 'application/json', Rails will automatically parse the body of a request(your json_str) into ruby Arrays and Hashes, which Rails makes available in the params hash. The array will be available as params['_json'] or params[provinces]['_json].
If you don't like having to look for your array under the '_json' key in the rails params hash, then in your js code you can convert your array to an object, like this:
var provinces = [];
...
var obj = {my_array: provinces};
var json_str = JSON.stringify(obj);
Then in your ruby code, the array will be available as params[my_array] or params[provinces][my_array].

Related

Autocomplete to loop through search terms with ajax callback results

I'm setting up an autocomplete form in which I need that every keyword/term is matched.
I'm using an ajax callback to get my results list and I tried many workarounds to convert json results to a autocomplete-capable array but I couldn't get it to work.
$(this).autocomplete({
source: function (request, response) {
$.ajax({
url: 'autocomplete.php',
data: request.term,
dataType: "json",
success: function (data) {
var dataArray = [];
for(var i in data)
dataArray.push(data[i]);
var matchArray = dataArray.slice();
var srchTerms = $.trim (request.term).split (/\s+/);
$.each (srchTerms, function (J, term) {
var regX = new RegExp (term, "i");
matchArray = $.map (matchArray, function (item) {
return regX.test (item) ? item : null;
} );
} );
response(matchArray);
},
error: function () {
response([]);
}
});
},
autoFocus: true
});
I think the code itself is working because if I push a normal javascript array it works just fine but as long as I get results from ajax and convert it to a javascript array, it doesn't work anymore.
What I trying to get is that if a given results is equal to "example book title", it should pop up even if my keywords are "example title" or "title book example" etc...
Based on your description, if the user enters multiple words, you want it to show the results for each of the searches for each of those words. For example, if the user enters "hot air", results would include all the results for "hot" and all the results for "air".
Consider the following example.
$(function() {
var availableTags = [
"win the day",
"win the heart of",
"win the heart of someone"
];
$("#tags").autocomplete({
source: function(req, resp) {
// Trim Query and split by " " (Space)
var srchTerms = req.term.trim().split(" ");
// Prepare result Arrays
var results = [],
uniqueResults = [];
// Iterate each search term and combine the results into one array
$.each(srchTerms, function(i, t) {
results = results.concat($.ui.autocomplete.filter(availableTags, t));
});
// Remove duplicates by iterating each result item
$.each(results, function(i, r) {
if ($.inArray(r, uniqueResults) === -1) uniqueResults.push(r);
});
// Send back to Autocomplete
resp(uniqueResults);
}
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="demo">
<div class="ui-widget">
<label for="tags">Multi-word search: </label>
<input id="tags">
</div>
</div>
If the user enters "win" or "win ", it will still hit the source data. If the user enters "win heart", it will filter the source data for both terms individually, combining all the results into one array. There will likely be duplicates. In the steps, we can filter those duplicates out and send the resulting array back.
In your code, you will want send each search term to PHP, which should return an Array or an Array of Objects. In the same way you'll collect all the results into one array and then filter.
Alternatively, you can do all the work on the PHP Side, send the entire chunk to PHP and have it perform the search and filtering (potentially faster) and return all the results.
Update
If all you want to do is get the array via ajax, review the following:
function (request, response) {
$.getJSON("autocomplete.php", {term: request.term}, function(data){
var matchArray = [];
$.each(data, function(key, val){
matchArray.push(val);
});
var srchTerms = $.trim(request.term).split(/\s+/);
$.each (srchTerms, function (J, term) {
var regX = new RegExp (term, "i");
matchArray = $.map (matchArray, function (item) {
return (regX.test(item) ? item : null);
});
});
response (matchArray);
});
}
This assumes that PHP will return JSON Data that is an array of results. Since you have not provided an example of the results nor a snippet of your PHP, it's hard to help further.
Hope this helps.

<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?

Is it possible to post json to mvc controller without jQuery?

I would like to post several input values to controller as a json string with only one method argument for example:
<input name="x" value="">
<input name="y" value="">
public void GetAsJson(string json)
{
}
And doing so without jQuery and with default model binding?
It is impossible to perform what you are saying without any kind of Javascript at all. With JSON, the JS stands for Javascript and Javascript is needed to perform an Ajax call anyways.
Here is how I would do it.
Remember that on the C# side of things that you aren't really accepting a JSON object, you are actually just accepting a list.
Here is the post that you are wanting. It is almost a string like you suggested however, the difference is because in your AJAX call, you need to specify the JSON.stringify and the dataType: json.
public ActionResult FruitPost(List<String> Fruit)
{
return null;
}
Here is the view:
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
function submitForm() {
var fruit = ["apple", "orange", "bananna"];
jQuery.ajax({
type: "POST",
url: "#Url.Action("FruitPost")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(fruit),
success: function (data) { alert(data); },
failure: function (errMsg) {
alert(errMsg);
}
});
}
</script>
<input type="button" value="Click" onclick="submitForm()"/>
If you are DEAD SET on doing an ajax call without JQuery... I would suggest reading this: https://www.sitepoint.com/guide-vanilla-ajax-without-jquery/
After doing so, you might change your mind.

Load partial view into div on button click without refreshing page

I know this question might be repeated but my query is different let me explain, I have a drop down in page and by selecting value in drop down list,and I click on submit button.. I want by click on submit button I need to load partial view in tag that is list of records of selected drop down list value.
i tried this :
$("#btnclick").click(function () {
$.ajax({
type: 'POST',
url: '#Url.Content("~/Search/MDLNoDataList")',
data: mdlno,
success: function (data) { $("#viewlist").innerHtml = data; }
});
});
but not getting result And I m using these many jquery plugins
<script src="../../Scripts/jquery-migrate-1.0.0.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.unobtrusive-ajax.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
If i understand correctly, below is what you need to do.
HTML Example:
<div id="records">
</div>
<select id="ddlRecordType">
<option value="1">Type 1</option>
<option value="2">Type 2</option>
</select>
<input type="submit" value="Load Records" id="btn-submit" />
jQuery Code
$(document).ready(function(){
$('#btn-submit').click(function(){
var selectedRecVal=$('#ddlRecordType').val();
$('#records').load('/LoadRecords?Id='+selectedRecVal);
return false; // to prevent default form submit
});
});
Here ?Id= is the query string parameter passed to server to get
the selected item in dropdown.
Edit: The below answer was added, as the question content changed from initial post
$("#btnclick").click(function () {
$.ajax({
type: 'POST',
url: '#Url.Action("MDLNoDataList","Search")',
data: mdlno,
success: function (data) {
// $("#viewlist")[0].innerHtml = data;
//or
$("#viewlist").html(data);
}
});
return false; //prevent default action(submit) for a button
});
Make sure you cancel the default action of form submission by returning false from your click handler:
$("#btnclick").click(function () {
$.ajax({
type: 'POST',
url: '#Url.Action("MDLNoDataList", "Search")',
data: mdlno,
success: function (data) {
$("#viewlist").html(data);
}
});
return false; // <!-- This is the important part
});
And if you are using the WebForms view engine and not Razor make sure you use the correct syntax to specify the url:
$("#btnclick").click(function () {
$.ajax({
type: 'POST',
url: '<%= Url.Action("MDLNoDataList", "Search") %>',
data: mdlno,
success: function (data) {
$("#viewlist").html(data);
}
});
return false; // <!-- This is the important part
});
If you do not return false, the form is simply submitted to the server when you click on the submit button, the browser redirects away from the page and obviously your AJAX call never has time to execute.
You will also notice some improvements I made to your original code:
Using the Url.Action helper when pointing to a server side controller action in order to take into account routes defined in your application.
Using jQuery's .html() method instead of innerHTML to set the contents of a given element.
You need AJAX for this purpose.
$.get(url, data, function(data) { $(element).append(data) });
and Partial View that is vague.
element {
overflow:hidden;
}

Jquery: How to make Slider working After Ajax call?

Hello!
i have a very nice Filter plugin i made with Jquery UI Slider, Here is the Full code And working Example:
http://jsbin.com/epikam/1/edit
Its working great, The Only problem is That After Ajax call it does not Change the Items..
Here is the Ajax call:
$.ajax({
url: "search.php",
dataType: 'json',
type: 'GET',
data: "q="+value+"&category="+cat+"&country="+country+"&page="+page,
success: function(data){
globalRequest = 0;
resultContainer.fadeOut('fast', function() {
resultContainer.html('');
for (var x in data) {
var html = '<li class="item" data-type="league2" data-id="id-'+x+'" style="position: relative;">';
html += '<label class="title">'+data[x].Title+'</label>';
html += '<img src="'+data[x].img+'">';
html += '<label class="price">New Price: '+data[x].newprice+'</label>';
html += '</li>';
resultContainer.append(html);
}
resultContainer.fadeIn('fast');
});
}
});
I tried to Use .live and .delegate With no success (Im not sure how\where to use it)
Any suggestions??
Thank you very much!!!
Eran.
Two things:
First, check that the success function is being called with something like console.log(data); in the success: callback and that there are not errors stopping the Ajax call from completing successfully. In the JavaScript console, check that the variable data has been correctly populated and contains the data you expect it to contain.
Secondly, use JQuery selectors instead of global variables within the ajax success call. E.g. use $("#resultContainer") (assuming the div has an id resultContainer) instead of the variable resultContainer.

Resources