Leaflet - updating a keyword search call to a restful api and refreshing map - api

My Question (UPDATED): How do I get my keyword to change in the API URL Search Query based off of an AJAX Call (having a scope problem here) ?
I connected a leaflet map to an an API to plot Wikipedia articles with geocoordinates. An example URL looks like: http://api.infochimps.com/encyclopedic/wikipedia/dbpedia/wikipedia_articles/search?g.radius=10000&g.latitude=30.3&g.longitude=-97.75&f.q=park&apikey=api_test-W1cipwpcdu9Cbd9pmm8D4Cjc469
So far so good. But I am stuck on how to implement an AJAX call that would allow the user to search for a new query term and reload the map. When I click the search box, the keyword alerts that the keyword is the text in the search box. But the map does not update based on the new keyword.
So I have as a JS script:
var map;
var pointsLayer;
var markerMap = {};
var keyword; //instantiating keyword for global scope
$(document).ready(function(){
map = new L.Map('mapContainer');
var url = 'http://{s}.tiles.mapbox.com/v3/mapbox.mapbox-streets/{z}/{x}/{y}.png';
var copyright = 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade';
var tileLayer = new L.TileLayer(url, {attribution:copyright});
//var startPosition = new L.LatLng(42.33143, -83.04575);//detroit
var startPosition = new L.LatLng(41.883333, -87.633333);//chicago
//var startPosition = new L.LatLng(40.7143528, -74.0059731);//new york
map.on('load', function(){
keyword = 'history'; //setting keyword to history on first load
requestUpdatedPoints();
keyword = ''; //clearing keyword after first load
});
map.setView(startPosition, 13).addLayer(tileLayer);
map.on('moveend', function(){
requestUpdatedPoints();
});
//////////////
/// WRONG ADDITION OF ADDING KEYWORD SEARCH?
//////////////
$('a#submitSearch').on('click', function(e, keyword){
e.preventDefault();
//keyword = '';
keyword = $('input#keyword').val(); //setting keyword to whatever is in the search box
alert(keyword); //did it set it?
requestUpdatedPoints(keyword); //send in new AJAX call with new keyword
location.reload();
});
});
function requestUpdatedPoints(keyword){
$.ajax({
type: 'GET',
url: 'http://api.infochimps.com/encyclopedic/wikipedia/dbpedia/wikipedia_articles/search?g.radius=100000&g.latitude=41.883333&g.longitude=-87.633333&f.q='+this.keyword+'&apikey=api_test-W1cipwpcdu9Cbd9pmm8D4Cjc469',
dataType: 'jsonp',
//data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
success: function(result){
for( var i=0; i<result.results.length - 1; i++ ){
console.log("adding " + result.results[i].wikipedia_id + " to the map")
var marker = L.marker([result.results[i].coordinates[1], result.results[i].coordinates[0]]).addTo(map);
marker.bindPopup(''+result.results[i].wikipedia_id+'');
}
},
error: function(){
alert('check your error log.');
}
});
}
the HTML is:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4/leaflet.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://cdn.leafletjs.com/leaflet-0.4/leaflet.js"></script>
<script type="text/javascript" src="./map.js"></script>
</head>
<body>
<h1>WikiMap</h1>
<div id="mapContainer"></div>
<div id="infoContainer">
<div id="search">
<form id="searchForm">
<label>Keyword:</label>
<input type="text" id="keyword" name="keyword" placeholder="search by keyword"/>
<a id="submitSearch" href="#">search</a>
</form>
</div>
</div>
</body>
</html>
My Question (UPDATED): How do I get my keyword to change in the API URL Search Query based off of an AJAX Call (having a scope problem here) ?

I've finally figured that my layout is poor for accomplishing what I want to get done. Even if the keyword is updating, the map.on() load function is reverting everything back to the beginning. I've decided to use Backbone.js to help me organize my data flows.

var searchControl = L.esri.Geocoding.Controls.geosearch({
providers: [
new L.esri.Geocoding.Controls.Geosearch.Providers.MapService({
label: 'States and Counties',
url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer',
layers: [2, 3],
searchFields: ['NAME', 'STATE_NAME']
})
]
}).addTo(map);
I am using leaflet map search api by address but I find an autosuggestion searching api something that.

Related

Unable to use Lazy load + Dynamic image manipulation Cloudinary

I am unable to use the feature Cloudinary Lazyload + Dynamic image manipulation both at the same time.
Is there any trick to use both the function at the same time?
I am using an HTML website.
My code is
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://unpkg.com/cloudinary-core#latest/cloudinary-core-shrinkwrap.js"></script>
<script type="text/javascript">
var cl = cloudinary.Cloudinary.new({cloud_name: "syg"});
// replace 'demo' with your cloud name in the line above
cl.responsive();
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const imageObserver = new IntersectionObserver((entries, imgObserver) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const lazyImage = entry.target
console.log("lazy loading ", lazyImage)
lazyImage.src = lazyImage.dataset.src
}
})
});
const arr = document.querySelectorAll('img.lzy_img')
arr.forEach((v) => {
imageObserver.observe(v);
})
})
</script>
<img class="cld-responsive lzy_img" data-src="https://res.cloudinary.com/syg/image/upload/w_auto,c_scale/sample.jpg" />
The responsive script will apply the relevant width value and replace w_auto in the URL based on the container size.
Since your code does not limit the <img> container, it applies the max width size of the screen.
For testing purposes, you can wrap your <img> element with <div style="width:50%;"></div> and you will see that the image URL adjusts the width transformation accordingly:
<div style="width:50%;">
<img class="cld-responsive lzy_img" data-src="https://res.cloudinary.com/syg/image/upload/w_auto,c_scale/v346346/sample.jpg"/>
</div>
In addition, you can take a look at the following broader implementation of LQIP+Lazy Loading+Responsive with Cloudinary for reference and ideas on how to implement these features within your site's pages.

Bootstrap input field inside tooltip popover removed from output html

Hello i`m using boostrap 4.3.1 and included popper 1.14.7.
Normally I can add input fields in the content of the popup/tooltip. I don`t since when, but at the moment when I put input field in the content then only the text is visible.
When I look in the source (compiled html) I can see that popper or bootstrap removed the input fields. Do I something wrong?
var options = {
html: true,
// content: function(){ return $(".amountElec.popup").html();},
placement: "bottom",
container: "body"
};
$(function(){
$('#manualinput').popover(options);
})
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div id="manualinput"
data-container="body"
data-toggle="popover"
data-content="test <input name='test' type='text' value='2'>"
data-html="true"
data-placement="bottom">
OPEN TOOLTUP
</div>
It's even easier as you think:
Add
sanitize: false
as config option if you want to disable sanitize at all. If you just want to adapt the whitelist, you are right with your solution
https://github.com/twbs/bootstrap/blob/438e01b61c935409adca29cde3dbb66dd119eefd/js/src/tooltip.js#L472
I found the solution...
I my case add this to the javascript:
var myDefaultWhiteList = $.fn.tooltip.Constructor.Default.whiteList;
myDefaultWhiteList.input = [];
https://getbootstrap.com/docs/4.3/getting-started/javascript/#sanitizer
After searching in the debug console I found somehting in the tooltip.js from bootstrap.
content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)
setElementContent($element, content) {
if (typeof content === 'object' && (content.nodeType || content.jquery)) {
// Content is a DOM node or a jQuery
if (this.config.html) {
if (!$(content).parent().is($element)) {
$element.empty().append(content)
}
} else {
$element.text($(content).text())
}
return
}
if (this.config.html) {
if (this.config.sanitize) {
content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn)
}
$element.html(content)
} else {
$element.text(content)
}
}
sanitizeHtml function removes the input fields :(.
I just turned of sanitize by default (globally):
$.fn.tooltip.Constructor.DEFAULTS.sanitize = false;
$.fn.popover.Constructor.DEFAULTS.sanitize = false;
https://getbootstrap.com/docs/3.4/javascript/#default-settings

How to display activity feed of my google plus page in my website?

I would like to display the activity feeds of my facebook, twitter, linkedIn, google+ pages in my website. For facebook and twitter, iam getting the feeds by referring their developer website(image attached) . But I dont know how to get the activity feeds from google plus page. Is there any options are available for it ?
There are tools to help you do this with Google+, but there is no pre-made widget that will do this. You need to combine two components of the Google+ API: the activities.list call and an embedded post.
One very simplistic implementation might look something like this:
<html>
<head>
<title>Plus Posts</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<style>
.post {
display: block;
padding-bottom: 10px;
}
</style>
</head>
<body>
<div id="posts"></div>
<script type="text/javascript">
var plusId = 'profile_id_to_view;
var apiKey = 'API key from developer console';
function start(){
gapi.client.setApiKey( apiKey );
gapi.client.load('plus','v1', function(){
console.log('loaded');
gapi.client.plus.activities.list({
userId: plusId,
collection: 'public',
maxResults: 10
}).execute(function(resp){
if( resp && resp.items && resp.items.length > 0 ){
for( var co=0; co<resp.items.length; co++ ){
$('#posts').append('<div class="post"><div id="posts-'+co+'"></div></div>');
var url = resp.items[co].object.url;
gapi.post.render('posts-'+co, {url:url});
}
} else {
console.log('invalid resp', resp);
}
});
});
}
(function(){
var po = document.createElement( 'script' );
po.type = 'text/javascript';
po.async = true;
po.src = 'https://plus.google.com/js/client:plusone.js?onload=start';
var s = document.getElementsByTagName( 'script' )[0];
s.parentNode.insertBefore( po, s );
})();
</script>
</body>
</html>
You need to create a project and get your own API key from http://console.developers.google.com/ and provide this and the ID for the posts you wish to follow.
There is a simple jquery plugin called Google+ Feed Widget.

How to auto-complete/suggest places (with address) on my website like on Google maps?

I am working a Yelp-like project that associates reviews to places. Yet, we don't have any database of places and we'd like to leverage a third-party api.
We'd like to start with a auto-complete search box like on Google Maps. For example, the user enters "tamar" and it suggests "Tamarine Restaurant, Palo Alto, CA, United States".
1) is it possible? what third party api would you use? Is Google maps the best?
Once the results are returned, the user selects one place and will leave a review.
2) how would you associate that review to that specific place in the DB? My concern is if later on we change api provider, that we can still associate our reviews to the new api places.
Thank you SO MUCH! Any suggestion would help.
Fab
this will generate autocomplete also get the latitutde and longitutde in 2 textbox for storage on your DB if need.initially center is set statically ..hope this is what you want
<head>
<script type="text/javascript" src=" https://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
<script type="text/javascript">
var map;
var geocoder;
geocoder = new google.maps.Geocoder();
function initialize() {
var pyrmont = new google.maps.LatLng(-33.8665433,151.1956316);
map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: pyrmont,
zoom: 15
});
var input = document.getElementById('searchTextField');
var options = {
bounds: pyrmont,
//types: ['establishment'] dont mention it we need to get both bussiness andaddress
};
autocomplete = new google.maps.places.Autocomplete(input, options);
}
$(document).ready(function() {
$("#find").click(function(){
var address = document.getElementById("searchTextField").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var test = results[0].geometry.location;
var latlang=String(test);
latlang = latlang.substring(0, latlang.length-1);
latlang= latlang.substr(1);
var latlan = latlang.split(",");
var lat = latlan[0];
var lon = latlan[1];
$("#latitude").val(lat);
$("#longitude").val(lon);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
});
});
</script>
<body onload="initialize();">
<label> Type address</label>
<input type="text" id="searchTextField" style="width:500px;" />
<div id="map" style="width:500px;height:500px;"></div>
<input type="text" id="latitude"/>
<input type="text" id="longitude"/>
<input type="button" id="find" value="Find"/>
</body>
There's an API at http://compass.webservius.com that can help. You can search a database of millions of businesses in the US (e.g. by a name prefix like in your example, by zip code, by latitude/longitude bounding box, etc) and get back results (such as business name, address, type, etc) in XML or JSON format.
For the second part of your question, it is tough because there is no "universal ID" for a business, but usually a combination of normalized postal address + business name will work well enough.
html
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
HTML Form Input
<input id="locationName" name="locationName" type="text">
JavaScript
function init() {
var input = document.getElementById('locationName');
var autocomplete = new google.maps.places.Autocomplete(input);
}
google.maps.event.addDomListener(window, 'load', init);

How to show next/previous links in Google Custom Search Engine paging links

The Google Custom Search integration only includes numbered page links and I cannot find a way to include Next/Previous links like on a normal Google search. CSE used to include these links with their previous iframe integration method.
I stepped through the javascript and found the undocumented properties I was looking for.
<div id="cse" style="width: 100%;">Loading</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en'});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl('GOOGLEIDGOESHERE');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
customSearchControl.setSearchCompleteCallback(null,
function() { searchCompleteCallback(customSearchControl) });
customSearchControl.draw('cse');
}, true);
function searchCompleteCallback(customSearchControl) {
var currentPageIndex = customSearchControl.e[0].g.cursor.currentPageIndex;
if (currentPageIndex < customSearchControl.e[0].g.cursor.pages.length - 1) {
$('#cse .gsc-cursor').append('<div class="gsc-cursor-page">Next</div>').click(function() {
customSearchControl.e[0].g.gotoPage(currentPageIndex + 1);
});
}
if (currentPageIndex > 0) {
$($('#cse .gsc-cursor').prepend('<div class="gsc-cursor-page">Previous</div>').children()[0]).click(function() {
customSearchControl.e[0].g.gotoPage(currentPageIndex - 1);
});
}
window.scrollTo(0, 0);
}
</script>
<link rel="stylesheet" href="http://www.google.com/cse/style/look/default.css" type="text/css" />
I've been using this to find the current page:
ctrl.setSearchCompleteCallback(null, function(gControl, gResults)
{
currentpage = 1+gResults.cursor.currentPageIndex;
// or, here is an alternate way
currentpage = $('.gsc-cursor-current-page').text();
});
And now it's customSearchControl.k[0].g.cursor ... (as of this weekend, it seems)
Next time it stops working just go to script debugging in IE, add customSearchControl as a watch, open the properties (+), under the Type column look for Object, (Array) and make sure there is a (+) there as well (i.e. contains elements), open[0], and look for Type Object, again with child elements. Open that and once you see "cursor" in the list, you've got it.