Unable to update div based on current value inside it - javascript

I have a php page that shows the server logs in a web interface. It is pretty simple. Basically there is an ajax call inside a setinterval() which hits a backend php file, which will read the log and echo it. The relevant code is:
setInterval(function()
{
$.get("log.php",{logId: $('#logId').val()}, function(data)
{
$("#logDetails").html(data);
//scroll to the bottom when updated...
$("#logDetails").stop().animate({scrollTop: $("#logDetails")[0].scrollHeight}, 800);
});
}, 2000);
As you can see, this just update a div with an id called logDetails with content from the log file in the server.
The div has a style="overflow:scroll" and the line $("#logDetails").stop().animate.. is to scroll to the bottom of the div when new content is added. All this works very well.
If a user has scrolled up the div and is examining the logs, and new content comes in then the div scrolls down. That is also fine. The problem is that the server log can have many hours of inactivity. During that time, when the user scrolls up, since setinterval is still working, he gets scrolled down even though new content is not available. This can become a real nuisance.
I wanted to handle this in the minimal way possible and I thought doing this might suffice:
$.get("log.php",{logId: $('#logId').val()}, function(data)
{
//new condition to check id new content has come
if($('#logDetails').val() != data)
{
//update div and scroll to the bottom..
}
...
However this is not working. I am aware of other ways like check the log modified time in server side etc, but I cannot modify any of those files due to other reasons.
So my question is - why does this not work? And how can I do this inside the interface file itself instead of resorting to other means?
The PHP code that pushes out the log is:
$contents = "";
$handle = #fopen($logFile, 'r');
if($handle)
{
while(($line = fgets($handle)) !== false)
{
//highlight errors
$txt = "Execution stopped because of error";
if(strstr($line,$txt))
{
$line = "<span style='color:red'>".$line."</span>";
}
$contents .= $line;
}
}
#fclose($handle);
echo nl2br($contents);

It would be difficult to exactly pinpoint what is wrong since you mentioned the data coming from the log will by dynamic. However you can figure it out by:
Do a console.log of $('#logDetails').val() and data
Then use a diff software like kDiff to find out what their differences are.
Once you find the differences, then you can think about ways to solve it.
Hope that helps!

.val() is unlikely to work, but since you haven't provided the contents of the html you're trying to work with, we can only offer suggestions. try either $('#logDetails').text() as mentioned in djidi's comment or $('#logDetails').html().

You could try this to make sure you are only ever getting new data back. Obviously I don't know anything about your system so this would have to be modified to work with the data you have:
$contents = "";
$handle = #fopen($logFile, 'r');
$lastHash = !empty($_GET['last_hash']) ? $_GET['last_hash'] : nulll
if($handle)
{
$stale = true;
while(($line = fgets($handle)) !== false)
{
//highlight errors
$txt = "Execution stopped because of error";
if(strstr($line,$txt))
{
$line = "<span style='color:red'>".$line."</span>";
}
if (empty($lastHash) || md5($line) == $lastHash) {
// this is the last stale line
$stale = false;
}
if (!$stale) {
$contents .= $line;
$lastHash = md5($line);
}
}
}
#fclose($handle);
echo json_encode(array('log_data' => nl2br($contents), 'last_hash'=> $lastHash));
and in javascript:
var lastHash = null;
setInterval(function()
{
$.getJSON("log.php",{logId: $('#logId').val(), last_hash : lastHash}, function(data)
{
lastHash = data.last_hash
if (data.log_data && data.log_data.length) {
$("#logDetails").html(data.log_data);
//scroll to the bottom when updated...
$("#logDetails").stop().animate({scrollTop: $("#logDetails")[0].scrollHeight}, 800);});
}
}, 2000);

Related

Initializing swiper sliders dynamically unexplainable behaviour

I have to create instances of swiper dynamically. These swipers have dynamically filled image contents. I have been fighting this the whole day with my lacking skills and cannot get this to work.
There are no javascript console errors, so I am assuming something is very fundamentally wrong but I don't know what it is.
Here is the code:
<!-- The sliders are initiated very standard way, i skipped showing them. These are my paginations where I cannot get the pagination to be rendered -->
<div class="secondary-0 swiper-pagination-clickable swiper-pagination-bullets"></div>
<div class="secondary-1 swiper-pagination-clickable swiper-pagination-bullets"></div>
<div class="secondary-2 swiper-pagination-clickable swiper-pagination-bullets"></div>
<script>
// I get lots of image data from php here
var imagearrays = <?php echo json_encode( $images_multiarray_js ); ?>;
// initialize variables for use in the loop.
var i;
var subNameArray = [];
var subSwiper = [];
// Loop through the imagearrays variable and initiate swipers.
for (i = 0; i < imagearrays.length; i++) {
subNameArray[i] = imagearrays[i].imagenames;
subSwiper = new Swiper('.subswiper-' + i, { // all my swiper-containers have extra class "subswiper-0" "subswiper-1" etc.
pagination: { // my main issue: I cannot get this pagination to render. WHY?
el: '.secondary-' + i, //my paginations have class like "secondary-0"
clickable: true,
renderBullet: function (index, className) {
return '<span class="' + className + '"><div class="pagination-ball"></div>' + subNameArray[index] + '</span>';
}
},
loop:true,
effect: 'fade',
clickable:true,
disableOnInteraction:false,
});
}
</script>
This is what my imagearrays variable looks like, just to show you that it's fine.
[
{"controllertype":false,"imagenames":["name1","name2"]},
{"controllertype":true,"imagenames":["name3","name4"]},
{"controllertype":false,"imagenames":["name5","name6"]}
]
I tried to go line by line in debugging JS mode, but it looks like the console simply leaps over the "new Swiper(..." line and everything inside it. Again, no errors in console.
How to feel really stupid:
Spend half a day figuring out why your code doesn't work
On a whim go check that your swiper selector class is attached to the correct html element and realize that it is not
Go cry in stackoverflow
I'm sorry guys, this question is useless. Everything works as intended with that d'oh fix.

Load html on an element with jQuery

I am trying to fill the html of a component with the result of an AJAX request, and it works... but only first time. This is for a phonegap application, and it tries to "encapsulate" a web on the app. I show you my code and after I´ll explain better.
My code is this:
function loadPage(rute, callback)
{
console.log("ruta: " + rute);
jQuery.get(rute, function(htmlTemplate)
{
var data = eraseExtraContentExternalPages(jQuery(htmlTemplate).filter("#wrapper"));
data = eraseLinksExternalPages(data);
console.log("#############BODY(wrapper)############# " + data.html());
jQuery('body').html(data.html());
});
}
function eraseExtraContentExternalPages(data)
{
data.find('#secondary').remove();
data.find('#dd_ajax_float').remove();
data.find('#author-bio-box').remove();
data.find('.googlepublisherpluginad').each(function(index){jQuery(this).remove();});
return data;
}
function eraseLinksExternalPages(data)
{
data.find("a").each(function(index)
{
var a = jQuery(this);
var href = a.attr("href");
if(href && href.indexOf(".jpg")==-1 && href.indexOf(".gif")==-1 && href.indexOf(".png")==-1 && href.indexOf(".jpge")==-1)
a.attr("href","javascript:loadPage('"+ href +"');");
});
return data;
}
What I do (I think is simple), I am trying to erease many html elements that are annoying on the app, and after change the href attribute of the "a" element, for a javascript action (loadPage), and it seems that works, becouse on the first console.log of the loadPage function I can see (when I press a link) how the rute is the correct, and on the second console.log I can see ALL THE CONTENT of data.html on the logcat (with eclipse), but the screen stay white-gray and with a little square on the left top corner...
Any Idea?? Why the html that I can see on the logs doesn´t load on the body??
Thank you very much!!

How Can I Insert My Javascript Into My Drupal Site/Node

I'm trying to insert a cookie that is provided by a video host that will resume a video where the user left off. They have an example that obviously works. When trying to insert this into my Drupal site, the cookie won't work. The video just starts back at the beginning.
I have enabled "PHP input filter", as I read that I needed to do that for drupal to insert the script. Please see the code that is in my node below.
Can anyone help me figure out why this isn't working, how to get it to work, or a better way of doing this with Drupal?
Thank you,
<script type="text/javascript">
wistiaEmbed.ready( function() {
var all_cookies = document.cookie.split(';'), // gets the value of the cookies on the page
cookie_str = "resume_video=",
resume_cookie = does_resume_cookie_exist(all_cookies);
function does_resume_cookie_exist(cookie_arr) {
var i, curr_string, found;
for (i = 0; i < cookie_arr.length; i++) {
curr_string = cookie_arr[i];
if (curr_string.substring(0,5) === cookie_str.substring(0,5)) {
// we've found it!
found = curr_string;
break;
}
}
return found;
}
function set_cookie_time(t) {
document.cookie = cookie_str + t.toString(); // this takes the time (t) and sets the cookie with that time
}
if (resume_cookie) {
num = resume_cookie.split('=')[1];
start_time = parseInt(num);
wistiaEmbed.time(start_time).play(); // plays the video at the specific time defined in the cookie upon return to the page
} else {
set_cookie_time(0); // places a cookie on the visitor
wistiaEmbed.play(); // starts the video from the beginning
}
wistiaEmbed.bind("timechange", function(t) { // on timechange, reset cookie
set_cookie_time(t);
});
wistiaEmbed.bind("end", function() { // if person has watched the entire video, sets the video to beginning upon retun
set_cookie_time(0);
});
});
</script>
<div id="wistia_npcc5k96s9" class="wistia_embed" style="width:640px;height:508px;"> </div>
<script charset="ISO-8859-1" src="http://fast.wistia.com/assets/external/E-v1.js"> </script>
<script>
wistiaEmbed = Wistia.embed("npcc5k96s9");
</script>**strong text**
What version of drupal are you using? Does the code that you gave actually output in your request response?
There are several solutions to this (IMO).
If the code is showing up in the response, it could be some other javascript error that preventing your code from executing.
If that snippet of code is applicable to all nodes of that type you can use the node_view hook in order to inject your code on that node type, for example (I am assuming D7):
function mymodule_node_view($node, $view_mode)
{
if($node->type =='video_page')
{
drupal_add_js('resume_video.js'); // this js holds your code snippet
}
}
Here's a reference that could help you out
https://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/hook_node_view/7
You can similarly inject that snippet of code at the theme layer using a theme hook, probably hook_preprocess https://api.drupal.org/api/drupal/modules!system!theme.api.php/function/hook_preprocess/7
Hope that helps.

If css() == X, else, not working, forms not working

I'm doing a chat for my social network. I'm using the following code and it seems to work while showing chat, but not while hiding it. You can see it on http://live-pin.com at the right bottom corner (the "system" bar).
What am I doing bad?
function toggleChat(obj){
current_margin = $(obj).css('marginBottom');
if (current_margin == 0){
$(obj).animate({marginBottom : "-270px"}).removeClass("active_box").addClass("hidden_box");
}else{
$(obj).animate({marginBottom : "0"}).removeClass("hidden_box").addClass("active_box");
}
}
Also, I'm having troubles because it shows/hides both chats & I don't want that to happen, and the "NEW MESSAGE" form doesn't work, just in the last chat created. As an additional detail, the boxes are created dynamically with data retrieved from JSON, so I can't use click() function or similars.
<?php echo "Thanks! (:"; ?>
Even though you can set the marginBottom to 0 it will internally be 0px, thus current_margin will be 0px which is not 0.
But you may try to parse the value first:
function toggleChat(obj) {
var currentMargin = parseInt($(obj).css('margin-bottom'));
if (currentMargin === 0) {
$(obj).animate({ marginBottom: "-270px" })
.removeClass("active_box")
.addClass("hidden_box");
} else {
$(obj).animate({marginBottom : "0px"})
.removeClass("hidden_box")
.addClass("active_box");
}
}

JQuery/Javascript works on & off

I am using JQuery 1.3.2-min in a project to handle JavaScript animations, ajax, etc. I have stored the file on the same server as the site instead of using Google. When I run the site locally on my development machine, everything works fine in FF, IE, Opera, and Safari (all the latest versions - I work from home and I only have 1 machine for personal use and development use) except for some CSS differences between them and when I go to the live site on my machine it works fine also. I have cleared my caches and hard refreshed the page, and it still works.
This is where it gets interesting however. When I send the site to my boss to test in various OS/Browser configurations, one page doesn't work correctly, some of it works, some doesn't. Also, the client (who uses IE 8) has also confirmed that it is not completely working - in fact he has told me that the page will work fine for a hour, and then just "turn off" for a while. I have never heard of this sort of thing before, and google isn't turning too much up. I have a hunch it may partly be with JQuery's .data(), but I'm not sure.
The page is basically nested unordered lists, and three basic actions happen on the list.
The top most unordered list is set to visible (all list via css are set to display: none to keep them hidden on a fresh page request); all list items divs are given a hover action of full opacity on mouseon, and faded back to 50% opacity on mouseoff; and then whenver a paragraph is clicked, the top most unordered list in that list item is displayed.
Here is my Javascript file for the page:
$(function() {
// Set first level ul visible
$('div#pageListing ul:first').css('display', 'block');
// Disable all the hyperlinks in the list
$('div#pageListing li a').click(function() {
var obj;
obj = $(this).parent(0).parent('div:first');
highlight(obj);
return false;
});
// List Item mouse hovering
$('#pageListing li').hover(
// Mouse On
function() {
if ($(this).children('div').attr('id') !== 'activePage') {
$(this).children('div').css('opacity', 1).css('filter',
'alpha(opacity=100)');
}
}, // Mouse off
function() {
if ($(this).children('div').attr('id') !== 'activePage') {
$(this).children('div').css('opacity', 0.4).css('filter',
'alpha(opacity=40)');
}
});
// Active list item highlighting
$('#pageListing li div').click(function() {
highlight($(this));
});
// Sub-list expanding/collapsing
$('#pageListing p.subpageslink').click(function() {
// Get next list
var subTree = $(this).parent('div').next('ul');
// If list is currently active, close it, else open it.
if (subTree.data('active') != true) {
subTree.data('active', true);
subTree.show(400);
} else {
subTree.data('active', false);
subTree.hide(400);
}
});
// Double clicking of list item - edit a page
$('#pageListing li div').dblclick(function() {
var classes = $(this).attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
editPage(pageID);
});
// Handle button clicking
$('button#addPage').click(function() {
addPage();
});
$('button#editPage').click(function() {
var div = $('div#activePage');
var classes = div.attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
editPage(pageID);
});
$('button#delPage').click(function() {
var div = $('div#activePage')
var classes = div.attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
delPage(pageID);
});
});
// Highlighting of page when clicked
function highlight(obj) {
// Get previous hightlighted element
// and un-highlight
var oldElement = $('div#activePage');
oldElement.css('background', 'white');
oldElement.css('opacity', 0.4).css('filter', 'alpha(opacity=40)');
oldElement.removeAttr('id');
// highlight current selection
obj.attr('id', 'activePage');
obj.css('opacity', 1).css('filter', 'alpha(opacity=100)');
obj.css('background', '#9dc0f4');
// add appropiate action buttons
$('button.pageButton').css('display', 'inline');
}
function addPage() {
window.location = "index.php?rt=cms/editPage";
}
function delPage(page) {
var confirm = window.confirm("Are you sure? Any sub-pages WILL BE deleted also.");
if (confirm) {
var url = './components/cms/controller/forms/deletePage.php';
$.ajax( {
url : url,
type : 'GET',
data : 'id=' + page,
success : function(result) {
if (!result) {
document.location = "index.php?rt=cms";
} else {
window.alert('There was a problem deleting the page');
}
}
});
}
}
function editPage(page) {
var url = "index.php?rt=cms/editPage/" + page;
window.location = url;
}
Is it possible that you are linking to (some of) the script files using a src that points to a file on your local disk/HDD? If so, that would explain why it works only on your machine, as then only your machine has access to the script file.
Thank you one and all for your suggestions. The end problem was miscommunication. I work from home, and upload my projects to a SVN server, which the boss then uses to update the live server. Somehow, the correct files were not getting updated - a communication error on my part. Another possible reason was that the page, while being declared XHTML 1.0 Strict, had something like 50 validation errors (mosting incorrectly nested UL), and I cleaned that up to 5 errors. So thank you all, but again a sad example of the importance of team work communication.

Categories

Resources