EDIT: Everything works; the pushes work. The only problem is that on each push the #load_info div
is reset to empty. How can I preserve the original content inside the div
, though the content would be the updated version of itself as the XML file is re-pushed.
I have a PHP script for long polling an XML file and encoding it as a JSON array. It is called from frontend with the JSON as the parameter.
$filename= dirname(__FILE__)."/people.xml";
$lastmodif = isset( $_GET['timestamp'])? $_GET['timestamp']: 0 ;
$currentmodif=filemtime($filename);
while ($currentmodif <= $lastmodif) {
usleep(10000);
clearstatcache();
$currentmodif =filemtime($filename);
}
$response = array();
$xObj = simplexml_load_file($filename);
// Loop for #loadMe.
foreach($xObj as $person){
$concat_buttons .= "<button class='mybutton' value='" . (string)$person->id . " '> " . (string)$person->fullName . "</button>";
}
// Loop for #toadMe.
foreach($xObj as $person){
$concat_info .= "<div class='div div_' data-person-id='" . (string)$person->id . "' id='" . (string)$person->id . "'><h1> " . (string)$person->job . "</h1></div>";
}
// Output for AJAX.
$response['msg'] = $concat_buttons;
$response['msg2'] = $concat_info;
$response['timestamp'] = $currentmodif;
echo json_encode($response);
Then I have a jQuery script for instancing the JSON object (msg2
) for appending each node into a div
called #load_data
. My question is why is the jQuery below not working? My guess is either the $(window).find
isn't working in the get_person(id)
function and/or my functions are out of scope with the polling. To note, the PHP and JS were 100% working before I started trying to incorporate the show_person()
and get_person()
functions. Working as in, when a certain button inside the #load_button
div
was clicked it would toggle a piece of information's view with an id
that matched the button's value
attribute with .show()
, which was initially hidden; then if another button was clicked the old info would be hidden with .hide()
and the new data would be seen. This was my round-about solution for using long-polling to update DOM elements by just loading them all up in the beginning, however if a piece of information is shown while a new poll occurs (var
timestamp
gets updated), then the elements inside of #load_info
will temporarily get lost from the DOM, therefore resulting in an empty #load_info
div
until the next button is clicked. So am trying to add some additional functions to store DOM data inside the var
$person
so that after a poll whatever was shown prior would reappear. What can be changed or added to get this jQuery script working as intended? Thanks in advance!
var timestamp=null;
function waitForMsg() {
$.ajax({
type: "GET",
url: "getData.php?timestamp="+timestamp,
async: true,
cache: false,
success: function(data) {
var json=eval('('+data+ ')');
if (json['msg'] != "") {
$("#load_buttons").empty();
$("#load_buttons").append(json['msg']);
// Update any person divs that were already visible.
$('#load_info .person').each(function() {
// Grabs the ID from data-person-id set earlier.
var id = $(this).data('person-id');
show_person(id);
});
}
timestamp = json["timestamp"];
setTimeout("waitForMsg()",1000);
},
error: function(XMLHttpRequest,textStatus,errorThrown) {
setTimeout("waitForMsg()",15000);
}
});
}
$(document).on('click', '.mybutton', function() {
$('#load_info').empty();
show_person(this.value);
});
function show_person(id) {
$('#person-detail-' + id).remove();
get_person(id).appendTo('#load_info');
}
function get_person(id) {
var $person = $(window).find('id:contains(id)');
var $div = $('<div>', {
'class': 'person',
'data-person-id': id,
id: id
});
$person.find(h1).text.appendTo($div);
return $div;
}
It looks like you have an issue generating your JSON in the PHP script:
$response['msg'] = $concat;
$response['msg2'] = $concat2;
$concat
and $concat2
aren't defined anywhere, did you mean to use $concat_buttons
and $concat_info
instead?
$response['msg'] = $concat_buttons;
$response['msg2'] = $concat_info;
In your jQuery, you reference #load_info .person
, but it doesn't look the divs that PHP builds are of class person
which might be why your loop isn't finding them.
I found your question fairly difficult to understand, but I like a challenge. As a note, I haven't tested any of this code so it would need to be debugged.
Now, as I understand it, you have a bunch of buttons with this structure:
<div id="load_buttons">
// repeater
<button class="mybutton" value="$person['id']">$person['fullName']</button>
// end repeater
</div>
And a bunch of detail divs with this structure, which are initially hidden:
<div id="load_info">
// repeater
<div class="div div_" data-person-id="$person['id']" id="$person['id']">
<h1>$person['job']</h1>
</div>
// end repeater
</div>
And these should get updated/appended on every poll.
What you would like to achieve: when a button is clicked, the associated info is shown. I would do your success function like this:
success: function(data) {
var json=eval('('+data+ ')');
var $buttons;
var $infos;
if (json['msg'] != "") {
addButtons($(json['msg']));
addInfos($(json['msg2']));
}
timestamp = json["timestamp"];
setTimeout("waitForMsg()",1000);
}
addButtons = function($buttons){
// loop through the button json data
$buttons.each(function(){
// look to see if the button already exists
var existing = $('[value='+$(this).attr("value")+']').length;
if(!existing){
// if not, add the button and assign a click handler
$(this).appendTo('#load_buttons').click(function(){
//hide all the children of info
$('#load_info').children().hide();
//show the info based on the button value
$('#'+$(this).val).show();
});
}
});
}
addInfos = function($infos){
//loop through the info json data
$infos.each(function(){
// check to see if an info exists
var existing = $('#'+$(this).attr("id")).length;
if(!existing){
//if not, add the info to the list and set it to hidden
$(this).appendTo('#load_info').hide();
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With