Submit Button Event Tracking in Google Analytics - analytics

I can't get event tracking to work for a submit button press on a site.
The relevant code is
button class="btn-submit validate contact-btn " type="submit" onclick="_gaq.push(['_trackEvent', 'ClutchEnquiry', 'Submit']);" >SUBMIT
Is this syntax correct?

https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits
// Gets a reference to the form element, assuming
// it contains the id attribute "signup-form".
var form = document.getElementById('signup-form');
// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {
// Prevents the browser from submiting the form
// and thus unloading the current page.
event.preventDefault();
// Sends the event to Google Analytics and
// resubmits the form once the hit is done.
ga('send', 'event', 'Signup Form', 'submit', {
hitCallback: function() {
form.submit();
}
});
});

Are you using the correct analytics object (ie. _gaq or ga)? It would depend on whether you are using Universal Analytics (analytics.js) or classic Google Analytics (ga.js) in your snippet. From you onclick handler, it looks like you may be using classic, but I've seen situations where the user mixes up the _gaq and the ga objects. Syntax-wise, it looks correct.
More information on the event push syntax can be found here https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide.
Hope this helps.

Nyuen is correct. You most likely are using Universal analytics so the JS object you want to use is below:
New syntax:
ga('send', 'event', 'button', 'click', 'ClutchEnquiry')
Old Syntax:
_gaq.push['_trackEvent', 'ClutchEnquiry', 'Submit'])

Related

If user 'touches' form inputs on profile & forgets to save: show `POP UP` when they click SideMenu icon

I've tried to come up with some sort of "error checker/validation" for my users IF they forget to Save the edits they made on their profiles.
The user enters the Profile.html state. They start to update some of their info (i.e name, phone number, etc.). INSTEAD of pressing the SAVE CHANGES button they navigate away from the Profile state by clicking the SideMenu icon at the top left of their mobile screen.
Since the form is technically now consider to be "$dirty". I've tried to use this angular property at first but I couldn't really get the results I wanted so I tried my luck with $watch..
ProfileController.js
$rootScope.isFormDirty = false;//global variable 'isFormDirty'->inject in controller.js (toggleLeftSideMenu())
$scope.$watch('updateDriverProfileInfo', function(newValue, oldValue) {//new & oldValue = ng-model when form is 1st 'viewed' is dirty
//http://tutorials.jenkov.com/angularjs/watch-digest-apply.html
if (newValue !== oldValue) {
// console.log("updatingg")
$rootScope.isFormDirty = true;
}
}, true);
Angular docs on $watch
Maybe I should of made a factory or Service for this now that I think about it but at the time I used $rootScope so that I can set a global variable isFormDirty on this controller and use it on the General Controller that holds the Side Menu's logic in this Ionic app.
controller.js (this is where the Controller for the SideMenu is)
$scope.sidemenuIsOpen = false;
$scope.toggleLeftSideMenu = function() {//ng-click from menu.html
$scope.sidemenuIsOpen = !$scope.sidemenuIsOpen;
if ($scope.sidemenuIsOpen && $rootScope.isFormDirty) {
var confirmPopup = $ionicPopup.confirm({
title: 'Changes were not saved',
template: 'Do you want to save your changes?',
});
confirmPopup.then(function(res) {
if (res) {
console.log('Run updateDriverProfile()');
} else {
console.log('Allow user to continue w/o changes');
}
});
}
};
That's basically the gist of my code. It actually "works" but I have identified a pattern and this is where I need your assistance to either suggest a whole different method to accomplish this or perhaps some refactoring tips for this current code.
The Pop up does show when the user clicks on the Side Menu button BUT I don't think it really matters if the form is $dirty or not..
The bigger issue is that the Pop up starts showing regardless if you are trying to leave the profile.html view or any other view for that matter.
When I wrote this code I was under the impression that the Pop up and toggleLeftSideMenu functions would ONLY work on the Profile view since I am "watching" the updateDriverProfileInfo object and I also created that global variable to use between the Menu Controller and Profile Controller.
you need to have a good understanding on ionic Lifecycle, try with any of the below events
$scope.$on('$ionicView.leave', function(){
// Anything you can think of
});
$scope.$on('$ionicView.beforeLeave', function(){
// Anything you can think of
});
$scope.$on('$ionicView.unloaded', function(){
// Anything you can think of
});
find more information here http://www.gajotres.net/understanding-ionic-view-lifecycle/

How to capture the Icheck checked event in backbone

How to capture the iCheck change event in backbone view.
I am unable to find any reference and using normal change event is not working.
My solution for events backbone.js is
events: {
'ifChanged #myIdCheckbox': 'changed'
},
First of all, you should try to search on the Internet almost all plugins have a web page, this one for example: http://icheck.fronteed.com/
But anyway, to listen to click event Ichecks, you must use ifChanged or check
$('input').on('ifChanged', function (e) {
var value = $(this).val();
....
});
You can also use an ID to select a checkbox just by typing: $('#Id').....

How to use `$window.history.back()` to go back in Angular.js?

I am using $window.history.back() to go 1 step back in my Ionic + Angular app.
It has an issue: if my URL is in proper form (http://localhost:8100/jobs.html) then it is working properly, but if my URL is in this form (http://localhost:8100/jobs.html#/category) then it is not working and does not go back.
Here is my function:
$scope.back3=function() {
$window.history.back();
}
I will be thankful for any help.
You need to use window.history.go(-1); in $ionicPlatform.registerBackButtonAction event. It will go back on pressing back button key. below is the example :
app.controller('HomeCtrl', function($ionicPlatform){
$ionicPlatform.registerBackButtonAction(onBackKeyDown, 100);
function onBackKeyDown() {
window.history.go(-1);
}
}
});
For giving back button action on any button use following code:
HTML
<div ng-click="goBack()">Back</div>
JavaScript
$scope.goBack = function() {
window.history.back();
};
If you want to use Ionic Framework history navigation you should also use proper Ionic Framework history object:
Use this if you want to go to the previous view:
$ionicHistory.goBack();
More about it can be found here: $ionicHistory

Backbone.js approach

I have a form (on localhost) with 2 fields:
First Name (text box)
Last Name (text box)
Once the form is submitted, I need to use API - https://beta.test.com/api
The documentation says -
"POST /user will add the details to system and generates a user ID which would be returned."
After I receive user ID in response, I need to call another endpoint -
"POST /user/metadata will fetch the metadata for a previously added user."
I have to build this in backbonejs. What should be my approach? Do you have any tutorials which I can look at?
I did some code but it gave me - "Access-Control-Allow-Origin". I have checked on server and the API already has cross domain allowed for all.
Please suggest.
For a good example look at TODO app in backbone way.
I will also suggest you to read Backbone's documentation and view the source code.
It will documented so you can find all you need there, if no look into the source.
Simple implementation of your form could be achieved like this:
For interaction with API and data exchange via REST create User model:
var UserModel = Backbone.Model.extend({
urlRoot: 'your/api/path',
default: { // this will be setted when model attributes are empty
firstname: 'Default Name',
lastname: 'Default Lastname'
}
});
Form view which will render you form and will bind model's attributes to the form's elements:
var UserForm = Backbone.View.extend({
initialize: function() {
this.render();
},
el: '.form-container', // this will attach view to the DOM's element with 'form-container' class
template: _.template($('#user-form').html()),
events: {
'submit': 'onFormSubmitted',
// validation logic could be added here
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
},
onFormSubmitted: function(e) {
e.preventDefault(); // we don't need to submit the form
// get form elements here and setting on model
// saving model at the end
var firstName = this.$('input[name="firstname"]').val();
var lastName = this.$('input[name="lastName"]').val();
this.model.set({firstname: firstName, lastname: lastName});
this.model.save(); // this will make POST request to your API
}
});
And then initialize you view and pass User model.
var userForm = new UserForm({model: new UserModel()});
I have left the declaration of template for you.
There is a lot of staff for cross origin requests policy issues when using Backbone. Actually it's not the Backbone thing. Backbone uses $.ajax to interact with REST-full resources. So you just need to configure $.ajax. Look here.

Intercept cake2 postLink() form posts with jQuery

Has anyone found a way to intercept the default Form::postLink() forms with Jquery?
I would like the form to work without JS (therefore the postLink).
But with JS enabled I want to intercept the post and call it via AJAX.
<?php echo $this->Form->postLink('Delete', array('action'=>'delete', $prospect['Prospect']['id']), array('class'=>'postLink', 'escape'=>false), __('Sure you want to delete # %s?', $prospect['Prospect']['id'])); ?>
generates:
<form action="/admin/prospects/delete/4f61ce95-2b6c-4009-9b89-07e852b0caef" name="post_4f648f773923b" id="post_4f648f773923b" style="display:none;" method="post">
<input type="hidden" name="_method" value="POST"/>
</form>
<a href="#" class="postLink" onclick="if (confirm('Sure you want to delete # 4f61ce95-2b6c-4009-9b89-07e852b0caef?')) { document.post_4f648f773923b.submit(); } event.returnValue = false; return false;">
Delete
</a>
The main problem is that the js is placed inline here. Therefore always triggers even if I try to intercept the click event (or the post event - tried that too):
<script>
$(document).ready(function() {
$('table.list a.postLink').click(function(e) {
e.preventDefault();
alert('Handler for .submit() called.');
// TODO: do ajax request here and return false
return false;
});
});
</script>
So in the end the form always submits normally and redirects - either ignoring any ajax call (catching the form submit) or posting/redirecting regardless of an ajax call just made (catching the click event).
I would like to delete this record via AJAX and - if successful - just remove that table row from DOM. It would be great if one doesn't have to modify all 300+ "delete buttons" in the application for it, though.
If everything fails I could probably still override the FormHelper (extend it and alias it). But I was hoping on a less invasive solution here.
I know this is old, but for any of those searching:
You need to first remove the 'onclick' attribute added to the delete
link.
Then, you add a .click function to the delete link
You need the url (which can be hardcoded or retrieved from the form, which is always the prev element in cakephp Form->postLink
Here is the code:
$(function(){
$('a:contains("Delete")').removeAttr('onclick');
$('a:contains("Delete")').click(function(e){
e.preventDefault();
var form = $(this).prev();
url = $(form).attr("action");
$.post(url);
return false;
});
});
jymboche - what a genius
why didnt i think of it myself?
Well, here is the modified answer of yours:
$(document).ready(function() {
$('table.list a.postLink').removeAttr('onclick');
$('table.list a.postLink').click(function(e) {
e.preventDefault();
if (!confirm('<?php echo __('Sure?')?>')) {
return false;
}
var form = $(this).prev();
var url = $(form).attr("action");
var tr = $(this).closest('tr');
url = url + '.json';
$.post(url).success(function(res) {
if (res.error) {
alert(res.error);
return false;
}
tr.fadeOut(200);
}).error(function() {
alert("Error");
})
return false;
});
});
This is for future reference only.
I will still accept your answer as you gave me the right idea.
jymboche's solution helped me to get to a working answer, but it didn't work fully for me, due to some security cake plugins that I have installed.
Here's what worked for me:
$(function(){
$('a:contains("Delete")').removeAttr('onclick');
$('a:contains("Delete")').click(function(e){
e.preventDefault();
var form = $(this).prev();
var url = $(form).attr("action");
$.ajax({
type: 'POST',
cache: false,
url: url,
data: $(form).serialize(),
success: function(msg) {
// do any extra calls you need to refresh the page
}
});
return false;
});
});
Just an idea, haven't tested it:
<?php echo $this->Form->postLink('Delete', array('action'=>'delete', $prospect['Prospect']['id']), array('class'=>'postLink', 'onclick' => false, 'escape'=>false), __('Sure you want to delete # %s?', $prospect['Prospect']['id'])); ?>
Couple of issues with the current solutions...
First and foremost, the postLink method requires Javascript to be enabled. From Cake's doco:
"Creates an HTML link, but access the url using method POST. Requires javascript to be enabled in browser."
If javascript is disabled, you just get the exact same output - a hidden form, and a link that tries to submit that form with Javascript (but fails, since JS is turned off).
Second, although it will work, it seems weird to use the postLink method, and then use Javacript to undo precisely all the magic that the postLink method creates.
If you want a non-javascript friendly solution, all you have to do is create a regular form that points to the delete method, and put a link below it like this:
<?php echo $this->Form->create('DefaultAvailability', array('url' array('action' => 'delete', $myRecord['ModelName']['id'])));?>
<?php echo $this->Form->end('Delete (no JS)');?>
<a href='#'>Delete (With JS, use AJAX)</a>
Then, for cases when there's no javascript, hide the link below, and the form will work as normal.
For cases when there is javascript, hide the form, and use javascript to make your delete link trigger a submit on your delete form, and handle that submit with ajax.
I've translated the previous jQuery version to Mootools
//We start with foreach, to select all ajax buttons on the page
$$('.ajaxbutton').each(function(item,index){
//remove onClick
item.removeProperty('onclick');
//attach click event
item.addEvent('click', function(e){
//stop click (in my case the form is inside another link)
e.stop();
var form = item.getPrevious();
url = form.get('action');
new Request({
url: url,//url
method: 'post',//method
onSuccess: function(responseText){
//This is not required, we are dimming the button on success
item.getParents()[0].tween('opacity',0.5)
}
}).send();
return false;
});
})

Resources