I would be nice to be able to use the text from another DOM element in the action, category, or label.
Currently
The code used looks like this.
array(
'event' => 'mousedown',
'selector' => '.horizontal-tabs ul.horizontal-tabs-list li a',
'category' => 'Product Page Interaction',
'action' => 'focus',
'label' => '!currentPage',
'value' => 0,
'noninteraction' => TRUE,
),
Maybe
We could change it to something like this:
array(
'event' => 'mousedown',
'selector' => '.horizontal-tabs ul.horizontal-tabs-list li a',
'category' => 'Product Page Interaction',
'action' => array(
'selector' => 'h1#page-title',
'return' => '!text'
),
'label' => '!currentPage',
'value' => 0,
'noninteraction' => TRUE,
),
Comments
Comment #1
dbassendine commentedI think this would be a great addition to improve the flexibility of the API.
In a simple example, I have a search form with a text field and a submit button. In order to track the search terms used, I would need to trigger the event when the form is submitted, but grab the value from the form field.
The API structure suggested above looks sensible to me. If I'm able to add this feature during some pending client work, would you be interested in rolling it into the module?
Thanks, David
Comment #2
frobfeel free to post a patch.
patches are very welcome.
:)
Comment #3
dbassendine commentedHey frob,
Thanks for getting back so quickly :)
I've just been taking a look through the module. The hook settings array looks like it's passed directly to the JS Drupal.settings, so it doesn't look too hard to add a second selector and pass an "action" JS object to pull the !text or !href selectors from:
I realised the change in structure of the hook array would break existing implementations, though, because the location of "action" would change. We could just add another array key called "selector-data" to point to the object to pull all of the tokens from - but it would be more restrictive in that all the tokens would need to come from one object (rather than being able to set different objects for category, action, label, but that's getting quite complicated anyway). This would look like:
What do you think?
Thanks, David
Comment #4
frobI like where your going. I will say that backwards compatibility is very important. At least till v2 (which is very far away).
How about something like this.
It will require a bit more but in the end this will be far more flexible. Ever sense I wrote the drush integration I have wanted to change the way the tokens are written. There is actually a bug in using the "BANG!" ! for a token passing in bash. Switching to the drupal standard (but keeping the old style around for backwards-compatibility).
Also by doing this we can allow for any number of custom tokens built on DOM. Maybe we should pick another wrapper for the tokens though. CSS uses [] for selectors. For that matter the : is used too. So we cannot switch to drupal standard tokens, unless we wrap the selectors in another wrapper.
Maybe we should have the tokens in drupal's standard token format and have the other section labeled in the example '[selector:h1#page-title]' we could just change that to 'selector : h1#page-title'. Or maybe just use json.
Whats your opinion?
Comment #5
dbassendine commentedI like the idea of tokens, and I think you could set the selector and method for each token. Setting the method allows some flexibility for elements where .text() isn't appropriate. For example, on some form fields you'd need to use .val() instead.
Tokens could be (optionally) defined and used instead of the existing !text, !currentPage etc. values where necessary. I don't think the token wrapper matters too much so long as it doesn't cause havoc in Javascript. Afaik, the tokens would be replaced before they ever reach CSS, no? I'll have a play around and see what works.
To build on your suggestion above, you could do something like this:
I've put the tokens at the end of the array to indicate they're optional. The idea is you could define tokens if you wanted, but if not everything should just look and work the same way as before.
What do you think?
Thanks, David
Comment #6
frobYes, I like that very much. It also allows for greater flexibility. If the implementation worked in a way that it didn't need to know that the methode existed when until the event fired, then this could o things that we don't necessarily intend. Which is good.
What I mean is that someone could add a lib that adds a methode that the api doesn't know about -- the api will just check to see if it exists and fire it if it does; if it doesn't exist then maybe send a message to the console.
I should probably move all the debug alerts to the console.
Comment #7
dbassendine commentedHere's a patch for this. It's currently against 6.x-1.x-dev, unfortunately, since I'm building against a 6.x build for this work - but hopefully it can be transferred relatively quickly. It's tested and working well for me. Some notes:
An example I'm using, to track a search form submission:
Let me know how this looks for you - it would be great to get this tested!
Thanks, David
Comment #8
jelo commentedThis is AWESOME. Exactly what I needed. David, I actually have the same use case, i.e. tracking a search form submission. I applied the patch and it works very well. I don't know much about jquery so I am not sure how to help test it, with the exception of saying that it works in my D6 site.
My other use case is related to Views. Views allows us to expose filters and I would like to properly track selections by users. With the original module code I managed to get it working this way:
However, this had several limitations. Using "change" does not mean that a user actually submitted the form. It would track any accidental change to any element and not only the selection that was made at submit time. And it did not allow grouping of filters. While I was able to track the filters individually, I was not able to identify if a single user might have applied 4 of the 6 filters at the same time (at submit).
How would you implement that with your patch? I used:
This setup results in 2 events (# of filters) when the form is submitted. Should it not be 1 event (# of submits) with multiple actions (# of filters applied) attached to it? I need to think about how/if GA can track this...
Other observations:
Please let me know what I can do to move this forward. I would love to see this committed to 6 and 7 versions as I have sites on both versions for which this feature would be very helpful!
Cheers, J.
Comment #9
jelo commentedRe: value vs. label
The count in GA is based on label. If you use the current page as label, GA would show you how often people have searched from that page. If you use the search term as label, GA would show you how often users have searched for the same term on any page... In the regular event tracking, label is always the most specific/granular option, e.g.
New issue:
If views "reset filter" button is enabled, it triggers a submit and the filters are counted twice (actually with the same values as you are resetting them from) which messes up the data.
Comment #10
frobWhy is the reset filter button an issue? Just target the submit button only.
Comment #11
jelo commentedRight now the clear button in views is implemented as
<input type="submit" name="op" id="edit-reset" value="Clear" class="form-submit">I guess you are suggestion to not use event "submit", but "click" on the button itself? I will try that tomorrow.
Comment #12
jelo commentedThanks for the hint to target the button only. That was an easy solution and works well ;-)
I adjusted the array to be
in case someone else is reading this thread.
Frob, may I ask what the next steps are to get this patch committed? I would be happy to try to help...
Comment #12.0
jelo commentedreformatted
Comment #13
ultimikeI'm pretty sure that the _google_analytics_et_sanitize_event_trackers() as re-written in the patch above does not adequately protect against XSS. I went ahead and updated it for Drupal 7 as follows below:
Also, if anyone is interested, I incorporated this change into my latest patch for the Google Analytics Event Tracking UI module #1994320-11: User Interface submodule.
Thanks,
-mike
Comment #14
lee20 commentedI needed this functionality for D7, so here is a patch for D7 that resembles the patch in #7
Comment #15
joelpittetTook the changes from #13 which look correct because the sanitization wasn't actually happening in HEAD.
Re-rolled #14 with the changes from #13 + a couple coding standards fixes in the introduced patch code.
There may need some more work here but give this a try.
Comment #16
joelpittetThere was a leftover
$in there and it's not wrapped in a closure so just put injQuery.Added tokens to the debug output and fixed a Namespace issue with
{string:value}with string as the key.Comment #17
jelo commentedThe latest patch actually makes the tokens resolve correctly. This is exactly what I needed. Works like a charm...