cannot read property 'channel' of null with simpleweather.js - jquery-plugins

I am using simpleweather plugin for displaying current weather and worked fine till yesterday. Now it shows error as 'cannot read property 'channel' of null'. When I debugged the script, I found that the yahoo data fails to retrieve saying service unavailable hence query.results.channel is null. Can anyone solve my issue? Here is my code:
<script type="text/javascript" src="/sites/dev/_catalogs/masterpage/NMSTheme/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="/sites/dev/_catalogs/masterpage/NMSTheme/js/jquery.simpleWeather.js"></script>
<script type="text/javascript" src="/sites/dev/_catalogs/masterpage/NMSTheme/js/yqlgeo.js"></script>
<script type="text/javascript">
$(document).ready(function() {
loadWeather();
setInterval(loadWeather, 6000);
});
function loadWeather() {
debugger;
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position) {
var location = (position.coords.latitude + ',' + position.coords.longitude);
var woeid = undefined;
$.simpleWeather({
location: location,
woeid: woeid,
unit: 'f',
success: function (weather) {
var time = ReturnCurrentTime();
placehtml = '<span><h5>' + weather.city + ',' + weather.region + '</h5><span/>';
datehtml = '<span><h5> ' + weather.forecast[0].day + ',' + time + '</h5><span/>';
html = '<span><h5> ' + weather.temp + '°' + ' ' + weather.units.temp + '</h5><span/>' ;
$("#date").html(datehtml);
$("#place").html(placehtml);
$("#weather").html(html);
},
error: function (error) {
$("#weather1").html('<p>' + error + '</p>');
}
});
});
}
}
</script>

Yahoo have introduced a bug into geo.placefinder querying. Use geo.places.
replace line 26 in simpleWeather.js with:
weatherUrl += 'select * from weather.forecast where woeid in (select woeid from geo.places where text="'+options.location+'" limit 1) and u="'+options.unit+'"';
If you are calling with geolocation lat/long surround options.location with parentheses:
$.simpleWeather({
location: '(' + lat_long + ')',
See more on simpleWeather issues in Github:
https://github.com/monkeecreate/jquery.simpleWeather/issues/174

Yahoo seems to have discontinued the geolocation services needed to find a location based on latitude and longitude. Using simpleWeather's woeid property instead of location still works, though.

Related

How do I get my topojson file to work with datamaps?

I am trying to load my custom topojson file but I am getting this error:
Cannot read property 'type' of undefined
from this line 219 in topojson.min.js v1.6.9
return o.type === "GeometryCollection" ? {
I am using d3 v3.5.3 and topojs v1.6.9 because I haven't been able to get the newer versions working with my custom topojson file.
<script src="d3.min.3.5.3.js"></script>
<script src="d3-geo-projection.min.js"></script>
<script src="topojson.min.1.6.9.js"></script>
<script src="datamaps.usa.min.js"></script>
<script>
var map = new Datamap({
element: document.getElementById('container'),
geographyConfig: {
dataUrl: 'Utah_Municipalities_custom.topojson'
},
scope: 'custom',
setProjection: function(element, options) {
var projection, path;
// Utah Central
projection = d3.geo.conicConformal()
.parallels([39 + 1 / 60, 40 + 39 / 60])
.rotate([111 + 30 / 60, 0]);
path = d3.geo.path()
.projection( projection );
return {path: path, projection: projection};
}
});
</script>
</body>
</html>
Utah_Municipalities_custom.topojson
{"type":"Topology","objects":{"Municipalities.gdb":{"type":"GeometryCollection","geometries":[{"type":"MultiPolygon","arcs":[[[0,1,2,3,4,5,6,7,8]]],"properties":{"COUNTYNBR":"06","NAME":"Farmington","COUNTYSEAT":1,"SHORTDESC":"FARMINGTON","UPDATED":"2018/10/05 00:00:00","FIPS":"24740","ENTITYNBR":3050,"SALESTAXID":"017","IMSCOLOR":3,"MINNAME":"Farmington","POPLASTCENSUS":18752,"POPLASTESTIMATE":22566,"GNIS":"1441004","Shape_Length":31551.51123429135,"Shape_Area":25990884.690499976}},
{"type":"MultiPolygon","arcs":[[[9]]],"properties":{"COUNTYNBR":"01","NAME":"Minersville","COUNTYSEAT":0,"SHORTDESC":"MINERSVILLE","UPDATED":"2012/04/02 00:00:00","FIPS":"50590","ENTITYNBR":3030,"SALESTAXID":"009","IMSCOLOR":3,"MINNAME":"Minersville","POPLASTCENSUS":921,"POPLASTESTIMATE":869,"GNIS":"1430376","Shape_Length":23283.92651941338,"Shape_Area":5645426.963867947}},
{"type":"MultiPolygon","arcs":[[[10]]],"properties":{"COUNTYNBR":"22","NAME":"Francis","COUNTYSEAT":0,"SHORTDESC":"FRANCIS","UPDATED":"2016/04/29 00:00:00","FIPS":"26940","ENTITYNBR":3020,"SALESTAXID":"013","IMSCOLOR":2,"MINNAME":" ","POPLASTCENSUS":1094,"POPLASTESTIMATE":1258,"GNIS":"1428080","Shape_Length":27357.49743179958,"Shape_Area":6733236.332748903}},
etc...
I'm guessing there might be something wrong with my topojson file, or maybe I need to figure out how to create this map with a newer version of topojson or something...
It turns out that it was a Chrome extension for CORS that was causing it to not work for some reason.

How can I clean this code up better?

I have a script inserted into Magento and it does not seem to be behaving properly. Whenever it runs it actually feeds the contents of the html document back into the text box rather than the autosuggestion. Can anyone tell me what the issue seems to be? I think it might be the two functions conflicting, is there a good way to clean this up?
<script type="text/javascript" src="jquery-2.1.1.js"></script>
<script type="text/javascript" src="jquery.autocomplete.js"></script>
<script type="text/javascript" >
//<![CDATA[
$j = jQuery.noConflict();
$j(document).ready(function(){
$j("#antique_toys_materials").keyup
(function()
{
var tag= $j(this).val();
if(tag!='')
{
$j.ajax(
{
type: "GET",
url: "autocomplete.php",
data: "q=" + tag,
cache: true,
success: function(result)
{
$j("#antique_toys_materials").val(result);
}
}
);
}
return false;
}
);
}
);
//]]>
</script>
<script type="text/javascript" >
//<![CDATA[
$j = jQuery.noConflict();
$j(window).load(function(){
function calculate()
{
var values = [
$j("#cost").val(),
$j("#shipping_paid").val(),
$j("#tax_paid").val()
];
var percent_value = $j("#our_markup").val();
//---------------------------//
if (percent_value == 285)
{
var percent_value = 0;
}
var sub_total = eval( values.join('+') );
var total = eval("sub_total+(sub_total * percent_value)");
var shortened_total = total.toFixed(2);
$j("#price").val(shortened_total);
}
$j( document ).ready(function() {
$j(document).on('input', 'input', calculate);
$j(document).on('change', 'select,input', calculate);
});
});
//]]>
</script>
and it hooks up with this
<?php
$q=$_GET['q'];
$my_data=mysql_real_escape_string($q);
$mysqli=mysqli_connect('localhost','XXXXXXX','XXXXXXX','XXXXXXX') or die("Database Error");
$sql = "SELECT DISTINCT auto_complete_suggestions FROM auto_complete WHERE auto_complete_suggestions LIKE '%$my_data%'
ORDER BY CASE WHEN auto_complete_suggestions = '$mydata' THEN 0
WHEN auto_complete_suggestions LIKE '$mydata%' THEN 1
WHEN auto_complete_suggestions LIKE '%$mydata%' THEN 2
WHEN auto_complete_suggestions LIKE '%$mydata' THEN 3
ELSE 4
END, auto_complete_suggestions LIMIT 0,1";
$result = mysqli_query($mysqli,$sql) or die(mysqli_error());
if($result)
{
while($row=mysqli_fetch_array($result))
{
echo $row['auto_complete_suggestions']."\n";
}
}
?>
It works fine in isolation without the noConflict but then when I put it in Magento it seems to need some help and I'm sure that since it's feeding the html file back into it that something's wrong.
Thoughts? Thanks!
This is just a quick guess, but try using the word "jQuery" instead of "$". I had to change a few plugin scripts that interfered with prototype since it too uses the "$". Once I replaced all instanced of $ with the word jQuery, things started working as I expected.

How to use pagination for displaying circles from Google+

I have set maxResults to 10 and i want to know how to use view more circles with nextpageToken and by clicking View More button the next 10 circles have to display and goes on till the last circles in Google+. Please help me fix this issue.
Please see my code below :
<html>
<head>
<title>Google+ JavaScript Quickstart</title>
<script type="text/javascript">
(function() {
var po = document.createElement('script');
po.type = 'text/javascript'; po.async = true;
po.src = 'https://plus.google.com/js/client:plusone.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
</script>
<!-- JavaScript specific to this application that is not related to API
calls -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" ></script>
</head>
<body>
<div id="gConnect">
<button class="g-signin"
data-scope="https://www.googleapis.com/auth/plus.login"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-clientId="my client id"
data-callback="onSignInCallback"
data-theme="dark"
data-cookiepolicy="single_host_origin">
</button>
</div>
<div id="authOps" style="display:none">
<h2>User is now signed in to the app using Google+</h2>
<p>If the user chooses to disconnect, the app must delete all stored
information retrieved from Google for the given user.</p>
<button id="disconnect" >Disconnect your Google account from this app</button>
<h2>User's profile information</h2>
<div id="profile"></div>
<h2>User's friends that are visible to this app</h2>
<div id="visiblePeople"></div>
<p>View More</p>
<h2>Authentication Logs</h2>
<pre id="authResult"></pre>
</div>
</body>
<script type="text/javascript">
var helper = (function() {
var BASE_API_PATH = 'plus/v1/';
return {
/**
* Hides the sign in button and starts the post-authorization operations.
*
* #param {Object} authResult An Object which contains the access token and
* other authentication information.
*/
onSignInCallback: function(authResult) {
gapi.client.load('plus','v1', function(){
$('#authResult').html('Auth Result:<br/>');
for (var field in authResult) {
$('#authResult').append(' ' + field + ': ' +
authResult[field] + '<br/>');
}
if (authResult['access_token']) {
$('#authOps').show('slow');
$('#gConnect').hide();
helper.profile();
helper.people();
} else if (authResult['error']) {
// There was an error, which means the user is not signed in.
// As an example, you can handle by writing to the console:
console.log('There was an error: ' + authResult['error']);
$('#authResult').append('Logged out');
$('#authOps').hide('slow');
$('#gConnect').show();
}
console.log('authResult', authResult);
});
},
/**
* Calls the OAuth2 endpoint to disconnect the app for the user.
*/
disconnect: function() {
// Revoke the access token.
$.ajax({
type: 'GET',
url: 'https://accounts.google.com/o/oauth2/revoke?token=' +
gapi.auth.getToken().access_token,
async: false,
contentType: 'application/json',
dataType: 'jsonp',
success: function(result) {
console.log('revoke response: ' + result);
$('#authOps').hide();
$('#profile').empty();
$('#visiblePeople').empty();
$('#authResult').empty();
$('#gConnect').show();
},
error: function(e) {
console.log(e);
}
});
},
/**
* Gets and renders the list of people visible to this app.
*/
people: function() {
var request = gapi.client.plus.people.list({
'userId': 'me',
'collection': 'visible',
'selfLink':'http://localhost/Google+/trail+.html',
'maxResults':10,`enter code here`
'items[]' : 'list',
'nextPageToken': 'CAIQ0K3cq5DEtAIgAygB'
});
request.execute(function(people) {
$('#visiblePeople').empty();
$('#visiblePeople').append('Number of people visible to this app: ' +
people.totalItems + '<br/>');
for (var personIndex in people.items) {
person = people.items[personIndex];
$('#visiblePeople').append('<img src="' + person.image.url + '">');
$('#visiblePeople').append(''+ person.displayName + '</br>'+ '</br>');
}
});
},
/**
* Gets and renders the currently signed in user's profile data.
*/
profile: function(){
var request = gapi.client.plus.people.get( {'userId' : 'me'} );
request.execute( function(profile) {
$('#profile').empty();
if (profile.error) {
$('#profile').append(profile.error);
return;
}
$('#profile').append(
$('<p><img src=\"' + profile.image.url + '\"></p>'));
$('#profile').append(
$('<p>Hello ' + profile.displayName + '!<br />Tagline: ' +profile.tagline + '!<br />Email id: ' +profile.email +
+ '<br />About: ' + profile.aboutMe + '</p>'));
if (profile.cover && profile.coverPhoto) {
$('#profile').append(
$('<p><img src=\"' + profile.cover.coverPhoto.url + '\"></p>'));
}
});
}
};
})();
/**
* jQuery initialization
*/
$(document).ready(function() {
$('#disconnect').click(helper.disconnect);
if ($('[data-clientid="YOUR_CLIENT_ID"]').length > 0) {
alert('This sample requires your OAuth credentials (client ID) ' +
'from the Google APIs console:\n' +
' https://code.google.com/apis/console/#:access\n\n' +
'Find and replace YOUR_CLIENT_ID with your client ID.'
);
}
});
/**
* Calls the helper method that handles the authentication flow.
*
* #param {Object} authResult An Object which contains the access token and
* other authentication information.
*/
function onSignInCallback(authResult) {
helper.onSignInCallback(authResult);
}
function getMore()
{
helper.people();
}
</script>
</html>
It looks like there may be a couple of issues here. You seem to have at least some of the gist of how to use people.list, but you seem to be trying to add some of the response fields to the request field. See https://developers.google.com/+/api/latest/people/list for full details of the request parameters and the expected response.
On the first call, you only need to pass the userId and collection parameters. Since you want to limit the page size, you'll need to pass maxResults as well, so your call will look something like
var requestParams = {
'userId': 'me',
'collection': 'visible',
'maxResults': 10
};
gapi.client.plus.people.list( requestParams ).execute(peopleCallback);
The parameter passed to peopleCallback() will contain the results, including a nextPageToken, which you will need to pass on subsequent calls to get additional items. You can store this token in a global variable, or as an attribute in your helper object, and process the other fields you need. So it might look something like this:
peopleCallback: function(response){
nextPageToken = response.nextPageToken;
items.forEach(function(item){
$('#visiblePeople').append(''+person.displayName+'');
});
}
The next time the "List more" button is called, you need to include the nextPageToken as part of your request, so the call would look something more like this:
var requestParams = {
'userId': 'me',
'collection': 'visible',
'maxResults': 10,
'pageToken': nextPageToken
};
gapi.client.plus.people.list( requestParams ).execute(peopleCallback);
Subsequent calls will get a new nextPageToken which should be passed the next time you're making a call to continue getting the list.
I leave it as an exercise to determine the best way for you to handle the differences between these calls (passing a token vs not), initializing the visiblePeople list, and other issues specific to your code structure.
One important caveat on what you're trying to do, however. Your question title suggests that you're trying to get circles of a person - this will not give you that info. The people.list call will give you people, not circles, that a person is willing to publicly say are added to a circle. A user may choose to not provide this information, or may choose to only provide a subset of the information, and you will not know what specifically named circles a person may have been added to

Problem running multiple instances of a plugin

I developed a simple plugin to sent request to a JSON text file, retrieve a data containing image list and append the html in the element calling the plugin.
Now, the code is working fine while it is running on only one element, but when I am using it on more than one element, now the elements get loaded on the last element calling the plugin only.
Plugin Code:
$.fn.testPlugin = function(param) {
var options = {
url : "",
pause : 2000,
callback : 5000
};
this.each(function() {
elementId = $(this).attr("id");
options = $.extend(options,param);
if(options.url=="") { console.log("URL is not specified"); }
else {
$.post(
options.url,
function(data) {
$("#"+elementId).html("<ul></ul");
$.each(data.dashboard, function(k,v) {
html = '<li>';
html += '<a href="'+v.TargetUrl+'" target="'+v.Target+'">';
html += '<img src="' + v.ImageUrl + '" alt="' + v.Alt +'" title="' + v.OverlayText +'" />';
html += '</a><p>'+v.OverlayText+'</p></li>';
$("ul",$("#"+elementId)).append(html);
});
},
"json"
);
}
});
}
Plugin Initialization/Execution
$("#this").testPlugin({
url: 'test.txt'
});
$("#that").testPlugin({
url: 'text.txt'
});
HTML
<div id="this" style="border-style: solid;border-color: #09f;padding: 10px;">
This is a sample div.
</div>
<div id="that" style="border-style: solid;border-color: #09f;padding: 10px;">
Another div
</div>
UPDATE
I also found out that the problem is happening due to AJAX request. If I create static list and then append it on the div, this time this works with any number of instantiation. A demo of static call is here. Now, help me do the same by retrieving the list from an AJAX request.
UPDATE 2
Thanks to Groovek, Here is a demo of the actual problem. You can notice, that the elements of both requests are append to the last element.
You're assigning to elementID without declaring it. This means it'll be a global variable, which means it'll always be equal to the last thing assigned to it (in this case, #that). If you just keep a local reference to the element, the code will work. Here's a modified jsfiddle: http://jsfiddle.net/s9BDT/
Code inside the each 'loop':
var el = $(this);
el.html("<ul></ul>");
options = $.extend(options,param);
if(options.url=="") { console.log("URL is not specified"); }
else {
$.post(
//options.url,
"/echo/json/",
{json:'{"dashboard":[{"TargetUrl":"toto.html", "Alt" : "sample 1", "ImageUrl":"toto.png", "OverlayText":"toto"},{"TargetUrl":"titi.html", "Alt" : "sample 2", "ImageUrl":"titi.png", "OverlayText":"titi" }]}'},
function(data) {
//alert(data.dashboard);
html = '';
$.each(data.dashboard, function(k,v) {
html += '<li>';
html += '<a href="'+v.TargetUrl+'" target="'+v.Target+'">';
html += '<img src="' + v.ImageUrl + '" alt="' + v.Alt +'" title="' + v.OverlayText +'" />';
html += '</a><p>'+v.OverlayText+'</p></li>';
});
//alert(html);
$("ul",el).append(html);
},
"json"
);
}

jqGrid display default "loading" message when updating a table / on custom update

I have a case where I need to update a jqgrid based on some search criteria which the user selects. I can get the data to update , but I would want the loading message to show while the new data is being fetched. Can someone please let me know how to get that working ?
Current code follows
var ob_gridContents = $.ajax( {
url : '/DisplayObAnalysisResults.action?getCustomAnalysisResults',
data : "portfolioCategory="+ $('#portfolioCategory').val()
+"&subPortfolioCategory="+ $('#subPortfolioCategory').val()
+ "&subportfolio=" + $('#subportfolio').val(),
async : false
}).responseText;
var ob_Grid = jQuery('#OBGrid')[0];
var ob_GridJsonContents = eval('(' + ob_gridContents + ')');
$('#ob_Grid').trigger("reloadGrid");
ob_Grid.addJSONData(ob_GridJsonContents);
ob_Grid = null;
ob_GridJsonContents = null;
}
If I correct understand what you will, I can recommend you to use jQuery blockUI plugin (http://malsup.com/jquery/block/). Then you don’t need more to use "async : false" parameter of $.ajax function and do something like following:
var WaitMsg = function () {
jQuery('#main').block({ message: '<h1>Die Daten werden vom Server geladen...</h1>' });
};
var StopWaiting = function () {
jQuery('#main').unblock();
};
WaitMsg();
$.ajax({url : '/DisplayObAnalysisResults.action?getCustomAnalysisResults',
data: jQuery.param({portfolioCategory: $('#portfolioCategory').val(),
subPortfolioCategory: $('#subPortfolioCategory').val(),
subportfolio: $('#subportfolio').val()}),
complete: function (data, status) {
if (status === "success" || status === "notmodified") {
var ob_GridJsonContents = jQuery.parseJSON(data.responseText);
...
}
StopWaiting();
},
error: function (xhr, st, err) {
// display error information
StopWaiting();
}
});
I recommend you don’t build parameters with the way like
"portfolioCategory="+ $('#portfolioCategory').val()
+"&subPortfolioCategory="+ $('#subPortfolioCategory').val()
+ "&subportfolio=" + $('#subportfolio').val()
because you can receive encoding problems, if data returned by .val() have some special characters. You could use JavaScript function encodeURIComponent in such cases (like encodeURIComponent($('#portfolioCategory').val()))
or jQuery.param function if you construct a string like p1=val1&p2=val2&...pN=valN.
Best regards
Oleg

Resources