I'm completely lost.
I have my html form, where I can write a city.
When the form is send, a data array is send in a each loop, below is the code :
geocoder = new google.maps.Geocoder();
$.each(data['list'],function(i,el)
{
var address = el.address1+','+el.city+' '+el.zipcode;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var getZipCode = $("#zipcode").val();
var getCity = $("#city").val();
geocoder.geocode( { 'address': getCity+' '+getZipCode }, function(resultsTwo, statusTwo) {
if (status == google.maps.GeocoderStatus.OK) {
var distanceKm = google.maps.geometry.spherical.computeDistanceBetween(results[0].geometry.location, resultsTwo[0].geometry.location);
var distanceMiles = distanceKm/1000*0.621371;
str = str +'<article><div class="leftDesc"><header><h3><span class="letter">'+alphabet[i]+'.</span>'+el.store_name+'</h3></header>';
str = str +'<div class="addressEnonce">Address:</div><div class="addressBig"><p class="address">'+el.address1+'</p>';
/*str = str +'<p>'+el.address2+'</p>';*/
str = str +'<br /><p class="city">'+el.city+'</p>';
str = str +' <p class="zipcode">'+el.zipcode+'</p>';
str = str +' <p class="state">'+el.state+'</p></div></div>';
str = str +'<div class="rightDesc"><p class="distance">Distance: '+distanceMiles+' Miles</p>';
str = str +'<p>'+el.description+'</p></div>';
str = str + '<p>Show on Map</p>';
if((i+1) < data['list'].length){
switch(i % 4){
case 0:
str = str +'<img src="img/line.png" >';
break;
case 1:
str = str +'<img src="img/line.png" >';
break;
case 2:
str = str +'<img src="img/line.png" >';
break;
}
}
str = str +'</article>';
tweets.append(str);
}
});
}
});
}) })
So the code is good, for Washington by example, I will have 3 items showed, also I want have 2! The first item is in double one =7
I think the problem is I must to put a callback function, because this is the asynchronous method in geocodes loops which cause the trouble... But how please ?!
The fact that it is asynchronous is the problem. You need to use a closure. Here's an example:
$.each(data['list'],function(i,el) {
var address = el.address1+','+el.city+' '+el.zipcode;
geocoder.geocode( { 'address': address}, (function(address1, city, zipcode) {
return function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
geocoder.geocode( { 'address': city+' '+zipcode },
function(resultsTwo, statusTwo) {
// ...
});
}
};
})(el.address1, el.city, el.zipcode));
});
Related
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
In my application i want to open gmail attachment with my application, i used intent filter for that,
I am getting URI and i want to use that and copy that attachment to my local device and want to display that with my application .
url = {content://com.google.android.gm.sapi/abc#gmail.com/message_attachment_external/%23thread-f%3A1610966348228029097/%23msg-f%3A1610966348228029097/0.1?account_type=com.google&mimeType=application%2Foctet-stream&rendition=1}
After a days of research and implementation, Here is a final solution for gmail attachment file , to view and down load in our application.
[IntentFilter(new string[] { Intent.ActionView }, Categories = new string[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "content", DataMimeType = "application/octet-stream")]
Stream inputsTream = resolver.OpenInputStream(url);
fs = File.Create(fileName);
byte[] buffer = new byte[32768];
int count;
int offset = 0;
while ((count = inputsTream.Read(buffer, offset, buffer.Length)) > 0)
{
fs.Write(buffer, 0, count);
}
fs.Close();
inputsTream.Close();
private fun deepLinkAcceptor(){
var ins: InputStream? = null
var os: FileOutputStream? = null
var fullPath: String? = null
var file: File;
try {
val action = intent.action
if (Intent.ACTION_VIEW != action) {
return
}
val uri = intent.data
val scheme = uri!!.scheme
var name: String? = null
if (scheme == "content") {
val cursor = contentResolver.query(
uri!!, arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME
), null, null, null
)
cursor!!.moveToFirst()
val nameIndex = cursor!!.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
if (nameIndex >= 0) {
name = cursor!!.getString(nameIndex)
}
} else {
return
}
if (name == null) {
return
}
val n = name.lastIndexOf(".")
val fileName: String
val fileExt: String
if (n == -1) {
return
} else {
fileName = name.substring(0, n)
fileExt = name.substring(n)
}
// create full path to where the file is to go, including name/ext
fullPath = ""
val filenm = fileName + fileExt
file = File(cacheDir, filenm)
ins = contentResolver.openInputStream(uri!!)
os = FileOutputStream(file.getPath())
val buffer = ByteArray(4096)
var count: Int
while (ins!!.read(buffer).also { count = it } > 0) {
os!!.write(buffer, 0, count)
}
os!!.close()
ins!!.close()
println("===onfile path: " + file.getAbsolutePath())
println("===onFile name: " + file.readText())
} catch (e: Exception) {
if (ins != null) {
try {
ins.close()
} catch (e1: Exception) {
}
}
if (os != null) {
try {
os.close()
} catch (e1: Exception) {
}
}
if (fullPath != null) {
val f = File(fullPath)
f.delete()
}
}
}
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.
I have two arrays containing latitude and longtitude of 7 locations,and I use the following
code for getting the location of these 7 points:
var geocoder;
initialize();
codeLatLng();
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng() {
var arrlat=[45.95268273, 47.00196833,45.99168238, 46.2186456, 45.91612197, 45.91606814, 45.91606814];
var arrlon=[-66.68426012, -65.56480221, -63.98068545, -64.44419501, -66.74801471, -66.74810832, -66.74810832];
var input = document.getElementById("latlng").getAttribute('value');
console.log(input);
var latlngStr = input.split(",", 2);
var lat = parseFloat(latlngStr[0]);
var lng = parseFloat(latlngStr[1]);
for(var i=0;i<arrlat.length;i++)
{
var latlng = new google.maps.LatLng(arrlat[i], arrlon[i]);
geocoder.geocode({
'latLng': latlng
}, function(results, status) {
//document.getElementById("test").innerHTML = '' + (results[4].formatted_address); + ''
alert(results[4].formatted_address);
});
}
}
whenever I feed the arrays with 5 of less elements the code works properly but for more than 5 I get 5 alert showing the location of the first 5 elements but for the last 2 I get the following error:
Uncaught TypeError: Cannot read property '4' of null
And here is the Jfiddle link:
link
Can anyone help?
Code more defensively. Check the status of the response before using it. If it isn't "OK", there won't be any results to process.
function codeLatLng() {
var arrlat=[45.95268273, 47.00196833,45.99168238, 46.2186456, 45.91612197, 45.91606814, 45.91606814];
var arrlon=[-66.68426012, -65.56480221, -63.98068545, -64.44419501, -66.74801471, -66.74810832, -66.74810832];
var input = document.getElementById("latlng").getAttribute('value');
console.log(input);
var latlngStr = input.split(",", 2);
var lat = parseFloat(latlngStr[0]);
var lng = parseFloat(latlngStr[1]);
for(var i=0;i<arrlat.length;i++)
{
var latlng = new google.maps.LatLng(arrlat[i], arrlon[i]);
geocoder.geocode({
'latLng': latlng
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK ) {
//document.getElementById("test").innerHTML = '' + (results[4].formatted_address); + ''
if (results.length >= 5)
alert(results[4].formatted_address);
else alert("less than 5 results");
} else alert("reverse geocode failed, status="+status);
});
}
}
See the documentation on Status Codes for what the failure codes mean.
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 + ')';
}
}
]
},
]