I am writing a dynamic website that uses AJAX to check the status of inventory items between front-end and back-end employees of a firm. One employee submits a request and the people in the back see it pop up on a queue and then respond if the requested item is or isn't in stock. The front-end employee then sees the status of their request change appropriately.
The problem I am having, and perhaps there is a better way of doing things, occurs when the code uses AJAX to retrieve all active requests from a table in a database and then uses jQuery 's .empty() function to clear out the container div which holds all of the old requests(setInterval() every 2 seconds) and regenerates the queue using a PHP script which builds a on the fly based on the AJAX results.
The setInterval() function which calls the function that .empty() the container div causes queue to visibly disappear and reappear. Is there a better way of updating a queue using jQuery rather than emptying out the entire queue and then rebuilding it based on updated statuses? I cannot simply query for the latest request because the statuses of older requests may have changed and need to be updated as well.
Hopefully this is clear, if not then please ask what more information is need, and any help will be greatly appreciated, thanks!
Something like this...
$(document).ready(function(){Update();});
function Update() {
$.ajax({
url: 'http://example.com/url/to/poll',
success: function(data) {
$('#MyDiv').html(data);
setTimeout('Update()', 2000);
},
fail: function() {
//Something went wrong. Inform user/try again as appropriate
alert('Failed');
setTimeout('Update()', 2000);
}
})
}
It only starts the next 2s delay after the current one completes. Also, it never actually empties the Div, it just replaces the old contents with the new.
Related
I have a problem with jQuery events.
First let me explain the setup of the page:
The main-page.php is consisted of:
a) a header (where the logo is)
b) a navbar (where the various selections are)
c) a dynamic content area (Where the content of the clicked element on the navbar will be loaded)
d) Footer
Lets say that the navbar is consisted of | HOME | MESSAGES | ABOUT US | ...
The content of HOME is a separate PHP file, with a separate CSS and JS file. The same goes for all selections.
As soon as I select HOME (for example), i remove any content from the DYNAMIC CONTENT area and I place the content of HOME using AJAX. At the same time I remove any CSS/JS files associated with the previous content and I link the CSS/JS files associated with the one loaded. This part is working perfectly.
Now, if I switch from one selection to other selections (lets say from HOME --> MESSAGES --> ABOUT US and then back to HOME), if I click on a button inside HOME it will fire the event multiple times. This is even worse if that event is causing an AJAX call to the server (imagine calling the server 5 times instead of 1).
**The reason I use the on() event on the element with radio-element class is because is a future DOM element. Initially this element is not on the page.
A sample of JS code:
$(document).on('click', '.radio-element', function(){
$.ajax({
url: "js/ajax/ajaxcall.php",
success: function(output){
$('#ajaxcall-container').html(output);
}
});
});
What I do is, as soon as I click an element with the class of radio-element, I go in the server and i fetch the output of ajaxcall.php script.
Watching the NETWORK tab inside INSPECT ELEMENT, I see that the click event is executing the AJAX call multiple times. Sometimes 2, other 3 or even 5.
What I did to solve the problem (non of them is working 100%):
A) unbind the event before binding it using "off"
$(document).off('click','.radio-element').on('click', '.radio-element', function(){ .... });
B) Use event.stopImmediatePropagation()
$(document).on('click', '.radio-element', function(event){
event.stopImmediatePropagation();
//rest of code
});
Below is a solution that I haven't tried yet since I read in an article that it will not stop event binding process, it will just prevent multiple event execution (don't know if this will cause other problems).
$(document).on('click', '.radio-element', function(event){
if(event.handled !== true)
{
//Code goes here
event.handled = true;
}
});
The problem with multiple event firing is that there are AJAX calls that perform actions that are not supposed to be executed more than once (eg. send email to clients).
Also, this behavior (multiple event firing) is not something i can predict. Sometimes it works fine, some others it fires the event 5 times in a row.
I have been searching the web for a week now, but everything i tried did not solve the problem. Any solution will be much appreciated :)
Thanks!
Based upon what I am reading here - I would guess you are bringing on the js file with the click bind event more than once. If you are using custom routing or single page app and not refreshing the page, it is very likely based on what you are saying.
You could test this theory by adding a console.log inside the click event (above the ajax) and fool around with it and check the logs. If you are clicking it and it is logging whatever you logged more than once, then you know that this is the issue. I don't think it is the ajax.
I have also encountered the same problem quite a while. I solved this by unbinding all the events associated with the element before executing new event handlers.
Use like this:
$('#element').unbind().click()
{
//write something here
}
This will unbind previous event handlers before creating a new one. I think this will works well for you.
If you are using jquery version 1.7+
you can use off() like this
$('#element').Off().click()
{
//write something here
}
My guess based on your description is that you are not removing the event listeners. So every time you switch tab/page the same event will be added over and over again. Even though you have tried to do it, something is not going right. I doubt it has anything to do with Ajax.
I'm developing app using Fullcalendar v1.
I successfully integrate connection to mysql database so my events are loaded from db as json array. But my app are going to use more than 2 people in one moment so i need automatically refresh after my db changes. If one user remove event, calendar refresh for all other users which see this calendar.
I have one experimenting script which i made. It works but not as well as i want.
I know, this script is completely bad but i was frustrated.
<script>
var i = setInterval(function(){
last_id = $.cookie('last_id');
$.get("foo.php", function(data) {
var id = data;
if(last_id !== id) {
$('#calendar').fullCalendar('changeView', 'month');
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('refetchEvents');
$('#calendar').fullCalendar( 'rerenderEvents');
last_id = $.cookie('last_id', data);
}
});
},500);
</script>
It works pretty simple ... foo.php loads number of rows. If this number is other than last number saved in cookies, calendar will be refreshed.
This method has tons of disadvantages and mistakes. It works only for deleting and creating events. Not for moving etc. And it is slowing app by getting results every 500ms ..
Have you better solution for this ?
I have the similar structure.. get data from DB as JSON...
I make a modal for change a event...
When i press the button who calls my db to update the event..
I use behind... a function on jQuery called ( .trigger('click') ) so..
$('.fc-prev-button').trigger('click');
$('.fc-next-button').trigger('click');
//Hide Modal.. button have a data-dismiss="modal"
$('#closeEdit').trigger('click');
That's my solutions because when load fullCalendar this call events.. param who get data from my db... so when you change the month this is called again for reload the data and don't load the full month with data..
Sorry for my english and i hope to help you, Happy Coding !!
I am really unsure of how to code this properly, so I would like it if someone could point me on the right track.
I will have a SOAP+XML array which will have values matched up to a MYSQL table of jobs. The jobs then display in a with a hidden row. In each hidden row, I will have 3 separate SOAP+XML requests which will display 3 other bits of info. The user can then click on the job and with javascript, it displays the hidden row below and therefor, the extra information.
My interface right now
1) http://i.imgur.com/Cx7qB.png
2) http://i.imgur.com/HzXe5.png
The problem is when I scale this up, if the user chooses to display 100 jobs on the page. I need to hit the server for the first SOAP+XML request to get the jobs, then for each job, hit it 3 more times. So if I'm displaying 100 jobs, I'm hitting the SOAP server 301 times.
What I need is a way for it to only hit the server for the 1 initial SOAP+XML request, and then when someone initiates the javascript to view the hidden row, it starts the 3 soap requests for extra job info. That way the user isn't waiting for information they don't want to see and it doesn't bog down my server. The problem is I really don't know how to do this.
I really don't know much javascript, but I do know a good deal more PHP. Here's the script I'm using to hide the secondary rows in the table: http://pastebin.com/jhvaW0X4
Can anyone chime in on how I should go about getting this done?
Thank you!
I'm not sure if I understand the problem, but you can make an ajax request on a javascript event, in this case, when the user click the job tr, make the ajax requests for the needed info, for that you can use the $.ajax jquery method:
$("table#report1.report > tbody > tr.odd").click(function()
{
if(!$(this).next("tr").hasClass('shown'))
{
//Put here your ajax request
$.ajax({
url: yourSoapURL, getting tracking info url
type: "POST",
dataType: "xml",
data: soapMessage,
processData: false,
contentType: "text/xml; charset=\"utf-8\"",
success: function(soapMessage) {
//Add the tracking info to the tr that will be show
$(this).next("tr").text(soapMessage);
//Now the text is in the tr, show it!
$(this).next("tr").show();
$(this).next("tr").addClass("shown");
},
error: OnError
});
}
else
{
$(this).next("tr").hide();
$(this).next("tr").removeClass("shown");
}
That's the idea. If you want to manage multiple AJAX requests then read this: Multiple AJAX requests in jQuery.
I've a page that show data inserted in a mysql db; I'd like (if it is possible) that this view page automatically update when a record is added to the db (data are not inserted from the same page or may be inserted from another user).
thanks in advance
ciao h.
First way (easiest but annoying):
Add a meta refresh to the page and the full page refreshes every x amount of time.
Second way (AJAX):
I'm assuming this is what you want.
Load default HTML page etc... lets call it index.php
On above page create a <div> element with style display:none like this
<div id="mydata" style="display: none;"></div>
Create a PHP page that retrieves and formats the database data and prints it out in x format, i.e a table or p tags. no headers or page specific stuff just data and simple tags
On index.php put something like this
<script type="text/javascript">
function update() {
$.ajax({
url: 'http://www.example.com/getData.php?q=latest',
success: function(response) {
$('#mydata'.html(response);
}
});
}
// .ready function
$(function() {
// do setup stuff here, I think there is a refresh timer or something
// that you'd use to trigger it every x amount of time
// i.e something like this
update();
});
</script>
EDIT: AJAX HTTP streaming forces data out to users
I know sure on the best method to do this, but and quick-and-easy solution would be to get the total number of rows in your table on page load. Then every x seconds use an AJAX script to re-check that table's row count. If it has changed you could have extra logic that then fetches the new rows.
I was thinking about this last night and realized that node.js (http://nodejs.org/) might be perfect for this if you're looking for an event driven system. There is a good tutorial on getting started using node.js at http://net.tutsplus.com/tutorials/javascript-ajax/learning-serverside-javascript-with-node-js/.
I have a table in the database which includes all active users. I then have a user list which needs refreshing to see who is the latest users online.
Whats the best way to tackle this?
The user list is always just who is in the active_users table.
Thanks for reading.
AJAX
You could use an AJAX request to pull regularly the list of active users and display them on your website.
You may want to cache that list for a little while on your server in case you have a lot of users requesting it constantly.
Or, if the list is long, or if you decide to pull a lot of HTML markup with the list, you could also regularly poll your server to check whether there are updates to the (cached...) list since the last time the client updated the list. The reply will be a simple true or false, and the client will only have to request the new list when it has changed.
Meta refresh tag
You could also use the meta refresh tag, either to update the entire page, or an iframe if you don't mind iframes.
Refresh after one minute:
<meta http-equiv="refresh" content="60" />
Or with an url:
<meta http-equiv="refresh" content="60;url=http://site.com/list.php?counter=1" />
Manual update
Finally, you may just add a button or a simply a link at the end of the list, and the user could decide for herself whether to reload or not.
Other considerations
As JoeGeeky pointed out in the comments, for performance and bandwidth reasons, you may want to implement a counter which limits the maximum number of times the user list is loaded. This is valid for Ajax and Meta refresh tags. In javascript you could simply have a variable incrementing every time you load the list, and in case of the meta refresh tag you could add the counter in the url as a get variable.
Also those three approaches do not exclude each other but should be combined: Use Ajax for the folks with javascript activated, a meta refresh iframe in a noscript tag as a fallback for the ones with javascript disabled (as mentioned by stagas), and a button or link for manual update once the maximum list reload count has been reached.
If your userlist is short, for example, you are just displaying the latest five users, I would go with a simple polling with Ajax to a PHP script that returns that data.
You can adjust the polling to whatever your needs are,
$(document).ready(function () {
function refreshUserlist () {
$.ajax({
url: "user_list.php",
success: function (data) {
// code to refresh your website with the info out of data
setTimeout(refreshUserlist, 5000);
}
});
}
refreshUserlist();
});
Simplest way I can think of is that you can make a simple php page that lists the data, and use jQuery .load() function to load that php's html response into a div
$("#divid").load("active-users.php");
Make a php script to retrieve the list of active_users and return a <ul> list. Then use jQuery and setInterval() to fetch that list with $.ajax() and replace the list every 1-2 minutes or so with $('#active_user_list').html(new_list_data). Here's what it might look like (untested) :
setInterval(function() {
$.ajax({ url: 'script_to_fetch_active_users_list.php', success: function(new_list_data) {
$('#active_user_list').html(new_list_data);
} });
}, 1000*120);
The php script is up to you...