Continuation with previous post Creating Calendar Agenda type widget will create a Weather & time widget.
The output will look like:
Desktop view of Weather and Date
Mobile view of Weather and Date
Features:
- Drop down with different locations to choose from
- Asynchronous call without full page load
- Real time weather using open source Yahoo API’s
- Current auto updating Date & Time.
- Responsive using Bootstrap
Again we need moment.js reference to your page.
The javascript will look like:
/***************************************************************** Weather App ******************************************************************/ angCXAngularApp.service('CXWeatherService', ['$http', '$q', function ($http, $q) { //Get the items this.getItems = function (locid) { var dfd = $q.defer(); var API_ROOT = "https://query.yahooapis.com/v1/public/yql?format=json"; var query = "select * from weather.forecast where woeid=" + locid + " and u='c'"; var fullUrl = API_ROOT + "&q=" + encodeURI(query); $.ajax({ url: fullUrl, type: "GET", headers: { "accept": "application/json;odata=verbose" }, success: function (data) { dfd.resolve(data.query.results.channel); }, error: function (xhr) { dfd.reject('Error : (' + xhr.status + ') ' + xhr.statusText + ' Message: ' + xhr.responseJSON.error.message.value); } }); return dfd.promise; } }]); angCXAngularApp.controller('CXWeatherAppCtrl', function ($scope, CXWeatherService, $timeout) { function setitems(weather) { var compass = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N']; $scope.weatherdetail = { code: "http://l.yimg.com/a/i/us/we/52/" + weather.item.condition.code + ".gif", temp: weather.item.condition.temp, windchill: weather.wind.chill, city: weather.location.city, region: weather.location.region, currently: weather.item.condition.text, winddirection: compass[Math.round(weather.wind.direction / 22.5)], windspeed: weather.wind.speed, unitsspeed: weather.units.speed, high: weather.item.forecast[0].high, low: weather.item.forecast[0].low }; } function setTime(offset) { var now = moment().zone(offset); $scope.worlddate = { today: moment(now).format("ddd, MMM DD YYYY"), hours: moment(now).format("hh"), minutes: moment(now).format("mm"), seconds: moment(now).format("ss"), ampm: moment(now).format("A") }; } $scope.getweather = function (location) { CXWeatherService.getItems(location.id).then( function (weather) { setitems(weather); setTime(location.offset); }, function (reason) { //$scope.errMessage = reason; }); } CXWeatherService.getItems('2180').then(function (result) { $scope.locations = [{ 'name': 'Saskatoon', 'id': '2180', 'offset': 6 }, { 'name': 'Shanghai', 'id': '2151653', 'offset': -8 }, { 'name': 'Singapore', 'id': '23424948', 'offset': -8 }, { 'name': 'Tokyo', 'id': '15015406', 'offset': -9 }, { 'name': 'Vancouver', 'id': '9807', 'offset': 7 }, { 'name': 'Portland', 'id': '2475687', 'offset': 7 }]; $scope.location = $scope.locations[0]; setitems(result); setTime($scope.locations[0].id); }); var tick = function () { setTime($scope.location.offset); $timeout(tick, 1000); }; $timeout(tick, 1000); });
Here we need WOEID (use this site to get WOEID for your location http://zourbuth.com/tools/woeid/ ) of location with offset X where X is (GMT + X ) value of time.
The tick function will make sure clock updates automatically.
The CSS needed here:
/* Weather */ .cx-weather-container ul { list-style-type: none; margin: 0; padding: 0; } .cx-weather-container ul li { display: inline; } .cx-weather-img { float: left; width: 55px; height: 55px; } .cx-weather-img img { margin: 2px; } .cx-weather-temp { margin-left: 60px; } .cx-weather-temp h2 { padding: 5px; font-weight: 600; } .cx-weather-temp sup { margin-top: 3px; font-size: 14px; } .cx-weather-temp h2 div { font-size: 12px; padding-top: 5px; } .cx-weather-deg { font-size: 12px; } .cx-weather-detail { float: left; padding-left: 5px; padding-right: 10px; } #ddlcxweatherlocations { min-width: 200px; } .cx-weather-extra { margin-top: -10px; } .cx-timedetail { font-size: 36px; font-weight: 600; } .cx-hours, .cx-minutes, .cx-seconds { color: #FFF; background-color: #666666; padding: 2px; margin: 2px 2px 0px 2px; } .cx-hours { padding-left: 12px; } .cx-ampm { font-size: 14px; } .cx-time-container { padding-top: 10px; float: left; margin-left: 15px; } .cx-time-container h3 { font-weight: 600; } .cx-weather-container h1, .cx-weather-container h2, .cx-weather-container h3, .cx-weather-container h4, .cx-weather-container h5, .cx-weather-container h6 { color: #666666; }
And finally the html that needed to be added in script editor web part:
<div ng-controller="CXWeatherAppCtrl"> <div id="cx-weather-app"> <div class="cx-weather-locations"> <select id="ddlcxweatherlocations" ng-init="location = locations[1]" ng-model="location" ng-options="location.name for location in locations" ng-change="getweather(location)"> </select> </div> <div class="cx-weather-container"> <ul> <li class="cx-weather" ng-model="weatherdetail"> <div class="cx-weather-detail"> <div> <div class="cx-weather-img"><img ng-src="{{weatherdetail.code}}" /></div> <div class="cx-weather-temp"> <h2> {{weatherdetail.temp}} <sup>°C</sup> <div class="cx-highlow"> H: {{ weatherdetail.high }}° | L: {{ weatherdetail.low }}° </div> <div class="cx-realfeal"> Real: {{weatherdetail.windchill}} ° </div> </h2> </div> </div> <div class="cx-weather-extra"> Wind: {{weatherdetail.winddirection}} {{weatherdetail.windspeed}} {{weatherdetail.unitsspeed}} </div> </div> </li> <li> <div class="cx-time-container" ng-cloak ng-model="worlddate"> <h3> {{worlddate.today}} </h3> <div class="cx-timedetail"> <span class="cx-hours"> {{worlddate.hours}} </span>:<span class="cx-minutes"> {{worlddate.minutes}} </span>:<span class="cx-seconds"> {{worlddate.seconds}} </span><span class="cx-ampm"> {{worlddate.ampm}} </span> </div> </div> </li> </ul> </div> </div> </div>
You need to add reference to your javascript file also if not added to page.
That’s it.
Hi I have added code according to above steps. But display is not coming as I want. (I am new to angular). Please guide on this.
My output on page:
{{weatherdetail.temp}} °C
H: {{ weatherdetail.high }}° | L: {{ weatherdetail.low }}°
Real: {{weatherdetail.windchill}} °
Wind: {{weatherdetail.winddirection}} {{weatherdetail.windspeed}} {{weatherdetail.unitsspeed}}
Hi,
Sorry for replying late.
You need to add reference to Angularjs to content editor if not added at page layout or masterpage level.