Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using Javascript within Google Analytics event tracking code to automate category naming

So I'm attempting to implement some google analytics event tracking on dynamically generated pages. I'll be using something like

<script>
$(document).ready(function(){
  $("#button1").click(function(){
    _gaq.push(['_trackEvent', category, action, opt_label, opt_value, opt_noninteraction)']);
  }); 
  $("#button2").click(function(){
    _gaq.push(['_trackEvent', category, action, opt_label, opt_value, opt_noninteraction']);
  });
});
</script>

I'm wondering is it possible to use something like document.title to auto generate the category section of the GA code from the html title of the pages? All the pages use unique titles and it would be great if the events tracked on those pages could show up in GA as separate entries and not just category.

like image 788
user2268663 Avatar asked Oct 04 '22 10:10

user2268663


1 Answers

That was tougher than I expected it. Hope it helps.

Live demo with examples

javascript

// Unbind default behaviour
    $(document).off("ready.ga").on("ready", function () {
        //hollow out
        pageLoc = $(location).attr('href');
        // Introduce helper functions.

        (function ($, window, undef) {
            // ga selector.

            $.extend($.expr[":"], {
                ga: function (a) {
                    var attr = a.attributes,
                        len = attr.length;

                    while (len--) {
                        if (attr[len].name.indexOf("data-ga-") !== -1) {
                            return true;
                        }
                    }

                    return false;
                }
            });

            $.gaaApi = {
                trackEvent: {
                    event: {
                        value: "_trackEvent",
                        validation: "isString",
                        type: "string"
                    },
                    category: {
                        value: null,
                        validation: "optString",
                        type: "currentloc"
                    },
                    action: {
                        value: null,
                        validation: "optString",
                        type: "string"
                    },
                    label: {
                        value: null,
                        validation: "optString",
                        type: "string"
                    },
                    value: {
                        value: null,
                        validation: "optInt",
                        type: "integer"
                    },
                    nonInteraction: {
                        value: null,
                        validation: "optBool",
                        type: "boolean"
                    }
                },
                trackPageview: {

                    event: {
                        value: ["trackPageview", $(location).attr('href')],
                        validation: "isString",
                        type: "string"
                    },
                    url: {
                        value: undef,
                        validation: "optString",
                        type: "string"
                    }
                }
            };

            var validation = {

                isString: function (obj) {

                    var empty = true;

                    if (obj && typeof obj === "string") {
                        empty = /^\s*$/.test(obj);
                    }
                    // If empty === true then something is wrong and we should return false.
                    return !(empty);

                },

                optString: function (obj) {
                    if (obj === undef) {
                        return true;
                    }

                    return validation.isString(obj);
                },

                isInt: function (obj) {
                    return (/^[\-+]?\d+$/).test(obj) || (obj === +obj && obj === (obj | 0));
                },

                optInt: function (obj) {

                    if (obj === undef) {
                        return true;
                    }

                    return validation.isInt(obj);
                },

                isFloat: function (obj) {

                    return (/^[\-+]?\d+(\.\d+)?$/).test(obj) || (obj === +obj && obj !== (obj | 0));
                },

                optFloat: function (obj) {
                    if (obj === undef) {
                        return true;
                    }

                    return validation.isFloat(obj);
                },

                isBool: function (obj) {
                    return (obj === true || obj === "true") || (obj === false || obj === "false");

                },

                optBool: function (obj) {

                    if (obj === undef) {
                        return true;
                    }

                    return validation.isBool(obj);
                }
            },

            methods = {

                validate: function (param, name, location) {

                    var $element = this.$element,
                        data = $element.data("ga-" + name.toLowerCase()),
                        isValid;
                    //pageLoc = $(location).attr('href');

                    if (!validation[param.validation]) {

                        throw new TypeError("Unknown validation type");
                    }

                    // Check the value.
                    isValid = validation[param.validation](data);

                    if (!isValid) {

                        throw new Error("object validation error on " + name);
                    }

                    // Assign the value.
                    // Some analytics methods accept numbers as strings so we check the return type.
                    switch (param.type) {
                        case "integer":
                            return data ? parseInt(data, 10) : null;
                        case "float":
                            return data ? parseFloat(data) : null;
                        case "boolean":
                            return data ? Boolean(data) : null;
                        case "currentloc":
                            return data;
                        default:
                            // Default to string.
                            return data ? data + "" : null;
                    }

                },
                createArgs: function () {

                    var binder = this,
                        event = this.event,
                        args = $.map(event, function (val, key, pageLoc) {
                            var pageLoc = $(location).attr('href');


                            var value;

                            if (key === "event") {
                                // We don't want to check for the event property in the DOM.
                                value = val.value;

                            } else {

                                // Validate and return the correct value from the DOM.
                                value = methods.validate.call(binder, val, key, pageLoc);

                            }

                            return value;
                        });

                    return args;
                }
            },

            gaa = function (element, options) {

                this.$element = $(element);
                this.options = $.extend({}, $.fn.gaa.defaults, options);
            };

            gaa.prototype = {
                constructor: gaa,
                trackEvent: function () {
                    var trackedEvent = $.Event("tracked.ga");
                    var currentLoc = $(location).attr('href');

                    this.args = methods.createArgs.call(this);

                    if (this.options.logit) {

                        if (window.console && window.console.log) {

                            // Push the data.
                            console.log("pushing to Google analytics", this.args);
                            this.$element.trigger(trackedEvent).trigger(currentLoc);

                            // this.$element.trigger(currentLocation);

                        }
                    } else {

                        var gaq = window._gaq;

                        if (gaq) {

                            // Set the context for our deferred callback.
                            var binder = this;

                            // Push the data.
                            $.when(gaq.push(args)).done(

                            function () {

                                this.$element.trigger(trackedEvent);

                                //    this.$element.trigger(trackedEvent);


                                // Redirect the location - delayed so that any other page functionality has time to run.
                                setTimeout(function () {
                                    var href = binder.attr("href");

                                    if (href && href.indexOf("#") !== 0) {
                                        window.location = href;
                                    }

                                }, 100);
                            });

                        } else {
                            throw new ReferenceError(" _gaq not there");
                        }
                    }
                }

            };

            // wrapper definition 
            $.fn.gaa = function (options) {
                return this.each(function () {

                    var $this = $(this),
                        data = $this.data("ga"),
                        opts = typeof options === "object" ? options : null;


                    if (!data) {
                        // Check the data and assign if not present.
                        $this.data("ga", (data = new gaa(this, opts)));
                    }

                    // Run the appropriate function is a string is passed.
                    if (typeof options === "string") {

                        data[options]();

                    } else {

                        var handler = data.options.handler.toLowerCase(),
                            // Check for the event attr here as it might be other than the default.
                            event = data.$element.attr("data-ga-event");

                        // Overwrite if necessary.
                        $.extend(data.options, {
                            event: event
                        });

                        // Build the data as we have nothing there.
                        // First assign the event.
                        data.event = $.gaaApi[data.options.event];

                        // Then bind the handler.
                        if (handler === "load") {

                            data.trackEvent();

                        } else {

                            data.$element.on(handler + ".ga", function (e) {

                                e.preventDefault();
                                data.trackEvent();
                            });
                        }
                    }
                });
            };

            // Define the defaults.
            $.fn.gaa.defaults = {
                event: ["trackEvent", "giveLocation"],
                handler: "load",
                logit: false
            };

            // Set the public constructor.
            $.fn.gaa.Constructor = gaa;

            // Let's BEGIN
            $(document).on("ready.ga", function () {

                // Bind using the custom selector.
                $(":ga").each(function () {
                    $(this).gaa();
                });
            });

        }(jQuery, window));


        // Set some options the ones below are the defaults.
        var options = {
            event: "trackEvent", // The event name unprefixed. 
            handler: "click", // The eventhandler to trigger the tracking. 
            // Using 'load' will track immediately.
            logit: true, //to logit

        };

        var options2 = {
            event: "trackPageview", // The event name unprefixed. 
            handler: "click", // The eventhandler to trigger the tracking. 
            // Using 'load' will track immediately.
            logit: true, //to logit
        };

        var options3 = {
            event: "trackPageview", // The event name unprefixed. 
            handler: "load", // The eventhandler to trigger the tracking. 
            // Using 'load' will track immediately.
            logit: true //to logit
        };

        // Binds using the custom selector.  

        $("load.trigger").gaa(options3); //fires a ga onload after domready
        $("button.button1").gaa(options2).click(function () {
            console.log('\nmore button events\n', 'heres the URL:', location.href)
        });

        $("#clickme").gaa(options).click(function () {
            $(this).toggleClass("changeIt");
        });


    });

index.html

<load class="trigger">loading triggers ga event</load>
<button class="button1">fire ga event with address</button>
<button class="button1" id="clickme">multiple events</button>

The location bind happens here and lets jquery consume location properly.

                  event: {
                            value: ["trackPageview",$(location).attr('href')],
                            validation: "isString",
                            type: "string"
                         }

your approach of using this was correct but you had to get the location earlier to get it into ga. It seems like anyways this format

 $("#button").gaa(options).click(function () {
            $(this).toggleClass("changeIt");
        });

Will get you going in the right directions.

This was a fun brainache. That should give you access to location.href where you want need it later on. The idea is to form a bind after DOM ready but before _gaq execution.

like image 198
29 revs Avatar answered Oct 10 '22 04:10

29 revs