Multiple POSTs with jQuery and AJAX - javascript

I'm having an issue with posting data via AJAX through a drag and drop interface. The data indeed is hitting my POST URL as defined, however, each and every time, the POST hits twice thereby causing the processing URL to handle the data again.
The premise of my application (at least this piece of it) was starting by basically using the code found at http://jsfiddle.net/UjQVw/2/ and to modify it for my needs.
I needed to have a container of items (in this case names) that were draggable to a user-defined number of divs on the opposite side of the screen -- whereby making 'room assignments' with a list of people.
Everything, except for the double POST is working well. If anyone can assist, I'd be most appreciative!
SAMPLE HTML CODE:
<div class="parent_list">
<h1>Registrants</h1>
<ul id="unplaced" class="group">
<?
foreach ($obj->function as $key => $value)
{
?>
<li data-group-id="0" data-post-id="<?=$value["rmid"]?>">
<?=$value["lname"]?>, <?=$value["fname"]?>
</li>
<?
}
?>
</ul>
</div>
<div class="lists">
<h1>Rooms</h1>
<ul style="display:none" id="new_list" class="group"></ul>
</div>
<input type="button" id='add' value="+ Add Room"/>
SAMPLE JS
<script>
var count = 0;
$("#add").click(function() {
count++;
var $clone = $("#new_list").clone();
$clone.attr({
id: count,
style: "" // remove "display:none"
});
$clone.find(".group").each(function(){
$(this).attr({
id: $(this).attr("id") + count
});
});
$(".lists").append($clone);
$('.group').sortable({
connectWith: '.group',
update: function(event, ui) {
var lodging = new Array();
$('.group li').each(function(i) {
var id = $(this).attr('data-post-id');
var group = $(this).parent().attr('id');
lodging.push(group+'_'+id);
});
console.log(event);
$.ajax({
type : "POST",
cache : false,
url : 'lodging_process.php',
data: {
'lodging[]': lodging
},
});
}
});
});
</script>

You could always buffer it with a boolean.
<script>
var sending = false; //Buffering variable
var count = 0;
$("#add").click(function() {
count++;
var $clone = $("#new_list").clone();
$clone.attr({
id: count,
style: "" // remove "display:none"
});
$clone.find(".group").each(function(){
$(this).attr({
id: $(this).attr("id") + count
});
});
$(".lists").append($clone);
$('.group').sortable({
connectWith: '.group',
update: function(event, ui) {
var lodging = new Array();
$('.group li').each(function(i) {
var id = $(this).attr('data-post-id');
var group = $(this).parent().attr('id');
lodging.push(group+'_'+id);
});
console.log(event);
if(!sending) { //Make sure we are not already sending a request
sending = true;
$.ajax({
type : "POST",
cache : false,
url : 'lodging_process.php',
data: {
'lodging[]': lodging
},
success: {
sending = false; //Upon finishing, allow another ajax command of this type
},
error: {
sending = false;
}
});
}
}
});
});
</script>
See if that works.

After the response by #John, I did some more testing and looking around and found this gem that's apparently stumped several others by me. As stated in the original question, the POST was indeed working...it was simply posting TWICE after each event. The reason for this is that there were changes in BOTH lists, thereby initiating the callback for EACH list that's affected.
Adding this simple if check as outlined here: https://forum.jquery.com/topic/sortables-update-callback-and-connectwith
update:function(e,ui) {
if (this === ui.item.parent()[0]) {
//your code here
}
}
has done the trick for me. Hope this information helps others with multiple callbacks using jQuery sortable and connectWith functions.
So...the new JS looks like this:
<script>
var count = 0;
$("#add").click(function() {
count++;
var $clone = $("#new_list").clone();
$clone.attr({
id: count,
style: "" // remove "display:none"
});
$clone.find(".group").each(function(){
$(this).attr({
id: $(this).attr("id") + count
});
});
$(".lists").append($clone);
$('.group').sortable({
connectWith: '.group',
update: function(event, ui) {
if (this == ui.item.parent()[0]) {
var lodging = new Array();
$('.group li').each(function(i) {
var id = $(this).attr('data-post-id');
var group = $(this).parent().attr('id');
lodging.push(group+'_'+id);
});
$.ajax({
type : "POST",
cache : false,
url : 'lodging_process.php',
data: {
'lodging[]': lodging
},
});
}
}
});
});
</script>

Related

Reload script (Poptrox) after ajax request

So I'm using an AJAX request to load data from the database into a DIV. At the same time, I'm using the same data inside the DIV in a different script (Poptrox) witch does some design stuff.
Without the AJAX request, poptrox works, but if I'm using it together with poptrox it doesn't do the designing anymore.
Is there a way to reload the poptrox-script after the ajax request?
NOTE: the AJAX-Code and the Poptrox-code are placed inside the "main.js"!
Thanks in advance!
php:
<script src="assets/js/jquery.min.js"></script>
<section class="wrapper">
<form action="kochbuch.html" method="get" id="searchfilter">
<input type="text" class="searchBox" name="searchBox" id="searchBox" placeholder="Search..">
<button type="submit" id="searchBtn"><i class="fas fa-search"></i></button>
</form>
</section>
<section class="wrapper">
<div id="gerichte"></div>
</section>
<script src="assets/js/main.js"></script>
js-ajax:
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
if (urlParams.has('searchBox')){
var searchBox = urlParams.get('searchBox');
$.ajax({
type: "POST",
url: "kochbuch/fetchdata.php",
data: {
"search_post_btn": 1,
"searchBox": searchBox,
},
dataType: "json",
success: function (response) {
$("#gerichte").html(response);
}
});
};
js-poptrox:
// Gerichte.
var $gerichte = $('#gerichte');
// Thumbs.
$gerichte.children('.thumb').each(function() {
var $this = $(this),
$image = $this.find('.image'), $image_img = $image.children('img'),
x;
// No image? Bail.
if ($image.length == 0)
return;
// Image.
// This sets the background of the "image" <span> to the image pointed to by its child
// <img> (which is then hidden). Gives us way more flexibility.
// Set background.
$image.css('background-image', 'url(' + $image_img.attr('src') + ')');
// Set background position.
if (x = $image_img.data('position'))
$image.css('background-position', x);
// Hide original img.
$image_img.hide();
});
// Poptrox.
$gerichte.poptrox({
baseZIndex: 20000,
caption: function($a) {
var s = '';
$a.nextAll().each(function() {
s += this.outerHTML;
});
return s;
},
fadeSpeed: 300,
onPopupClose: function() { $body.removeClass('modal-active'); },
onPopupOpen: function() { $body.addClass('modal-active'); },
overlayOpacity: 0,
popupCloserText: '',
popupHeight: 150,
popupLoaderText: '',
popupSpeed: 300,
popupWidth: 150,
selector: '.thumb > a.image',
usePopupCaption: true,
usePopupCloser: true,
usePopupDefaultStyling: false,
usePopupForceClose: true,
usePopupLoader: true,
usePopupNav: true,
windowMargin: 50
});
// Hack: Set margins to 0 when 'xsmall' activates.
breakpoints.on('<=xsmall', function() {
$main[0]._poptrox.windowMargin = 0;
});
breakpoints.on('>xsmall', function() {
$main[0]._poptrox.windowMargin = 50;
});
alright, i found one possible solution, but know the preloaded data ist formated:
the whole poptrox code has to be wrapped by this function:
$(document).ajaxStop(function () {
// function after ajax
});
If you know any better solution, feel free to submit :)
EDIT:
alright, my solution was as follows:
if (urlParams.has('searchBox')){
var searchBox = urlParams.get('searchBox');
} else {
var searchBox = '';
}
$.ajax({ .....

what would be the javascript derived code for media title editing based on following delete and update codes?

The following code chunk lets users add images and add a title to them, I want to develop a function which could let users edit and update the pre-added title
//delete
$(document).on('click', 'a.wptr-delete-media', function() {
var id = $(this).data('id');
$.post(ajaxurl, {
action:'wptr_delete_media',
id: id,
cookie: encodeURIComponent(document.cookie)
}, function( resp ){
if( resp.success)
$('#mpp-uploaded-media-item-'+id).remove();
else
alert(resp.message);
}, 'json');
return false;
});
This is the code for deleting the image.
//update captions
$(document).on('click', 'button.wptr-update-media-caption', function loreal() {
var $form = $($(this).parents('form.wptr-media-edit-form').get(0));
var id = $form.find('.wptr-editable-media-id').val();
var title = $form.find('.wptr-media-editable-caption').val();
$.post(ajaxurl, {
action:'wptr_update_media',
id: id,
title:title,
cookie: encodeURIComponent(document.cookie)
}, function( resp ){
if( resp.success) {
$form.toggleClass('wptr-hidden');
$form.prev('.wptr-media-caption ').find('span').html(title);
$form.prev('.wptr-media-caption').toggleClass('wptr-hidden');
}
else
alert(resp.message);
}, 'json');
return false;
});
This is the code for adding a title to the uploaded image.
How can I develop a function to edit the already added title to that image ?
EDIT::
$(document).on('click', 'a.wptr-edit-media', function hilton() {
var id = $(this).data('id');
var $lee = $($(this).parents('li.mpp-uploaded-media-item').get(0));
var forma = "<form class='wptr-media-edit-form'><textarea class='wptr-media-editable-caption' value='<%= title %>' style='width:93%;line-height:115%;' placeholder='Please enter caption'></textarea><input type='hidden' class='wptr-editable-media-id' value='<%= id %>' /><button class='wptr-update-media-caption'>done</button></form>";
document.getElementsByClassName('.wptr-media-caption').toggleClass('wptr-hidden');
$lee.insertAfter(forma, $lee.firstChild);
return id;
});
this is what i tried to no avail, the error is "document.getElementsByClassName('.wptr-media-caption').toggleClass('wptr-hidden'); " is not a function.
What am i doing wrong ? how to get it done god damn it.

Loading more posts not working

I am adding a LoadMore function to append more posts based on the length of current displayed posts and total posts in DOM. The issue I am having is when I console log the listofposts and I inspect the element in Google Chrome, I see the length is showing zero (0). I am not sure exactly where I have gone wrong or if the aproach I have taken is right or should I separate the two functions by first loading the first 4 posts, then create a new function separate to handle the appending?
$(document).on('pagebeforeshow', '#blogposts', function() {
//$.mobile.showPageLoadingMsg();
$.ajax({
url: "http://howtodeployit.com/category/daily-devotion/?json=recentstories&callback=",
dataType: "json",
jsonpCallback: 'successCallback',
async: true,
beforeSend: function() { $.mobile.showPageLoadingMsg(true); },
complete: function() { $.mobile.hidePageLoadingMsg(); },
success:function(data){
var $listofposts = $('data');
console.log($listofposts);
var $loadMore = $listofposts.parent().find('.load-more');
// console.log($loadMore);
currentPage = 0;
postsPerPage = 4;
var showMorePosts = function () {
$offset = currentPage * postsPerPage, //initial value is 0
posts = data.posts.slice($offset, $offset + postsPerPage);
console.log(posts);
$.each(posts, function(i, val) {
//console.log(val);
$("#postlist").html();
var result = $('<li/>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).wrapInner('');
$('#postlist').append(result);
console.log(result);
});
if(posts.length !== postsPerPage){
alert ('True');
$loadMore.hide();
}
currentPage++;
$("#postlist").listview();
$("#postlist").listview('refresh');
}
showMorePosts();
$loadMore.on('click', showMorePosts);
}});
var $listofposts = $('data');
is asking jQuery for a list of all <data> tags in the document.
You might want to use $(data) instead.

How to create/find right ID in multiple Form elements of same type $ajax function with jQuery Mobile?

I have a collapsible part of my jQuery Mobile page that are generated from PHP output from a MS Sql databas and content render as I like it to so that part is ok.
in each section I create a form with 3 buttons and they are supposed to have unique Id:s.
All forms are also created to have a unique id created in runtime.
actions.php (renders out my elements into mobilepage i a DIV)
$counter=0; reset counter for ID:s
while (odbc_fetch_row($rs)){
// data output from Db to make like 10 collapsible with different data
$html = "";
$html = "<div data-role='collapsible-set' data-mini='true'>";
$html.="<div data-role='collapsible' data-mini='true'>";
$html.="<h3><span style=float:left;><img src='../_pic/$image' alt='$imageText' /> ".substr($Time,0,16)." $Area</span><span style='float:right;' class='ui-btn-up-c ui-btn-corner-all' cnt> $data </span></h3>";
$html.="<p>ID: $ID $Id $Status<br />$Status $Description)</p>";
$html.="<form method='post' action=''>";
$html.="<button value='action1' id='action1$counter' data-mini='true' type='Submit'>Take Action1</button>";
$html.="<button value='action2' id='action2$counter' data-mini='true' type='Submit'>Take Action1</button>";
$html.="<button value='action3' id='action3$counter' data-mini='true' type='Submit'>Take Action1</button>";
$html.="<input type='hidden' id='id$counter' name='id' value='$dataName' />";
$html.="</form>";
$html.="</div>";
$html.="</div>";
echo utf8_encode($html);
$counter++; //upcount to make Id:s unique
} //end While
Then I have this function that listens for a button that submit:
$(':submit').live('click', function() {
var button = $(this).val();
if (button == 'action1') {
$.ajax({
url: '../_php/Functions.php',
data: 'button=' + $(this).val()+'&id='+$('#id').val(),
async: true,
beforeSend: function() {
$.mobile.showPageLoadingMsg(true);
},
complete: function() {
$.mobile.hidePageLoadingMsg();
},
error: function (request,error) {
alert('error');
}
});
}
return false;
});
I cant seem to get another id than the first one since i need to make all ID:s unique in my forms and all I do now is to check: &id='+$('#id').val(). what I would like to have done is to link the button pressed-id number to my hidden field id-number so i get the right data out from it. As of now I only get the first form:s id evaluated...
If someone could point me in the right direction how to make that happen i´d be greatful.
functions.php (a switch statement is pre-testing for submit:ed action
function actions1(){
try {
if(isset($_GET['id'])){
do stuff with 'id'
}else{
do other stuff with 'id'
}
} catch(Exception $e) {
show error
}
}
If some part is unclear or if you feel I missed posting somepart - let me know. /thanks
Within event handlers this referes to the element
$(':submit').live('click', function(){
var id= this.id;
var button = $(this).val();
/* traverse within form to set hidden input, no need to worry about using ID's for them*/
$(this).closest('form').find('input[name=id]').val(id);
/* then in ajax */
data: 'button=' +button+'&id='+id,
})
Not full code....I left some of your code out for simplicity
You can use jQuery .attr() function to get an id or any other attribute value of an element.
$(':submit').live('click', function() {
var button = $(this).val();
var id = $(this).attr("id");
if (button == 'action1') {
$.ajax({
url: '../_php/Functions.php',
data: 'button=' + $(this).val()+'&id='+ id,
async: true,
beforeSend: function() {
$.mobile.showPageLoadingMsg(true);
},
complete: function() {
$.mobile.hidePageLoadingMsg();
},
error: function (request,error) {
alert('error');
}
});
}
return false;
});
The solution was to go by attributes name of my hidden input.
var id = $(this).closest("form").find(':hidden').val();

AJAX list update, get new elements and count

I have this HTML list
<ul id='usernameList'>
<li class='username'>John</li>
<li class='username'>Mark</li>
</ul>
and a form to add new names via AJAX, multiple add separated by commas. The response is a list with the names
[{name:David, newUser:yes}, {name:Sara, newUser:yes}, {name:Mark, newUser:no}]
I'm trying to insert this names sorted alphabetically in the list, like this example https://jsfiddle.net/VQu3S/7/
This is my AJAX submit
var form = $('#formUsername');
form.submit(function () {
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
dataType: "json",
beforeSend: function () {
//
},
success: function (data) {
var listUsernames = $('#usernameList');
var numUsernames = listUsernames.children().length;
$.each(data, function(i, user) {
if(user.newUser == "yes"){
var htmlUser = "<li class='username'>" + user.name + "</li>";
var added = false;
$(".username", listUsernames).each(function(){
if ($(this).text() > user.name) {
$(htmlUser).insertBefore($(this));
added = true;
}
});
if(!added)
$(htmlUser).appendTo($(listUsernames));
}
// HERE I DO alert('numUsernames')
// I get the same number of users before sending form
// How can I update here the value of listUsernames and numUsernames?
});
}
});
return false;
});
My question is, how I can update the value of listUsernames and numUsernames after adding an item?
You just need to update numUsernames at that point.
Add this where your comments are:
numUsernames = listUsernames.children().length;
listUsernames already has the updated children, as it's a reference to the parent element.
Edit: Re: your comment below:
This should probably work:
$(".username", listUsernames).each(function(){
if ($(this).text() > user.name) {
$(htmlUser).insertBefore($(this));
added = true;
return false; // stop `.each` loop.
}
});
First you don't need a double jQuery wrapping:
$(htmlUser).appendTo($(listUsernames));
listUsernames is already a jQuery object, so try:
$(htmlUser).appendTo(listUsernames);
And after every adding, you can update the numUsernames variable with:
numUsernames = listUsernames.children().length;
but this is not necessary because you can always access listUsernames.children().length in the success handler.
I update your JSFiddle
var listUsernames = $('#usernameList');
var numUsernames = listUsernames.children().length;
var data = [{name:'David', newUser:'yes'}, {name:'Sara', newUser:'yes'}, {name:'Mark', newUser:'no'}]
$.each(data, function(i, user) {
if(user.newUser == "yes"){
var htmlUser = "<li class='username'>" + user.name + "</li>";
var added = false;
$(".ingredient", listUsernames).each(function(){
if ($(this).text() > user.name) {
$(htmlUser).insertBefore($(this));
added = true;
}
});
if(!added)
$(htmlUser).appendTo($(listUsernames));
}
// HERE I DO alert('numUsernames')
// I get the same number of users before sending form
// How can I update here the value of listUsernames and numUsernames?
});

Categories

Resources