jQuery doesn't work on secondary pages (DataTables) - php

I have a simple table (created with DataTables), with a final column filled with 2 buttons. These buttons are connected to jquery. The problem is next: If I'm on first page of table and I press one of the buttons, everything works fine. If I press same button on second / third /etc page, function doesn't work anymore... Can you explain me why ? It's first time when I meet this problem. Thank you !
Buttons call jQuery with class, not Id (just a little note)
EDIT:
$('.generare_diploma').click(function(){
var user_id = $(this).attr('id').split('-');
if(user_id[1] != ''){
$.ajax ({
url: "./genereaza.php",
type: "POST",
data: {user_id:user_id[1],todo:'generare_diploma_admin'},
cache: false,
success: function(){
$('#diploma-'+user_id[1]).attr('onclick',location.href = './genereaza.php?user_id='+user_id[1]+'&todo=download_diploma_admin');
},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});
}
});
And this is how my anchor looks like:
<a id="diploma-'.$user['user_id'].'" class="btn btn-sm btn-success generare_diploma" data-toggle="tooltip" title="Genereaza diploma !"><i class="fa fa-calendar-check-o"></i></a>

$(document).on('click', '.generare_diploma',function(){
var user_id = $(this).attr('id').split('-');
if(user_id[1] != ''){
$.ajax ({
url: "./genereaza.php",
type: "POST",
data: {user_id:user_id[1],todo:'generare_diploma_admin'},
cache: false,
success: function(){
$('#diploma-'+user_id[1]).attr('onclick',location.href = './genereaza.php?user_id='+user_id[1]+'&todo=download_diploma_admin');
},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});
}
});
EDIT: jQuery is only aware of the elements in the page at the time it runs, so new elements added to the DOM are unrecognized by jQuery. To combat the problem use event delegation, bubbling events from newly added items up to a point in the DOM which was there when jQuery ran on page load. Many people use document as the place to catch the bubbled event, but it isn't necessary to go all the way up the DOM tree. Ideally you should delegate to the nearest parent existing at the time of page load.

You use .click event on element who are not yet on the dom when you init it.
So you have to init that fonction each time you get new lines in your DataTable or to add a listener with .on(
Since newest jQuery version .on( event has change. Now your principal element have to be present in your DOM when you init the fonction, you can add listener on new elements who gonna be made with DataTable (when you change page with a pagination for example).
so your code : $('.generare_diploma').click(function(){
has to be : $(document|'body'|selector).on('click','.generare_diploma',function(){
But in case that you have to init more than one time , often better to had a .off before your .on( like : $(document|'body'|selector).off('click','.generare_diploma').on('click','.generare_diploma',function(){

Related

innerhtml+= How to Get load data from ajax then make an action?

im newbie that newbie learn here...
i want add some event from loaded part dynamically but it return to 1 id
so i problem with innerHTML+= and call with ajax like this..
$.ajax({
url: 'getuser.php',
type: 'POST',
data: {
id_user: id_user
},
success: function(data) {
listuser.innerHTML+=data;
}
});
then with getuser.php i got result like this
<div id="listuser">
<button id="1" class="pickmember">Member1</button >
<button id="2" class="pickmember">Member2</button>
</div>
so when i call a function
$(".pickmember").click(function(){
var id_user=$(this).attr('id');
alert('u pick member'+id_user);
});
when i call it,, it always return to last added to innerhtml, and cant detect member2 when click,, there is solution to this?
use .on() instead of .click()
$(".pickmember").on('click', function () {
var id_user = $(this).attr('id');
alert('u pick member' + id_user);
});
more information --> jQuery $(".class").click(); - multiple elements, click event once

AJAX overwritting

I'm currently using AJAX for live submit a post which is then appended to a list. The problem I am having is when I submit a post more than once, AJAX overwrites the previous posts submitted.
var data = $("#form_write_post").serialize();
$.ajax({
type: "POST",
url: $("#form_write_post").attr("action"),
data: data,
beforeSend: function() {
$("ul.timeline").prepend("<img class='textarea_ajax_loading' src='img/ajax-loader.gif' style='margin: 0 auto; display: block;' />");
},
complete: function() {
$('.textarea_ajax_loading').remove();
},
success: function () {
//var successCount = successCount++;
$("ul.timeline").prepend('<li class=ajax_post></li>').fadeIn();
$("ul.timeline .ajax_post").load("ajax_post.php").fadeIn();
//$('ul.timeline').prepend(wall_post);
//console.log("success");
return false;
}
});
How can I achieve a new post after each submission?
Thanks
I'm not sure that I fully understand your problem, but when you say "AJAX overwrites the previous posts submitted" I assume the problem is on the front-end right?
From the code I see, it might be because you prepend a new <li class=ajax_post></li> and then you select all the li with this class and load something in all of them.
If you want to load something only in the latest li, change the selector to
$("ul.timeline .ajax_post:first").load("ajax_post.php").fadeIn();
to select only the first post.
you're inserting the new content into every child of the same class. instead of using classes you should be using IDs: declare count outside your Ajax call and then do the following.
success: function () {
count = count++;
$("ul.timeline").prepend('<li class=ajax_post id="post'+count+'"></li>').fadeIn();
$("#post"+count).load("ajax_post.php").fadeIn();

jQuery full calendar $.ajax call issue ( using static events on page open )

So I am using Yii and full calendar as a widget which is called in a view of CalendarController. Uppon call for a widget, the widget retrives existing events from the DB and puts them inside the full calendar to display. Now I have also made a simple filter for filtering out events by category they are in ( dropdown with a submit ), so I want to send request to a calendarController method called actionEvents() which then takes what is passed to it ( the category of events for which we want to retrieve events ), gets them back to the jQuery which then calls the calendar again passing it a json_encode(d) array of needed properties to correctly render events under the selected category in the dropdown. The problem I have is that it seems fullcalendar is doing my wanted call ( POST ) as well as one another GET call along with it for some reason so it does return properly formatted json to the jQuery from the method of controller, but just shows an empty calendar without events in it on return. This is how the console looks like after the returned data.
This is the code that calls ajax call
$(document).ready(function() {
var date = new Date(),
d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear();
$('form.eventFilter').submit(function() {
var selectedOption = $('form.eventFilter select').val(),
eventContainer = $('.fc-event-container');
var objectToSend = { "categories" : [selectedOption],"datefrom" : "september2013"/*month + "" + year*/ , "dateto" : "september2013"/*month + "" + year*/};
$.ajax({
url: '<?php echo Yii::app()->createUrl('calendar/events'); ?>',
type: "POST",
async:false,
data: {data : JSON.stringify(objectToSend)},
success: function(data) {
$('#fc_calendar').html('');
$('#fc_calendar').fullCalendar({
events: data
});
console.log(data);
},
error: function() {
console.log(data);
}
});
return false;
})
})
The code that renders initial calendar events on first page load ( open ) is this
<div id="fc_calendar"></div>
<script class="fc_calendar_script">
// gets calendar and its events working and shown
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#fc_calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: true,
events: [
<?php foreach ($eventItems as $event): ?>
{
title: '<?php echo htmlentities($event['eventItems']['title']); ?>',
start: new Date(y,m,d + <?php echo $event['eventItems']['startdate_day_difference']; ?>),
end: new Date(y,m,d + <?php echo $event['eventItems']['enddate_day_difference']; ?>),
url: '<?php echo $event['eventItems']['url']; ?>',
className: [
<?php foreach($event['eventCategories'] as $category) { echo ''.json_encode($category['slug']).','; }?> // and categories slugs as classnames, same purpose
]
},
<?php endforeach; ?>
]
});
</script>
The code in controller is not that important since you can see what it returns in the screenshot :) If someone has an idea of how to get around this I would really be grateful :) Tried everything I know
Ok so bounty goes to whoever answers this question :)
I am having problems with full calendar month rendering when ajax data is returned and events populated. Since I have checkboxes for each category ( events have MANY_MANY relation with categories ) and each time a checkbox is checked or unchecked, JSON array of chosen categories of events is passed on to PHP method which queries DB for all events that go under chose categories and returns all events in a jquery encoded array to the view which then takes that events array and rerenders the calendar like shown in the upper code.
Problem is that when a checkbox is checked or unchecked and ajax returned the calendar always renders on the current month ( so right now it would always rerender itself to show events for september, untill the end of the month, then always for Ocbober and so on ), but what if a user was on lets say November 2013 when he checked event category for which he wanted to filter the events? The calendar would rerender on September still. How could I make it rerender on the month the user was on when he checked / unchecked a checkbox ?
The code that I have which keeps track ( or at least it should ) of the current month when prev or next month buttons are clicked is this
$('.fc-button-next span').click(function(){
start = $('#fc_calendar').fullCalendar('getView').visEnd;
console.log(start);
});
$('.fc-button-prev span').click(function(){
start = $('#fc_calendar').fullCalendar('getView').visStart;
console.log(start);
});
However this code is not tracking properly, sometimes it skips a month, sometimes it stays on the month without change and sometimes it returns propper month, which is bugging me so I cant call this function of the calendar properly which should set calendar to propper month on rerender.
$('#fc_calendar').fullCalendar('gotoDate', start);
I think what you might be looking for is something like
jQuery(function($){
$('form.eventFilter').submit(function() {
$('#fc_calendar').fullCalendar( 'refetchEvents' );
return false;
});
$('#fc_calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
editable: true,
events: function(start, end, callback) {
var selectedOption = $('form.eventFilter select').val(),
eventContainer = $('.fc-event-container');
//create the data to be sent
var objectToSend = {
"categories": [selectedOption],
"datefrom": start.getDate() + '-' + start.getMonth() + '-' + start.getYear(),
"dateto": end.getDate() + '-' + end.getMonth() + '-' + end.getYear()
};
//use jsonp based jQuery request
$.ajax({
url: 'events.json',
data: objectToSend,
cache: false
}).done(function(data){
//on success call `callback` with the data
callback(data)
})
}
});
});
Demo: Plunker
Note: The date param formatting and jsonp is not used here, you will have to change it to match your requirements
I see that you use JSON.stringify(data); this is what i tought your error was
maybe you need a jsonp, and below you have my example
$.ajax({
'url': 'http://domain.com/index.php/api/news?callback=?',
'data': {'data': JSON.stringify(data), callback: 'jsonPCallback'},
'success': function(data) {
// console.log(data);
},
jsonpCallback: jsonPCallback,
dataType: 'jsonp'
});
function jsonPCallback(cbdata){
console.log('callback2')
// console.log(cbdata);
return false;
}
now, do you also use something like
echo $_GET['callback'].'('.CJSON::encode(array('status_live' => 1, 'data' => $data_decoded)).')';
in the controller to return the results ?
also, createUrl might be wrong, because you need a absolute path
Actualy the problem solution is as weird as the problem itself and it is the following. You must use designated way of doing an ajax call to fetch json that is in the plugin documentation, any other way you send your own call ( GET or POST ) and the calendar after that makes yet another call ( hence the another GET call ) if you are using just a "regular" $.ajax, $.post or $.get call using jQueries native functionality
This should really be posted somewhere on the website in some section so that people do not get confused why their calendar is not making ajax calls and I wonder how noone else had similar problem before . So this is the "correct" documentation way of calling it with full calendar which you can find HERE
$('#fc_calendar').html('');
$('#fc_calendar').fullCalendar({
eventSources: [
// your event source
{
url: '?r=calendar/events',
type: 'POST',
data: { data : JSON.stringify(objectToSend)},
error: function(data) {
alert(data);
},
}
// any other sources...
]
});
So it will automaticly fetch any returned ( properly formatted data ) and use it to rerender new calendar with those events. It is very weird way of doing it, but the only way that will work.
I can't comment so, you have an assignment to variable:"nothing" in your last query parameter
double check if you have looked for ajax request in your controller(important!),
and also if this is this a 404 by the apache, you have url rewriting problems,
and it looks like index.php is missing from url?!

gmail like star button -jquery problem

I've built star button to use it like "starred items". I have the code running. but i have a problem.
When i click on star it becomes a starred item and and the star image changes.
But when i click again to unstar, it just doesn't work. i need to refresh the page to unstar it.
Also even the first step doesn't work for chrome.
add star codes:
jquery
$(function() {
$(".yildiz").click(function() {
var id = $(this).attr("id");
var dataString = 'id='+id ;
var parent = $(this).parent();
$.ajax({
type: "POST",
url: "yildizekle.php",
data: dataString,
cache: false,
success: function toggle()
{
$('.yildizbutton'+id).animate({
src:"star-icon.png",
class:"yildizsizbutton"+id,
},0);
}
});
return false;
});
});
php:
<img class="yildizsizbutton'.$row['id'].'" border="0" src="star-icon.png" alt="Yildizi kaldir" width="16" height="16" />
remove star
$(function() {
$(".yildizf").click(function() {
var id = $(this).attr("id");
var dataString = 'id='+id ;
var parent = $(this).parent();
$.ajax({
type: "POST",
url: "yildizsil.php",
data: dataString,
cache: false,
success: function toggle()
{
$('.yildizsizbutton'+id).animate({
src:"star-icon-f.png",
class:"yildizbutton"+id,
},0);
}
});
return false;
});
});
php:
<img class="yildizbutton'.$row['id'].'" border="0" src="star-icon-f.png" alt="Yildiz ekle" width="16" height="16" />
To add the star, do something similar to this:
$("#"+id).find("img").attr("src", "star-icon.png");
To remove:
$("#"+id).find("img").attr("src", "sstar-icon-f.png");
You shouldn't use animate in the way you are using it at all. I also used the ID of the container, then found the image inside of it, instead of putting together that class like you were doing. That's just personal preference, though...the main takeaway is to use attr("src") to set the src of an image in jQuery.
EDIT: Here is a full solution that should work.
$(function() {
$(".star").click(function() {
var id = $(this).attr("id");
if($(this).hasClass("starred")) {
$.post("yildizekle.php", {id: id}, function(resp) {
$(this).removeClass("starred").find("img").attr("src", "star-icon-f.png");
});
}
else {
$.post("yildizsil.php", {id: id}, function(resp) {
$(this).addClass("starred").find("img").attr("src", "star-icon.png");
});
}
return false;
});
});
Notice that we are using a class to track whether or not the element is already starred. This means in your PHP you will need to add the starred class to any elements that are already starred when the page loads. Also, I used $.post instead of $.ajax since it is a simpler way of doing the same thing.
There are a few problems in your code, and both of the answers here are relevant and both are correct. Being as green as you are, I'd say you are on the road to learning well.
I'd use a separate class for ALL of the stars, one that doesn't relate to if its starred or unstarred. Maybe something like 'star'. :) You need to refresh the page to un-star it is because you never actually change it on the FRONT-end to be starred. If you use a tool like firebug of WebKit's Web inspector, you'll see that the class of the link is still "yildiz".
I'm not going to give you a complete answer because I'd be robbing you of an awesome learning experience here. Here are some pointers:
Remember which objects your click() events are connected to: $(".yildizf") and $(".yildiz")
When you click on an item, does it actually change class so that jQuery knows it's different? Essentially, you are 'starring' the same item over and over again because you never allow jQuery to see it as something it needs to un-star
If you use a 'star' class in addition to the other class (like <a class="star yildiz" ...>), then you can attach your click event to $('a.star'), and figure out in THERE if you should be starring or unstarring the item.
I hope this all makes sense.
You've defined the click event to both star and un-star the item. In the event you need to look at the current state of the item then decide if you want to star or un-star it. you need to branch inside your click event.

jQuery, need help with 'sortreceive' ajax call and POST vars

I have a dilemma that just seems beyond my abilities at the moment!
I have a group of connected sortables using the class 'biglist'.
What I want to do is bind #biglist 's sortreceive callback (which is made whenever a list receives an element from another) to take the 'boxnum' value of the element (which signifies which list its coming from) and perform an UPDATE query changing the id's boxnum value from say 5(list it came from) to 7 (list its been dragged to) so that the state persists.
So the exchange would happen like so (roughly)
$( "#biglist" ).bind( "sortreceive", function(event, ui) {
ajax call to boxchange.php
create vars to represent elements 'boxnum' value and 'box moved to' value
});
Then inside boxchange.php ->
$id = $_POST['id']
$box = $_POST['boxnum']
->update query SET boxid to new boxid WHERE id = posted ID of element
I hope this makes sense. It seems like a pretty slick way to make my program work!
Any help is greatly appreciated.
EDIT:
Just cleaned up the function to see if there are any changes that need to be made to it (which I know there are, because it looks sloppy) This function would need to be copied/altered for each sortable separately but it'd totally make the program work at least!
function ReceiveTwo()
{
$('#sortable2').bind('sortreceive', function(event, ui)
{
boxnum = $(this).attr('boxnum');
id = $(this).attr('id');
$.ajax
({
url: "boxchange.php",
type: "POST",
data: boxnum, id,
success : function(feedback)
{
$('#data').html(feedback)
}
})
});
$('#sortable2').sortable("refresh");
});
$('#sortable2').bind('sortreceive', function(event, ui) {
$.ajax({
url: "boxchange.php",
type: "POST",
beforesend: function(){
boxnum = $(this).attr('boxnum');
id = $(this).attr('id');
},
data: {'boxnum': boxnum, 'id': id},
success : function(feedback) {
$('#data').html(feedback),
}
});
});
beforesend is the event that fires before the ajax call. I believe here you could set your properties to accomplish what you want.
I think the way you want to send your Javascript data to your server-side PHP script is using a Javascript associative array, like so:
$.ajax({
url: "boxchange.php",
type: "POST",
data: {'boxnum': boxnum, 'id': id},
success: function(data,status) { ... }
Your "boxchange.php" script would then be able to access those variables via $_POST['boxnum'] and $_POST['id'].
I think that was your goal, but I'm not entirely sure...

Categories