My goal is to have several input fields with Autocomplete functionality and each input will generate a marker on the map. I then need the map to zoom in to contain all of the markers. I have this working partially, without the Autocomplete functionality. I have tried adding the Google Maps API Places Autocomplete code to my for loop, but to no avail. It gives autocomplete functionality to all the input fields but only places a marker for the last input.
Any help/insight/guidance is appreciated.
Here is my code, the autocomplete is currently deleted since I couldn't get it to work.
<div class="container-fluid">
<div class="row-fluid">
<div class="span4 well">
<div id="locations">
<form>
<label>Location 0</label>
<input id="address0" type="text" size="50" >
<button id="clearField0">Clear</button>
<div class="panel">
<label>Location 1</label>
<input id="address1" type="text" size="50">
<button id="clearField0">Clear</button>
</div>
<div class="panel">
<label>Location 2</label>
<input id="address2" type="text" size="50">
<button id="clearField0">Clear</button>
</div>
</form>
</div>
<button id="addField">+</button>
<button id="deleteField">-</button>
<button id="submit">Submit form</button>
</div>
<div class="span8">
<div id="map-wrapper">
<div id="google-map"></div>
</div>
</div>
</div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCtNo_o0u8wYeqgiFF-KpvAtEy18T-PvAo&sensor=false&callback=createMap"></script>
<script type="text/javascript">
var inputFields = parseInt($('form input').size());
var markers = [];
var createMap = function() {
var latlngbounds = new google.maps.LatLngBounds();
var geocoder = new google.maps.Geocoder();
var myOptions = {
center : new google.maps.LatLng(35.9081, -78.8628), //center to RTP
zoom : 12,
zoomControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById("google-map"), myOptions);
$("#submit").on("click", function() {
setAllMap(null);
markers.pop();
for (i=0; i<inputFields; i++) {
var location = $("#address" + i).val();
geocoder.geocode( {'address': location}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
latlngbounds.extend(results[0].geometry.location);
map.fitBounds(latlngbounds);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
};
});
function setAllMap(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
}
$('#addField').click(function(){ //add input field to bottom of form
$('form').append('<div class="panel"><label>Location '+ inputFields +'</label><input id="address'+ inputFields +'" type="text" size="50"><button id="clearField'+ inputFields +'">Clear</button></div>');
inputFields++;
});
$('#deleteField').click(function(){ //delete last input field
$('.panel').last().remove();
inputFields--;
});
};
</script>
My first problem was including the places library in the API reference. Following that, I simply needed two lines of code from Google's Places Autocomplete example page, as opposed to the entire script they offer:
var input = /** #type {HTMLInputElement} */(document.getElementById('searchTextField'));
var autocomplete = new google.maps.places.Autocomplete(input);
These two lines in my for loop solved the problem. Thanks again to Dr. Molle whose comment made me rethink what code I needed.
Related
I am trying to access the Wikimedia API and display ten results. I have written a function that accesses the API and works on its own.
However, when I try to integrate a Search button to call that function and pass the search string to the function nothing happens in Chrome or Firefox.
(oddly though when I use the snippet function within stackoverflow it works fine!)
I'm wondering why my code doesn't work in the browser - could this have something to do with synchronous/asynchronous behavior and if so what is happening?
I'd really appreciate some insight into what is going on...
Thanks!
$(document).ready(function() {
// Initialize the Global Variables
var api = "http://en.wikipedia.org/w/api.php?callback=?&format=json&action=query&generator=search&gsrnamespace=0&gsrlimit=10&prop=pageimages|extracts&pilimit=max&exintro&explaintext&exsentences=1&exlimit=max&gsrsearch=";
var searchTitle = "";
var searchString = "";
$('#submit').click( function() {
searchTitle = $("input:text").val();
searchString = api + searchTitle;
getWiki(searchString);
});
// the following function works if I call it statically outside of the button click
// for example: getWiki(api + "giraffe");
// but it doesn't work if I call it dynamically from within the button. Why?
function getWiki(val) {
$.getJSON(val, function(json) {
$.each(json.query.pages, function(prop, item) {
var id = "#result" + item.index
$(id).html(item.title + "<br>" + item.extract);
});
});
}
// END Document Ready Function
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<body>
<form class="form-wrapper">
<input type="text" id="search" placeholder="Search for..." required>
<input type="submit" value="go" id="submit">
</form>
<div class="container">
<div class="row">
<div class="col-xs-12">
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>
<div id="result4"></div>
<div id="result5"></div>
<div id="result6"></div>
<div id="result7"></div>
<div id="result8"></div>
<div id="result9"></div>
<div id="result10"></div>
</div>
</div>
</div>
</body>
I'm using nervgh's angular-file-upload, https://github.com/nervgh/angular-file-upload/wiki/Module-API.
Is there a way to use the angular-file-upload and allow additional properties to each file when doing a multi-file upload?
I'm using their image sample to start out with: http://nervgh.github.io/pages/angular-file-upload/examples/image-preview/
Trying to add a boolean to each file that the user can set and then I use that on the server side when it's picked up.
You can use formData property shown in Properties section to send to server whatever you need.
formData {Array}: Data to be sent along with the files.
If you're using PHP in server side, I think this post can help you out.
The question is rather old, but as the documentation didn't really help me much, I would like to note down my solution here:
This is how my html looks like (look for "options"):
<div ng-controller="UploadCtrl2" nv-file-drop="" uploader="uploader" filters="customFilter">
<div class="progress progress-xs margin-top-5 margin-bottom-20">
<div class="progress-bar" role="progressbar" ng-style="{ 'width': uploader.progress + '%' }"></div>
</div>
<div class="row">
<div class="col-md-6">
<div ng-show="uploader.isHTML5">
<div class="well my-drop-zone" nv-file-drop="" options="{formData:[{folder:'attachments'}, {recordid:0}]}" uploader="uploader">
Dateien hierher ziehen.
</div>
</div>
</div>
<div class="col-md-6">
<span class="btn btn-primary btn-o btn-file margin-bottom-15"> Dateien auswählen
<input type="file" nv-file-select="" options="{formData:[{folder:'attachments'}, {recordid:0}]}" uploader="uploader" multiple />
</span>
</div>
</div>
</div>
And this is my controller (look for "fileItemOptions"):
app.controller('UploadCtrl2', ['$rootScope', '$scope', 'FileUploader', 'Store',
function ($rootScope, $scope, FileUploader, Store) {
var fileItemOptions = {};
var uploader = $scope.uploader = new FileUploader({
url: $rootScope.app.api.url + '/?c=uploads&a=set&authToken=' + encodeURIComponent(Store.get('X-Xsrf-Token')),
});
// FILTERS
uploader.filters.push({
name: 'customFilter',
fn: function (item/*{File|FileLikeObject}*/, options) {
if(options) fileItemOptions = options;
return this.queue.length < 10;
}
});
uploader.removeAfterUpload = true;
// CALLBACKS
uploader.onAfterAddingFile = function (fileItem, options) {
//console.info('onAfterAddingFile', fileItem);
if(fileItemOptions.formData) {
fileItem.formData = fileItemOptions.formData;
}
};
uploader.onAfterAddingAll = function (addedFileItems) {
setTimeout(function () {
console.log(uploader);
uploader.uploadAll();
}, 500);
};
uploader.onCompleteAll = function () {
$scope.$parent.run.uploadComplete();
fileItemOptions = {}; // cleanup
};
}]);
Whenever a file is added, the custom filter stores the option object in a global variable. The callback "onAfterAddingFile" will read that variable and it to the fileItem object. Quite hacky, but this was the only way I got it running.
Starting from a simple list of favorite venues stored in an array as objects, I need to have these venues show up on google maps with their own markers. When the markers are clicked, their info windows should open and display their information. That’s pretty straight forward and I’ve already done that.
In addition to this, I also have the names of those venues displayed in a list to the right of the map. My trouble is connecting these two things — the markers and their respective titles in the list to the right. For instance, when I click on an item (venue name) in the list view, I need the map marker on that location to display its info.
For the life of me I can’t seem to make sense of how to connect the two things. I’m using Knockout.js to keep the Javascript and html in sync, and you can see below the map that when I click an item in the list the ‘currentPlace’ is displayed. This won’t be in the end application, but it illustrates what I’m going for. Basically I need that currentPlace to trigger a marker click???
Some things I’ve looked at:
google maps api .... showing a markers infowindow from a link outside of the map
This seems to work at first, but a click on a map marker doesn’t open a window…Also they’re using jQuery and I’m trying to get this to work using only Knockout.js and vanilla JavaScript.
Also, this:
http://jsfiddle.net/RASG/X5mhL/
This illustrates exactly what I’m shooting for but with this example the hrefs are simply entered into the html. I’m trying to have this work in JavaScript in a way that I can easy add new locations just by adding a new place to the initialPlaces array.
Any help would be greatly appreciated.
Here is my html with the Knockout.js data-binds:
<body>
<div class="row">
<div class="col-md-8">
<hr>
</div>
<div class="col-md-4" id="search-header">
<form id="new-search">
<input type="text" class="text-input" data-bind="value: searchEntry">
<input type="submit" value="look for things" class="search-button" data-bind="">
</form>
</div>
</div>
<div class="row">
<div class="col-md-8" id="mapContainer">
<div class="map" id="map-canvas"></div>
</div>
<div class="col-md-4">
<div id="places">
<h2 id="list-title">FAVORITE PLACES</h2>
<hr>
<div id="place-list" data-bind="foreach: placeList">
<h3 data-bind="text: $data.name, click: $parent.setPlace" id="list-item"></h3>
</div>
</div>
</div>
</div>
<div id="place" data-bind="with: currentPlace">
<h2 data-bind="text: name"></h2>
</div>
And here is my JavaScript:
var infowindow = new google.maps.InfoWindow();
var Place = function(data) {
var self = this;
this.name = ko.observable(data.name);
this.lat = ko.observable(data.lat);
this.long = ko.observable(data.long);
var titleString = String(data.name);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.long),
title: titleString,
map: map
});
google.maps.event.addListener(marker, 'click', function () {
map.panTo(marker.position);
infowindow.open(map, marker);
infowindow.setContent(titleString);
});
markers.push(marker);
};
var markers = ko.observableArray([]);
var mapCanvas = document.getElementById('map-canvas');
var mapOptions = { center: { lat: 40.675087, lng: -73.975524},
zoom: 12,
disableDefaultUI: true
};
map = new google.maps.Map(mapCanvas, mapOptions);
var initialPlaces = [
{
name: 'Soda Bar',
lat: '40.678396',
long: '-73.968349'
},
{
name: 'Brooklyn Roasting Co.',
lat: '40.704334',
long: '-73.986524'
},
{
name: 'Prospect Park',
lat: '40.661034',
long: '-73.968876'
}
];
var ViewModel = function() {
var self = this;
this.placeList = ko.observableArray([]);
initialPlaces.forEach(function(placeItem){
self.placeList.push( new Place(placeItem));
console.log(placeItem);
});
this.currentPlace = ko.observable(this.placeList()[0]);
this.setPlace = function(clickedPlace) {
self.currentPlace(clickedPlace);
};
/*
* Create a thing to hold search entry
*/
this.searchEntry = ko.observable('Search')
};
ko.applyBindings(new ViewModel());
I am new to knockout.js. I am following this tutorial. It is working fine on knockout site but not for me. Error console is also not showing any error.
Below is my code
View:
Tasks
<form data-bind="submit: addTask">
Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
<button type="submit">Add</button>
</form>
<div >
<ul data-bind="foreach: tasks, visible: tasks().length > 0" id="testing">
<li>
<input type="checkbox" data-bind="checked: isDone" />
<input data-bind="value: title, disable: isDone" />
Delete
</li>
</ul>
</div>
View Model:
<script>
function Task(data) {
this.title = ko.observable(data.title);
this.isDone = ko.observable(data.isDone);
}
function TaskListViewModel() {
// Data
var self = this;
self.tasks = ko.observableArray([]);
self.newTaskText = ko.observable();
self.incompleteTasks = ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() });
});
// Operations
self.addTask = function() {
self.tasks.push(new Task({ title: this.newTaskText() }));
self.newTaskText("");
};
self.removeTask = function(task) { self.tasks.remove(task) };
}
ko.applyBindings(new TaskListViewModel(),document.getElementById("testing"));
</script>
The problem is that the ko.applyBindings doesn't apply to all data-bind attributes. Move your "testing" id to a place where it covers all the HTML code with the relevant "data-bind" attributes.
I have drawn a map on my page using OPENLAYERS 3.0.
And in document.ready() i have drawn the map and have plotted few markers on it using
some Longitude and latitude combinations.
And i have added draw line,polygon and select feature on my map.
My idea is to plot few markers on the map while page load, and i would like to a
draw a ploygon or bounding box and then on clicking those selections i should be
able to get the markers plotted inside those selection, is it possible to do this
without looping, anyone please give me a suggestion to accomplish this.
my HTML and JAVASCRIPT code is as follows
var map, layer;
var drawControls;
OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';
$('document').ready(function () {
console.log('in');
OpenLayers.ProxyHost = "/proxy/?url=";
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", { layers: 'basic' });
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
var newl = new OpenLayers.Layer.Text("text", { location: "./content/textfile.txt" });
map.addLayer(newl);
var markers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markers);
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
//markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0, 0), icon));
var halfIcon = icon.clone();
//markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0, 45), halfIcon));
var Latitudes = '12.98267,13.00118,12.97161,12.97977,12.92828,12.97597';
var Longitudes = '80.26338,80.2565,80.24343,80.25288,80.23621,80.22121';
var LatArray = Latitudes.split(',');
var LonArray = Longitudes.split(',');
for (var g = 0; g < LatArray.length; g++) {
marker = new OpenLayers.Marker(new OpenLayers.LonLat(LonArray[g], LatArray[g]), icon.clone());
//marker.setOpacity(0.2);
marker.events.register('mousedown', marker, function (evt) { alert(this.icon.url); OpenLayers.Event.stop(evt); });
markers.addMarker(marker);
}
//marker = new OpenLayers.Marker(new OpenLayers.LonLat(90, 10), icon.clone());
//marker.setOpacity(0.2);
//marker.events.register('mousedown', marker, function (evt) { alert(this.icon.url); OpenLayers.Event.stop(evt); });
//markers.addMarker(marker);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.zoomToMaxExtent();
halfIcon.setOpacity(0.5);
var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;
var vectors = new OpenLayers.Layer.Vector("Vector Layer",
{
renderers: renderer
});
vectors.events.on(
{
'featureselected': function (feature) {
$('counter').innerHTML = this.selectedFeatures.length;
$('myd').innerHTML = 'this.selectedFeatures.length :' + this.selectedFeatures.length + 'this.selectedFeatures[0].geometry.bounds :' + this.selectedFeatures[0].geometry.bounds;
},
'featureunselected': function (feature) {
$('counter').innerHTML = this.selectedFeatures.length;
$('myd').innerHTML = 'UNSEL this.selectedFeatures.length :' + this.selectedFeatures.length + 'this.selectedFeatures[0].geometry.bounds :' + this.selectedFeatures[0].geometry.bounds;
}
});
map.addLayers([layer, vectors]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
drawControls =
{
point: new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Point
),
line: new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Path
),
polygon: new OpenLayers.Control.DrawFeature(
vectors, OpenLayers.Handler.Polygon
),
select: new OpenLayers.Control.SelectFeature(
vectors,
{
clickout: false, toggle: false,
multiple: false, hover: false,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey", // shift key adds to selection
box: true
}
),
selecthover: new OpenLayers.Control.SelectFeature(
vectors,
{
multiple: false, hover: true,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey" // shift key adds to selection
}
)
};
for (var key in drawControls) {
map.addControl(drawControls[key]);
}
});
function init()
{
}
function toggleControl(element)
{
for (key in drawControls) {
var control = drawControls[key];
if (element.value == key && element.checked) {
control.activate();
}
else {
control.deactivate();
}
}
}
function update()
{
var clickout = document.getElementById("clickout").checked;
if (clickout != drawControls.select.clickout)
{
drawControls.select.clickout = clickout;
}
var box = document.getElementById("box").checked;
if (box != drawControls.select.box)
{
drawControls.select.box = box;
if (drawControls.select.active)
{
drawControls.select.deactivate();
drawControls.select.activate();
}
}
}
<div id="content"></div>
<h1 id="title">
Markers Layer Example</h1>
<div id="tags">
Marker, event, mousedown, popup, inco</div>
<div id="shortdesc">
Show markers layer with different markers</div>
<div id="map" class="smallmap">
</div>
<ul id="controlToggle">
<li>
<input type="radio" name="type" value="none" id="noneToggle" onclick="toggleControl(this);"
checked="checked" />
<label for="noneToggle">
navigate</label>
</li>
<li>
<input type="radio" name="type" value="point" id="pointToggle" onclick="toggleControl(this);" />
<label for="pointToggle">
draw point</label>
</li>
<li>
<input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" />
<label for="lineToggle">
draw line</label>
</li>
<li>
<input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
<label for="polygonToggle">
draw polygon</label>
</li>
<li>
<input type="radio" name="type" value="selecthover" id="selecthoverToggle" onclick="toggleControl(this);" />
<label for="selecthoverToggle">
Select features on hover</label>
</li>
<li>
<input type="radio" name="type" value="select" id="selectToggle" onclick="toggleControl(this);" />
<label for="selectToggle">
select feature (<span id="counter">0</span> features selected)</label>
<ul>
<li>
<input id="box" type="checkbox" checked="checked" name="box" onchange="update()" />
<label for="box">
select features in a box</label>
</li>
<li>
<input id="clickout" type="checkbox" name="clickout" onchange="update()" />
<label for="clickout">
click out to unselect features</label>
</li>
</ul>
</li>
</ul>
<div id="myd">
</div>
This may be helpful.
I have found complete details at below location:
https://gis.stackexchange.com/questions/115500/how-to-find-markers-in-selected-dragbox-openlayers-3
You can also check live demo here:
http://jsfiddle.net/GFarkas/fk1mqq25/1/