jQuery ajax loop containing onclick event only changes last occurrance - ajax

My page displays posts stored in my database and pairs a like/dislike button to each post.
I am trying to make it so that when a user clicks like or dislike, the value is sent to my database for later recollection.
I have a complex loop that I hope to explain:
On page load, an ajax call is made to an external php file to fetch data from my database. The result is an object array which holds "postID":value. Inside a for loop, I am storing the value inside var postID for easy access. I'm obviously going about this wrong because the code does execute, but only sends the value and postID of the last occurrence in the loop no matter which pair of buttons I press: If I have 11 posts in my database and I press "like" on post 3 it will store the value 'like' but for post 11. If I press dislike on post 7 it will store the value 'dislike' but for post 11.
So the question is, how do I fix this so when I press like or dislike for post x, it will store the value for that same post and not the last post in my database?
The array looks like this:
{"s":0,"d":[{"postID":"1"},{"postID":"2"},{""pos‌​tID":"3"},{""pos‌​tID":"4"},{""pos‌​tID":"5"},{""pos‌​tID":"6"},{""pos‌​tID":"7"},{""pos‌​tID":"8"},{""pos‌​tID":"9"},{""pos‌​tID":"10"},{""pos‌​tID":"11"}]}
The post divs are the following format:
<div id="post_#"> //# representing the postID in the database
<div id="like_#"></div> //# repesenting the postID in the database
<div id="dislike_#"></div> //# representing the postID in the database
</div>
My jQuery (includes only the like button):
$(document).ready(function() {
$.ajax({
url: 'postID.php', //fetch the above array
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (post) {
if (post.s == 0) {
//Loop through returned data array using: post.d
for (var key in post.d) {
var obj = post.d[key];
for (var prop in obj) {
var postID = obj[prop];
//When like button is clicked do this
$('#like_' + postID).click(function() {
// Declare variables
var value = '1';
// Send values to database
$.ajax({
url: 'check.php', //check.php receives the values sent to it and stores them in the database
type: 'POST',
data: 'postID=' + postID + '&value=' + value,
success: function(result) {
$('#Message_'+ contestID).html('').html(result).prependTo('#post_' + postID);
}
});
});
}
}
}
}
});
});
So again, my problem is that the second ajax loop is only sending the last instance of var postID instead of sending the postID of the post that was actually clicked.
Any ideas?

*updated to use .on() instead of .live() as its deprecated since 1.7
try this instead:
html
<div id="post_#" class="post"> //# representing the postID in the database
<div id="like_#" class="like">test</div> //# repesenting the postID in the database
<div id="dislike_#" class="dislike"></div> //# representing the postID in the database
</div>
jquery
$(document).ready(function() {
//When like button is clicked do this
$('.like').on('click', function() {
var postID = $(this).attr('id').replace('like_', '');
// Declare variables
var value = '1';
// Send values to database
$.ajax({
url: 'check.php',
//check.php receives the values sent to it and stores them in the database
type: 'POST',
data: 'postID=' + postID + '&value=' + value,
success: function(result) {
$('#Message_' + contestID).html('').html(result).prependTo(this);
}
});
});
});
Here is the link to a sample http://jsfiddle.net/TXwZk/

Related

Multiple Ajax PUTs in Laravel 4 Giving Errors

I am updating my Model through a resource controller via jQuery Ajax Put. No problems at all the first time. This works fine:
$(".addNest").click(function() {
var nid = msg; //once the LI is added, we grab the return value which is the nest ID
var name = $('.nestIn').val();
if(name == '') {
$("textarea").css("border", "1px solid red");
}else {
$.ajax({
type: 'PUT', // we update the default value
url: 'nests/' + nid,
data: {
'name': name
},
success: function(msg) {
alert(msg)
window.location.replace('nests/' + nid ); //redirect to the show view
}
});
}
});
Later in a separate code block, I try to call the PUT again like this:
$(".nestEdit").click(function() {
$(".nestEdit").hide();
var name = $('.nestName').data("name");
var nid = $('.nestName').data("id");
$(".nestName").html("<textarea class='updateNest'>"+ name +"</textarea> <span><a href='#' class='btn btn-mini nestUpdate'><i class='icon-plus'></i> Update</a></span>");
$(".nestUpdate").click(function() {
var updatedName = $('.updateNest').val();
$.ajax({
type: 'PUT', // we update the default value
url: 'nests/' + nid,
data: {
'name': updatedName
},
success: function(msg) {
alert(msg) // showing the error here
location.reload( ); //refresh the show view
}
});
});
The 'updatedName' values and the 'nid' values are passing fine when I 'alert' them. When I view the return for the first PUT it comes back fine. However, when I view the return for the second PUT I get this:
{"error":{"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"","file":"\/Applications\/MAMP\/htdocs\/n4\/bootstrap\/compiled.php","line":8643}}
Anyone have some insights here? As you can tell, I am trying to do an inline edit. I have tried to wrap everything into a function but still not helping...
Laravel does not use PUT and DELETE natively since it is not supported in all browsers, you need to send a POST request with '_method' set to either put or delete.
$.ajax({
type: 'POST',
url: 'nests/' + nid,
data: {
'name': updatedName,
'_method': update
},
success: function(msg) {
alert(msg) // showing the error here
location.reload( ); //refresh the show view
}
EDIT: Ajax request do support PUT AND DELETE.
In your JavaScript code, for the inline editing, you are not making proper use of $.
If you click on .nestEdit, it's inner function should not be calling it by name, provided you have multiple objects of the same class on that page. This is why you get the error. Instead of sending the nest ID, it's sending an array object, which your Laravel Router will not pick up, because it is more than likely not defined.
Simply put, you should not be doing this:
$(".nestEdit").click(function() {
$(".nestEdit").hide();
...
You should be making a call to this:
$(".nestEdit").click(function() {
$(this).hide();
...
So, for every .nestEdit within the inner function, you need to call for this instead.

Putting a JSON response into a hidden field and retrieving it into a function

I'm retrieving the number of rows contained by a table in my database with the following function using JSON.
function rowCount()
{
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
datatype:"json",
type: "GET",
url: "/wagafashion/ajax/CmsRowCount.htm",
success: function(response)
{
$("#rows").val(response);
},
error: function(e)
{
alert('Error: ' + e);
}
});
}
In the success handler, the response is arriving as expected. There is no problem on the server side.
The response is just mapped with the long type of Java which represents the number of rows in a database table.
I'm putting this response in a hidden field whose id is rows using $("#rows").val(response); in the success handler.
The above function is invoked when the form is submitted using the following jQuery function.
$(function() {
$('#dataForm').submit(function() {
rowCount(); //Invokes the above function that makes a JSON request.
var rows=$("#rows").val();
alert("rows = "+rows);
return false;
});
});
The alert box attempts to alert the value contained by the hidden field (which is the JSON response as described above) but it is empty for the first time. It alerts the actual value only when I press the submit button once again (without a page refresh).
Also tried to replace the preceding function with the following.
$(function() {
$('#dataForm').submit(function() {
rowCount(); //Invokes the first function that makes a JSON request.
var form = $(this),
url = form.attr('action'),
rows = form.find('input[name="rows"]').val();
alert("rows = "+rows);
return false;
});
});
But it didn't work either. Why does this happen? What is the way of retrieving the correct value of that hidden field into the preceding jQuery function?
The alert box attempts to alert the value contained by the hidden field (which is the JSON response as described above) but it is empty for the first time.
Ajax calls are asynchonrous. When you call rowCount, you start the call, but then rowCount returns and your code continues. The call doesn't complete until later (which is why ajax accepts a callback).
If you trigger the next step in what you're doing from the callback, you'll have the value. You typically do this by having rowCount accept a callback of its own, like this:
function rowCount(callback) // <==== Accept the callback
{
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
datatype:"json",
type: "GET",
url: "/wagafashion/ajax/CmsRowCount.htm",
success: function(response)
{
$("#rows").val(response);
callback(); // <==== Call the callback
},
error: function(e)
{
alert('Error: ' + e);
callback(); // <==== Probably want to give it a value telling it things failed
}
});
}
Then using it:
$(function() {
$('#dataForm').submit(function() {
var form = $(this); // <== Grab this outside the callback
rowCount(function() {
var url = form.attr('action'),
rows = form.find('input[name="rows"]').val();
alert("rows = "+rows);
});
return false;
});
});
If you want to decide whether to allow the form to be submitted on the basis of the callback, you'll have to always cancel the submission, and then trigger submitting it programmatically from the callback if you want to allow it.

mvc3 partialview doesn't load query string

I have Partial View that is updated with AJAX. The problem is that Partial View needs to take two parameters and one isn't in query string.
this is controller
public ActionResult _Unutrasnjost(string verzijaIme,int bojeId=0)
{
return PartialView(repositoryU.BojeUnutrasnjostVezano.Where(v =>v.VerzijaIme==verzijaIme&&v.BojeId == bojeId).ToList());
}
string verzijaIme is in query string but when the partialview is loaded it tells me that is undefined
int bojeId isnt in query string but when user clicks on button its send by AJAX.
I dont understand why everything is working if I put only one parameter (string or int) and if I put two parameters verzijaIme is undefined?
Its also working if I remove =0 from int bojeId and put that parameter in query string but I cant accept that kind of solution
Any suggestion?
Ajax code
function unutrasnjostData(id) {
var urlclear = '#Url.Action("_Unutrasnjost", "Configurator")' + "?bojeId=" + id;
$.ajax({
cache: false,
type: 'POST',
url: urlclear,
success: function (data) {
$('#meniDesnoIzmjeneUnutrasnjost').html(data);
}
});
}
Looks like you're not passing verzijaIme to partial view at all. You need to extend your unutrasnjostData function:
function unutrasnjostData(id, verzijaIme) {
var urlclear = '#Url.Action("_Unutrasnjost", "Configurator")' + "?bojeId=" + id + "&verzijaIme=" + verzijaIme;
$.ajax({
cache: false,
type: 'POST',
url: urlclear,
success: function (data) {
$('#meniDesnoIzmjeneUnutrasnjost').html(data);
}
});
}
Or, even better, send it in post:
$.ajax({
cache: false,
data: { bojeId: id, verzijaIme: verzijaIme },
type: 'POST',
url: urlclear,
success: function (data) {
$('#meniDesnoIzmjeneUnutrasnjost').html(data);
}
});
Don't confuse the query string from the request to the page with the query string from the AJAX call. Those are two separate requests.

Appending data on an area in the view MVC

$("##ViewBag.PageGroupID").append(data);
Now ViewBag.PageGroupID returns the id of the div at runtime.What if i want to append data in the div(the id which i will get runtime).How do i acheive this?
$('#btnPageElementClick').click(function () {
var flag = false;
var b;
$.ajax({ type: 'GET', url: '/ScriptedTestCase/pageElementPV/' + $('#PageElements').val(), data: null,
success: function (data)
{
$("##ViewBag.PageGroupID").append(data); //where divID is the id of the div you append the data.
}
});
return false;
});
Make sure that inside the controller action that rendered the view that contains the script you have shown, you have actually set this data:
ViewBag.PageGroupID = "someDivId";
Also note that in HTML ids cannot start with numbers.

Wrong to use AJAX?

I have a view(MVC3) that users place orders from. The view is bound to a model that i use to display modelitems from. There are two functionalities on this view. First you enter the customers details and then you choose the items the user has ordered. This is the code i´m using to build another model to be sent back to serverside:
var modelItems = {
ModelID: [],
Amount: []
};
var serviceModel = {
Name: $.trim($('#name').val()),
Customernumber: $.trim($('#customernumber').val()),
Address1: $.trim($('#address1').val()),
Address2: $.trim($('#address2').val()),
Zipcode: $.trim($('#zipcode').val()),
City: $.trim($('#city').val()),
Country: $.trim($('#country').val()),
Phone: $.trim($('#phone').val()),
Mobile: $.trim($('#mobile').val()),
Email: $.trim($('#email').val())
};
$('div.modelSpan').each(function (i) {
var textBox = $(this).children();
var value = $(textBox).val();
if (value != '0' && value != '') {
var modelID = $(textBox).attr('name');
modelItems.ModelID.push(modelID);
modelItems.Amount.push(value);
}
});
var accessory = {
ModelItems: modelItems,
ServiceModel: serviceModel
};
$.ajax({
url: '/Site/Order', //Renamed sec reasons
type: "POST",
data: JSON.stringify(accessory),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (ordernumber) {
window.location.href = "/Site/OrderInfo/" + businessAB + "/" + ordernumber;
},
error: function () {
alert('error');
}
});
Cool thing in MVC3 is that my accessory automatically binds to my model on serverside called AccessoriesModel. On callback success i´m setting new href to a receipt site to show user what has been created. This all works but my issue is that i would like the receipt view(OrderInfo) to be returned from my controller that receives the [httppost] and not setting new href. Is there a way to do this? This is easy when using regular form submit but because the values for my model dont come from one form it complicates things. Maybe I shouldn´t use AJAX?
You could use knockout JS with Ajax and render your pages with a mixture of JavaScript objects and regular html.

Resources