I have a map on my index page. I want to click on the map and place a marker on the position. The click event has a function where i want to open up a modal (jquery dialog box) and load a form from another child html page with the position now filled in the right form-field.
My problem is passing the value (the marker position) to the input field in the form. My function seems to work if i put the input field somewhere on the index page but not in the child template in the dialogbox.
I'm trying with this $('#test_input').val(lng + ',' + lat); But it only show the value for millisecond then disappears. Do you have any ideas why this isn't working? Or how to reconstruct this? Thanks!
function onMapClick(e) {
var lat = e.latlng.lat;
var lng = e.latlng.lng;
if (typeof marker != 'undefined') {
map.removeLayer(marker);
marker = L.marker([lat, lng], {icon: redMarker}).addTo(map);
}
else {
marker = L.marker([lat, lng], {icon: redMarker}).addTo(map);
}
$('#upload-modal').load('upload/ #myform');
$('#test_input').val(lng + ',' + lat); //This is what I'm trying<----------
$('#upload-modal').dialog({
height: 550,
width: 500,
modal: false,
buttons: {
Upload: function() {
var dialog = $(this),
form = $('#myform'),
data = form.serialize();
$('.off').remove();
$.ajax({
url: 'upload/',
data: data,
type: 'post',
success: function(response) {
res = $.parseJSON(response);
if (res['status'] == 'OK') {
alert('Thank you! Form has been submitted');
dialog.dialog('close');
}
else if (res['status'] == 'bad') {
delete res['status']
var errors = res;
$.each(errors, function(key, value) {
var err = $('<span></span>', {
'class': 'off',
'text': value
}),
br = $('<br></br>', {
'class': 'off',
}),
input = $('#id_'+key).parent();
br.appendTo(input);
err.appendTo(input);
err.css('color', 'red').css('font-size', '10px');
});
}
}
});
}
}
});
}
It seems #test_input is in your form so you have to wait until the other form is completely loaded, use a callback like this:
$('#upload-modal').load('upload/ #myform', function(){
$('#test_input').val(lng + ',' + lat);
});
Related
The requirement is to add a new feature from template picker but without applying it, can i show the attribute inspector than save the feature.
selectedTemplate = templatePicker.getSelected();
This selectedTemplate is then selected to put the points on the map than opens the attribute inspector by selecting it.
selectedTemplate.featureLayer.applyEdits([newGraphic], null, null);
Sample Code Block :
dojo.connect(drawToolbar, "onDrawEnd", function(geometry) {
//display the editable info window for newly created features
if (map.infoWindow.isShowing) {
map.infoWindow.hide();
}
drawToolbar.deactivate();
var fieldAttributes = layerFieldToAttributes(selectedTemplate.featureLayer.fields);
var newAttributes = dojo.mixin(fieldAttributes, selectedTemplate.template.prototype.attributes);
var newGraphic = new esri.Graphic(geometry, null, newAttributes);
var layerInfos = [{
'featureLayer': selectedTemplate.featureLayer,
'isEditable': true
}];
var attInspector = new esri.dijit.AttributeInspector({
layerInfos: layerInfos
}, dojo.create("div"));
selectedTemplate.featureLayer.applyEdits([newGraphic], null, null, function() {
var screenPoint = map.toScreen(getInfoWindowPositionPoint(newGraphic));
map.infoWindow.setContent(attInspector.domNode);
map.infoWindow.resize(325, 185);
map.infoWindow.show(screenPoint, map.getInfoWindowAnchor(screenPoint));
templatePicker.clearSelection();
});
dojo.connect(attInspector, "onAttributeChange", function(feature, fieldName, newFieldValue) {
feature.attributes[fieldName] = newFieldValue;
feature.getLayer().applyEdits(null, [feature], null);
});
dojo.connect(attInspector, "onDelete", function(feature) {
feature.getLayer().applyEdits(null, null, [feature]);
map.infoWindow.hide();
});
});
}
I would like my client first add the attribute to feature and (save & apply) it.
Any help would be appreciated.
Here is the sample project : https://www.dropbox.com/s/fh71g1k9nsa70nq/index-2.html.zip?dl=0
I dont think you can do that with the AttributeInspector, try creating a custom popup that will have options to save and delete/cancel, when saving fire the applyEdits, when clicking delete, remove, ect.
Content:
var content = "<input id='text1'></input> </br>" +
"<input id='text1'></input> </br>" + "<button id='submit'>Submit</button>" + "<button id='delete'>Delete</button>"
/*
var attInspector = new AttributeInspector({
layerInfos: layerInfos
}, dojo.create("div"));
*/
map.infoWindow.setTitle(selectedTemplate.featureLayer.name);
map.infoWindow.setContent(content);
map.infoWindow.resize(350, 240);
map.infoWindow.show(evt.geometry, map.getInfoWindowAnchor(evt.geometry));
Listener:
on(map.infoWindow, "show", function () {
on(dom.byId("submit"), "click", function () {
alert("I should be saving");
});
on(dom.byId("delete"), "click", function () {
alert("I should be deleting");
});
})
Check out this fiddler: https://jsfiddle.net/kreza/jpLj5y4h/2/
I'm currently working on a map that's meant to load multiple layers from different sources based on a config.json file.
Each layer should also display a popup on click but for some reason I only get the popup for the last loaded layer.
I'm using the ready event on the layers to make sure all the data gets loaded and iterating through them using .eachLayer method before binding the popup but still no success and can't figure out what am I missing.
Please find below my code as well a reproduction on: plnkr.co
var myMap = function(options) {
var self = this;
this.settings = $.extend({
layersConfig: 'config.json',
layerData: 'layer',
accessToken: 'pk.eyJ1IjoibWF0dGJsaXNzIiwiYSI6ImNpb3dwczBwZjAwOTh3OWtqOWZ1aG5ob3gifQ.Ot6GdtKew9u27TROm_4A6Q'
}, options);
this.map;
this.layers;
$.ajax({
url: this.settings.layersConfig,
cache: true
}).done(function(data) {
self.init(data);
});
};
myMap.prototype = {
init: function(data) {
var self = this,
settings = this.settings;
L.mapbox.accessToken = settings.accessToken;
var map = this.map = L.mapbox.map('map', 'mapbox.streets')
.setView([54.6, -2.3], 4);
var popup = new L.Popup({
minWidth: 250
});
for (var i = 0; i < data.length; i++) {
var featureLayers = this.layers = L.mapbox.featureLayer(null, {
style: {
weight: 2,
color: data[i].color,
fillColor: data[i].color,
fillOpacity: 0.4
}
}).addTo(map);
// load layers data
featureLayers.loadURL(settings.layerData + data[i].layerId + '.json')
.on('ready', function(e) {
featureLayers.eachLayer(function(layer) {
// cache layer properties
var layerProps = layer.feature.properties;
// cache feature bounds
var bounds = layer.getBounds().toBBoxString();
// bind modal
layer.bindPopup(showPopup(layer, bounds));
});
});
}
map.on('popupopen', function() {
$('.zoom-to').on('click', function() {
var array = $(this).data('zoom').split(',');
map.fitBounds([
[array[1], array[0]],
[array[3], array[2]]
])
});
});
function showPopup(popup, bounds) {
var popupData = popup.feature.properties;
var popupLabel = popupData.NAME;
var popupStructure = '<div class="leaflet-popup-label">' + popupLabel + '</div><button class="zoom-to" data-zoom="' + bounds + '">Zoom to</button></div>'
return popupStructure;
}
}
}
var map = new myMap();
.on('ready',...)
^ Has nothing to do with an AJAX call.
You need to perform actions after the ajax call is finished, that is, inside the AJAX callback.
Here:
}).done(function(data) {
/* do stuff */
});
Found the issue.
Just replace featureLayers.eachLayer with e.target.eachLayer and the popup will show as desired.
I have written following code.. which fires Add Listener event on Place_change but i want to fire that event on page load.. which is copied from google and i have made some changes.
function _initMap(latlng){
// google map
$map = $(".lwizard-step1-map");
_latlng = latlng || new google.maps.LatLng(41.3833333,2.1833333);
if (!_STEP1_LOCATION_MAP) {
_STEP1_LOCATION_MAP = new google.maps.Map($map[0],{
center: _latlng,
zoom:11,
mapTypeId:google.maps.MapTypeId.ROADMAP,
streetViewControl:false,
scrollwheel:false
});
} else {
_STEP1_LOCATION_MAP.setCenter(_latlng);
}
if (!_STEP1_LOCATION_MARKER) {
_STEP1_LOCATION_MARKER = new google.maps.Marker({
position: _latlng,
map: _STEP1_LOCATION_MAP,
draggable: true
});
google.maps.event.addListener(_STEP1_LOCATION_MARKER, "dragend", function(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
$("#lwizard-step1-location-autocomplete").val('');
STEP1_PLACE.latLng = [lat,lng];
STEP1_PLACE.address = null;
$.ajax({
url: 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+lng+'&sensor=false',
success: function(response){
if ((response) && (response.results) && (response.results.length)){
$(".lwizard-step1-chosen-address").parent().show();
var $address = $(".lwizard-step1-chosen-address");
$address.text(response.results[0].formatted_address);
$("#lwizard-step1-adjust-onmap").data("location", response.results[0].geometry.location);
STEP1_PLACE.address = nc.utils.convertGoogleAddressComponents(response.results[0].address_components);
}
}
})
});
} else {
_STEP1_LOCATION_MARKER.setPosition(_latlng);
}
}
// autocomplete
$input = $("#lwizard-step1-location-autocomplete");
_STEP1_LOCATION_GA = new google.maps.places.Autocomplete($input[0],{ types: [] });
google.maps.event.addListener(_STEP1_LOCATION_GA, 'place_changed', function () {
var place = _STEP1_LOCATION_GA.getPlace();
console.log(place)
var $where = $(".lwizard-step1-chosen-address");
var found = ((place) && (place.formatted_address) && (place.geometry) && (place.id));
if (place && found) {
$("#lwizard-step1-adjust-onmap").data("location", place.geometry.location);
STEP1_PLACE.address = nc.utils.convertGoogleAddressComponents(place.address_components);
STEP1_PLACE.latLng = [place.geometry.location.lat(),place.geometry.location.lng()];
STEP1_PLACE.location = place.geometry.location;
$where.parent().show();
$where.text(place.formatted_address);
$("#lwizard-step1-right-1").show();
$("#lwizard-step1-right-2").hide();
_initMap(place.geometry.location);
} else {
$where.parent().hide();
$("#lwizard-step1-right-1").show();
$("#lwizard-step1-right-2").hide();
_initMap();
}
});
I have one textbox named lwizard-step1-location-autocomplete which shows value from session named SessionLocation on page load.
but i also want to show the map on page load of the location specified in textbox.
But the problem is the addlistener fires only on textbox change means Place_changed event.
pls. Give some suggestions or new method for it.
You can just call change event on load and than it will fired.
$('#lwizard-step1-location-autocomplete').trigger("change");
Or with js;
document.getElementById('lwizard-step1-location-autocomplete').fireEvent("onchange");
I've create dynamic popup in my Backbone.view by clicking button:
var Section = Backbone.View.extend({
className: 'sqs-frontend-overlay-editor-widget-section',
events:{
'click .sqs--section--control__edit': 'Section_control'
},
initialize: function(){
},
render: function(){
this.$el.append(_.template(_section).apply(this.options));
return this.$el;
},
Section_control: function(){
var me = this;
require(['View/Popup/Section_control'], function(_Section_control){
var sec = new _Section_control({popup: popup, sec: me.options.section});
var popup = new Popup({content: sec.render()});
});
}
});
return Section;
in the created dynamic popup i have button with trigger:
events:{
'click .module-invert-mode': 'invert'
},
invert: function(e){
console.log('hello');
if(this.options.sec.hasClass('.module-invert')) {
console.log('yse');
}
this.options.sec.toggleClass('module-invert');
this.options.sec.trigger('invertChange');
},
and button invertChange trigger:
el.on("invertChange", function(e){
var section = el.parents('section');
var index = section.index();
var model = collection.at(index);
model.set(Helper.sectionToObj(section),{doReload: true})
});
take a look at the {doReload: true} function that i call in invertChange:
change: function(model, options){
me = this;
if( model._changing && options.doReload ) {
$.ajax({
url: 'wp-admin/admin-ajax.php',
type: 'post',
data: {
action: 'getShortcode',
shortcode: model.attributes.shortcode
},
success: function (data) {
//var section = $(data);
me.$el.find('section:eq(' + model.collection.indexOf(model) + ')').replaceWith(data);
me.add( model, model.collection );
//me.collection.add({shortcode: model.attributes.shortcode}, {at: section.index()});
}
});
}
},
the problem is when I create dynamic popup and click on the button with invertChange trigger, ajax works only once, when I click on button in popup again, ajax doesn't works ( next ajax request works only if close and create dynamic popup again). How I can call ajax without constantly closing and opening my dynamic popup?
The problem that you have code which overrides child views
me.$el.find('section:eq(' + model.collection.indexOf(model) + ')').replaceWith(data);
And this listener is not able to handle event
el.on("invertChange", function(e){
because your code
this.options.sec.trigger('invertChange');
doesn't trigger event on correct view, it has lost the reference to this view after replaceWith()
As a solution you need parse your data object and apply each changes locally to elements
something like this
$(data).find("* [attr]").each(function(i, el) {
var $el = $(el),
attr = $el.attr("attr"),
$parent = me.$el.find('section:eq(' + model.collection.indexOf(model) + ')');
if ($el.is("div, span")) {
$parent.find('[attr=' + attr + ']').html($el.html());
} else if ($el.is("img")) {
$parent.find('[attr=' + attr + ']').attr("src", $el.attr("src"));
} else if ($el.is("a")) {
$parent.find('[attr=' + attr + ']').attr("href", $el.attr("href"));
} else if (attr == "image_back_one") {
$parent.find('[attr=' + attr + ']').attr("style", $el.attr("style"));
} else {
console.log($el);
}
});
I have a custom toolbar that fires events on html button click, there is a problem with one where it's activated on init instead of after button click.. it seems to trigger the function on init.
The controls toggle correctly but it seems to be activated by default or within init.
Here is the code:
/* other Controls */
polygon: new OpenLayers.Control.Measure(
OpenLayers.Handler.Polygon, {
persist: true,
immediate: true,
handlerOptions: {
layerOptions: {
renderers: renderer,
styleMap: styleMap
}
}
}
),
choose: new OpenLayers.Control.Button({ /** **/
activateControl: false, /** Problem here **/
trigger: tochiSentaku() /** **/
})
};
var control;
for(var key in allControls) {
control = allControls[key];
control.events.on({
"measure": handleMeasurements,
"measurepartial": handleMeasurements,
"button": tochiSentaku
});
map.addControl(control);
}
function toggleControl(element){
for(key in allControls){
var control = allControls[key];
if(control.active){
control.deactivate();
}
if(element.value == key && element.click){
control.activate();
vlayer.removeAllFeatures();
var mybutton = document.getElementById('output');
var xyz = "";
mybutton.innerHTML = xyz;
}
else{
control.deactivate();
}
}
}
tochiSentaku Function
function tochiSentaku(evt){
var element = document.getElementById("attribute");
map.events.register('click', map, function(e){
vlayer.destroyFeatures(vlayer,features);
var coord = $(".olControlMousePosition").text();
$("#attribute").html('<center><img src="images/loading.gif" alt="Now Loading..." /></center>');
$.getJSON("scripts/tochi_sentaku.php",{coord:coord}, function(data){
$("#attribute").html("<button id=\"attribute_map\" onclick=\"" + data.the_geom + "\">地図</button><table id='attribute_tbl'><tr><th>項目名</th><th>値</th></tr></table>");
for(var key in data){
if(key != "the_geom"){
$("#attribute_tbl").append("<tr><td>" + key + "</td><td>" + data[key] + "</td></tr>");
}
}
$("#attribute_map").click();
});
});
}
If anyone can give me some advice would greatly appreciate it.
You haven't provided the definition of tochiSentaku in your code snippet.
But my initial guess would be, to change the code to
choose: new OpenLayers.Control.Button({
activateControl: false,
trigger: tochiSentaku
})
Figured it out. Instead of using
trigger:tochiSentaku
I used
activate:tochiSentaku
#simplyharsh Thanks for your suggestion