File: D:/web/castironradiatorcentre/changes prev/2023-10-20/prev/gtm-lib.asp
<%
' (SS,13/10/23) Google Tag Manager module
Class GTMDef
' can't use a const, using a variable instead, see https://stackoverflow.com/questions/21052084/constant-inside-class
' Const GTM_DATA_INDENT_SPACES = 2
Private INDENT_SPACES ' used as a constant
Private FGTMContainerID, FAffiliation
Private FDataIndentLevel, FGTMData, FItemDataCount
' Private FProductCode, FProductName, FProductVariant, FBrand, FCategory, FSubcategory, FPrice
Private FEventName, FCurrency, FDiscountCode, FSearchTerm ' FDiscount
Private FTransactionID, FPurchaseValue, FPurchaseTax, FShipping
' field constants
Private F_EVENT_NAME, F_PRODUCT_CODE, F_PRODUCT_NAME, F_PRODUCT_VARIANT, F_PRICE, F_QUANTITY, F_BRAND, F_CATEGORY, F_SUBCATEGORY, F_FIELD_COUNT
' items array
Private FItems, FFieldNo
' event name constants
Private E_VIEW_ITEM, E_VIEW_CART, E_ADD_TO_CART, E_REMOVE_FROM_CART, E_BEGIN_CHECKOUT, E_ADD_SHIPPING_INFO, E_ADD_PAYMENT_INFO, E_PURCHASE, E_SEARCH
' Private FViewItemCount, FViewCartCount, FAddToCartCount, FRemoveFromCartCount
Private Function FieldNo
FFieldNo = FFieldNo + 1
F_FIELD_COUNT = FFieldNo
FieldNo = FFieldNo
End Function
Private Sub Class_Initialize
INDENT_SPACES = 2
FGTMContainerID = ""
FAffiliation = ""
'FGTMDataIndentLevel = 0
'FGTMData = ""
'FItemDataCount = 0
E_VIEW_ITEM = "view_item"
E_VIEW_CART = "view_cart"
E_ADD_TO_CART = "add_to_cart"
E_REMOVE_FROM_CART = "remove_from_cart"
E_BEGIN_CHECKOUT = "begin_checkout"
E_ADD_SHIPPING_INFO = "add_shipping_info"
E_ADD_PAYMENT_INFO = "add_payment_info"
E_PURCHASE = "purchase"
E_SEARCH = "search"
FEventName = ""
FCurrency = "GBP"
' FDiscount = 0
FDiscountCode = ""
FSearchTerm = ""
FTransactionID = ""
FPurchaseValue = 0
FPurchaseTax = 0
FShipping = 0
' field contants
FFieldNo = -1 ' held in FieldNo and increments in each call
F_EVENT_NAME = FieldNo
F_PRODUCT_CODE = FieldNo
F_PRODUCT_NAME = FieldNo
F_PRODUCT_VARIANT = FieldNo
F_PRICE = FieldNo
F_QUANTITY = FieldNo
F_BRAND = FieldNo
F_CATEGORY = FieldNo
F_SUBCATEGORY = FieldNo
ReDim FItems(F_FIELD_COUNT, -1)
End Sub
Public Sub Class_Terminate
End Sub
' contruct with parameter see http://johna.compoutpost.com/blog/806/classic-asp-class-constructors-with-parameters/
Public Default Function Init(AContainerID, AAffiliation)
FGTMContainerID = AContainerID
FAffiliation = AAffiliation
Set Init = Me
End Function
' Public Property Let Discount(AValue)
' FDiscount = AValue
' End Property
Public Property Let DiscountCode(AValue)
FDiscountCode = AValue
End Property
Public Property Let TransactionID(AValue)
FTransactionID = AValue
End Property
Public Property Let PurchaseValue(AValue)
FPurchaseValue = AValue
End Property
Public Property Let PurchaseTax(AValue)
FPurchaseTax = AValue
End Property
Public Property Let Shipping(AValue)
FShipping = AValue
End Property
Private Sub SetDataIndentLevel(AIndentLevel)
FDataIndentLevel = AIndentLevel
End Sub
Private Sub IncDataIndentLevel
FDataIndentLevel = FDataIndentLevel + 1
End Sub
Private Sub DecDataIndentLevel
FDataIndentLevel = FDataIndentLevel - 1
End Sub
Private Function GetDataIndentSpaces
GetDataIndentSpaces = Space(INDENT_SPACES * FDataIndentLevel)
End Function
Private Sub StartGTMData
FGTMData = ""
End Sub
Private Sub EndGTMData
End Sub
Private Sub ShowGTMData
Response.Write FGTMData
End Sub
Private Sub StartItem
FItemDataCount = 0
FGTMData = FGTMData + GetDataIndentSpaces + "{" + NL
IncDataIndentLevel
End Sub
Private Sub NextItem
FGTMData = FGTMData + "," + NL
End Sub
Private Sub EndItem
DecDataIndentLevel
FGTMData = FGTMData + NL + GetDataIndentSpaces + "}"
End Sub
' *** ? to be improved with JSON object handling
' NB. thought number needs to be passed without quotes around it, later discovered the debug view multiplies by 1000000 causing confusion
Private Sub AddGTMDataLine(AName, AValue)
Dim LValue
LValue = NB(AValue) ' converts to string including the null
If LValue = "" Then Exit Sub
' add quote around string types only
Dim LQuote
If VarType(AValue) = VBString Then
LQuote = """"
Else
LQuote = ""
End If
If FItemDataCount > 0 Then FGTMData = FGTMData + "," + NL
FItemDataCount = FItemDataCount + 1
FGTMData = FGTMData + GetDataIndentSpaces + AName + ": " + LQuote + JavaScriptStrEscape(AValue) + LQuote
End Sub
Private Function GetNameValueStr(AName, AValue, AAppendComma)
Dim LResult, LValue
LValue = NB(AValue) ' converts to string including the null
If LValue <> "" Then
' add quote around string types only
Dim LQuote
If VarType(AValue) = VBString Then
LQuote = """"
Else
LQuote = ""
End If
LResult = GetDataIndentSpaces + AName + ": " + LQuote + JavaScriptStrEscape(AValue) + LQuote + iif(AAppendComma, ",", "") + NL
Else
LResult = ""
End If
GetNameValueStr = LResult
End Function
Private Sub ShowEcommerceValue(AName, AValue, AAppendComma)
Response.Write GetNameValueStr(AName, AValue, AAppendComma)
End Sub
Private Sub ShowEcommerceScriptHeader
' may not need first line, to check // Clear the previous ecommerce object.
%>
<script>
dataLayer.push({ ecommerce: null });
<%
End Sub
Private Sub ShowEcommerceEventHeader(AEventName)
%>
dataLayer.push({
event: "<%=AEventName%>",
ecommerce: {
<%
End Sub
Private Sub ShowEcommerceEventFooter
%>
}
});
<%
End Sub
Private Sub ShowEcommerceScriptFooter
%>
</script>
<%
End Sub
Private Sub ShowEcommerceEventItemsStart
Response.Write GetDataIndentSpaces + "items: [" + NL
End Sub
Private Sub ShowEcommerceEventItemsEnd
Response.Write NL + GetDataIndentSpaces + "]" ' + NL
End Sub
' returns true if there is at least one event
Private Function IsEvent
IsEvent = UBound(FItems, 2) > -1
End Function
Private Function EventCount(AEventName)
Dim i, LResult
LResult = 0
For i = 0 To UBound(FItems, 2)
If FItems(F_EVENT_NAME, i) = AEventName Then
LResult = LResult + 1
End If
Next
EventCount = LResult
End Function
Private Function EventValue(AEventName)
Dim i, LResult
LResult = 0
For i = 0 To UBound(FItems, 2)
If FItems(F_EVENT_NAME, i) = AEventName Then
LResult = Round(LResult + Round(FItems(F_PRICE, i) * FItems(F_QUANTITY, i), 2), 2)
End If
Next
EventValue = LResult
End Function
Private Sub ShowEcommerceEventItems(AEventName)
StartGTMData
Dim i, LIndex
LIndex = 0
For i = 0 To UBound(FItems, 2)
If FItems(F_EVENT_NAME, i) = AEventName Then
If LIndex > 0 Then NextItem
StartItem
' only item_id and item_name are required
'AddGTMDataLine "event_name_**_to_remove", FItems(F_EVENT_NAME, i)
AddGTMDataLine "item_id", FItems(F_PRODUCT_CODE, i)
AddGTMDataLine "item_name", FItems(F_PRODUCT_NAME, i)
AddGTMDataLine "item_variant", FItems(F_PRODUCT_VARIANT, i)
AddGTMDataLine "affiliation", FAffiliation
AddGTMDataLine "index", LIndex
AddGTMDataLine "item_brand", FItems(F_BRAND, i)
AddGTMDataLine "item_category", FItems(F_CATEGORY, i)
AddGTMDataLine "item_category2", FItems(F_SUBCATEGORY, i)
AddGTMDataLine "price", FItems(F_PRICE, i)
AddGTMDataLine "quantity", FItems(F_QUANTITY, i)
EndItem
LIndex = LIndex + 1
End If
Next
EndGTMData
ShowGTMData
End Sub
Public Sub EventViewItem
FEventName = E_VIEW_ITEM
End Sub
Public Sub EventViewCart
FEventName = E_VIEW_CART
End Sub
Public Sub EventAddToCart
FEventName = E_ADD_TO_CART
End Sub
Public Sub EventRemoveFromCart
FEventName = E_REMOVE_FROM_CART
End Sub
Public Sub EventBeginCheckout
FEventName = E_BEGIN_CHECKOUT
End Sub
Public Sub EventAddShippingInfo
FEventName = E_ADD_SHIPPING_INFO
End Sub
Public Sub EventAddPayment
FEventName = E_ADD_PAYMENT_INFO
End Sub
Public Sub EventPurchase
FEventName = E_PURCHASE
End Sub
' (SS,19/10/23) *** to be completed
Public Sub EventSearch(ASearchTerm)
FEventName = E_SEARCH
FSearchTerm = ASearchTerm
End Sub
' quick single line method of adding an item, to be called after calling EventViewCart or EventAddToCart
Public Sub AddItem(AProductCode, AProductName, AProductVariant, APrice, AQuantity, ABrand, ACategory, ASubcategory)
' add to array to store new item
Dim i
i = UBound(FItems, 2) + 1
Redim Preserve FItems(UBound(FItems, 1), i) ' resize the array preserving the existing data
FItems(F_EVENT_NAME, i) = FEventName
FItems(F_PRODUCT_CODE, i) = AProductCode
FItems(F_PRODUCT_NAME, i) = AProductName
FItems(F_PRODUCT_VARIANT, i) = AProductVariant
FItems(F_PRICE, i) = APrice
FItems(F_QUANTITY, i) = AQuantity
FItems(F_BRAND, i) = ABrand
FItems(F_CATEGORY, i) = ACategory
FItems(F_SUBCATEGORY, i) = ASubcategory
End Sub
Public Function Enabled
Enabled = FGTMContainerID <> ""
End Function
Public Sub DoEcommerceEvents
If Not Enabled Then Exit Sub
If IsEvent Then ' if at least one event
ShowEcommerceScriptHeader
DoEcommerceEvent E_REMOVE_FROM_CART
DoEcommerceEvent E_ADD_TO_CART
DoEcommerceEvent E_VIEW_CART
DoEcommerceEvent E_VIEW_ITEM
DoEcommerceEvent E_BEGIN_CHECKOUT
DoEcommerceEvent E_ADD_SHIPPING_INFO
DoEcommerceEvent E_ADD_PAYMENT_INFO
DoEcommerceEvent E_PURCHASE
ShowEcommerceScriptFooter
End If
End Sub
Private Sub DoEcommerceEvent(AEventName)
If EventCount(AEventName) > 0 Then
ShowEcommerceEventHeader AEventName
SetDataIndentLevel 2
ShowEcommerceValue "currency", FCurrency, True
'ShowEcommerceValue "value", FValue, True
If AEventName = E_PURCHASE Then
ShowEcommerceValue "transaction_id", FTransactionID, True
End If
If AEventName = E_ADD_SHIPPING_INFO Or AEventName = E_ADD_PAYMENT_INFO Or AEventName = E_PURCHASE Then
ShowEcommerceValue "value", FPurchaseValue, True
Else
ShowEcommerceValue "value", EventValue(AEventName), True
End If
' coupon for begin_checkout, add_shipping_info, add_payment_info, purchase
If FDiscountCode <> "" And AEventName = E_BEGIN_CHECKOUT Or AEventName = E_ADD_SHIPPING_INFO Or AEventName = E_ADD_PAYMENT_INFO Or AEventName = E_PURCHASE Then
ShowEcommerceValue "coupon", FDiscountCode, True
End If
'? to add payment info with payment type
If AEventName = E_PURCHASE Then
ShowEcommerceValue "shipping", FShipping, True
ShowEcommerceValue "tax", FPurchaseTax, True
End If
ShowEcommerceEventItemsStart
ShowEcommerceEventItems AEventName
ShowEcommerceEventItemsEnd
ShowEcommerceEventFooter
End If
End Sub
Public Sub DoGoogleTagManagerScript
If Enabled Then
%>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<%=FGTMContainerID%>');</script>
<!-- End Google Tag Manager -->
<%
End If
End Sub
' (SS,5/10/23) following called from HTMLBodyEnd adds recommended <noscript> GTM script for Javascript being disabled the Tag Assistant recommends it (otherwise I wouldn't have added it)
Public Sub DoGoogleTagManagerNoScript
If GTMEnabled Then
%>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<%=FGTMContainerID%>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<%
End If
End Sub
End Class
%>