How to get SUM of all CouchDB values? - view

How to extract SUM depending on ID or something, with goal of getting SUM of all values?
I am able to get all values but canot SUM beacouse its a single variable, so there must be some kind of segmentation to SUM them?? any ideas?
$db = $.couch.db("fuel");
function refreshFuel() {
$("div#fuel").empty();
$db.view("fuel/bill", {success: function(data) {
for (i in data.rows) {
id = data.rows[i].id;
bill = data.rows[i].key;
date = data.rows[i].value;
html = '<div class="fuel">' +
'<span class="bill">' + bill + '</span> ' +
'<span class="date">' + date + '</span> ' +
'</div>';
$("div#fuel").append(html);
}
}});
}
function getAll(){
$("div#all").empty();
$db.view("fuel/bill", {success: function(data) {
for (i in data.rows) {
id = data.rows[i].id;
bill = data.rows[i].key; // how to get SUM of all this values
date = data.rows[i].value;
html =
'<span class="all">' + bill + '</span> '
$("div#all").append(html);
}
}});
}
EDIT:
my JSON looks like this:
{
"_id": "1a06982d3434f37a04a02dbf360010ee",
"_rev": "1-c8c9d5252a76abd8f565ff82bf63b0e8",
"value": "200",
"date": "2011-09-05T10:28:55.101Z"
}
and my VIEW look like this:
function(doc) {
if (doc.value, doc.date) {
emit(doc.value,doc.date, doc);
}
}

You just need to add a reduce function, e.g,
function(keys, values, rereduce) {
return sum(values);
}
This is so common that we have a built-in function that's much faster;
_sum
You'll need to emit the value you want to sum as the value, so something like;
function(doc) {
emit(doc.date, doc.value);
}

Related

Google Map doesn't appear on load

I am developing an app where I use 2 API's a.k.a Instagram API and Google Map API. Using AJAX, I get the first set of Images filtered by a tag name. In the 1st set we receive 20 images. Among the received images, the images that have the latitude and longitude info (geotagged images) are displayed on the map.
Now the first time when my page loads, I cannot see the map. But when I press the load more button to get the next set of images, the Map works fine showing my previous images too.
Here is the code for what happens on page load:
$( window ).load(function() {
$.ajax({
type: "GET",
url: "https://api.instagram.com/v1/tags/nyc/media/recent?client_id=02e****",
dataType:'JSONP',
success: function(result) {
onAction(result, 2, tag);
instaMap(result, 2, from);
}
});
});
These are the functions being called:
/**
* [initialize description]
* Initialize the map with markers showing all photos that are geotagged.
*/
var initialize = function(markers) {
var bounds = new google.maps.LatLngBounds(),
mapOptions = {
scrollwheel: false,
mapTypeId: 'roadmap',
center: new google.maps.LatLng(22.50, 6.50),
minZoom: 2
},
gmarkers = [],
map,
positions,
markCluster;
markers = remDuplicate(markers);
// Info Window Content
var infoWindowContent = [];
for (var j = 0; j < markers.length; j++ ) {
var content = [
'<div class="info_content">' +
'<h3>' + markers[j][2] + '</h3>' +
'<a href="' + markers[j][3] + '" target="_blank">' +
'<img src="' + markers[j][4] + '" style="z-index:99999">' + '</a>' +
'</div>'
];
infoWindowContent.push(content);
}
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Display multiple markers on a map
var oms = new OverlappingMarkerSpiderfier(map);
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
positions = new google.maps.LatLng(markers[i][0], markers[i][1]);
marker = new google.maps.Marker({
position: positions,
map: map,
animation:google.maps.Animation.BOUNCE,
title: markers[i][2]
});
oms.addMarker(marker);
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.close();
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
map.setCenter(marker.getPosition());
};
})(marker, i));
gmarkers.push(marker);
}
google.maps.event.addListener(map, 'click', function() {
infoWindow.setMap(null);
});
markCluster = new MarkerClusterer(map, gmarkers);
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
map.setZoom(2);
google.maps.event.removeListener(boundsListener);
});
};
/**
* [onAction]
* OnAction() function helps in loading non-geotagged pics.
*
* #param {[type]} result [Result retruned from the Instagram API in json format]
* #param {[type]} likey [hearts the user has entered as per which the posts will be filtered]
*/
var onAction = function (result, likey, tag) {
$('.load-pics').remove();
if (result.pagination.next_url) {
paginate = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations === null) {
output = '<li class="img-wrap">' + '<div class="main-img">' +
'<a href="' + link + '" target="_blank">' +
'<img src="' + imgUrl + '" ><span class="hover-lay"></span></a>' +'<p>' +
'<span class="heart"></span><span class="likes-no">' + liked + '</span>' +
'<span class="comment-box"></span><span class="comment-no">' +
val.comments.count + '</span> ' + '</p>' + '</div>' +
'<div class="img-bottom-part">'+ '' + '<div class="headin-hastag">' +
'by ' + '<h2>Sebastien Dekoninck</h2>#hello <span>#kanye</span> #helloagain #tagsgohere</div>'
+'</div></li>';
$('#instafeed').append(output);
}
}
});
}
});
if ($('#instafeed').children().length === 0) {
alert('There are no pics with ' + likey + ' likes or #' + tag + ' was not found.');
} else {
// $('.not-geo').remove();
// $('#instafeed').before('<button class="not-geo">Click To See Images That Are Not Geotagged <img src="assets/imgs/down.png" ></button>');
}
$('#instafeed').append('<div class="load-pics"><button id="show-more">Show more <span></span></button> </div>');
};
/**
* [instaMap]
* instaMap() will be the function which will deal with all map based functionalities.
*/
var instaMap = function(result, likey, from) {
$('.load-mark').remove();
if (result.pagination.next_url) {
pagiMap = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations && locations.latitude !== null) {
tempArr = [
locations.latitude,
locations.longitude,
val.user.username,
val.link,
val.images.low_resolution.url
];
mark.push(tempArr);
}
}
});
}
});
if (mark.length) {
initialize(mark);
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
} else {
alert('No geotagged pics found in the retrieved set. Click see more');
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
}
};
I have created a See More button to retrieve the next set of images and load those on the Map. When clicking see more, everything seems to work fine. Not sure why it's happening so. Console.log does not show any error. Also, all the values I feed does flow appropriately. I even tried clearing cache. Not sure, why it's happening.
If instaMap is the function which is going to handle all your map based functionality, it has to be the one that loads map in your $( window ).load function ();
Otherwise, if you want Google maps to load on initial window load you need to put below in there:
google.maps.event.addDomListener(window, 'load', initialize);

Search Box Google Fusion Table/Google API

I have a Google Fusion Table containing a land parcels layer. Each parcel is assigned an ARN number. I am trying to create a search box where one can type in the ARN number and it will select and hopefully zoom to that parcel. I'm new to java script and am unsure as to why my search box is not working. The Fusion table has a 'geometry' column containing the spatial information and 'ARN' column is a 'number' field containing the ARN numbers. Here is my code.
function changeMapl0() {
var searchString = document.getElementById('search-string-l').value.replace(/'/g, "\\'");
layer.setOptions({
query: {
select: 'geometry',
from: 'tableID',
where: "'ARN' CONTAINS IGNORING CASE '" + searchString + "'"
}
});
}
<body>
<div style="margin-top: 10px;">
<label>Enter Roll Number</label><input type="text" id="search-string-l">
<input type="button" onclick="changeMapl0()" value="Search">
</div>
</body>
Any help would be appreciated.
Thanks;
Matt
You would probably want to do something like this, you will have to call a zoom2query function. You will want to probably want to calculate the lat and long of the centroid of parcel for zoom functionality, make sure to call you geometry column column on the map so you don't have the points.
function changeMap() {
var searchString = document.getElementById('search').value.replace("'", "\\'");
if(searchString == "") {
var query="SELECT 'Lat' FROM " + tableid;
}
else {
var query="SELECT 'Lat' FROM " + tableid + " WHERE 'PARCEL_ID' = '" + searchString + "'";
}
// layer.setQuery(query);
if(searchString == "") {
var query="SELECT 'Lat','Long' FROM " + tableid;
}
else {
var query="SELECT 'Lat','Long' FROM " + tableid + " WHERE 'ARN' = '" + searchString + "'";
}
zoom2query(query);
}
var infowindow = new google.maps.InfoWindow();
function zoom2query(query) {
// zoom and center map on query results
//set the query using the parameter
document.getElementById("query").innerHTML = query;
var queryText = encodeURIComponent(query);
var query = new google.visualization.Query('https://www.google.com/fusiontables/gvizdata?tq=' + queryText);
//set the callback function
query.send(zoomTo);
}
function zoomTo(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
var lat = response.getDataTable().getValue(0,0);
var lng = response.getDataTable().getValue(0,1);
var zoom_level = 19;
var location = new google.maps.LatLng(lat,lng);
map.setCenter(location);
map.setZoom(zoom_level);
}
Here is an example of what I have done, we have RP numbers but mine zooms to the parcel
https://googledrive.com/host/0B0J_A50xWBAqNHZqVlUxSkNUbWs/Shoshone.html

AJAX loop for WordPress (posts from different categories)

I try to implement AJAX posts loop for WordPress from Tuts+
I want this loop to show under comments form in single post page in three columns (each for another category)
In single.php I have divs (numbers comes from category):
<div class="news_posts-6"></div>
<div class="news_posts-3"></div>
<div class="news_posts-2"></div>
My ajaxLoop:
jQuery(function($){
var page = 1;
var loading = true;
var $window = $(window);
var cat = [6,3,2];
var load_posts= jQuery.each(cat, function(){
var $content = $(".news_posts-" + this);
$.ajax({
type : "GET",
data : {numPosts: 2, pageNumber: page, cat: this},
dataType : "html",
url : "http://127.0.0.1:4001/wordpress/wp-content/themes/twentyeleven-child-theme/loopHandler.php",
beforeSend : function(){
if(page != 1){
$content.append('<div id="temp_load" style="text-align:center">\
<img src="/images/ajax-loader.gif" />\
</div>');
}
},
success : function(data){
$data = $(data);
if($data.length){
$data.hide();
$content.append($data);
$data.fadeIn(500, function(){
$("#temp_load").remove();
loading = false;
});
} else {
$("#temp_load").remove();
}
},
error : function(jqXHR, textStatus, errorThrown) {
$("#temp_load").remove();
alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
});
$window.scroll(function() {
var content_offset = $content.offset();
console.log(content_offset.top);
if(!loading && ($window.scrollTop() +
$window.height()) > ($content.scrollTop() + $content.height() + content_offset.top)) {
loading = true;
page++;
load_posts();
}
});
load_posts();
});
Part of loopHandler.php:
$numPosts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;
$cat = (isset($_GET['cat'])) ? $_GET['cat'] : 0;
echo $numPosts;
echo $page;
query_posts(array(
'posts_per_page' => $numPosts,
'paged' => $page,
'cat' => $cat
));
I tried use simple array containing categories numbers but it doesn't work. Depends on
data : {numPosts: X, pageNumber: page, cat: this},
there is X post displaying in each column (same posts from first category).
I guess I need to use JSON, which I tried, but it was total disaster (I don't know how to put it together). I just need to call AJAX for three different arguments.
Thanks for any help
Well, there are various ways you can go about this.
One way is looping over your categories client side first, and make separate request per category. This is what you are essentially doing in your code. You are iterating over an array of categories and making a request for each.
Another way is to pass that array of categories to your handler. All you need to do is modify your handler to accept an array of integers or categories. Then you can return a JSON object. But this involves a lot more editing and on top of that it does not solve the issue of having different sizes and heights for each section.
Thus, below, I have modified the code a little bit to also keep track of multiple sections. There are just a few small edits we need:
Each section needs to have a category number, pagination number, content section, and a flag whether its loading or not. Each needs to be stored in a single list for tracking.
We need to iterate over each category to initialize it.
We need to iterate over each category on window scroll and check if the next item should be loaded
We need to make sure that each request relates to the requested category
Start by modifying your divs a little (this is just a matter of preference, i prefer storing metadata like this in an attribute instead of a class):
<div class="news_posts" data-category="6"></div>
<div class="news_posts" data-category="3"></div>
<div class="news_posts" data-category="2"></div>
Here's a modified JS (please be aware that I changed up some variable and function names):
jQuery(function($){
var $window = $(window);
var cats = [];
var contentDivs = $(".news_posts");
var initializeCats = function(){
// adds category objects to a list for tracking
for(var i = 0; i < contentDivs.length; i++){
var catNum = $(contentDivs[i]).attr("data-category");
var cat = {
catNum : catNum,
catPage : 1,
loading : true,
catDiv : $(contentDivs[i]);
};
cats.push(cat);
load_post(cat);
}
};
var load_post = function(cat) {
$.ajax({
type : "GET",
data : {
numPosts : 2,
pageNumber : cat.catPage,
cat : cat.catNum
},
dataType : "html",
url : "http://127.0.0.1:4001/wordpress/wp-content/themes/twentyeleven-child-theme/loopHandler.php",
beforeSend : function(){
if(page != 1){
// this was a bad idea when i wrote the article originally
// never concatenate strings on multiple lines by escaping
// the carriage return
// $content.append('<div id="temp_load" style="text-align:center">\
// <img src="/images/ajax-loader.gif" />\
// </div>');
cat.catDiv.append("<div class='temp_load' style='text-align:center'>" +
"<img src='/images/ajax-loader.gif' />" +
"</div>");
}
},
success : function(data){
$data = $(data);
if($data.length){
$data.hide();
cat.catDiv.append($data);
$data.fadeIn(500, function(){
cat.catDiv.find(".temp_load").remove();
cat.loading = false;
});
} else {
cat.catDiv.find(".temp_load").remove();
}
},
error : function(jqXHR, textStatus, errorThrown) {
cat.catDiv.find(".temp_load").remove();
alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
}
});
});
var onWindowScroll = function(){
for(var i = 0; i < cats.length; i++){
var cat = cats[i];
var contentDiv = cat.catDiv;
var content_offset = contentDiv.offset();
if( !cat.loading &&
($window.scrollTop() + $window.height()) >
(contentDiv.scrollTop() + contentDiv.outerHeight() + content_offset.top)
) {
cat.loading = true;
cat.catPage++;
load_post(cat);
}
}
}
initializeCats();
$window.scroll(onWindowScroll);
});
The PHP file is pretty much the same, just comment out the echo $numPosts line:
$numPosts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;
$cat = (isset($_GET['cat'])) ? $_GET['cat'] : 0;
// echo $numPosts;
echo $page;
query_posts(array(
'posts_per_page' => $numPosts,
'paged' => $page,
'cat' => $cat
));
This is just something quick I whipped up. I HAVE NOT TESTED IT. Try it out, watch out for syntax errors, and cross your fingers :). I hope this will work for you and if it does not, we can look into modifying it so that it does.

How can i define a variable in Json?

i want define a variable in Json callback.
Code;
$("select").change(function () {
var $variable = "";
$("select option:selected").each(function () {
$variable += $(this).text() + " ";
});
$("div.yaz").text($variable);
$('#result').html('loading...');
$.getJSON('program-bilgileri.php', function(JSON){
$('#result').empty();
$.each(JSON.$variable, function(i, program){
$('#result')
.append(program.isim +'<br />')
.append(program.bilgi+'<br />')
.append(program.adres+'<hr />');
});
});
})
.trigger('change');
program-bilgileri.php returns;
{
"programlar":[
{
"isim":"Zone Alarm",
"bilgi":"bilgisayarın güvenliğini sağlar",
"adres":"www.zonealarm.com"
},
{
"isim":"Opera",
"bilgi":"güvenli ve hızlı bir web tarayıcısıdır",
"adres":"www.opera.com"
},
{
"isim":"Photoshop",
"bilgi":"güçlü bir imaj işleme yazılımıdır",
"adres":"www.adobe.com"
}
]
}
The problem is here "$.each(JSON.$variable, function(i, program)" if I define $variable in JSON it isn't working.
Any idea?
The problems i see are
Inside the change event you are using $("select option:selected") which finds all select elements in the page, and not the changed one only.
use $(this).children('option:selected') instead.
I am assuming that you are allowing multiple selection on the select element and that is why you are doing += with the $variable.. (you are also adding a space at the end). That means, though, that the variable will be something like "programlar " or "programlar somethingelse".
Your returned JSON though has a key of programlar. A single word, no spaces.. so when you do JSON[$variable] which is the correct way to access an element based on the name in a variable, it does not match.
If the <select> element does not allow multiple selection then the solution is
$("select").change(function() {
var $variable = $(this).children("option:selected").text();
$("div.yaz").text( $variable );
$('#result').html('loading...');
$.getJSON('program-bilgileri.php', function(JSON) {
$('#result').empty();
$.each(JSON[$variable], function(i, program) {
$('#result')
.append(program.isim + '<br />')
.append(program.bilgi + '<br />')
.append(program.adres + '<hr />');
});
});
}).trigger('change');
If indeed it is a multiselect and each option can appear in the JSON then you must check for each option found in the variable.
$("select").change(function() {
var $variable = $(this).children("option:selected").map(function(){
return $(this).text();
}).get();
$("div.yaz").text( $variable.join(' ') );
$('#result').html('loading...');
$.getJSON('program-bilgileri.php', function(JSON) {
$('#result').empty();
for (index=0, length = $variable.length; index < length; index ++) {
$.each(JSON[$variable[index]], function(i, program) {
$('#result')
.append(program.isim + '<br />')
.append(program.bilgi + '<br />')
.append(program.adres + '<hr />');
});
}
});
}).trigger('change');
Try
$.each(JSON['programlar'], function(i, program) ... );
This will iterate over this part of your returned JSON object from PHP:
{
"isim":"Zone Alarm",
"bilgi":"bilgisayarın güvenliğini sağlar",
"adres":"www.zonealarm.com"
},
{
"isim":"Opera",
"bilgi":"güvenli ve hızlı bir web tarayıcısıdır",
"adres":"www.opera.com"
},
{
"isim":"Photoshop",
"bilgi":"güçlü bir imaj işleme yazılımıdır",
"adres":"www.adobe.com"
}

What is the correct JSON structure for this while loop?

I'm a little new to JSON so trying to understand what is the best way to do this. I have two variables: postcode and energyrating that I want to put into JSON and then parse to a for loop.
I can get it to work with one variable but when I have two it doesn't work.
Here is my JSON:
header('Content-type: application/json');
$postcodeArray = array('postcodes' => array("E6 2JG","SE1 2AQ","DA1 1DZ"), 'energyrating' => array("A","B","C","D","E","F","G"));
die(json_encode($postcodeArray));
Here is my jQuery:
function addNew(postcodes) {
if(postcodes.length > 0) {
for(var i = 0; i < postcodes.length; i++) {
var address = postcodes[i];
var rating = energyrating[i];
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var image = '../img/markers/' + rating + '.png';
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: image
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
} else {
alert("Sorry, no data was found.");
}
}
How do I get this to work with both variables?
What does not work exactly ?
Reading your code, I would say there is an error into your code. The energyrating argument is missing into your addNew function:
function addNew(postcodes, energyrating) {
Assuming that you call your function like this:
addNew(jsonData.postcodes, jsonData.energyrating);
Use json variables to store the data like that :
$postcodeArray = '{"postcodes":{"0":E6, "1":"2JG", "3":"SE1 2AQ","4":"DA1 1DZ"}, "energyrating":{"0":"A","1":"B","2":"C","3":"D","4":"E","5":"F","6":"G"}}';
In the place of
$postcodeArray = JSON.parse('postcodes' => array("E6 2JG","SE1 2AQ","DA1 1DZ"), 'energyrating' => array("A","B","C","D","E","F","G"));
And you can access the values.
Or try json_decode(postcodes) in the function addNew in first line.

Resources