Google Analytics pushing worng value in 'checkout' actionField option - google-analytics

There is common JSPF var dataLayer = window.dataLayer = dataLayer || []; has declared.
On Checkout step -3
dataLayer.push({
'event' : 'checkout',
'ecommerce' : {
'currencyCode' : 'GBP',
'checkout' : {
'actionField' : {
'step' : 3,
'option' : '<some-value>',
'tax' : '<some-value>',
**'action' : 'checkout'**
},
'products' : '<some-value>'
}
}
});
It is working fine. Pushing correct data.
On Checkout step - 4
dataLayer.push({
'event' : 'checkout',
'ecommerce' : {
'currencyCode' : 'GBP',
'checkout' : {
'actionField' : {
'step' : 4,
'option' : '<some-value>',
'tax' : '<some-value>',
**'action' : 'purchase'**
},
'products' : '<some-value>'
}
}
});
It still pushing 'checkout' not 'purchase'. The datalayer pushing of elements from same file for step-3 and step-4. And declaration is from .JSPf which is included in it. It seems like 'action' element is cached.I had tried with cleaning browser history but no success.
Please tell where i had lacked.

The actionField.action field is automatically populated by GTM/Universal Analytics. You should never manually add a value to it.
The field value is derived from the property name that wraps actionField and products. Thus if the hit is a "Checkout" hit, the property key would be checkout, and if the hit is a "Purchase" hit, the property key would be purchase.
Example Checkout hit for step 4:
event: 'checkout',
ecommerce: {
checkout: {
actionField: {
step: 4,
option: 'some-option'
}
}
}
Example Purchase hit:
event: 'purchase',
ecommerce: {
currencyCode: 'GBP',
purchase: {
actionField: {
id: 'some-transaction-id',
revenue: 'some-transaction-revenue',
tax: 'some-transaction-tax',
shipping: 'some-transaction-shipping'
},
products: [{
...products in the purchase...
}]
}
}

Related

Full Calender Delete an event which is in recurring sequence

I have a complex scenario in which i want to implement. I am using Full Calendar v4.4.0 and for showing recurring events i am using rrule plugin. I am loading events from mysql. I am succesfull in loading them and showing them on website. Its working perfectly fine but now the client has come up with another requirement.
As told earlier i am using rrule plugin to show recurring events. In my portal there are only 2 recurring events
Weekly
Monthly
Now client wants to delete an event e.g, an event which is occurring weekly he wants to delete it for one time. For example an event is added on 13th April and is repeated every week. That is he wants to delete the event for 27th April only and want to continue with the sequence as it is. How can i achieve it as the event id is same for all repeating events.
It needs to be mention that i am using Mysql from where the events are coming.
My Code for Loading events
$model = Event::find()->all(); // getting all events
foreach ($model as $mod)
{
$day=array();
if ($mod->event_frequency==2)
{
$start=date('N', strtotime($mod->start_time));
$end=date('N', strtotime($mod->end_time));
if($start==$end)
{
$day[]=$start;
}
else
{
$day[]=$start;
$day[]=$end;
}
$data[]=[
'id' =>$mod->id,
'title'=>$mod->event_name,
// 'start' => $mod->start_time,
// 'end' => $mod->end_time,
'backgroundColor' => $mod->event_tag_color,
'textColor' => '#FFF',
'rrule'=> [
'freq'=> 'WEEKLY',
'interval'=> 1,
'dtstart'=> $mod->start_time,
'until' => '2022-12-31',
],
];
}
else if($mod->event_frequency==3)
{
$start=date('N', strtotime($mod->start_time));
$end=date('N', strtotime($mod->end_time));
if($start==$end)
{
$day[]=$start;
}
else
{
$day[]=$start;
$day[]=$end;
}
$data[]=[
'id' =>$mod->id,
'title'=>$mod->event_name,
// 'start' => $mod->start_time,
// 'end' => $mod->end_time,
'backgroundColor' => $mod->event_tag_color,
'textColor' => '#FFF',
'rrule'=> [
'freq'=> 'MONTHLY',
'interval'=> 1,
'dtstart'=> $mod->start_time,
'until' => '2022-12-31',
],
];
}
else
{
$data[]=[
'id' =>$mod->id,
'title'=>$mod->event_name,
'start' => $mod->start_time,
'end' => $mod->end_time,
'backgroundColor' => $mod->event_tag_color,
'textColor' => '#FFF',
];
}
}
return JSON::encode($data);
the calender.js for loading is as follows
var calendarEl = document.getElementById('calendar-event');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['interaction', 'dayGrid', 'timeGrid', 'list','rrule'],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
navLinks: true, // can click day/week names to navigate views
businessHours: true, // display business hours
editable: true,
//uncomment to have a default date
//defaultDate: '2020-04-07',
events: url+'calender/load', // loading events
}
Deleting an event on server
$event_id=Yii::$app->request->post('event_id');
$model= Event::findOne($event_id);
$model->delete();
$response= array();
$response['status']="ok";
return JSON::encode($response);
The js file calling the action delete action
$(".delete-event-calender").on("click",function(evt) {
$data=$('form').serialize();
$url=$(this).data('url');
$.ajax({
type: "POST",
url: $url,
data: $data,
dataType: "json",
traditional: true,
success: function (response) {
//alert(response.status);
if (response.status==="ok"){
calendar.refetchEvents();
$(".ajax_form").trigger("reset");
}
else
{
}
},
error: function (response) {
debugger;
alert(response.d);
}
});
});
If i try to delete the event for 27th April it will take the event id of main event (The day it was set) and will delete whole sequence? How can i prevent it.
How can i achieve it? Any suggestions please
Thanks

WordPress TinyMCE custom styles with input option

I want to add a custom style to the wordpress tiny mce. There are tons of tutorials for just adding a simple option like "highlight" which will add a span with a "highlight" class. Like: https://torquemag.io/2016/09/add-custom-styles-wordpress-editor-manually-via-plugin/
But what I need is an option to add additional data, like if you add a link. You mark the words, hit the link button, an input for the url shows up.
What I want to achieve? A custom style "abbriation" (https://get.foundation/sites/docs/typography-base.html). The solution I'm thinking of is, the user marks the word, chooses the abbriation style, an input for the descriptions shows up. fin.
Hope you can help me out!
So I have something similar in most of my WordPress projects. I have a TinyMCE toolbar button that has a couple of fields that output a bootstrap button.
What you need to do is create your own TinyMCE "plugin" and to achieve this you need two parts:
A javascript file (your plugin)
A snippet of PHP to load your javascript (plugin) into the TinyMCE editor.
First we create the plugin:
/js/my-tinymce-plugin.js
( function() {
'use strict';
// Register our plugin with a relevant name
tinymce.PluginManager.add( 'my_custom_plugin', function( editor, url ) {
editor.addButton( 'my_custom_button', {
tooltip: 'I am the helper text',
icon: 'code', // #link https://www.tiny.cloud/docs/advanced/editor-icon-identifiers/
onclick: function() {
// Get the current selected tag (if has one)
var selectedNode = editor.selection.getNode();
// If we have a selected node, get the inner content else just get the full selection
var selectedText = selectedNode ? selectedNode.innerHTML : editor.selection.getContent();
// Open a popup
editor.windowManager.open( {
title: 'My popup title',
body: [
// Create a simple text field
{
type: 'textbox',
name: 'field_name_textbox',
label: 'Field label',
value: selectedText || 'I am a default value' // Use the selected value or set a default
},
// Create a select field
{
type: 'listbox',
name: 'field_name_listbox',
label: 'Field list',
value: '',
values: {
'value': 'Option 1',
'value-2': 'Option 2'
}
},
// Create a boolean checkbox
{
type: 'checkbox',
name: 'field_name_checkbox',
label: 'Will you tick me?',
checked: true
}
],
onsubmit: function( e ) {
// Get the value of our text field
var textboxValue = e.data.field_name_textbox;
// Get the value of our select field
var listboxValue = e.data.field_name_listbox;
// Get the value of our checkbox
var checkboxValue = e.data.field_name_checkbox;
// If the user has a tag selected
if ( selectedNode ) {
// Do something with selected node
// For example we can add a class
selectedNode.classList.add( 'im-a-custom-class' );
} else {
// Insert insert content
// For example we will create a span with the text field value
editor.insertContent( '<span>' + ( textboxValue || 'We have no value!' ) + '</span>' );
}
}
} );
}
} );
} );
} )();
Now we add and modify the below snippet to your themes functions.php file.
/functions.php
<?php
add_action( 'admin_head', function() {
global $typenow;
// Check user permissions
if ( !current_user_can( 'edit_posts' ) && !current_user_can( 'edit_pages' ) ) {
return;
}
// Check if WYSIWYG is enabled
if ( user_can_richedit() ) {
// Push my button to the second row of TinyMCE actions
add_filter( 'mce_buttons', function( $buttons ) {
$buttons[] = 'my_custom_button'; // Relates to the value added in the `editor.addButton` function
return $buttons;
} );
// Load our custom js into the TinyMCE iframe
add_filter( 'mce_external_plugins', function( $plugin_array ) {
// Push the path to our custom js to the loaded scripts array
$plugin_array[ 'my_custom_plugin' ] = get_template_directory_uri() . '/js/my-tinymce-plugin.js';
return $plugin_array;
} );
}
} );
Make sure to update the file name and path if you it's different to this example!
WordPress uses TinyMCE 4 and the documentation for this is lacking so finding exactly what you need can be painful.
This is merely a starting point and has not been tested.
Hope this helps!
EDIT
The below code should help you with the insertion of an "abbreviations" tag and title attribute.
( function() {
'use strict';
tinymce.PluginManager.add( 'my_custom_plugin', function( editor, url ) {
editor.addButton( 'my_custom_button', {
tooltip: 'Insert an abbreviation',
icon: 'plus',
onclick: function() {
var selectedNode = editor.selection.getNode();
var selectedText = selectedNode ? selectedNode.innerHTML : editor.selection.getContent();
editor.windowManager.open( {
title: 'Insert an abbreviation',
body: [
{
type: 'textbox',
name: 'abbreviation',
label: 'The abbreviated term',
value: selectedText
},
{
type: 'textbox',
name: 'title',
label: 'The full term',
value: ''
}
],
onsubmit: function( e ) {
var abbreviation = e.data.abbreviation;
var title = e.data.title.replace( '"', '\"' );
if ( selectedNode && selectedNode.tagName === 'ABBR' ) {
selectedNode.innerText = abbreviation;
selectedNode.setAttribute( 'title', title );
} else {
editor.insertContent( '<abbr title="' + title + '">' + abbreviation + '</abbr>' );
}
}
} );
}
} );
} );
} )();

Semantic: Trigger functions (Dimmer) after form validation passes

Using Semantic-ui.
Have a form that uses Semantic built in form validation.
On form submit I want to call a dimmer.
Is there a way to trigger the dimmer after the form passes validation.
As it is now I have the dimmer connected to a onclick="dimmer()" on the submit button.
This means that the dimmer triggers even if the form is not submitting because of failed validation.
onSuccess: function(event, fields) {
dim();
}
example
$(document)
.ready(function() {
$('.ui.form')
.form({
fields: {
trailer: {
identifier : 'trailer',
rules: [
{
type : 'empty',
prompt : 'Please select a Trailer'
}
]
},
movie: {
identifier : 'movie',
rules: [
{
type : 'empty',
prompt : 'Please select a Movie'
}
]
}
},
onSuccess: function(event, fields) {
dim();
}
})
;
})
;

Several options for checkout_option in GA Enhanced Ecommerce

What would be the best way to register several options for a single checkout step with GA Enhanced ecommerce?
As the documentation describes:
// Called when user has completed shipping options.
function onShippingComplete(stepNumber, shippingOption) {
ga('ec:setAction', 'checkout_option', {
'step': stepNumber,
'option': shippingOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: function() {
// Advance to next page.
}
});
}
The problem is that we collect the shipping and the payment option in one step, and we would like to track both selections. Here is our initial idea:
// Called when user has completed shipping and payment options.
function onStepComplete(stepNumber, shippingOption,paymentOption ) {
ga('ec:setAction', 'checkout_option', {
'step': stepNumber,
'option': shippingOption
});
ga('ec:setAction', 'checkout_option', {
'step': stepNumber,
'option': paymentOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: function() {
// Advance to next page.
}
});
}
Would this work as expected? Could we afterwards segment correctly?
I'm afraid options are exclusive and they act as a dimension in the new enhanced checkout funnel reports from GA. If you want to analyse which shipping method works better, then you cannot mix it together with the payment method, both must be different dimensions since the values of a dimension are exclusive.
I would separate shipping and payment in two separate steps each one with their own dimension shipping/payment, even if you have a onestep checkout (quite normal nowadays) you can create as many steps as you want.
Take a look to the Enhanced Ecommerce Demo Store, here they are presenting the payment methods in the step 2 but when the user hits the selector in order to chose Visa/transfer/etc a step 3 is created.
Change the checkout_option to checkout - Seems to be the way Google handles the two separate types of events and what data is required for each to work in enhanced ecommerce. Just been facing the same issues myself and have managed to resolve with that fix.
Example based on your code would be:
// Called when user has completed shipping and payment options.
function onStepComplete(stepNumber, shippingOption,paymentOption ) {
ga('ec:setAction', 'checkout', {
'step': stepNumber,
'option': shippingOption
});
ga('ec:setAction', 'checkout', {
'step': stepNumber,
'option': paymentOption
});
ga('send', 'event', 'checkout', 'option', {
hitCallback: function() {
// Advance to next page.
}
});
}
each step allows only 1 dimension. The solution is to create sub-steps, and when you fire 2 sub-steps remember to send 2 events instead of 1, otherwise the last one will overwrite.
Here it is:
async.parallel([
function shippingOption(callback) {
ga('ec:setAction', 'checkout_option', {
'step': 1,
'option': shippingOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: callback(null, true)
});
},
function paymentOption(callback) {
ga('ec:setAction', 'checkout_option', {
'step': 2,
'option': paymentOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: callback(null, true)
})
}
], function(err, hitCallback){
// do something like going to next page
})

How to get Total Results using Google Analytics Embed API

I'm trying to simply pull the total number of pages on my site.
Using the GA Query Explorer (https://ga-dev-tools.appspot.com/query-explorer/), you can see the "Total results found" number when the results are displayed after running a query.
How can I apply this to GA Embed API query format? ...
var pageTitles = new gapi.analytics.googleCharts.DataChart({
reportType: 'ga',
query: {
'dimensions': 'ga:pageTitle',
'metrics': 'ga:pageviews',
'segment': 'gaid::-1',
'sort': '-ga:pageviews',
'filters': 'ga:pagePath!=/',
'max-results': '10',
'totalResults': 'integer',
},
chart: {
type: 'TABLE',
container: 'page-titles',
options: {
title: 'Top Pageviews',
width: '100%'
}
}
});
Thank you!!
If you add an event handler for successful queries, you can get access to the totals. Here's an example:
var pageTitles = new gapi.analytics.googleCharts.DataChart({
query: {
'dimensions': 'ga:pageTitle',
'metrics': 'ga:pageviews',
'segment': 'gaid::-1',
'sort': '-ga:pageviews',
'filters': 'ga:pagePath!=/',
'max-results': '10'
},
chart: {
type: 'TABLE',
container: 'page-titles',
options: {
title: 'Top Pageviews',
width: '100%'
}
}
});
pageTitles.on('success', function(result) {
// Print the total pageview count to the console.
console.log(result.response.totalsForAllResults['ga:pageviews']);
});
And here's the documentation for the parameters passed to the 'success' event:
https://developers.google.com/analytics/devguides/reporting/embed/v1/component-reference#datachart
Also note that you don't need the 'totalResults': 'integer' part that you have in your example, nor do you need the reportType: 'ga' part (it's optional).

Resources