AJAX POST can reach "success" but passed variables don't exist - javascript

I have a problem with AJAX. I'm trying to POST variable from JQuery from 1 file to another file. When I use a tag "Pokračovať" to redirect myself to next page where I want to use POST variable, it says it doesn't exist. Here's my code:
HTML echoed via PHP:
echo "
<div id=posMid>
<div id=postage>
<div data-value='Slovenská pošta-1,99€' class=pick>Slovenská pošta - 1,99€ (doručenie do 3 pracovných dní)</div>
<div data-value='Kuriér-3,99€' class=pick>Kuriér - 3,99€ (doručenie nasledujúci pracovný deň)</div>
<div data-value='Osobne-0,00€' class=pick>Odber osobne na pobočke - bez poplatkov</div>
</div><!--
--><div id=pay>
<div data-value='Na účet-0,00€' class=pick>Platba na účet - bez poplatkov (overenie do 3 dní)</div>
<div data-value='Platba kartou-0,00€' class=pick>Platba kartou - bez poplatkov (overenie ihneď)</div>
<div data-value='Dobierka-2,99€' class=pick>Dobierka - 2,99€ (platba pri prevzatí)</div>
</div>
</div>";
echo "<div id=navCart>
<a href='cart.php' id=Back>Späť do košíka</a>
<a href='cartStep3.php' id=Next>Pokračovať</a></form>
</div>";
JQuery:
$('#posMid #postage .pick').click(function(){
$(this).parent().find('.pick').removeClass('selected');
$(this).addClass('selected');
var postage = $(this).attr('data-value');
$.ajax({
type: "POST",
url: "cartStep3.php",
data:{ post: postage },
success: function(data){
console.log(postage);
}
});
});
Please help, I really don't know where's the problem.
Postage sent:
Response received:

I see it now. When I click on one of the items it performs the AJAX request and returns a truckload of HTML. The problem isn't the code - it's the logic. Once an item is picked, the AJAX runs right away but the variable is no longer available when you click "pokračovať". What you need to do is rethink your logic for what you want done when you click "pokračovať". I am adding two images to your original post to show you what I see. – Jay Blanchard 11 mins ago

Related

Toggle DIV element

Ok, this seems to be a easy question but I'm not able to get it.
I have index.php and find.php in my project.
In index.php, I'm showing results of list-group items as follows
<div id="showDetails">
</div>
<div id="showList">
//All my list-group items are listed here
</div>
My Ajax returning the list-group as follows
function funcReadRecord() {
var readrecord1 = "readrecord1";
var sometext = $('#SNOW_INC').val();
$.ajax({
url : "find.php",
type : 'post' ,
data : { readrecord1 : readrecord1,
sometext : sometext } ,
success : function(data, status){
$('#showList').html(data);
}
});
}
Now, I'm returning the values as a HTML link so it looks like this
<div id="showList">
data 1
data 2
data 3
</div>
What I want is when I click data 1 link, I want to show showDetails div with data 1 populated. Then when I click data 2 link, it changes to data 2 in showDetails.
How do I do that?
Probably the information I've provided is not enough but feel free to ask and I'll provide more.
The simplest solution would be to add a click handler to each item that calls a function, passing in the id of the item you want to display.
Within that function, fetch the data for the given item and show it.
function showData(which) {
console.log(`fetch data ${which} here and show it in the data div.`);
document.getElementById('showData').innerHTML = `show data ${which}`
return false; // prevents navigation on the clicked link
}
<div id="showList">
<a onclick="showData(1)" href="#">data 1</a>
<a onclick="showData(2)" href="#">data 2</a>
<a onclick="showData(3)" href="#">data 3</a>
</div>
<div id="showData"></div>

is there a way to update a div with new content only using ajax

This is the div that i am updating
but i want to add a active class to the (li) item
every time the div refreshes the active class goes away
so i don`t want to refresh all the data in the (ul) but
only add (li) if there is a new data in the database,
with out refreshing the previous (li) items
<div id="contacts">
<ul id="rooms" class="rooms">
<!-- This is where the data get inserted -->
<!-- the ajax call and this -->
<li class='contact' data-val='<?php echo $room['id']; ?>'>
<div class='wrap'>
<div class='meta'>
<p class='name'><?php echo $room['sender']; ?></p>
<p class='preview'><?php echo $room['senderemail']; ?></p>
</div>
</div>
</li>
</ul>
</div>
this is my ajax call
$(document).ready(function() {
var interval = setInterval(function(){
$.ajax({
url: 'rooms.php',
success: function(data){
$('#rooms').html(data);
}
});
}, 1000);
});
in the room php
$rooms = get_rooms();
foreach($rooms as $room){
?>
<li class='contact' data-val='<?php echo $room['id']; ?>'>
<div class='wrap'>
<div class='meta'>
<p class='name'><?php echo $room['sender']; ?></p>
<p class='preview'><?php echo $room['senderemail']; ?></p>
</div>
</div>
</li>
<?php
}
the get_rooms() function
function get_rooms() {
$sql = "SELECT id, sender, senderemail FROM chatroom ";
$result = mysqli_query($GLOBALS['dbh'], $sql);
$rooms = array();
while($room = mysqli_fetch_assoc($result)){
$rooms[] = array('id'=>$room['id'], 'sender'=>$room['sender'],
'senderemail'=>$room['senderemail']);
}
return $rooms;
}
You Just need to push new data to the div as below just replace your line with:
$('#rooms').append(data);
this will add new <li> in your existing <div> after the last <li>
jquery append()
To get the id of the last <li>
var lastId = $( "#rooms li" ).last().attr('id');
Once you get the last id then pass it in your ajax call.
If I understand you correctly, your problem is that you lose the active class (which you clicked on the li container) when there is new data.
This has to do with the fact that you exchange all of the content.
There are now three options. Either
You give the rooms.php the id of the currently active li-container
and this script sets the active class for the affected container.
You transfer all the chatrooms (ids) already shown to rooms.php and only
load the new ones (this means effort later with sorting).
You save the active li class and re set it after content changed (this is the fastest)
f.e: in your Ajax succes functions:
let id=0;
let active_li = $('li.active');
if (active_li.length>0) id=active_li.data('val');
$('#rooms').html(data);
if (id!=0) $('li[data-val="'+id+'"]').addClass ('active');
A few other thoughts:
Note the interval of 1000ms. Possible it makes Problems if the request lasts longer than 1000ms. This may still work well in your tests, but maybe not anymore if there are a hundred or 1000 users in your application.
Doesn't it make sense to tell the server when you click the active room and save it in a session so that the server knows which room is active in the client?
You need to simply update your JS code like:
$(document).ready(function() {
var active_list = '';
var interval = setInterval(function(){
$.ajax({
url: 'rooms.php',
beforeSend: function(){
active_list = $('#rooms').find('li.contact.active').attr('data-val');
}
success: function(data){
$('#rooms').html(data);
$(data).find('li[data-val="' + active_list +'"]').addClass('active');
}
});
}, 1000);
});
This should solve your problem and Let me know if you still face any issue.

Jquery Classes and InnerHtml

So what I'm doing is pulling battery voltage and the state of a battery from a Mysql database processing the data in data.php and putting that into a Json array all that is fine. When I get to the Javascript side I get stuck.
2 Questions:
Question 1: How do insert the value into id voltage in html without removing the span?
HTML Code:
<div id="voltState" class="tile-box bg-green">
<div class="tile-header">
Battery Status
<div class="float-right">
<i class="glyph-icon icon-bolt"></i>
Green
</div>
</div>
<div class="tile-content-wrapper">
<i class="glyph-icon icon-database"></i>
<div id="voltage" class="tile-content">
<span>volts</span>
</div>
</div>
</div>
Questions 2: class="tile-box bg-green"> I want to replace with the var status from the Javascript so it looks something like class="tile-box bg-(status var here)">
$(document).ready(function() {
sensorData();
});
function sensorData(){
$.ajax({
type:'GET',
url:"data.php",
data:"json",
success:function(sensor) {
//document.write(sensor);
var volt = sensor[0];
var status = sensor[1];
var date = sensor[2];
document.getElementById('voltage').innerHTML = (volt);
$("#voltState").toggleClass('bg-green bg-(STATUS VAR HERE??)');
},
dataType:'json'
});
}
setInterval(sensorData, 3000);
You can use $("#voltage").append(volt) or $("#voltage").prepend(volt) based on if you want the span before or after the value. In this case I assume you want the span after the volt so you can use the second code. If you would like the value inside a new span you can also use:
$("#voltage").prepend($("").text(volt));
You can store the previous status value in a variable lets say pastStatus. So once you have set
$("#voltState").removeClass('bg-'+pastStatus).addClass('bg-'+status);
pastStatus = status
Note: toggleClass is used when you want to switch between adding and removing the same class. It can't be used in this case since you want to add a class and remove another.
document.getElementById('voltage').appendChild(volt);
or
document.getElementById('voltage').innerHTML = '<span>'+volt+'</span>';

Like Unlike toggle button with jQuery's AJAX

Goal: I'm trying to create a button that allows users to like posts on a website, (similar to the way Facebook does it), which would also increment/decrement the number of likes besides the button as well.
Issue: Everything works well except in one edge case. If the user has already liked the post, he can unlike it but no longer like it again. It seems like the like/unlike toggle is not working and the browser is only sending an 'unlike' request to the server. If the user has never previously like the image, the like/unlike toggle seems to work just fine.
I make use of the post's data attribute to toggle like/unlike requests by making manipulations on these attributes. I'm currently using PHP through a Laravel framework, and jQuery for my front end manipulations.Below is an example of my code.
favorite.js file
$(function(){
$('.favorite-button').click(function(){
var $this=$(this);
var post_id=$this.data('postId');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
if($this.data('favoriteId')){
//decrement the favorite count
count=$this.siblings('.favorite-count');
count.html(parseInt(count.html())-1);
//send ajax request
var fav_id=$this.data('favoriteId');
$this.removeData('favoriteId');
$.ajax({
url:'/post/'+post_id+'/favorite/'+fav_id,
type:'DELETE',
success: function(result){
console.log('post was unfavorited');
},
error: function(){
console.log('error: did not favorite the post.');
}
});
}
else{
//update the favorite count
count=$this.siblings('.favorite-count');
count.html(parseInt(count.html())+1);
//send ajax post request
$.ajax({
url:'/post/'+post_id+'/favorite',
type:'POST',
success: function(result){
//update the data attributes
$this.data('favoriteId',result['id']);
console.log(result);
console.log('post was favorited');
},
error: function(){
console.log('error: did not favorite the post.');
}
});
}
});
});
The HTML file
<div class="pull-right">
<span class="marginer">
#if(Auth::guest() || $post->favorites->where('user_id',Auth::user()->id)->isEmpty())
<i data-post-id="{{ $post->id }}" class="fa fa-heart fa-lg favorite-button"></i>
#else
<i data-favorite-id="{{ Auth::user()->favorites()->where('post_id',$post->id)->first()->id }}" data-post-id="{{ $post->id }}" class="fa fa-heart fa-lg favorite-button"></i>
#endif
<span class="favorite-count">{{ $post->favorites->count() }}</span>
</span>
</div>
Aside from solving my issue, if you think I am not conforming with best practices with this task, please do comment. I'd like to hear your opinion.
Instead of trying to make use of jQuery, try to simplify the action of "like/unlike/favorite/count" as much as possible
Avoid querying from blade templates and just send data to the view
Here is how i would approach this problem instead of letting jQuery do the heavy lifting
HTML/rendered
<button class='likebutton' data-identifier='1' data-state='liked'>Like</button>
<button class='favoritebutton' data-identifier='1' data-state='favorited'>Favorite</button>
<span class='count counts-1'>123</span>
Blade
<button class='likebutton' data-identifier='{{!! Post->ID !!}' data-state='{{!! /*<something to see if user liked this>*/?'liked':'unliked' !!}'>{{!! <something to see if user liked>?'liked':'unliked' !!}</button>
<button class='favoritebutton' data-identifier='{{!! Post->ID !!}' data-state='{{!! /*<something to see if user liked>*/?'favorited':'notfavorited' !!}'>{{!! <something to see if user liked>?'favorited':'notfavorited' !!}</button>
<span class='count counts-{{!! $Post->ID !!}}'>{!! $Post->totallikes !!}</span>
JS
$.ajaxSetup({headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}});
function UserLike(_event){
var state = $(_event.target).data('state');
var postID = parseInt($(_event.target).data('identifier'));
console.log('Status => '+$(_event.target).data('state'));
$.post('/posts/metadata/likes',{
'postID':postID
},function(res){
$(_event.target).data('state',res.state);
$(_event.target).text(res.text);
$('.counts-'+postID).text(res.totallikes);
}).fail(function(){
/* do something on fail */
});
}
function UserFavorite(_event){
var postID = parseInt($(_event.target).data('identifier'));
$.post('/user/metadata/favorites',{
'postID':postID
},function(res){
$(_event.target).data('state',res.state);
$(_event.target).text(res.text);
}).fail(function(){
/* do something on fail */
});
}
$("body").on('click','.likebutton',function(_event){ UserLike(_event); });
$("body").on('click','.favoritebutton',function(_event){ UserFavorite(_event); });
PHP
// Routes
Route::post('/posts/metadata/likes',function(){
// auth check
// handle state/likes
// ex. response
// response with json {'state':notliked,'text':'<translated string>','postID':1}
});
Route::post('/user/metadata/favorites',function(){
// auth check
// handle state/favorites
// response with json {'state':favorited,'text':'<translated string>,'postID':1}
});
I would suggest replacing $this.data('favoriteId'); by $this.attr("data-favourite-id") everywhere. It made the difference for me. check this codepen
http://codepen.io/jammer99/pen/PNEMgV
However I have no idea why your solution does not work
JQuery data('favoriteId') does not set the attribute data-favourite, it's a runtime only setting, it becomes property of the elements, not attrubutes (That's not the same).
Jquery data can hence not be set by server side code.
You can read more it in the jquery doc for .Prop():
http://api.jquery.com/prop/
There's an explanation about the difference.
EDIT: Made the bold sentence!

jQuery - on load of element with ajax

I searched for some time but could not find a working solution for my problem (sorry if I searched wrongly)...
I would like to have the equivalent of the following function for an element loaded with ajax:
$(document).ready(function() {
$('.div-modal-text').css("background-color","red");
});
Therefore I am using the following code:
$('#parent_id').on('action', '#id or class to be born', function to be performed() );
In my example the parent-child structure is: #projectModals (div whose content is dynamically loaded)>...>.div-project-description>.div-modal-text
This translates into the following code in my example:
$('#projectModals').on('load', '.div-project-description', function() {
$(this).find('.div-modal-text').each(function() {
$(this).css("background-color","red");
});
});
I know 'load' does not work with .on(), but I tried different alternatives and I could not find anything working.
Thanks for your help!
EDIT: Here is my (simplified) HTML code:
<div id="projectModals"></div>
content loaded in #projectModals with Ajax:
<div class="row">
<div class="div-project-idcard">
column 1, don't bother too much about this column
</div>
<div class="div-project-description">
<div id="summary" class="div-modal-text">
Column2, text 1
</div>
<div id="purpose" class="div-modal-text"">
Column2, text 2
</div>
<div id="reforestation" class="div-modal-text">
Column2, text 3
</div>
<div id="certification" class="div-modal-text">
Column2, text 4
</div>
</div>
</div>
If you're waiting for it to be loaded via ajax, consider using $(window).ajaxSuccess() instead:
$(window).ajaxSuccess(function(){
$('#projectModals .div-project-description .div-modal-text').each(function() {
$(this).css("background-color","red");
});
});
for what I understand, you want to change some background color after an ajax has been executed.
I think it's best to make the operation in the ajax success
$.ajax({
url: "some url",
data: {some data},
success: onAjaxSuccess,
});
and then;
function onAjaxSuccess(data){
//.. do things with data
var toExecute = $('#projectModals .div-project-description');
toExecute.find('.div-modal-text').each(function() {
$(this).css("background-color","red");
});
}

Categories

Resources