0

I'm trying to track registered user activity, specifically, when they click a link to a file for download. The filesystem plugin is WP-Filebase.

I found that when I added a click() handler through jQuery, it wasn't happening, so I switched to a mousedown() handler for my Ajax-based tracking.

What appears to be occurring (based on Firebug's Network activity monitor) is that if I press the mouse (mousedown) and then release, the resulting file download dialog box that occurs cancels the mousedown activity (Network tab shows the mousedown Ajax call as "cancelled"). The Ajax call therefore never makes it to the server and so I don't get my tracking.

On the other hand, if I press the mouse and DON'T release for a while, I do get to see my test Ajax response, (an alert()).

This is not viable for obvious reasons. Is there another solution? Can both the mousedown and the anchor click work together, or will one always cancel the other?

EDIT, here's some code that's behaving as I described (linkx.js):

(function($) {
    $(document).ready(function(){
        $('.wpfilebase-attachment a').mousedown(function(){
            var postParams = {};
            postParams['action'] = ZGAjax.TRACKING_ACTION;
            postParams[ZGAjax.FILE_ID_PARAM] = this.id;

            $.post(
                ZGAjax.ajaxurl, 
                postParams,
                function( response ) {
                    alert( response );
                }
            );

            return true;
        });

    });
})(jQuery);

And the handler on the php side...

// Add AJAX tracking of file downloads.
// First, add the link tracking script and create a global namespace to hold the admin_url() for the AJAX call
if (!is_admin()) add_action('wp_enqueue_scripts', 'gsn_add_tracking_script');
function gsn_add_tracking_script(){
    wp_enqueue_script( 'zg-link-tracker', SCRIPTS_URI . '/linkx.js', array('jquery'), '1.0' );
    wp_localize_script( 'zg-link-tracker', 'ZGAjax', array( 
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'TRACKING_ACTION' => TRACKING_ACTION,
        'FILE_ID_PARAM' => FILE_ID_PARAM
    ) );
} 

 // Works in conjunction with linkx.js
 add_action( 'wp_ajax_' . TRACKING_ACTION, 'gsn_track_downloads' );

function gsn_track_downloads() {
    // get the submitted parameters
    $file_id = $_POST[FILE_ID_PARAM];

    // generate the response
    $response = json_encode( array( 'success' => true, 'file_id' => $file_id ) );

    // response output
    header( "Content-Type: application/json" );
    echo $response;

    // IMPORTANT: don't forget to "exit"
    exit;
}

The PHP side is pretty textbook, and really just sends me back a confirmation that it worked.

And it DOES work, if I keep my mouse button held down long enough for the entire transaction to complete. If I release, and thus allows the download to begin, I never get the confirmation. Firebug tells me that the Ajax request is "cancelled" so it's not even a matter of the transaction piggy-backing on top of the download transaction (which was a wild theory in the first place).

4
  • Do you have a code example or live demo? In general, when dealing with problems that seem to not work as they should, it's helpful to have something to debug and tweak. (Because as far as I can tell, a mousedown event works fine on an anchor click, and a mouseup event shouldn't be canceling a mousedown event)
    – Jared Cobb
    Sep 12, 2011 at 20:16
  • @JaredCobb done.
    – Tom Auger
    Sep 12, 2011 at 21:36
  • 1
    Try switching to a .live() bind. Anyway, I'd say it's def. no wp question. You should ask that on SO.
    – kaiser
    Sep 12, 2011 at 21:46
  • @kaiser - yeah, you're right, it's almost certainly not a WP issue. I wanted to post here in case anyone knew something specific regarding the WP-Filebase plugin or some quirk of WP.
    – Tom Auger
    Sep 13, 2011 at 12:30

1 Answer 1

1

It's a good idea to prevent mixing your click/mouse handling. In the past when faced with the same problem, I've used one of two approaches (depending on my mood at the time):

Mouseup

Rather than use mousedown, use jQuery's mouseup event. Mousedown is typically stepped on by click. By using mouseup instead, you fire your event after the mouse is released (typically at the same time as click or just after) and shouldn't run in to the same problem.

Bind directly to click

This is the one I use the most often. Loop through the anchor tags on your page and change their event binding. You can set the click event of each link to first fire your AJAX call and then (after completion) it will fire the original event.

For example:

jQuery(document).ready(function($) {

    $('a').bind('click', function(e) {

        // Do your AJAX stuff

        return true;
    });

});

Since you're using jQuery, make sure you set async: false when you use AJAX. This will force the browser to execute the request before moving on to loading the link.

If you're using forms, you can easily unbind/rebind the submit handler ... unfortunately click is a little less cooperative.

4
  • Holy crap @EAMann, that's a lot of good info. The only comment I'd have is that I would bet that mouseup gets swallowed by the File Save dialog box. Since the click on the anchor starts a download and then invokes a dialog box, I"m sure the DB flushes the rest of the mouse events on that object. Besides, you have to click on the "SAVE" button, and that in itself will swallow the mouseup right there.
    – Tom Auger
    Sep 13, 2011 at 12:32
  • 1
    Thaks @EAMann, switching async = false sorted me right out, while leaving the Ajax onMousedown. Note, though this should be obvious: if you're testing your Ajax to see if it works by having an alert() to display the Ajax success results, you WILL cancel the click and the download / link will not take place. This only makes sense because you consume the mouse event by dismissing the alert dialog box.
    – Tom Auger
    Sep 13, 2011 at 13:21
  • @Tom Auger Just use console.log(); instead of alert();. This doesn't interrupt normally.
    – kaiser
    Sep 14, 2011 at 9:36
  • 1
    @kaiser right you are. I have to start remembering to do that!
    – Tom Auger
    Sep 14, 2011 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.