How can we get traffic source data without the __utmz cookie? - google-analytics

I used to be able to pull traffic source data by reading the __utmz cookie, by doing so I can post the data to an internal conversion tracking database. but now GA doesn't use this cookie and it appears that the other cookies don't have any client-side data we can use.
Are there any other ways we can pull the traffic source data into our own internal db?

You can simulating the Google Analytics Processing Flow and determine the values of traffic sources parameters like source, medium, campaign, ... using a custom JavaScript in page or through Google Tag Manager.
This can be a solution:
function crumbleCookie(a) {
for (var d = document.cookie.split(";"), c = {}, b = 0; b < d.length; b++) {
var e = d[b].substring(0, d[b].indexOf("=")).trim(),
i = d[b].substring(d[b].indexOf("=") + 1, d[b].length).trim();
c[e] = i
}
if (a) return c[a] ? c[a] : null;
return c
}
function bakeCookie(a, d, c, b, e, i) {
var j = new Date;
j.setTime(j.getTime());
c && (c *= 864E5);
j = new Date(j.getTime() + c);
document.cookie = a + "=" + escape(d) + (c ? ";expires=" + j.toGMTString() : "") + (b ? ";path=" + b : "") + (e ? ";domain=" + e : "") + (i ? ";secure" : "")
}
function writeLogic(n) {
var a = getTrafficSource(n, '.example.com'); //Insert your domain here
a = a.replace(/\|{2,}/g, "|");
a = a.replace(/^\|/, "");
a = unescape(a);
bakeCookie(n, a, 182, "/", "", "") // Cookie expiration sets to 182 days
};
function getParam(s, q) {
try{
var match = s.match('[?&]' + q + '=([^&]+)');
return match ? match[1] : '';
} catch(e){
return '';
}
}
function calculateTrafficSource() {
var source='', medium='', campaign='', term='', content='';
var search_engines = [['bing', 'q'], ['google', 'q'], ['yahoo', 'q'], ['baidu', 'q'], ['yandex', 'q'], ['ask', 'q']]; //List of search engines
var ref = document.referrer;
ref = ref.substr(ref.indexOf('//')+2);
ref_domain = ref;
ref_path = '/';
ref_search = '';
// Checks for campaign parameters
var url_search = document.location.search;
if(url_search.indexOf('utm_source') > -1) {
source = getParam(url_search, 'utm_source');
medium = getParam(url_search, 'utm_medium');
campaign = getParam(url_search, 'utm_campaign');
term = getParam(url_search, 'utm_term');
content = getParam(url_search, 'utm_content');
}
else if (getParam(url_search, 'gclid')) {
source = 'google';
medium = 'cpc';
campaign = '(not set)';
}
else if(ref) {
// separate domain, path and query parameters
if (ref.indexOf('/') > -1) {
ref_domain = ref.substr(0,ref.indexOf('/'));
ref_path = ref.substr(ref.indexOf('/'));
if (ref_path.indexOf('?') > -1) {
ref_search = ref_path.substr(ref_path.indexOf('?')+1);
ref_path = ref_path.substr(0, ref_path.indexOf('?'));
}
}
medium = 'referral';
source = ref_domain;
// Extract term for organic source
for (var i=0; i<search_engines.length; i++){
if(ref_domain.indexOf(search_engines[i][0]) > -1){
medium = 'organic';
source = search_engines[i][0];
term = getParam(ref_search, search_engines[i][1]) || '(not provided)';
break;
}
}
}
return {
'source' : source,
'medium' : medium,
'campaign': campaign,
'term' : term,
'content' : content
};
}
function getTrafficSource(cookieName, hostname) {
var trafficSources = calculateTrafficSource();
var source = trafficSources.source.length === 0 ? 'direct' : trafficSources.source;
var medium = trafficSources.medium.length === 0 ? 'none' : trafficSources.medium;
var campaign = trafficSources.campaign.length === 0 ? 'direct' : trafficSources.campaign;
// exception
if(medium === 'referral') {
campaign = '';
}
var rightNow = new Date();
var value = 'source=' + source +
'&medium=' + medium +
'&campaign='+ campaign +
'&term=' + trafficSources.term +
'&content=' + trafficSources.content +
'&date=' + rightNow.toISOString().slice(0,10).replace(/-/g,"");
return value;
}
// Self-invoking function
(function(){
var date = new Date();
var fr_date = date.getUTCFullYear().toString() + ((date.getUTCMonth() < 9) ? '0' + (date.getUTCMonth()+1).toString() : (date.getUTCMonth()+1).toString()) + ((date.getUTCDate() < 10) ? '0' + date.getUTCDate().toString() : date.getUTCDate().toString());
var session = crumbleCookie()['FirstSession'];
if (typeof session == 'undefined') {
writeLogic('FirstSession');
}
else {
writeLogic('ReturningSession');
}
})();
Code here: http://clients.first-rate.com/firstrate/NewSession%20and%20ReturningSession%20cookies.txt

Related

Adding Application Insights on Blazor Client (Web Assembly)

I am wanting to add application insights sdk into a blazor web assembly project. I came across multiple articles such as Application Insights for web pages and stackoverflow that has the exact thing I am looking for. However, after adding the snippet of code from the microsoft link and using connectionString over instrumentationKey to the index.html page and injecting IJSRuntime in order to call JavaScript methods from .NET code then calling Application Inisghts methods... when running the application at the top of the home page I will see #inject IJSRuntime _jsRuntime.
Am I not properly setting up the injecting? Also, do I need to add these lines of code into each razor component (page folder) or just having it in the index.html will cover everything from the start to end no matter what I click and what page is rendered?
Index.html
#inject IJSRuntime _jsRuntime
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
!function (T, l, y) { var S = T.location, k = "script", D = "connectionString", C = "ingestionendpoint", I = "disableExceptionTracking", E = "ai.device.", b = "toLowerCase", w = "crossOrigin", N = "POST", e = "appInsightsSDK", t = y.name || "appInsights"; (y.name || T[e]) && (T[e] = t); var n = T[t] || function (d) { var g = !1, f = !1, m = { initialize: !0, queue: [], sv: "5", version: 2, config: d }; function v(e, t) { var n = {}, a = "Browser"; return n[E + "id"] = a[b](), n[E + "type"] = a, n["ai.operation.name"] = S && S.pathname || "_unknown_", n["ai.internal.sdkVersion"] = "javascript:snippet_" + (m.sv || m.version), { time: function () { var e = new Date; function t(e) { var t = "" + e; return 1 === t.length && (t = "0" + t), t } return e.getUTCFullYear() + "-" + t(1 + e.getUTCMonth()) + "-" + t(e.getUTCDate()) + "T" + t(e.getUTCHours()) + ":" + t(e.getUTCMinutes()) + ":" + t(e.getUTCSeconds()) + "." + ((e.getUTCMilliseconds() / 1e3).toFixed(3) + "").slice(2, 5) + "Z" }(), iKey: e, name: "Microsoft.ApplicationInsights." + e.replace(/-/g, "") + "." + t, sampleRate: 100, tags: n, data: { baseData: { ver: 2 } } } } var h = d.url || y.src; if (h) { function a(e) { var t, n, a, i, r, o, s, c, u, p, l; g = !0, m.queue = [], f || (f = !0, t = h, s = function () { var e = {}, t = d.connectionString; if (t) for (var n = t.split(";"), a = 0; a < n.length; a++) { var i = n[a].split("="); 2 === i.length && (e[i[0][b]()] = i[1]) } if (!e[C]) { var r = e.endpointsuffix, o = r ? e.location : null; e[C] = "https://" + (o ? o + "." : "") + "dc." + (r || "services.visualstudio.com") } return e }(), c = s[D] || d[D] || "", u = s[C], p = u ? u + "/v2/track" : d.endpointUrl, (l = []).push((n = "SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)", a = t, i = p, (o = (r = v(c, "Exception")).data).baseType = "ExceptionData", o.baseData.exceptions = [{ typeName: "SDKLoadFailed", message: n.replace(/\./g, "-"), hasFullStack: !1, stack: n + "\nSnippet failed to load [" + a + "] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: " + (S && S.pathname || "_unknown_") + "\nEndpoint: " + i, parsedStack: [] }], r)), l.push(function (e, t, n, a) { var i = v(c, "Message"), r = i.data; r.baseType = "MessageData"; var o = r.baseData; return o.message = 'AI (Internal): 99 message:"' + ("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) (" + n + ")").replace(/\"/g, "") + '"', o.properties = { endpoint: a }, i }(0, 0, t, p)), function (e, t) { if (JSON) { var n = T.fetch; if (n && !y.useXhr) n(t, { method: N, body: JSON.stringify(e), mode: "cors" }); else if (XMLHttpRequest) { var a = new XMLHttpRequest; a.open(N, t), a.setRequestHeader("Content-type", "application/json"), a.send(JSON.stringify(e)) } } }(l, p)) } function i(e, t) { f || setTimeout(function () { !t && m.core || a() }, 500) } var e = function () { var n = l.createElement(k); n.src = h; var e = y[w]; return !e && "" !== e || "undefined" == n[w] || (n[w] = e), n.onload = i, n.onerror = a, n.onreadystatechange = function (e, t) { "loaded" !== n.readyState && "complete" !== n.readyState || i(0, t) }, n }(); y.ld < 0 ? l.getElementsByTagName("head")[0].appendChild(e) : setTimeout(function () { l.getElementsByTagName(k)[0].parentNode.appendChild(e) }, y.ld || 0) } try { m.cookie = l.cookie } catch (p) { } function t(e) { for (; e.length;)!function (t) { m[t] = function () { var e = arguments; g || m.queue.push(function () { m[t].apply(m, e) }) } }(e.pop()) } var n = "track", r = "TrackPage", o = "TrackEvent"; t([n + "Event", n + "PageView", n + "Exception", n + "Trace", n + "DependencyData", n + "Metric", n + "PageViewPerformance", "start" + r, "stop" + r, "start" + o, "stop" + o, "addTelemetryInitializer", "setAuthenticatedUserContext", "clearAuthenticatedUserContext", "flush"]), m.SeverityLevel = { Verbose: 0, Information: 1, Warning: 2, Error: 3, Critical: 4 }; var s = (d.extensionConfig || {}).ApplicationInsightsAnalytics || {}; if (!0 !== d[I] && !0 !== s[I]) { var c = "onerror"; t(["_" + c]); var u = T[c]; T[c] = function (e, t, n, a, i) { var r = u && u(e, t, n, a, i); return !0 !== r && m["_" + c]({ message: e, url: t, lineNumber: n, columnNumber: a, error: i }), r }, d.autoExceptionInstrumented = !0 } return m }(y.cfg); function a() { y.onInit && y.onInit(n) } (T[t] = n).queue && 0 === n.queue.length ? (n.queue.push(a), n.trackPageView({})) : a() }(window, document, {
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js", // The SDK URL Source
// name: "appInsights", // Global SDK Instance name defaults to "appInsights" when not supplied
// ld: 0, // Defines the load delay (in ms) before attempting to load the sdk. -1 = block page load and add to head. (default) = 0ms load after timeout,
// useXhr: 1, // Use XHR instead of fetch to report failures (if available),
crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
// onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument -- the sdk instance (DO NOT ADD anything to the sdk.queue -- As they won't get called)
cfg: { // Application Insights Configuration
connectionString: "CONNECTIONSTRING_KEY_GOES_HERE"
/* ...Other Configuration Options... */
}
});
</script>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorWeb</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="BlazorWeb.styles.css" rel="stylesheet" />
</head>
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
Reload
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
</body>
await _jsRuntime.InvokeVoidAsync("appInsights.trackPageView");
</html>
Injecting the Application Insights for Blazor web applications. Steps to be followed
Add BlazorApplicationInsights
Nuget
dotnet add package BlazorApplicationInsights
Add call to Program.cs
builder.Services.AddBlazorApplicationInsights();
Add using statement to _Imports.razor
#using BlazorApplicationInsights;
Add component to App.razor
<ApplicationInsightsComponent />
Add Application Insights JS to head in index.html
Source
Set 'ld: -1' so that the page will be blocked until the JS is loaded and enter your instrumentationKey
Add the Source like below screenshot
Add JS Interop to the bottom of body in index.html
I can see the Track Event button which I was used.
Also, I can see the custom Event in Application Insights.
Refer here

Google sheet + App Script : Rename every sheet if it meet criteria

Hi I'm using this script to rename every sheet by inserting 'Copy of' in front of the existing sheet name where the text in cell 'B36' = 'SAFETY ANALISIS' and the date from cell 'K3'is older then 30 days. My issue is having to do with the date I can't quite figure how to do it. Cell 'K3' cell are in this format "1-Aug-2021" I think I need to convert the date in 'K3' to a number format.
Any help would be greatly appreciated
function getSheet() {
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var sum = 0;
for (var i = 0; i < sheets.length ; i++ ) {
var sheet = sheets[i];
var date = new Date();
var ageInDays = 30;
var threshold = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate() - ageInDays)
.getTime();
var val = sheet.getRange('K3').getValue();
var val2 = sheet.getRange('B36').getValue();
if (val >= threshold && val2 == 'SAFETY ANALYSIS') {
var sheetName = sheet.getName()
sheet.setName('Copy Of '+sheetName)
}
}
}
You may want to wrap the value you get from cell K3 in a Date() constructor. That should work with spreadsheet dates as well as text strings that look like dates.
I think you have the comparison in val >= threshold the wrong way around. Try something like this:
function renameOldSafetyAnalysisSheets() {
const timeLimit = 30 * 24 * 60 * 60 * 1000; // 30 days
const now = new Date();
const sheets = SpreadsheetApp.getActive().getSheets();
sheets.forEach(sheet => {
if (sheet.getRange('K3').getValue() !== 'SAFETY ANALYSIS') {
return;
}
const date = new Date(sheet.getRange('B36').getValue());
if (!date.getTime()
|| now.getTime() - date.getTime() < timeLimit) {
return;
}
try {
sheet.setName('Copy of ' + sheet.getName());
} catch (error) {
;
}
});
}
function getSheet() {
const shts = SpreadsheetApp.getActive().getSheets();
let d = new Date();
let ageInDays = 30;
let threshold = new Date(d.getFullYear(),d.getMonth(),d.getDate() - ageInDays).valueOf();
shts.forEach(sh => {
let val = new Date(sh.getRange('K3').getValue()).valueOf();
let val2 = sh.getRange('B36').getValue();
if (val <= threshold && val2 == 'SAFETY ANALYSIS') {
sh.setName('Copy Of ' + sh.getName())
}
});
}

How to change wordpress post content before generate

My post has content:
<p>download Download</p>
<p>download mirror Download</p>
And i have a script to add prefix domain, i put it before </body>:
<script type="text/javascript">
var tui_url = 'https://mydomainasd.com';
var tui_domains = ['mediafire.com', 'www.abc.com','mega.nz', 'drive.google.com','secufiles.com'];
</script>
<script>
function tui_get_url(e) {
var n = document.createElement("a");
return n.href = e, n
}
function tui_get_host_name(e) {
var n;
return void 0 === e || null === e || "" === e || e.match(/^\#/) ? "" : -1 === (e = tui_get_url(e)).href.search(/^http[s]?:\/\//) ? "" : (n = e.href.split("/")[2], (n = n.split(":")[0]).toLowerCase())
}
document.addEventListener("DOMContentLoaded", function(e) {
if ("undefined" != typeof tui_url) {
var l = document.getElementsByTagName("a");
if ("undefined" == typeof tui_domains)
if ("undefined" == typeof tui_exclude_domains);
else
for (o = 0; o < l.length; o++) {
var t = tui_get_host_name(l[o].getAttribute("href"));
t.length > 0 && -1 === tui_exclude_domains.indexOf(t) ?
l[o].href = tui_url + "?u=" + encodeURIComponent(l[o].href) : "magnet:" ===
l[o].protocol && (l[o].href = tui_url + "?u=" + encodeURIComponent(l[o].href))
} else
for (var o = 0; o < l.length; o++)(t =
tui_get_host_name(l[o].getAttribute("href"))).length > 0 &&
tui_domains.indexOf(t) > -1 ? l[o].href = tui_url + "?u=" +
encodeURIComponent(l[o].href): "magnet:" === l[o].protocol && (l[o].href =
tui_url + "?u=" + encodeURIComponent(l[o].href))
}
});
</script>
It works well.
But now I want to it perform this task before generating post content, mean that above script will not appear in output HTML.
I think about creating a plugin or function but I don't know how to do.
Can you help me solve this? sorry for my English
You can try this filter : https://codex.wordpress.org/Plugin_API/Filter_Reference/the_content
You will get the content of the post in your function so you can edit it with PHP before display it.
You can put this code in functions.php at the root of your theme or in a plugin.

Handlebars precompiled template returning function text

I have a precompiled template called "ReportOptions_Timeframe". When I call Handlebars.templates.ReportOptions_Timeframe(data) I do not get the rendered template html. Instead I get this for output:
"function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0']; helpers = this.merge(helpers,
Handlebars.helpers); data = data || {}; var buffer = "", stack1,
helper, functionType="function",
escapeExpression=this.escapeExpression, self=this;
function program1(depth0,data) {
var buffer = ""; buffer += "\r\n "
+ escapeExpression((typeof depth0 === functionType ? depth0.apply(depth0) : depth0))
+ "\r\n "; return buffer; }
buffer += "Term:\r\n\r\n "; stack1 = helpers.each.call(depth0,
(depth0 && depth0.TermList),
{hash:{},inverse:self.noop,fn:self.program(1, program1,
data),data:data}); if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\r\n\r\n\r\n \r\n\r\nDate range:\r\n\r\nto\r\n"; return buffer; }"
What am I doing wrong?
Edited to add the precompiled template:
(function() { var template = Handlebars.template, templates =
Handlebars.templates = Handlebars.templates || {};
templates['ReportOptions_Timeframe'] = template(function
(Handlebars,depth0,helpers,partials,data) { this.compilerInfo =
[4,'>= 1.0.0']; helpers = this.merge(helpers, Handlebars.helpers);
data = data || {};
return "function (Handlebars,depth0,helpers,partials,data) {\n
this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers,
Handlebars.helpers); data = data || {};\n var buffer = \"\", stack1,
helper, functionType=\"function\",
escapeExpression=this.escapeExpression, self=this;\n\nfunction
program1(depth0,data) {\n \n var buffer = \"\";\n buffer +=
\"\r\n \"\n + escapeExpression((typeof depth0 === functionType ? depth0.apply(depth0) : depth0))\n + \"\r\n \";\n return
buffer;\n }\n\n buffer += \"Term:\r\n\r\n \";\n stack1 =
helpers.each.call(depth0, (depth0 && depth0.TermList),
{hash:{},inverse:self.noop,fn:self.program(1, program1,
data),data:data});\n if(stack1 || stack1 === 0) { buffer += stack1;
}\n buffer += \"\r\n\r\n\r\n \r\n\r\nDate range:\r\n\r\nto\r\n\";\n return buffer;\n }"; }); })();
I was giving node the wrong input file. The input file I was using had been previously precompiled.

Extjs4 multigrouping header value css

I am using the Extjs4 multigrouping plugin from here.
I have used it successfully, however i want to show the summary of the totals of each column within the group header itself . how do i set up the appropriate CSS for that ?
In Multigrouping.js
getFragmentTpl: function() {
var me = this;
return {
indentByDepth: me.indentByDepth,
depthToIndent: me.depthToIndent,
renderGroupHeaderTpl: function(values, parent) {
return Ext.XTemplate.getTpl(me, 'groupHeaderTpl').apply(values, parent);
//var z = new Ext.XTemplate('{name} ({rows.grouplength})');
//return z.apply(values, parent);
}
};
},
In my grid
features: [
{
ftype:'multigrouping',
groupHeaderTpl: [
'{[this.readOut(values)]}',
{
readOut:function(values) {
debugger;
var sum1 =0 ,sum2=0,sum3=0;
for( var i = 0 ; i< values.records.length ; i++)
{
var val = parseFloat(values.records[i].data.d2012.mp);
sum1 += isNaN(val) ? 0.0 : val;
val = parseFloat(values.records[i].data.d2013.mp);
sum2 += isNaN(val) ? 0.0 : val;
val = parseFloat(values.records[i].data.d2014.mp);
sum3 += isNaN(val) ? 0.0 : val;
}
return values.name + '(' + values.records.length + ')' + ' ' + sum1.toFixed(2) + ' ' + sum2.toFixed(2) + ' ' + sum3.toFixed(2);
}
}
]
},
had to resort to a few hacks to get this to work. still waiting on an official answer.
The main reason i had to do this and not use the multigrouping summary is because
- i want to limit the number of records from the server. I can do some smart grouping of
my business objects at the server side.
- the main reason to do this is because of IE8's performance on larger sets of data.
- had already tried the extjs4 tree grid component which works well on chrome but had performance issues on IE8.
the hack is to
a) use an array property in the grid to store the dom elements which i want to manipulate
b) use a boolean to know when the layout is completed the first time
b) add listeners for afterlayout ( when your app can do an Ext.get('..dom element..') you know you are done )
The listener :
listeners :
{
afterlayout : function(eopts)
{
var x = this.mOwnArray;
if(!this.loadedwithVals && x.length > 0)
{
for(var i =0 ; i<x.length ; i++)
{
var dom = Ext.get(x[i].id);
var theId = dom.id;
theId = theId.match(/\d+/)[0];
var title = dom.query("td[class='x-grid-cell x-grid-cell-first']");
title[0].className = 'x-grid-cell x-grid-cell-gridcolumn-' + theId + ' x-grid-cell-first';
title[0].colSpan=1;
var groupedHeader = dom.query("div[class='x-grid-group-title']");
groupedHeader[0].innerHTML = x[i].name + '(' + x[i].length + ')';
for(var year=2012;year<=2018;year++)
{
var t = "t"+year;
var someText1 = '<td class=" x-grid-cell x-grid-cell-numbercolumn">';
var someText2 = '<div class="x-grid-cell-inner " style="text-align: left; ;">';
var someText3 = '<div class="x-grid-group-title">' + x[i].total[t] + '</div></div></td>';
var someText = someText1 + someText2 + someText3;
dom.insertHtml("beforeEnd",someText);
}
}
this.loadedwithVals = true;
}
}
And the feature as in
features: [
{
ftype:'multigrouping',
startCollapsed : true,
groupHeaderTpl: [
'{[this.readOut(values)]}',
{
readOut:function(values) {
var header = new Object();
header.id = values.groupHeaderId;
header.sum = [];
header.total = new Object();
for(var year = 2012 ; year <= 2018 ; year++)
{
var t = "t"+year;
header.total[t] = [];
}
// all the records in this header
for( var i = 0 ; i< values.records.length ; i++)
{
// for all the 'years' in this record
for(var year=2012;year<=2018;year++)
{
var d = "d"+year;
var ct = "t" + year;
var arecord = values.records[i].data;
var val = parseFloat(arecord[d].mp);
val = isNaN(val) ? 0.0 : val;
Ext.Array.push(header.total[ct],val);
}
}
// push the sum of the records into its top level group
for(var year = 2012 ; year <= 2018 ; year++)
{
var t = "t"+year;
var sum = Ext.Array.sum(header.total[t]);
header.total[t] = sum.toFixed(2);
}
header.name = values.name;
header.length = values.records.length;
var headerName = values.name;
if(values.hasOwnProperty('parent'))
{
var parent = values.parent;
headerName = headerName.replace(parent,'');
}
header.name = headerName;
header.length = values.records.length;
Ext.Array.push(grid.mOwnArray,header);
// really not used
return values.name + '(' + values.records.length + ')';
}
}
]
},
]

Resources