I'm no javascript wiz, but am a bit puzzled as to how this is working in three major browsers, but not Safari... is there something wrong with this code? Basically I'm just using this in conjunction with a php/mysql callback at the given url to track link clicks.
Drupal.behaviors.NodeDownloadCounter = function() {
$('a.ndc-link').click(function() {
$.post('/' + this.name);
return true;
});
};
Using Drupal behaviors here instead of
$(document).ready(function() {
(correct Drupal method) but I've tried it both ways and it doesn't make a difference.
I've also tried removing "return true", but with no effect.
Okay, further testing reveals that having the click trigger an alert DOES work in Safari:
$('a.ndc-link').click(function() {
alert('testing (ignore)');
$.post('/' + this.name);
return true;
});
But still nothing being logged to mysql. Here is my callback function:
function node_download_counter_log($nid)
{
global $user;
$timestamp = time();
$title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $nid));
db_query("INSERT INTO {node_download_counter} (nid, title, download_count, last_download, last_uid) VALUES (%d, '%s', %d, %d, %d)
ON DUPLICATE KEY UPDATE download_count=download_count+1, last_download = %d, last_uid = %d", $nid, $title, 1, $timestamp, $user->uid, $timestamp, $user->uid);
db_query("INSERT INTO {node_download_counter_log} (nid, title, uid, timestamp) VALUES (%d, '%s', %d, %d)", $nid, $title, $user->uid, $timestamp);
}
I'm no javascript wiz, but am a bit puzzled as to how this is working in three major browsers, but not Safari... is there something wrong with this code? Basically I'm just using this in conjunction with a php/mysql callback at the given url to track link clicks.
Drupal.behaviors.NodeDownloadCounter = function() {
$('a.ndc-link').click(function() {
$.post('http://www.pixeledmemories./node-download-counter/log/' + this.name);
return true;
});
};
Using Drupal behaviors here instead of
$(document).ready(function() {
(correct Drupal method) but I've tried it both ways and it doesn't make a difference.
I've also tried removing "return true", but with no effect.
Okay, further testing reveals that having the click trigger an alert DOES work in Safari:
$('a.ndc-link').click(function() {
alert('testing (ignore)');
$.post('http://www.pixeledmemories./node-download-counter/log/' + this.name);
return true;
});
But still nothing being logged to mysql. Here is my callback function:
function node_download_counter_log($nid)
{
global $user;
$timestamp = time();
$title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $nid));
db_query("INSERT INTO {node_download_counter} (nid, title, download_count, last_download, last_uid) VALUES (%d, '%s', %d, %d, %d)
ON DUPLICATE KEY UPDATE download_count=download_count+1, last_download = %d, last_uid = %d", $nid, $title, 1, $timestamp, $user->uid, $timestamp, $user->uid);
db_query("INSERT INTO {node_download_counter_log} (nid, title, uid, timestamp) VALUES (%d, '%s', %d, %d)", $nid, $title, $user->uid, $timestamp);
}
Share
Improve this question
edited Jul 5, 2010 at 6:38
Jordan Magnuson
asked Jul 5, 2010 at 5:48
Jordan MagnusonJordan Magnuson
8843 gold badges10 silver badges22 bronze badges
9
-
why do you have to
return true
? just curious.. – Reigel Gallarde Commented Jul 5, 2010 at 5:59 - Good question Reigel... like I said, I'm no javascript wiz... I took this basic code from a tutorial that had the "return true" at the end... is in not necessary? – Jordan Magnuson Commented Jul 5, 2010 at 6:12
- I would check the error console as safari shows the responses that e back from the server in a nice link that you can click and then view what came back. So try returning a value from the ajax call and see if you are getting back the response you expect. – spinon Commented Jul 5, 2010 at 6:23
- Sorry for my lack of expertise spinon... could you give me a little more detail on how to do what you're suggesting? I really appreciate your help! – Jordan Magnuson Commented Jul 5, 2010 at 6:31
-
can you remove
return true;
... I think that should not be there... onlyreturn false;
is mostly use... and that is if you want your page not jumping to other page when clicking that anchor... – Reigel Gallarde Commented Jul 5, 2010 at 6:36
3 Answers
Reset to default 3Sounds like the problem is the browser is changing the page before the data post can be finished. You can try adding return false to see if it starts working then. If it does, you are going to need to add a short delay before following the link.
UPDATE: Since it works try adding the following before "return true;"
if(jQuery.browser.safari){
setTimeout("window.location.href= '"+this.href+"'",500);
return false;
}
Okay, based on our conversation on ments above, try
$('a.ndc-link').click(function() {
var href = this.href;
$.post('http://www.pixeledmemories./node-download-counter/log/' + this.name,
function() {
window.location.href = href;
}
);
return false;
});
Firs,t you have to be careful not to attach your handler more than once to each 'a.ndc-link'
, one way to do it is to tag the elements with a custom class.
Drupal.behaviors.NodeDownloadCounter = function() {
$('a.ndc-link:not(.node-download-counter-processed)').addClass('node-download-counter-processed').click(function(event) {
// ...
});
};
One reason I see for this not to work is that, because it closes the page to open the link target, Safari will cancel the $.post
request before it is actually sent to the server. Returning false and calling event.preventDefault
(event being the first argument of your event handler) should prevent this from happening but will also prevent the browser to actually load the link's target. One way to solve this is to defer the page change until the POST request is plete.
Drupal.behaviors.NodeDownloadCounter = function() {
$('a.ndc-link:not(.node-download-counter-processed)').addClass('node-download-counter-processed').click(function(event) {
var link = this;
event.preventDefault();
$.post('http://www.pixeledmemories./node-download-counter/log/' + this.name, function() {
window.location.href = link.href;
});
return false;
});
};
But this will only works if there is no error in the POST request.
A better solution would be to hijack the server-side handler for the link target to add the click logging and then call the original handler.