Refreshing DIV using ajax when XML data is updated - javascript

I've spent the last 4 years trying to solve this problem (on and off) and quite frankly my brain hurts.
I'm a voluntary designer for a local community project (a radio station). We have an "On Air" module that displays what track is currently playing and coming up.
Until recently I was using auto refreshing iframes that contained HTML files with the track information (these HTML files are automatically uploaded via FTP every 15 seconds by our playout system). These iframes refreshed every 15 seconds, however, this often lead to 404's in the iframe and ugly flickering as they reloaded.
I've spent some time looking in to an AJAX solution. I currently have an XML file with the track information (which the playout system automatically uploads via FTP every 15 seconds) and a HTML document that uses AJAX to refresh every 10 seconds. However, while I've helped fix the 404 issue, I'm still left with the ugly flicker as the text refreshes.
I have read that there is a way to have ajax refresh only if values in a database have changed, but I haven't had much luck in researching ways to do this if an XML document is updated.
If anyone can help point me in the right direction, many cookies and love will be bestowed upon you. Thanks!
Here's the code I currently have:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
(function($)
{
$(document).ready(function()
{
$.ajaxSetup(
{
cache: false,
beforeSend: function() {
$('#content').hide();
$('#loading').show();
},
complete: function() {
$('#loading').hide();
$('#content').show();
},
success: function() {
$('#loading').hide();
$('#content').show();
}
});
var $container = $("#content");
$container.load("test.xml");
var refreshId = setInterval(function()
{
$container.load('test.xml');
}, 10000);
});
})(jQuery);
</script>
</head>
<body>
<div id="wrapper">
<div id="content"></div>
<img src="loading.gif" id="loading" alt="loading" style="display:none;" />
</div>
</body>
</html>
And here is the test.xml:
<OnAirInfo>
<CurrentTrack><OCP_NOW_ITEMNAME></CurrentTrack>
<CurrentArtist><OCP_NOW_ARTIST1NAME></CurrentArtist>
<NextTrack><OCP_NEXT_ITEMNAME></NextTrack>
<NextArtist><OCP_NEXT_ARTIST1NAME></NextArtist>
</OnAirInfo>

You can use HTML5's Server-Sent Events
A server-sent event is when a web page automatically gets updates from a server.
All you have to do is create an EventSource object and pass it the URL of your server file(Here I am assuming .php file).
var source = new EventSource('your_file.php'); //This file will fetch the updates from `database`.
Then you can listen to the events for the updates.
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
There is a very nice explanation on HTML5rocks- EventSource about this concept. You should definitely take a look into it.
Hope this helps.

By default, any AJAX call is cached by the browser itself and won't transfert the whole file if the server say it hasn't changed.
For you case, I would suggest the folowing :
<div id="content">
<p id="CurrentTrack"></p><br/>
<p id="CurrentArtist"></p><br/>
<p id="NextTrack"></p><br/>
<p id="NextArtist"></p>
</div>
<script>
setInterval(function()
{
$.get("/url/to/your/xml/",
function(data){
// In case your server don't serve the file with the right mime type
var response = $($.parseXML(data)).find("OnAirInfo");
// Data extraction from xml
var CurrentTrack = response.children("CurrentTrack").text();
var CurrentArtist = response.children("CurrentArtist").text();
var NextTrack = response.children("NextTrack").text();
var NextArtist = response.children("NextArtist").text();
// Smooth text transition to prevent the "flickering"
$("#CurrentTrack").fadeOut(function() {
$(this).text(CurrentTrack).fadeIn();
});
$("#CurrentArtist").fadeOut(function() {
$(this).text(CurrentArtist).fadeIn();
});
$("#NextTrack").fadeOut(function() {
$(this).text(NextTrack).fadeIn();
});
$("#NextArtist").fadeOut(function() {
$(this).text(NextArtist).fadeIn();
});
});
}, 10000);
</script>
The smooth transition with the fadeout/fadein should look better than the text changing directly.
off course you have to adapt it to your system but this loading way will :
Prevent any 404 to interfear (the ajax success will just not be called so the text will stay the same until the next update
Allow for a wide range of data to be transmited (you could add the album cover thumbnail as a base64 string in your xml, or the url to the picture)
Allow you to keep the formating on the page and not on a separate one
Edit : Updated to your code specification

Related

How to implement auto-save on a webapp

I am trying to incorporate this code
var timeoutId;
$('textarea').keypress(function () {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
$.ajax({
url: '/savecomment',
data: { comment: $(this).val() }
});
}, 750);
});
from the tutorial here to implement auto-save in my web app. However, I am confused about two things.
Where exactly is the code being saved in this example? When I reload the page, the text I wrote is no longer there.
I tried to incorporate their example of this implementation into my code, but it did not work. The text box and the gray "no change" text above it appears fine, but this text does not change when I type. How could this be if I copied the HTML, CSS, and JS exactly as they are in the example?
Sorry for the elementary questions and thanks in advance.
The short answer is: Because you probably did not implement the server-side, e.g. the /savecomment endpoint for the $.ajax() call.
I would argue that this is quite an over-engineered example and could easily be solved with localStorage, could be as simple as this:
// check if we have something to restore on page-load
$(window).on('load', function() {
if ( localStorage.getItem('text') ) {
$('textarea').val(localStorage.getItem('text'));
}
});
$('textarea').on('input', function () {
localStorage.setItem('text', $(this).val());
// in a real browser you could verify it by
// uncommenting the following line, does not work
// in the sandbox this snippet runs in...
console.log('Saved text: ', localStorage.getItem('text'));
});
$('form').on('submit', function() {
alert('Actually save the text to the server via AJAX call');
// you should then clear the saved text after you successfully saved
// the content on the server
localStorage.removeItem('text');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="/savecomment">
<textarea name="sometext"></textarea>
<button type="submit">Save To Server</button>
</form>
then, when the user is actually done, have a "Save" button that can be clicked, that actually sends the finished text to the server.
Where is it saved?
It is saved in the app which runs in the /savecomment path. You need to implement this endpoint.
Is it sufficient to produce html, css and js?
Not sufficient. You need to implement the server app which saves the comment too.

Load a jquery event only after the preloader ends

My website is : https://365arts.me/
So it loads about 16mbs of pics(Yes I know, I'm stupid. I'll try to change it very soon, also if someone could tell me a way to reduce size of do something else(like dynamic loading only when needed, if something like that exists) I'd be very grateful).
I added a preloader for it using:
[html]:
<div class="spinner-wrapper">
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
</div>
</div>
and corresponging [jquery]:
<script>
$(document).ready(function() {
//Preloader
$(window).on("load", function() {
preloaderFadeOutTime = 500;
function hidePreloader() {
var preloader = $('.spinner-wrapper');
preloader.fadeOut(preloaderFadeOutTime);
}
hidePreloader();
});
});</script>
this works well but the problem is I have a javascript code that comes and says Hi! but it runs only for 2.8 seconds. So if loading takes up more than that, It doesnt show up. Can someone please tell me how to make sure that it loads only exactly after loading is completed.
Thanks a ton.
Code for my website:
https://github.com/richidubey/365-Days-Of-Art/blob/master/index.html
this may work
document.addEventListener('DOMContentLoaded', function() {
// your code here
}, false);
if you are happy with pure javascript
My first suggestion is to just get rid of the "Hi!" message since you already have a splash page in the form of the loader. But if you really want that second splash page, you can use the JQuery when() method:
$(window).on("load", function() {
$.when($('.spinner-wrapper').fadeOut(500)).then(displaySplashPage);
});
This assumes that displaySplashPage() is your function for showing the "Hi!" message.
You don't need $(document).ready() and window.on("load") here. Document ready waits for the HTML to be built, then applies event listeners/functions/etc to the structure. Window onload waits for everything to get loaded, then fires. In your case, you're trying to wait for all your pictures to load, so you only need onload.
You might need to have a container around all your main content set to opacity: 0 that switches to opacity: 1 as part of displaySplashPage(). That would prevent things from leaking through as you do the .fadeOut() on the loader.
JavaScript version - run js code when everything is loaded + rendered
window.onload = function() {
alert("page is loaded and rendered");
};
jQuery version (if you need it instead pure JS)
$(window).on('load', function() {
alert("page is loaded and rendered");
});
You can try this:
<script>
// Preloader
$(window).on("load", function() {
fadeOutTime = 500;
sayHelloDuration = 5000;
function hideSayHello() {
var sayHello = $('.say-hello');
sayHello.fadeOut(fadeOutTime);
}
function hidePreloader() {
var preloader = $('.spinner-wrapper');
preloader.fadeOut(fadeOutTime);
setTimeout(function() {
hideSayHello();
}, sayHelloDuration);
}
hidePreloader();
});
</script>
Also, remove the code from lines 83 ~ 87:
<script>
$(document).ready(function() {
$('.say-hello').delay(2800).fadeOut('slow');
});
</script>
About your website performance, you can improve a lot of things right now:
Use smaller thumbnail images on your front page, don't load FULL SIZE images at once. "work-showcase" section is really heavy without real necessity.
Try to incorporate src-set and smaller images for small screens, larger/heavier images for bigger screens. All modern browsers support it, and it will improve performance/loading speed.
Try to lazyload your big images, e.g. only when users scroll down to them, not before. It may take some work to integrate it with your image viewer, but it will additionally speed things up on initial load. My favorite library for this is this one: https://github.com/aFarkas/lazysizes but, you may find something else...
Unrelated to your original question, I have noticed that you have a bug in your HTML - see this screenshot. What kind of code editor do you use? Instead of empty space it apparently inserts invisible dots symbols which are not good. Actually, it's not the invisible dot (that's my editor's space indentation symbol), it's caused by 2 long dash (instead of short dash or minus) in your code after opening html comment tag:

How to use information from an API request to interact with a website?

I'm quite familiar with html and css but absolutely not with Javascript and I probably need Javascript to achieve what I want:
Each friday I'm livestreaming at Hitbox.tv. I've embedded the video player on my website. I would like to display an image stored on my server in front of the video player when I'm offline. I always edit the html page manually to show or hide the image, but it would be nice if it works automatically.
At https://api.hitbox.tv/media/status/masta (masta=channelname) I get a response with information of the live-status of my channel at Hitbox.tv. I believe the type of response is called JSON, but how can I use the value of "media_is_live" to show or hide the image on my server?
I searched for a long time on all kind of forums but didn't find an answer that worked out for me. Any help appreciated!
A good thing you can use is something called AJAX. AJAX is a piece of web technology that makes a request to a resource after your page has loaded. In order to do this kind of thing, I use the JQuery AJAX function.
In a script tag, you can do something like this:
<script>
$(document).ready(function() {
$.ajax({
dataType: "jsonp",
url: "https://api.hitbox.tv/media/status/masta",
success: function(data){
var img = $('myImageId');
if(data.media_is_live){
img.style.visibility = 'visible';
} else {
img.style.visibility = 'hidden';
}
});
});
</script>
The $(document).ready(function() { part means that the code inside will execute once the page has loaded.
This answer could be improved with some more information. I am, of course, guessing what the json object you get looks like. If you can post that, I can help more. Remember to import JQuery before the script above.

jQuery stops working after ajax loading

some info
I'm working on a webpage that can load data on multiple layouts, so user can choose which one is best. It can be loaded in a list or a cards like interface, and the data is loaded using ajax.
In this page I also have a notifier for new messages that the user received. The ajax function is new, and when page was loaded by the php scripts, the js script (that add a badge with the number of unread messages to a link on a menu item) was working ok.
I'm using HTML5, PHP, jQuery and a mySQL DB.
jQuery is imported onto the HTML using
<script src="https://code.jquery.com/jquery.js"> </script>
So it's a recent version.
the problem
Now, when I load the data onto the page using ajax, the js script won't work anymore. I had the same issue with another js script and I managed to solve it by using the delegate event binder.
But my unread messages updater runs on a time interval, using
<body onload="setInterval('unread()', 1000)">
the unread() js is quite simple:
function unread() {
$(document).ready(function(){
$('#menu_item').load('ajax_countNewMsgs.php');
});
}
it calls a php script which grabs the unread msgs count from the DB and echo into a element that jQuery will point. Hope I'm being clear.
The problem is that I cannot figure out how I would call a timed event using delegate. Without much hope I've tried
$(document).on('ready()','#menu_item', function () {
$(this).load('ajax_countNewMsgs.php');
});
That didn't work.
I read many posts about js stop working after changes in the DOM, but, again, I couldn't figure out a way to solve that, nor found a similar question.
Any help or tips would be highly appreciated.
EDITED to change second php script's name
2nd EDIT - trying to make things clearer
I tried the way #carter suggested
$(document).ready(function(){
function unread(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
$('#menu_item').html(response);
},
error: function(response){
//no error handling at this time
}
});
}
setInterval(unread(), 1000);
});
the ajax_countNewMsgs.php script connects to the DB, fetch the unread messages, and echoes the number of unread messages.
If I try to apply the ajax reponse to another element, say, the <body> the results are as expected: at each 1 sec , the body html is changed. So the function is working.
As I said, none of my JS changes the #menu_item. Actuallly this element is part of another php scritp (menu.php) which is imported to the top of the page.
the page structure is this way:
<html>
<head>
some tags here
</head>
<body>
<?php include (php/menu.html); ?>this will include menu with the #menu_item element here
<div id='wrapper'>
<div id='data'>
here goes the data displayed in two ways (card and list like). Itens outside div wrapper are not being changed.
</div>
</div>
</body>
</html>
Even though the elemente is not being rewritten js cannot find it to update it's value.
It's not the full code, but I think you can see what is being done.
$(document).on('ready()','#menu_item', function () {
is an invalid event listener. If you wanted to be made aware of when the DOM is ready you should do this:
$(document).ready(function () {
However I don't think that is actually what you want. Your function unread will fire repeatedly but it attaches an event listener everytime. Instead if you want to make an ajax call every so many seconds after initial page load, you should do something like this (dataType property could be html, json, etc. pick your poison):
$(document).ready(function(){
function makeCall(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
//handle your response
},
error: function(response){
//handle your error
}
});
}
setInterval(makeCall, 1000);
});
remove that on your unread function:
$(document).ready(function(){
WHY?
The Document is already "ready" and this document state will only fired 1x - After that the "ready state" will never ever called. Use follwing syntax:
jQuery(function($){

How to refresh a Div every 10 seconds without refreshing the entire page?

I'm working on a website platform that doesn't allow for any server sided scripting, so jquery and javascript are pretty much all I have to work with. I am trying to create a script to work with the site that will update a div that contains an inbox message count every 10 seconds. I've been successful with making the div refresh every ten seconds, but the trouble lies in the page views count. My script is refreshing the whole page and counting for a page view, but I only want to refresh just the one div. An example of the trouble my script causes is when viewing anything on the site that has a page view counter (forum posts, blog posts, ect...), the page views go crazy because of the script refreshing. I'm pretty new to Javascript, so I'm not entirely sure there is a way around this.
What I'm working with is below:
<div id="msgalert" style="display: none"; "width: 100px !important">
You have $inbox_msg_count new messages.
</div>
$inbox_msg_count is a call that grabs the message count, and provided by the platform the site is on. It displays the message count automatically when used.
Then the script that does all the work is this:
<script>
setInterval(function(facepop){
var x= document.getElementById("SUI-WelcomeLine-InboxNum");
var z = x.innerText;
if(x.textContent.length > 0)
$("#msgalert").show('slow');
}, 1000);
facepop();
</script>
<script>
setInterval(function() {
$("#msgalert").load(location.href+" #msgalert>*","");
}, 1000); // seconds to wait, miliseconds
</script>
I realize I've probably not done the best job of explaining this, but that's because I'm pretty confused in it myself. Like I mentioned previously, this code function just how I want it, but I don't want it to refresh the entire page and rack up the page views. Any help is much appreciated.
You might try to look into iframe and use that as a way to update/refresh your content (div). First setup an iframe, and give it an id, then with JS grab the object and call refresh on it.
well your prob seems a little diff so i think submitting a from within the div might help you so ...
$(document).ready(function()
{
// bind 'myForm' and provide a simple callback function
$("#tempForm").ajaxForm({
url:'../member/uploadTempImage',//serverURL
type:'post',
beforeSend:function()
{
alert(" if any operation needed before the ajax call like setting the value or retrieving data from the div ");
},
success:function(e){
alert("this is the response data simply set it inside the div ");
}
});
});
I think this could probably be done without a form, and definitely without iframes (shudder)..
Maybe something like this?
$(document).ready(function()
{
setInterval(function(facepop)
{
var x= document.getElementById("SUI-WelcomeLine-InboxNum");
var z = x.innerText;
if(x.textContent.length > 0)
$("#msgalert").show('slow');
$.ajax({
type: "POST",
url: location.href,
success: function(msg)
{
$("#msgalert").html(msg);
}
});
},1000);
It's not entirely clear exactly what you're trying to do (or it may just be that I'm ultra tired (it is midnight...)), but the $.ajax() call in the above is the main thing I would suggest.
Encapsulating both functions in a single setInterval() makes things easier to read, and will extinguish the 1 second gap between showing the msgalert element, and "re-loading" it.

Categories

Resources