I've encountered another problem with jQuery $.load(). I have two buttons, their visibility is mutually exclusive. A PHP conditional statement determines which is shown. All of that is contained in a div element #subDiv. Once either button is pressed, a PHP post file (two slightly different files for the two different buttons) is ran, and it writes a value to a database. Then, upon post success, I use $.load() to refresh #subDiv, which would (in theory) run the conditional again, and determine that the button that was not there last will now be shown.
My problem is the following:
When I click on the button when it is in State A, it will post correctly, and refresh the div to show the button in State B.
When I click on the button when it is in State B, it will post correctly, and refresh the div (according to Chrome Dev Tools), but the button remains in State B. Upon actual browser refresh, the button will appear in the correct State.
The two States and their respective post files are almost identical except for the minor necessary differences (one adds to a database table, one deletes from a database table). Seeing as the button correctly changes from State A to State B, but not the reverse, I'm not sure where the problem lies. To complicate things, a browser refresh will reveal the button in the correct state. $.load() is being used by myself to simulate a browser refresh of only one div element, for usability purposes and to cut down on loads. Therefore, I can only assume it is an error of the $.load() method.
Here's the jQuery code that controls the button click handling of both State A and State B:
//State A
$('#subButton').live('click',function() {
$.post("php/retailerNameNotif.php", $("#retailerNameNotif").serialize(), function(){
$('#retailerNameSubDiv').load('coupon.php #retailerNameSubDiv', function(){$( "button, input:submit, input:button, a#jql, input:radio" ).button();});
});
});
//State B
$('#unsubButton').live('click',function() {
$.post("php/retailerNameNotifUnsub.php", $("#retailerNameNotifUnsub").serialize(), function(){
$('#retailerNameSubDiv').load('coupon.php #retailerNameSubDiv', function(){$( "button, input:submit, input:button, a#jql, input:radio" ).button();});
});
});
Any help?
Edit:
As a further complication, I've noticed that occasionally, it will work correctly, switching states exactly as I want. However, on the 6th (and consistently the 6th) time, it goes back to the behavior I described here, getting stuck on one of the States.
My guess would be that the browser is caching the results of the load() call.
You could try inserting a random string to the filename to be sure that the request is made every time.
For example (not tested) :
var rnd = Math.random()
$('#retailerNameSubDiv').load('coupon.php?rnd=' + rnd + ' #retailerNameSubDiv', function(){$( "button, input:submit, input:button, a#jql, input:radio" ).button();});
Related
TESTING ENVIRONMENT: Windows 8 using the tool XAMMP. PHP and Mysql are up to date.
MY KNOWLEDGE: Starter.
QUESTION: I can't get the updated content immediately after the first click, only after the second, which can become pretty nasty considering I have two kind of buttons for my little voting system. Yes, I said a lot not alot : )
What is the cause for this predicament and how can I fix this?
WHAT I TRIED: Checked my developer tools network analysis and I get a status 200 with the correct value for every click. When using my firefox DOM inspector view I saw something unusual: upon the first click only #votes is marked in orange probably denoting that it has been affected. However, only on the second attempt on the same button both divs, #votes and #progress, get marked orange in addition with the updated values. So I expect it does on second click but not on the first one. Then I refreshed my page and tried something else. I clicked on "bad" and this time the second click landed on "good" with bad updating the value in the DOM. It seems as if the entire process is split and does not happen simultaneously which is why I speculate that:
Click 1: Sends data to php.
Click 2: Gets the data from php and displays it on the DOM.
The PHP code itself in conjunction with my database and HTML (if set to submit) works perfectly fine so I dont assume there is anything wrong on the server side. Connection to the database is set. My sessions work perfectly. No errors.
My console shows 0 javascript errors.
Test 1 : I commented out my entire php code and set up a testing variable with a simple string and changed the values in my code below accordingly. To my suprise, on clicking it immediately took the data and display the content of my testing variable.
Test 2 :: I removed the php codes from the two div tags which you will see below. They act as placeholders that show the current value before any AJAX happens. I removed those and I get an update on first click as the container was first empty. Although, on second click and toggling between good and bad happened to be a mess again.
Test 2 :: Placing jquery and my AJAX script in the head of the document did not do the job either (just to be on the safe side). Prior it was before the </body> tag
I access the returned json object through my callback parameter named data which then inserts html and css via jquery into the respective div containers.
Converted the jquery below to pure javascript but no positive change could be observed.
JAVASCRIPT / AJAX
function vote(type) {
$.get('php/core/voting_system_function.php', {vote:type}, function(data) {
$('#votes').html(data.votes_sum);
$('#progress').css('width', data.progress);
}, 'json');
}
HTML
The buttons onclick event feeds the data on to the parameter within my vote functions which then sends it to {vote:type} and then to my php file. This allows me to do several checks to see if the click was either 'good' or 'bad' and substract or add data accordingly in my database.
#votes and #progress
<div id="quality_meter">
<div id="progress" style="width:<?php echo $progress ?>"></div>
</div>
<div id='votes'><?php echo $votes_sum ?></div>
The connection to the database is correct and readable through a require.
The script works assuming the user actually logged in as they cant access the page otherwise. As you can see I am making use of two session variables.
As you can see, I am making checks to see which button has been clicked and query accordingly.
The last bit of the code returns a json object through an associative array with the data stored by the variables you see there which is votes_sum and progress. I use json_encode to return the json representation of my value.
When you say you're not getting the response until the second click, do you mean the "votes_sum" in the votes div isn't updating with the latest votes?
The reason for this is that you calculate the $votes_sum value before you call the voting_system() function which is what updates the votes count, then after voting_system() you move the $votes_sum - unchanged - to the $output array.
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.
This is my first post so I hope I am not violating any rules. I have searched quite extensively, but possibly may have not looked for the correct terms that I am looking to resolve.
At any rate, my problem is this:
I have a table generated with a list of items, the left-most column has a button when clicked calls an ajax Post and or load function to query the history of the item and list it below the table. This works in its true sense of the expected result, however, reviewing the console through FireBug, subsequent clicks on buttons in the list result in the doubling of posts. ie. 1st click shows 1 console event, 2nd click shows 2 console events, 3rd click shows 4 console events, and so on. this continues until I select a different location and the count resets.
The below is what I see in the console. This presents a problem with timing as each subsequent post takes longer.
clicking the hist-tag button 5365
>GET http://localhost/digipens/query.php?rec_id=5365
clicking the hist-tag button 5365
>GET http://localhost/digipens/query.php?rec_id=5365
clicking the hist-tag button 5365
>GET http://localhost/digipens/query.php?rec_id=5365
clicking the hist-tag button 5365
>GET http://localhost/digipens/query.php?rec_id=5365
code:
$('.hist-tag').click(function(){
var ID=$(this).closest('tr').attr('id')
itemid = $("#itemid_input_"+ID).val();
dataString = '?rec_id='+ID;
$('#item_hist').load('query.php' + dataString);
});
Any ideas or different ways to accomplish the same goal would be excellent.
Thanks!
It sounds as if you are adding a click handler as a result of your click. Do you call $('.hist-tag').click() after the table updates? If so, you are adding new click handlers each time, which means the click is handled twice, and then 4 times, and then 8 times, etc.
I can only guess, because I don't see the relevant code here.
If so, the correct solution is to only add your click handler once, and do it via an .on() call. This way, the clicks are handled for current and future elements:
$('#mytable').on('click', '.hist-tag', function(){
var ID=$(this).closest('tr').attr('id');
itemid=$("#itemid_input_"+ID).val();
dataString = '?rec_id='+ID;
$('#item_hist').load('query.php' + dataString);
});
This attaches a handler to an element that you know will always exist #mytable, or whatever the ID of your table is, and then watches for clicks on children that propagate to the table and filters them on the selector you provide, i.e. .hist-tag.
Again, I am guessing, but that's what it seems like is happening from the evidence I have.
I suspect your click event is somehow being re-bound on each return.
Perhaps the same script is included in the response from your load call?
Try this:
$('.hist-tag').off('click');
$('.hist-tag').on('click', function(){
var ID=$(this).closest('tr').attr('id');
itemid=$("#itemid_input_"+ID).val();
dataString = '?rec_id='+ID;
$('#item_hist').load('query.php' + dataString);
return false; // prevents bubbling the click to the container
});
So I have this site that dynamically posts content using jquery and php. I would like to know how to generate permalinks. I think I could do it, but I dont even know what I should be searching for on google. You can see the site at www.eataustineat.com.
For example, I would like a link like eataustineat.com/claypit to that would go directly to the video review, instead of having to to search for it and then click the link.
I will describe the how the site works on a basic level:
first the user selects the "All Restaurants tab" in the content slider, then jquery slides to the third frame.
Next, a user selects a link from a list. This list is generated by sql queries in php, while javascript pushes the result of the php to a specific div.
When a user selects a link, jquery slides to the second slide. Once again, php runs a query while javascript pushes the content to a specific div. As a result, the user never leaves the index page.
I think it depends on how your website works. The ideal thing that I have in my mind at the moment is:
Decide a unique way to find your video (could be a title, a file name, an id: must not change), if you are using a database it's a column with a value different for each entry
Create a webpage that accept as a parameter (not optional) (possibly a $_GET parameter, not a post) that unique key and fills it's content with entry's data (the video review hopefully)
Now the permalink will be yourwebsite/yourwebpage?myparam=myvalue
Normally the permalink is the numerical id referred to that entry (thinking about databases in this case)
Edit 1: If what you mean is "moving the webpage to the link" (and not creating it), maybe you should ignore my answer, I didn't understand the question so.
What suggested Tadeck, if this is the case, is good
Edit 2: What about if, following the keylines I given you to create a permalink, you pass this value to the homepage and on page load you fire the event through the click() function (so it's like if the user clicks on the link, fires everything that you need, even the scroller thing)
Obviusly you need to give an ID to each tag, but I don't think it's a big problem (just use directly your "permalink value" as an id
The alternative in using click() method, is: give to the slider function a name so you can call it instead of waiting the click event only, expecially this part
$('.cross-link').live("click", function(){
You'll have to replace function() with a named function
then you will call, on page load, that function + ajaxpage('result.php?id=9', 'results2') + ajaxpage('videoloader.php?id=9') completely emulating the click event in this case.
You still need however an id in the a tag to find out which is the link
You should search for one (or both) of the following points:
pushState and onStateChange - preferred, nicest and probably what you are looking for,
location.hash and onhashchange - probably easier to implement (does not require you to support it on server side and works in older browsers too), but in this case you would get URL like http://eataustineat.com/#!claypit instead of http://eataustineat.com/claypit.
In this first case you would need to make sure server side scripting / configuration will invoke proper state within JS, when visited eg. by entering URL (http://eataustineat.com/claypit).
I've created a page using JQuery and Ajax that helps a user filter through a series of options and ultimately displays a filtered list of products meeting their specification.
This all works fine.
The problem i'm having is the "Back Button" problem with Ajax, i know how to get around this with anchors on static content (i.e. Filter.php#Step2).
However, the page works by returning a list of product specifications, when a spec link is clicked, Ajax loads the same page again applying the links parameters, this is repeated up to six times, after which, the user is redirected to the filtered product URL.
If the user then clicks "Back", then of course, the filter page reloads from step 1 rather than the last step (step 6).
Does anyone know if this is even possible?
Every time you want to be able to go back to the previous step, change window.location.hash.
Ie.
window.location.hash = 'step1';
This changes the #foo part in the URL. You will also need a timer in JavaScript which checks if the hash was changed, as there is no way to reliably detect hitting the back button. Something along the lines of...
var oldHash = window.location.hash;
setInterval(function(){
if(window.location.hash != oldHash) {
//the hash was changed, do something
}
}, 50);
I hope this helps
I can't say I've implemented this before personally, but I remember the jQuery Tools tab component doing something similar. I'm not sure if it will work for your particular situation, but it may be worth looking at their approach as a starting point.
jQuery Tools AJAX:ed tabs with History support