I did a multilevel ajax call .i.e. make an ajax call and use the id value from the call to make another call... I tried calling a jquery .empty() isn't working for the data generated in the inner ajax call... But when i place the .empty() function on the outer generated element, it worked just fine... How can i fix this issue? This is my code../
$(document).on('click', '.stories', function(e) {
e.preventDefault();
var request = $.ajax({ //first ajax call///
url: 'includes/functions.php?job=front_title',
cache: false,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
type: 'get'
});
request.done(function(output) {
if (output.result === 'success') {
$('.blog').empty();
var jsonArray = $(jQuery.parseJSON(JSON.stringify(output.data))).each(function() {
var id = this.titleID;
var storyTitle = this.story_view;
var frontTitle = '<div class="blog-item"><h3>' + storyTitle + '</h3>' + '<img class="img-responsive img-story" src="images/blog/blog1.jpg" width="100%" alt="" />' + '<div class="blog-content"><div class="entry-meta"><h4>Episodes</h4></div>' + '<div class="well" style="padding-right: 10px; padding-left: 5px; width: 105%;">' + '<ul class="tag-cloud stories">';
var request2 = $.ajax({ ////inner ajax call//////
url: 'includes/functions.php?job=story_episodes',
cache: false,
data: 'id=' + id,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
type: 'get'
});
request2.done(function(output2) {
var i = 1;
if (output2.result === 'success') {
var jsonArray2 = $(jQuery.parseJSON(JSON.stringify(output2.data))).each(function() {
var id2 = this.id;
var title = this.title;
var count = this.episode_count;
if (count == 0) {
frontTitle += id2;
} else if (i % 20 == 0) {
frontTitle += '<li data-id="' + id2 + '" id="singleEpisode"><a class="btn btn-sm btn-primary" href="#story/' + storyTitle + '/' + title + '">' + i + '</a></li></ul><ul class="tag-cloud">';
} else {
frontTitle += '<li style="margin: 1px" data-id="' + id2 + '" id="singleEpisode"><a class="btn btn-sm btn-primary" href="#story/' + storyTitle + '/' + title + '">' + i + '</a></li>';
}
i += 1;
})
}
$('.blog').append(frontTitle);
frontTitle += '</ul></div></div>';
})
})
} else {
console.log('failed');
}
});
});
I really need help for this, i av been on this for two days now... I would really appreciate the help.. or is there a better way i could do this?
Related
Im not sure what is happening here, but I can not update this DIV per every row using this code. This code loads a initial user list, and loads the rest (after first 3) to a DIV dropdown triggered by click event.
<? foreach ($res as $row) { ?>
<script>
function fetchIndexUsers() {
$(function () {});
$.ajax({
url: '/ajax/ajax_live_index_users.php',
method: 'GET',
cache: false,
dataType: 'JSON',
data: {
item_id: <?=intval($row["item_id"])?>
},
success: function (data) {
var html_to_append = '';
array = [];
results = [];
$.each(data, function (i, item) {
results[i] = data[i];
array[0] = item.total;
array[1] = item.calc;
let icon = item.user.match(/(^|\W)yes($|\W)/i) ? 'arrow_upward' : 'arrow_downward';
html_to_append += '<div style="display:inline;float:left"><span class="material-icons" style="vertical-align:top;width:16px;padding-right:30px;color:#c0c0c0">' + icon + '</span></div><div style="display:inline;float:left;padding-bottom:1px"><a class="tooltip-newusers" title="' + item.username + '" href="/user/?id=' + item.user_id + '"><img style="box-shadow:2px 2px 10px #D3D3D3;height:35px;width:35px;border-radius:50%;margin-bottom:6px;margin-right:-20px;margin-top:-5px;vertical-align:middle;position:relative;z-index:10005;border:2px solid #FFF" src="/' + item.avatar + '" /></a></div><div style="clear:both"></div>';
return i <= 3;
});
if (array[0] >= 3) {
$("#live-peers-more-<?=intval($row["item_id"])?>").html('<div id="slidedown-<?=intval($row["item_id"])?>" style="user-select:none;margin-top:-14px;position:absolute;right:-20px;font-size:13px;background:purple;padding:0 6px;text-align:center;border-radius:3px;color:#FFF;font-weight:500;text-decoration:none;text-shadow:0 1px 1px rgba(0,0,0,.3);box-shadow:2px 2px 10px #D3D3D3"><a style="color:#fff;cursor:pointer">+ ' + (array.length - array[1]) + (array[1] >= 2 ? ' peers' : ' peer') + '</a></div>')
if (array[1] === 0) {
$("#live-users-more-<?=intval($row["item_id"])?>").hide();
}
}
$("#live-users-<?=intval($row["item_id"])?>").html(html_to_append);
$('.tooltip-newusers').tooltipster({
animation: 'grow',
delay: 200,
interactive: true,
theme: 'tooltipster-punk'
});
$("#live-peers-<?=intval($row["item_id"])?>").css('background', 'none');
$("#slidedown-<?=intval($row["item_id"])?>").html('<span><a style="color:#fff;cursor:pointer">+ ' + array[0] + (array[0] >= 2 ? ' peers' : ' peer') + '</a></span>');
}
});
$("#live-users-more-<?=intval($row["item_id"])?>").click(function () {
$("#slidedown-<?=intval($row["item_id"])?>").css('z-index', '9999999');
$.ajax({
url: '/ajax/ajax_live_index_users.php',
method: 'GET',
cache: false,
dataType: 'JSON',
data: {
item_id: <?=intval($row["item_id"])?>,
more: 1
},
success: function (data) {
var html_to_append = '';
$.each(results, function (i, item) {
html_to_append += '<div id="more_users" style="padding:6px;text-shadow:0 1px 1px rgba(0,0,0,.3)"><div id="peer-username">' + truncateString(item.username, 6) + '</div><a class="tooltip-newusers" title="' + item.username + '" href="/user/?id=' + item.user_id + '"><img style="height:35px;width:35px;border-radius:50%;border:2px solid #FFF" src="/' + item.avatar + '" /></a><div style="font-size:11px;font-weight:normal">' + formatBytesSpeed(item.totalspeed) + '</div></div>';
$("#slidedown-<?=intval($row["item_id"])?>").css('height', 'auto');
});
$("#slidedown-<?=intval($row["item_id"])?>").html(html_to_append);
$('.tooltip-newusers').tooltipster({
animation: 'grow',
delay: 200,
interactive: true,
theme: 'tooltipster-punk'
});
}
});
});
}
fetchIndexUsers();
setInterval(function () {
fetchIndexUsers()
}, 5000);
</script>
<div id="live-users-<?=intval($row["item_id"])?>" style="padding:10px;background:url(/images/loading-ellipsis.svg) no-repeat left">
<span style="padding-right:89px"></span>
</div>
<div id="live-users-more-<?=intval($row["item_id"])?>"></div>
<? } ?>
But any action coming back only updates the last row in from the array (PHP foreach array, with the JS emedded in the loop picking up on the ID from the iteration).
How come it only interacts with the last row? How can I update all rows since I am using a unique ID?
Thank you
You need to move the script out from the loop completely. Have ONE version of the script that delegates like this
$("#container").on("click", ".live-users-more",function () {
const item_id = $(this).prev().attr("id"); ....
and then change
<div id="live-users-more-<?=intval($row["item_id"])?>"></div>
to
<div class="live-users-more"></div>
where you have a
<div id="container"></div>
that wraps all the live user divs
I have to load more products with an ajax call when the page reaches the end.
<script>
$(window).scroll(function() {
if ($(document).height() <= ($(window).height() + $(window).scrollTop())) {
var _token = '{{ csrf_token() }}';
var theurl = 'homePaginate';
console.log(skip_arr);
$.ajax({
type: 'post',
url: theurl,
data:{_token:_token,page:page,avoid:skip_arr},
dataType: 'json',
success: function (data) {
page+=1;
printProducts(data,false,true,true)
}
});
}
});
I use a function to loop over my product to print it, in ajax call I send the page number and some times i need to avoid some products to show
function printProducts(data,is_ad,get_void,is_animate) {
console.log(page);
for (i=0;i< data.length;i++){
var id = '#col'+columnIndex;
columnIndex++;
if (columnIndex == 6){
columnIndex = 1;
}
var stars = '';
for(star = 0 ;star < Math.floor(data[i]['rate']);star++){
stars += '<i class="fas fa-star"></i>';
}
var fraction = data[i]['rate']%1;
if (fraction > 0 ){
stars += '<i class="fas fa-star-half-alt"></i>';
for(star = 0 ;star < 4-data[i]['rate'];star++){
stars += '<i class="far fa-star"></i>';
}
}else{
for(star = 0 ;star < 5-data[i]['rate'];star++){
stars += '<i class="far fa-star"></i>';
}
}
var discount ='';
if (data[i]['runningDiscount']){
discount = '<span class="discount-tag">'+data[i]['discount']['valuePercentage']+'% Off</span>';
}
if(get_void){
skip_arr.push(data[i]['id']);
}
var isFavorite = data[i]['isFavourite']?'fas':'far';
var image = '{{ url('') }}'+'/'+data[i]["image"];
var url = '{{ url('product') }}'+'/'+data[i]["id"];
var quick_cart = '';
if (data[i]["quickCart"] === true){
quick_cart = 'class="quick-add" data-item-id="'+data[i]['item']["id"]+'"';
}else{
quick_cart = 'href="'+url+'"';
}
var ad = '';
if (is_ad) ad = ' <span class="ad">Ad</span>';
var animate = '';
if(is_animate){
animate = ' animated fadeInDown ';
}
var product = '<div class="col-xs-12 product'+animate+'" data-id="'+id+'">\n' +
' <div class="row product-body">\n' +ad+ // print ad tag
' <span class="actions">\n' +
' <a '+quick_cart+'>\n' +
' <img src="{{ asset("site_assets/img/cart.png") }}" class="product-cart">\n' +
' </a>\n' +
' <a>\n' +
' <i class="'+isFavorite+' fa-heart shoptizer-color" data-id="'+data[i]["id"]+'"></i>\n' +
' </a>\n' +
' </span>\n' +
' <span class="view-icon" data-id='+ data[i]["id"]+'>\n' +
' <img src="{{ asset("site_assets/img/eye.png") }}">\n' +
' </span>\n' +discount+
' <img class="img-fluid" src="'+image+'">\n' +
' '+
' </div>\n' +
' <div class="col-sm-12">\n' +
' <span>'+data[i]['name']+' </span>\n' +
' <h6 class="shoptizer-color price">'+data[i]['price']+' EGP</h6>\n' +
' </div>\n' +
' <div class="col-xs-12 p-rate">\n' +stars+'</div>\n' +
' </div>';
$(id).append(product);
}
}
So when I reach the end it works fine but while testing the client scrolled up and down, so I got a repeated product in two rows. Why is that and how can I prevent it?
I think the problem in $(window).scroll()!!
the problem was in my ajax call I update the page on the success function so if the user reached the bottom twice before the request respond it duplicate the printed data because it send the same page so same response.
so the solution for me was to update the page
$(window).scroll(function() {
if ($(document).height() <= ($(window).height() + $(window).scrollTop())) {
var _token = '{{ csrf_token() }}';
var theurl = 'homePaginate';
$.ajax({
type: 'post',
url: theurl,
data:{_token:_token,page:page,avoid:skip_arr},
dataType: 'json',
success: function (data) {
printProducts(data,false,true,true)
}
});
page+=1;
}
});
I have this Array
var testFlows = ["test1","test2","test3","test4","test5"];
I'm trying to get the inputs one by one and generating some html (the html generated doesn't really matter).
What matters is that I want to see this html panels by the order of the testFlows array. My code is completely random. If I refresh the page they are on different positions.
One solution would be to make a synchronous ajax but it's deprecated and bad, so what else can I do?
Code:
var testFlows = ["test1","test2","test3","test4","test5"];
$.each(testFlows, function (index, testFlow) {
//get the inputs
$.ajax({
url: '/flow/getInputs',
type: 'post',
data: {testCaseName: testFlow.testCase.name},
success: function (inputNames) {
testCaseAccordion = '<div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a class="collapseTitle" data-toggle="collapse" data-parent="#accordion" href="#collapse-' + testFlow.testCase.name + index + '">' + testFlow.testCase.name + '(' + testFlow.testCase.type.name + ') <span id="eyeIcon" class="fas fa-eye float-right"></span></a></h4></div>';
testCaseAccordion += '<div id="collapse-' + testFlow.testCase.name + index + '" class="panel-collapse collapse"><div id="panel-body-' + testFlow.testCase.name + index + '" class="panel-body"></div></div>';
$('#accordion').append(testCaseAccordion);
if (testFlow.params !== null) {
var inputs = testFlow.params.split(',');
for (var i = 0; i < inputs.length; i++) {
$('#panel-body-' + testFlow.testCase.name + index).append('<strong class="color-red">' + inputNames[i] + ': </strong>' + inputs[i] + '<br>');
}
}
else {
$('#panel-body-' + testFlow.testCase.name + index).append("This test case doesn't have any inputs");
}
}
});
});
You can use promises, for example, in your case:
var testFlows = ["test1","test2","test3","test4","test5"];
function success(testFlowAndInputNames, index) {
var testFlow = testFlowAndInputNames[0];
var inputNames = testFlowAndInputNames[1];
var testCaseAccordion = '<div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a class="collapseTitle" data-toggle="collapse" data-parent="#accordion" href="#collapse-' + testFlow.testCase.name + index + '">' + testFlow.testCase.name + '(' + testFlow.testCase.type.name + ') <span id="eyeIcon" class="fas fa-eye float-right"></span></a></h4></div>';
testCaseAccordion += '<div id="collapse-' + testFlow.testCase.name + index + '" class="panel-collapse collapse"><div id="panel-body-' + testFlow.testCase.name + index + '" class="panel-body"></div></div>';
$('#accordion').append(testCaseAccordion);
if (testFlow.params !== null) {
var inputs = testFlow.params.split(',');
for (var i = 0; i < inputs.length; i++) {
$('#panel-body-' + testFlow.testCase.name + index).append('<strong class="color-red">' + inputNames[i] + ': </strong>' + inputs[i] + '<br>');
}
}
else {
$('#panel-body-' + testFlow.testCase.name + index).append("This test case doesn't have any inputs");
}
}
var arrayOfPromises = testFlows.map(function (testFlow) {
return new Promise(function (resolve, reject) {
$.ajax({
url: '/flow/getInputs',
type: 'post',
data: {testCaseName: testFlow.testCase.name},
success: resolve
});
})
.then(function(inputNames) {
return [testFlow, inputNames];
})
});
Promise.all(arrayOfPromises)
.then(function(results) {
results.forEach(success)
});
jQuery ajax returns a promise, so you could save all the promises into an array, eg:
var testFlows = ["test1", "test2", "test3", "test4", "test5"];
var testFlowsPromises = $.map(testFlows, function(testFlow, index) {
//get the inputs
return $.ajax({
url: '/flow/getInputs',
type: 'post',
data: {testCaseName: testFlow.testCase.name}
}).then(function(inputNames) {
return {
inputNames: inputNames,
testFlow: testFlow
};
});
});
Then, wait until all of them are done:
$.when.apply($, testFlowsPromises).done(function() {
$.each(arguments, function(index, data) {
// do stuff with index, data.inputNames, data.testFlow
});
});
Now you'd have an array of ajax data in the same order.
DEMO:
https://jsbin.com/fixuxezale/edit?js,console
I have HTML code looped with another jQuery. There is an input which looped too. I want to address it in jQuery Ajax... but only the first input works... and the same values are printed for the rest in the console.
success: function (r) {
var posts = JSON.parse(r)
$.each(posts, function (index) {
$('.timelineposts').html(
$('.timelineposts').html() + '<blockquote><p>' + posts[index].PostBody + '</p><footer>Posted by ' + posts[index].PostedBy + ' on ' + posts[index].PostDate + '<button class="btn btn-default" data-id="' + posts[index].PostId + '" type="button" style="color:#eb3b60;background-image:url("none");background-color:transparent;"> <i class="glyphicon glyphicon-heart" data-aos="flip-right"></i><span> ' + posts[index].Likes + ' Likes</span></button><button class="btn btn-default comment" type="button" data-postid="' + posts[index].PostId + '" style="color:#eb3b60;background-image:url("none");background-color:transparent;"><i class="glyphicon glyphicon-flash" style="color:#f9d616;"></i><span style="color:#f9d616;"> Comments</span></button></footer><input type="text" class="c"><button comment-postid="' + posts[index].PostId + '">comment</button></blockquote>'
)
/////////////////////ajax/////////////////////////
$('[comment-postid]').click(function () {
var buttonid = $(this).attr('comment-postid');
var value = $('.c').val();
$.ajax({
type: "POST",
url: "api/comments1?id=" + buttonid,
processData: false,
contentType: "application/json",
data: '{ "commentBody": "' + value + '"}',
success: function (r) {
//var res = JSON.parse(r)
console.log(buttonid);
console.log(value);
value = "";
buttonid = "";
},
error: function (r) {
console.log("ddd")
}
});
})
})
I have figured it out!
I named each class with a different postid value...so when the loop iterates, each post will have anew class, so I address it in the ajax!
<input type="text" class="'+posts[index].PostId+'" >
and in ajax: var buttonid = $(this).attr('comment-postid');
var v=$('.'+buttonid).val();
I have a jquery save function like this -
$(".SaveBtn").click(function () {
if ($("#Form1").valid()) {
var rowData = $("#TestTable").getRowData($(this).data("rowid"));
var currentRow = $(this).closest("tr");
var postData = {
testID: rowData.testID,
testNotes: currentRow.next().find(".NotesEntry").val(),
isActive: currentRow.next().next().find(".CheckEntry") == null ? "false" : currentRow.next().next().find(".CheckEntry").prop("checked"),
};
$.ajax({
type: "POST",
url: "../Services/test.asmx/UpdateTestRowData",
data: JSON.stringify(postData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.d != null) {
$("#TestTable").setGridParam({ postData: { myID: $('#hfmyID').val() }, datatype: 'json' }).trigger("reloadGrid");
}
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
}
});
The problem is with this line -
isActive: currentRow.next().next() == null ? "false" : currentRow.next().next().find(".CheckEntry").prop("checked"),
};
When currentRow.next().next() is not available, the isActive is not set as "false" and is even not in the request body to web service.
Currently the request body is {"testID":"e9c966ace446-4f73-9ba0-26e686b2a308","testNotes":"TEST"}
I expect it to be -
{"testID":"e9c966ace446-4f73-9ba0-26e686b2a308","testNotes":"TEST", "isActive":"false"}
Why the "isActive" parameter is missed and how to make it available when currentRow.next().next() is not available?
Thanks
I fixed the problem by adding the else part in the following statement -
if (data.d.IsActived) {
output += "<td colspan='6' align=\"left\"><input type='checkbox' id='cbActive" + rowId + " checked" + " name='cbManualDeactive" + rowId + "' class='CheckEntry CheckEntry' data-registrationid='" + data.d.ID + "' data-rowid='" + rowId + "'/></td>";
}
else {
output += "<td style=\"display:none;\"><input type='checkbox' id='cbActive" + rowId + " name='cbActive" + rowId + "' class='CheckEntry CheckEntry' data-registrationid='" + data.d.ID + "' data-rowid='" + rowId + "'/></td>";
}
Thanks