Detect content change on refresh - javascript

I'm doing a refresh inside the page to update a div, I'm trying to catch when the content in the div is changed, I tried using "DOMSubtreeModified" but it just detected the refresh every time.
I'm grabbing info from a page (donations.php) that just contains a dollar amount etc: $20.00 it refreshes every 5 seconds to look for new content. It updates okay but I want to trigger an alert on change not every 5 seconds.
function loadlink(){
$.get("donations.php", function(data) {
$('#results').html(data);
});
}
loadlink();
setInterval(function(){
loadlink()
}, 5000);
is my current code, I'm trying to detect a complete change on #results
Its a donation tracker for stjudes charity and I want to trigger an alert on the change.

You can store the old value of data and do a check against it.
(function () {
var dollarVal = "";
function loadlink() {
$.get("donations.php", function (data) {
$('#results').html(data);
if (dollarVal !== data) {
// trigger alert
alert("Value has changed!");
}
dollarVal = data;
});
}
loadlink();
setInterval(loadlink, 5000);
}) ();
If you don't want an alert on the first time load, then do:
if (dollarVal !== "" && dollarVal !== data)

Related

Show modal to user when updated

I have made this modal and it shows only on first visit to the website
$(document).ready(function(){
setTimeout(function(){
if(!Cookies.get('modalShown')) {
$("#myModal").modal('show');
Cookies.set('modalShown', true);
} else {
alert('You already saw the modal')
}
},1000);
});
In the modal it shows content of what new functionality to the application is added. So my target is to show the modal to the user every time I update the modal content. How can I do this?
You could use versionning in your cookies values :
var currentRelease = "1.0.1",
currCookie = Cookies.get('modalShown')
setTimeout(function(){
if(!currCookie || currCookie != currentRelease) {
$("#myModal").modal('show');
Cookies.set('modalShown', currentrelease);
} else {
alert('You already saw the modal')
}
},1000);
Note that this method forces you to update the value of "currentRelease"
you could also crypt the text content of the modal into md5 and use that value in your cookie, so whenever the modal value change, the md5 changes
So this is what worked for me:
$(document).ready(function() {
var currentRelease = document.getElementById("version").innerHTML;
var currCookie = Cookies.get('modalShown');
setTimeout(function () {
if(!currCookie || currCookie != currentRelease) {
$("#myModal").modal('show');
Cookies.set('modalShown', currentRelease);
}
}, 1000);
});
The id version is part of modal-content so as soon as I change something within the content the user will see the modal again on first visit since the change in the content.

Rerun original function upon completion of another function in jQuery AJAX

I'm still trying to master jQuery, AJAX, and JSON.
On my application, I have the following dropdown select menu:
<select id="serviceload" name="serviceload"></select>
I auto populate the OPTIONS with another function which I don't think is necessary to display here. Just know that the above SELECT has 1 or more OPTION values.
This is followed by the content section:
<div class="row" id="completeProfile">
// series of DIVS and TABLES
</div>
Initially, the content section is hidden, so the user will only see the dropdown menu:
$('#completeProfile').hide();
And now, the jQuery: this next piece of code is what I use when the user chooses a selection from the dropdown menu. Every time they pick a new selection, queries rerun, and new content is displayed to the screen, unless they select a blank OPTION.
$('#serviceload').change(function () {
var page = $('#serviceload').val();
if (page == "") {
$('#completeProfile').hide();
} else {
$.post('api/profileSearch.php', {
page: page
}, function (data) {
var obj = JSON.parse(data);
$('#portBody').empty();
var htmlToInsert = obj.map(function (item) {
return '<tr><td>' + item.PORT + '</td><td>' + item.NAME + '</tr>';
});
$('#portBody').html(htmlToInsert);
});
// I do several more $.post to return data into specific tables
// Take note of this next $.post
$.post('api/vesselSearch.php', {
page: page
}, function (data) {
var obj = JSON.parse(data);
$('#vesselinfo').empty();
var htmlToInsert = obj.map(function (item) {
return '<tr><td>Edit</td><td>' + item.VESSEL_NAME + '</td></tr>';
});
});
// after all the queries are ran, and the data is returned, now we show the content
$('#completeProfile').show();
}
});
In the vesselInfo portion above, there is section that prints a hyperlink with which you can click, and it opens a modal window. This is for editing purpose. This functions properly.
Here is where the issue lies.
Back in the content section, there is another hyperlink that opens a modal window to add a new vessel.
<h3>Vessels</h3> / Add New
This opens an Add New Vessel modal. In that modal there is a FORM with a button that reads like this:
<button type="button" id="addVesselSubmit">Add</button>
When this button is clicked, it sends the values entered by the user to a PHP script which updates a table.
$('#addVesselSubmit').click(function () {
var addservice = $('#addservice').val();
var addvessel = $('#addvessel').val();
$.post('api/addInfo.php', {
addservice: addservice,
addvessel: addvessel
}, function (data) {
// here is where my problem lies
if (data == 0) {
alert("Vessel was not saved");
} else {
alert("Vessel was saved");
// At this point, I need to rerun the main function above so that it shows the vessel that was added immediately to the content section without a page refresh
}
});
});
So in the code directly above, if the new record was successfully saved to the table, the whole content section should rerun without a page refresh, with the new record automatically showing in the vesselInfo section.
I think the code that is used to display the content needs to be turned into a main function that can be called when the addVesselSubmit is successful, but I am not sure how to proceed with that.
To reiterate my question: I need to be able to save a new record, and print the new record to the page without a page refresh.
$.post('api/addInfo.php', {
addservice: addservice,
addvessel: addvessel
}, function (data) {
// here is where my problem lies
if (data == 0) {
alert("Vessel was not saved");
} else {
alert("Vessel was saved");
// At this point, I need to rerun the main function above so that it shows the vessel that was added immediately to the content section without a page refresh
//Trigger a change on element
$('#serviceload').trigger('change');
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
}
});

How to use mouse event to do AJAX call only if user is idle for X seconds

Apologies if this is a repost. I have seen many examples. But I can't seem to put together my needs.
I have a "today" page which displays all groups. Throughout the day more and more groups will appear. I want to be able to dynamically update these groups if the user has the page open and hasn't moved the mouse for X seconds. I have this chunk of code:
var timeout = null;
j$(document).on('mousemove', function() {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
timeout = null;
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
}
})
.done(function( html ) {
});
}, 3000);
});
What this is doing is if the user hasn't moved the mouse after 3 seconds, do an AJAX call to update the group. This semi works. If you don't move the mouse, it will update. But it won't update again unless the mouse is moved and idle again for 3 seconds which is not good user experience.
I'm trying to find a way to just continually update the page every 3 seconds (for this example) if the user is idle. But if he's moving the mouse, there is to be no updating. Please ask questions if I'm unclear! Thanks in advance.
Should be straigh forward, use an interval and a function call instead
jQuery(function($) {
var timer;
$(window).on('mousemove', function() {
clearInterval(timer);
timer = setInterval(update, 3000);
}).trigger('mousemove');
function update() {
$.ajax({
url : "/include/new_Groups.php",
}).done(function (html) {
$(".group_Container_Main").append(html).fadeIn('slow')
});
}
});
FIDDLE
EDIT:
To solve the issue of stacking ajax requests if for some reason they take more than three seconds to complete, we can just check the state of the previous ajax call before starting a new one, if the state is pending it's still running.
jQuery(function($) {
var timer, xhr;
$(window).on('mousemove', function() {
clearInterval(timer);
timer = setInterval(update, 1000);
}).trigger('mousemove');
function update() {
if ( ! (xhr && xhr.state && xhr.state == 'pending' ) ) {
xhr = $.ajax({
url : "/include/new_Groups.php",
}).done(function (html) {
$(".group_Container_Main").append(data).fadeIn('slow')
});
}
}
});
On the AJAX parameter, use the complete option to trigger a mouse move :
j$(document).on('mousemove', function() {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
timeout = null;
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
},
complete: function(data){
j$(document).trigger('mousemove');
}
})
.done(function( html ) {
});
}, 3000);
});
You can invert your timer idea to this logical connection...
Set a timer for 3 seconds after which you will do the AJAX call
If the mouse is moved, reset the timer for 3 seconds
You now have a three second timer running whether or not the mouse is moved and you reset it on mouse move to get the behaviour you want in respect of only updating on idle.
var timeout = setTimeout(update, 3000);
function update() {
clearTimeout(timeout);
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
}
}).done(function(html) {
}).always(function() {
timeout = setTimeout(update, 3000);
});
}
j$(document).on('mousemove', function() {
clearTimeout(timeout);
timeout = setTimeout(update, 3000);
});
You should use setInterval() instead of setTimeout() to make a repeating event.
I would call setInterval() outside of your event handler code, and then make your event handler code update a lastTimeMouseMoved (or something) timestamp, which would be checked by the code passed to your setInterval() call.
So, your code might look like this:
const IDLE_TIME = 3000;
var lastTimeMouseMoved = Date.now();
timer = setInterval(function() {
if(Date.now() - lastTimeMouseMoved >= IDLE_TIME) {
//calls another page to check if there's new data to display. if so, wipe existing data and update
j$.ajax({
url: "/include/new_Groups.php",
cache: false,
success: function(data){
j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
}
})
.done(function( html ) { });
} // end idle if
}, IDLE_TIME);
j$(document).on('mousemove', function() {
lastTimeMouseMoved = Date.now();
});

How to create timer in my case?

I am trying to have my button doing two things.
init a timer to call a function
call the same function
I have something like the following
test.prototype.setupEvent= function(){
var instance = this;
$('#btn').on('click', function(){
clearInterval(instance.timer);
this.showStuff()
instance.timer=setInterval(function(){
instance.showStuff()
},10000);
})
}
test.prototype.showStuff= function(btnID){
//jump to another page
}
My problem is that I want the user be able to see some contents after 10 second when they first click it, however, if they click the button again before 10 second is up, they can see the contents too. I am not sure how to distinguish the two different states with one click event. Can anyone help me out? Thanks!
Try
test.prototype.setupEvent = function () {
var instance = this;
$('#btn').on('click', function () {
//if there is a timer running then clear the timer, show the content and delete the timer reference
if (instance.timer) {
clearInterval(instance.timer);
instance.showStuff();
delete instance.timer
return;
}
//also you may want to use setTimeout() not setInverval()
instance.timer = setInterval(function () {
instance.showStuff();
delete instance.timer
}, 10000);
})
}
test.prototype.showStuff = function (btnID) {
//jump to another page
}

function is looped according to setinterval but with different parameters

i have a simple question, there is a function with parameter emp_id that opens up a form for a chat with different attributes, i want it to be refreshed automatically each 10 sec, now it works a bit wrongly, since there is a parameter emp_id that is can be changed, and once i change it, the chat with messages and form are refreshed double time or triple times :) depend on how many times u change the emp_id, i hope i was clear )) anyway here is the javascript function:
function load_chat(emp_id) {
var url = "#request.self#?fuseaction=objects2.popup_list_chatform"
url = url + "&employee_id=" + emp_id;
document.getElementById('form_div').style.display = 'block'; AjaxPageLoad(url,'form_div',1,'Yükleniyor');
setInterval( function() {
load_chat(emp_id);
},10000);
}
there a list of names, once i click on one of them, this form is opened by this function, but if i click another user, i mean if i change the emp_id, it refreshes, the previous and present form. how do i change it so that it will refresh only the last emp_id, but not all of id's which i've changed
thank you all for the help, i really appreciate it!
This would nicely encapsulate what you're doing. The timer id (tid) is kept inside the closure, so when you call load_chat it will stop the interval if there was one running.
Once the new url is set up, it will start the interval timer again.
var ChatModule = (function() {
var tid,
url;
function refresh()
{
AjaxPageLoad(url, 'form_div', 1, 'Yükleniyor');
}
return {
load_chat: function(emp_id) {
if (tid) {
clearInterval(tid);
}
// setup url
url = "#request.self#?fuseaction=objects2.popup_list_chatform"
url = url + "&employee_id=" + emp_id;
document.getElementById('form_div').style.display = 'block';
// load ajax
refresh();
// set timer
tid = setInterval(refresh, 10000);
}
}
}());
ChatModule.load_chat(123);
Use setTimeout instead. Each time your function is executed, it will set up the next execution (you could also make it conditional):
function load_chat(emp_id) {
... // do something
if (condition_still_met)
setTimeout(function() {
load_chat(emp_id); // with same id
}, 10000);
}
load_chat("x"); // to start
Or you will have to use setInterval outside the load_chat function. You can clear the interval when necessary.
function get_chat_loader(emp_id) {
return function() {
... // do something
};
}
var id = setInterval(get_chat_loader("x"), 10000); // start
// then, somewhen later:
clearInterval(id);

Categories