Show maps with multiple markers in a reveal modal(foundation) - modal-dialog

I've create a map with multiple markes.
Now I'd like to show it in a reveal modal (foundation 6), can someone help me?
I would like to display the google map in a modal reveal, to be visible only when I click on "Open google map".
It seems that what I did does not work properly and I do not understand why.
Look here: http://jsfiddle.net/x6nqL3po/1388/
<div id="map" class="reveal-modal" data-reveal aria-labelledby="modalTitle" aria-hidden="true" role="dialog">
<div id="map"></div>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
<div>Click Me For A Modal</div>
<script>
//Google Maps
jQuery(function() {
if ($("#map").length) {
initMap();
}
});
//initMap
function initMap() {
var locations = [
[
"Locatie title 1",
52.147173,
4.470745,
"http://cdn.leafletjs.com/leaflet-0.6.4/images/marker-icon.png",
"city 1",
"Address 1",
"+38/(071)/123/45/67"
],
[
"Locatie title 2",
52.166245,
4.51764,
"https://maps.google.com/mapfiles/ms/micons/blue.png",
"city 2",
"",
"+38/(071)/123/45/67"
],
[
"Locatie title 4",
52.126607,
4.619146,
"https://maps.google.com/mapfiles/ms/micons/blue.png",
"",
"Address 4",
"+38 (071) 123-45-67"
],
];
];
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 9,
center: new google.maps.LatLng(52.159393,4.673784),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infoWindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
var lat = locations[i][1];
var lng = locations[i][2];
var pin = locations[i][3];
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
animation: google.maps.Animation.DROP,
icon: pin,
map: map
});
google.maps.event.addListener(marker, "click", (function(marker, i) {
var title = (locations[i][0] !== undefined) ? locations[i][0] : '';
var city = (locations[i][4] !== undefined) ? locations[i][4] : '';
var address = (locations[i][5] !== undefined) ? locations[i][5] : '';
var html = ( (title !== '') ? "<h5>" + title + "</h5>" : title ) + ( (city !== '') ? "<h6>" + city + "</h6>" : city ) + ( (address !== '') ? "<p>" + address + "</p>" : address ) ;
return function() {
infoWindow.setOptions({
content:html
});
infoWindow.open(map, marker);
};
//auto center map
map.setCenter(marker.getPosition());
})(marker, i)
);
}
}
function load() {
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(30.0599153,31.2620199,13),
zoom: 13,
mapTypeId: 'roadmap'
});
}
</script>

in first place you must change the id of modal container, this should be the same that data-reveal-id on the link (now one is "MyModal" and the other is "map").
Open google map
<div id="myModal" class="reveal-modal">
In your jsfiddle file it seems not loading foundation.css, foundation.js, foundation.reveal.js and jquery, these are necessary as indicated on Reveal Modal Foundation docs (Using the Javascript section)
You can check a updated working version here: http://jsfiddle.net/x6nqL3po/1488/

Related

How do I pin a location on laravel backpack

I want to pin a location when user enter his address information in laravel backpack?
this is Address field in controller
'name' => 'address-input',
'type' => 'customGoogleMaps',
'label' => "Google Maps",
'hint' => 'Help text',
'attributes' => [
'class' => 'form-control map-input',
],
'view_namespace' => 'custom-google-maps-field-for-backpack::fields',
This is customGoogleMaps field (customGoogleMaps.blade.php)
<div #include('crud::inc.field_wrapper_attributes')>
<label>{!! $field['label'] !!}</label>
<input type="text" id="{{ $field['name'] }}" name="{{ $field['name'] }}"
value="{{ old($field['name']) ? old($field['name']) : (isset($field['value']) ? $field['value'] : (isset($field['default']) ? $field['default'] : '' )) }}"
#include('crud::inc.field_attributes')>
<input type="hidden" name="address_latitude" id="address-latitude" value="0" />
<input type="hidden" name="address_longitude" id="address-longitude" value="0" />
<div id="address-map-container" style="width:100%;height:400px; ">
<div style="width: 100%; height: 100%" id="address-map"></div>
</div>
{{-- HINT --}}
#if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
#endif
</div>
#if ($crud->checkIfFieldIsFirstOfItsType($field, $fields))
{{-- FIELD EXTRA CSS --}}
{{-- push things in the after_styles section --}}
#push('crud_fields_styles')
<!-- no styles -->
#endpush
{{-- FIELD EXTRA JS --}}
{{-- push things in the after_scripts section --}}
#push('crud_fields_scripts')
<!-- no scripts -->
<script
src="https://maps.googleapis.com/maps/api/js?key={{ env('GOOGLE_MAPS_API_KEY') }}&libraries=places&callback=initialize" async defer></script>
<script>
function initialize() {
$('form').on('keyup keypress', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode === 13) {
e.preventDefault();
return false;
}
});
const locationInputs = document.getElementsByClassName("map-input");
const autocompletes = [];
const geocoder = new google.maps.Geocoder;
for (let i = 0; i < locationInputs.length; i++) {
const input = locationInputs[i];
const fieldKey = input.id.replace("-input", "");
const isEdit = document.getElementById(fieldKey + "-latitude").value != '' && document.getElementById(fieldKey + "-longitude").value != '';
const latitude = parseFloat(document.getElementById(fieldKey + "-latitude").value) || -33.8688;
const longitude = parseFloat(document.getElementById(fieldKey + "-longitude").value) || 151.2195;
const map = new google.maps.Map(document.getElementById(fieldKey + '-map'), {
center: {lat: latitude, lng: longitude},
zoom: 13
});
const marker = new google.maps.Marker({
map: map,
position: {lat: latitude, lng: longitude},
});
marker.setVisible(isEdit);
const autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.key = fieldKey;
autocompletes.push({input: input, map: map, marker: marker, autocomplete: autocomplete});
}
for (let i = 0; i < autocompletes.length; i++) {
const input = autocompletes[i].input;
const autocomplete = autocompletes[i].autocomplete;
const map = autocompletes[i].map;
const marker = autocompletes[i].marker;
google.maps.event.addListener(autocomplete, 'place_changed', function () {
marker.setVisible(false);
const place = autocomplete.getPlace();
geocoder.geocode({'placeId': place.place_id}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
const lat = results[0].geometry.location.lat();
const lng = results[0].geometry.location.lng();
setLocationCoordinates(autocomplete.key, lat, lng);
}
});
if (!place.geometry) {
window.alert("No details available for input: '" + place.name + "'");
input.value = "";
return;
}
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
marker.setPosition(place.geometry.location);
marker.setVisible(true);
});
}
}
function setLocationCoordinates(key, lat, lng) {
const latitudeField = document.getElementById(key + "-" + "latitude");
const longitudeField = document.getElementById(key + "-" + "longitude");
latitudeField.value = lat;
longitudeField.value = lng;
}
</script>
#endpush
#endif
It display the following Error:
InvalidArgumentException View [inc.field_wrapper_attributes] not found. (View:
C:\xampp\htdocs\CRM\vendor\abr4xas\gmaps-input-backpack\src\resources\views\fields\customGoogleMaps.blade.php)

Google Markers with dynamic data for Ionic Modal

I am new to hybrid mobile app creation. And my use case is very simple. I have a single ionic modal using template html.
What I want is populating the same ionic template with different values based on some records data. Basically it is a google map and on click on any of the markers, the same template should open with different values based on the marker.
My controller code -
.controller('MyLocationCtrl', function(
$scope,
$stateParams,
force,
$cordovaGeolocation,
$ionicModal,
GoogleMapService,
ForceService,
$q
) {
console.log('this is in my location page');
var currentPosition = GoogleMapService.getCurrentLocation();
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
var allContacts = ForceService.getAllContactsWithGeo();
var promises = [];
promises.push(currentPosition);
promises.push(allContacts);
promises.push(restaurantModal);
var allMarkers = [];
var allContactDetails = [];
currentPosition.then(
function(position) {
console.log('position data -->', position);
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
allContacts.then(
function(contacts) {
console.log('contacts final -->', contacts);
for (var i=0; i<contacts.records.length; i++) {
var contact = contacts.records[i];
console.log('single contact -->', contact.MailingLatitude, contact.MailingLongitude);
var contactlatLng = new google.maps.LatLng(contact.MailingLatitude, contact.MailingLongitude);
var contactInfo = {};
//contactInfo.marker = {};
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: contactlatLng
});
contactInfo.marker = marker;
contactInfo.recordDetails = contact;
allMarkers.push(marker);
allContactDetails.push(contactInfo);
// Set boundary for markers in map
bounds.extend(contactlatLng);
}
// Fit map based on markers
$scope.map.fitBounds(bounds);
}
);
// google.maps.event.addListenerOnce($scope.map, 'idle', function(){
// });
},
function(error) {
console.log("Could not get location" + error);
}
);
// Add listener for marker pop up once all promises resolved
$q.all(promises).then(
function(values) {
console.log('first -->', values[0]);
console.log('second -->', values[1]);
console.log('third -->', values[2]);
var detailModal = values[2];
$scope.modal = detailModal;
for (var i=0; i<allContactDetails.length; i++) {
allContactDetails[i].marker.addListener('click', function() {
console.log('helllos from marker');
console.log('all contactInfo -->', allContactDetails[i].recordDetails.Name);
$scope.contactName = allContactDetails[i].recordDetails.Name;
detailModal.show();
});
}
}
);
})
Front end template code -
<script id="templates/bottom-sheet.html" type="text/ng-template">
<ion-bottom-sheet-view>
<ion-header-bar align-title="left">
<h1 class="title">New Particle</h1>
<button class="button button-icon icon ion-android-close" ng-click="modal.hide()"></button>
{{contactName}}
</ion-header-bar>
</ion-bottom-sheet-view>
</script>
Now the modal opens properly when i click on the google marker, but I am not sure how to pass dynamic data to the pop modal.
Since you are doing this :
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
Your modal can access to the scope of your controller.
So if you declare any variable in your controller it will be accessible through the modal.

Bing cluster need to display tooltip & popup

Need to display marker bunch(cluster) title on bing map.
And I want to display tooltip#hover and popup#click with cluster is there any option to display with map.
I have tried usign following code (but there is no tooltip and popup on click):
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Your Bing Maps Key'
});
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), null);
var layer = new Microsoft.Maps.Layer();
layer.add(pushpin);
map.layers.insert(layer);
thanks
You can use the infobox class to do this. As luck would have it I was just putting together sample to do this. Here you go:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type='text/javascript'
src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
async defer></script>
<script type='text/javascript'>
var map, infobox, tooltip;
var tooltipTemplate = '<div style="background-color:white;height:20px;width:150px;padding:5px;text-align:center"><b>{title}</b></div>';
function GetMap() {
map = new Microsoft.Maps.Map('#myMap', {
credentials: Your Bing Maps Key'
});
//Create a second infobox to use as a tooltip when hovering.
tooltip = new Microsoft.Maps.Infobox(map.getCenter(), {
visible: false,
showPointer: false,
showCloseButton: false,
offset: new Microsoft.Maps.Point(-75, 10)
});
tooltip.setMap(map);
//Create an infobox at the center of the map but don't show it.
infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
visible: false
});
//Assign the infobox to a map instance.
infobox.setMap(map);
//Create random locations in the map bounds.
var randomLocations = Microsoft.Maps.TestDataGenerator.getLocations(5, map.getBounds());
for (var i = 0; i < randomLocations.length; i++) {
var pin = new Microsoft.Maps.Pushpin(randomLocations[i]);
//Store some metadata with the pushpin.
pin.metadata = {
title: 'Pin ' + i,
description: 'Discription for pin' + i
};
//Add a click event handler to the pushpin.
Microsoft.Maps.Events.addHandler(pin, 'click', pushpinClicked);
Microsoft.Maps.Events.addHandler(pin, 'mouseover', pushpinHovered);
Microsoft.Maps.Events.addHandler(pin, 'mouseout', closeTooltip);
//Add pushpin to the map.
map.entities.push(pin);
}
}
function pushpinClicked(e) {
//Hide the tooltip
closeTooltip();
//Make sure the infobox has metadata to display.
if (e.target.metadata) {
//Set the infobox options with the metadata of the pushpin.
infobox.setOptions({
location: e.target.getLocation(),
title: e.target.metadata.title,
description: e.target.metadata.description,
visible: true
});
}
}
function pushpinHovered(e) {
//Hide the infobox
infobox.setOptions({ visible: false });
//Make sure the infobox has metadata to display.
if (e.target.metadata) {
//Set the infobox options with the metadata of the pushpin.
tooltip.setOptions({
location: e.target.getLocation(),
htmlContent: tooltipTemplate.replace('{title}', e.target.metadata.title),
visible: true
});
}
}
function closeTooltip() {
tooltip.setOptions({
htmlContent: ' ',
visible: false
});
}
</script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>

Extjs 4.0 MVC Add components to a form based on Store

I am ashamed to say I have spent most of today on this. I am trying to build a form based on the contents of an data store. I am using Ext.js and the MVC architecture. Here's what I have:
var myitems = Ext.create('Ext.data.Store', {
fields: ['name', 'prompt', 'type'],
data :
[
{"name":"name", "prompt":"Your name" , "type":"textfield"},
{"name":"addr", "prompt":"Your street address", "type":"textfield"},
{"name":"city", "prompt":"Your city" , "type":"textfield"}
]
});
function genwidget(name, prompt, type)
{
console.log("In genwidget with name=" + name + ", prompt=" + prompt + ", type=" + type + ".");
var widget = null;
if (type == "textfield")
{
// widget = Ext.create('Ext.form.field.Text',
widget = Ext.create('Ext.form.TextField',
{
xtype : 'textfield',
name : name,
fieldLabel: prompt,
labelWidth: 150,
width : 400, // includes labelWidth
allowBlank: false
});
}
else
{
// will code others later
console.log("Unrecongized type [" + type + '] in function mywidget');
}
return widget;
};
function genItems(myitems)
{
console.log("Begin genItems.");
var items = new Ext.util.MixedCollection();
var howMany = myitems.count();
console.log("There are " + howMany + " items.");
for (var i = 0; i < myitems.count(); i++)
{
var name = myitems.getAt(i).get('name');
var prompt = myitems.getAt(i).get('prompt');
var type = myitems.getAt(i).get('type');
var widget = genwidget(name, prompt, type) ;
items.add(widget);
console.log("items.toString(): " + items.toString());
}
return items;
};
Ext.define('MyApp.view.dynamicform.Form' ,{
extend: 'Ext.form.Panel',
alias : 'widget.dynamicformform',
// no store
title: 'Dynamic Form',
id: 'dynamicform.Form',
bodyPadding: 5,
autoScroll: true,
layout: 'auto',
defaults:
{
anchor: '100%'
},
dockedItems: [ ],
items: genItems(myitems),
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
console.log('Reset not coded yet');
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
form.submit({
success: function(form, action)
{
console.log('Success not coded yet');
}
});
}
}
} // end submit
], // end buttons
initComponent: function()
{
console.log("--> in dynamicform init");
this.callParent(arguments);
console.log("--> leaving dynamicform init");
}
}); // Ext.define
The error I am getting (I've had many throughout the day) is "my.items.push is not a function".
Thanks in advance for any help you can offer!
items is expected to be an array not MixedCollection. It is changed to MixedCollection later on if I remember good. So to fix your issue change:
var items = new Ext.util.MixedCollection();
// ...
items.add(widget);
to
var items = [];
// ...
items.push(widget);
Consider as well defining items of form as an empty array and then in initComponent make use of Ext.apply:
var me = this,
items = genItems(myitems);
Ext.apply(me, {
items:items
});

Is it possible to change the editoptions value of jqGrid's edittype:"select"?

I am using jqGrid 3.8.1. I want to change the pull-down values of a combobox based on the selected value of another combobox. That's why I am searching on how to change the editoptions:value of an edittype:"select".
Here's the sample jqGrid code:
<%# page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%>
<script type="text/javascript" src="<c:url value="/js/jquery/grid.locale-ja.js" />" charset="UTF-8"></script>
<link type="text/css" rel="stylesheet" href="<c:url value="/css/jquery/ui.jqgrid.css" />"/>
<script src="<c:url value="/js/jquery/jquery.jqGrid.min.js" />" type="text/javascript"></script>
<table id="rowed5"></table>
<script type="text/javascript" charset="utf-8">
var lastsel2;
$("#rowed5").jqGrid({
datatype: "local",
height: 250,
colNames:['ID Number','Name', 'Stock', 'Ship via','Notes'],
colModel:[
{name:'id',index:'id', width:90, sorttype:"int", editable: true},
{name:'name',index:'name', width:150,editable: true,editoptions:{size:"20",maxlength:"30"}},
{name:'stock',index:'stock', width:60, editable: true,edittype:"checkbox",editoptions: {value:"Yes:No"}},
{name:'ship',index:'ship', width:90, editable: true,edittype:"select",editoptions:{value:"FE:FedEx;IN:InTime;TN:TNT;AR:ARAMEX;AR1:ARAMEX123456789"}},
{name:'note',index:'note', width:200, sortable:false,editable: true,edittype:"textarea", editoptions:{rows:"2",cols:"10"}}
],
caption: "Input Types",
resizeStop: function (newwidth, index) {
var selectedRowId = $("#rowed5").getGridParam('selrow');
if(selectedRowId) {
//resize combobox proportionate to column size
var selectElement = $('[id="' + selectedRowId + '_ship"][role="select"]');
if(selectElement.length > 0){
$(selectElement).width(newwidth);
}
}
}
,
onSelectRow: function(id){
if(id && id!==lastsel2){
//$(this).saveRow(lastsel2, true);
$(this).restoreRow(lastsel2);
$(this).editRow(id,true);
lastsel2=id;
$(this).scroll();
//resize combobox proportionate to column size
var rowSelectElements = $('[id^="' + id + '_"][role="select"]');
if(rowSelectElements.length > 0) {
$(rowSelectElements).each(function(index, element){
var name = $(element).attr('name');
var columnElement = $('#rowed5_' + name);
if(columnElement.length > 0) {
var columnWidth = $(columnElement).width();
$(element).width(columnWidth);
}
});
}
}
}
});
var mydata2 = [
{id:"12345",name:"Desktop Computer",note:"note",stock:"Yes",ship:"FedEx"},
{id:"23456",name:"Laptop",note:"Long text ",stock:"Yes",ship:"InTime"},
{id:"34567",name:"LCD Monitor",note:"note3",stock:"Yes",ship:"TNT"},
{id:"45678",name:"Speakers",note:"note",stock:"No",ship:"ARAMEX123456789"},
{id:"56789",name:"Laser Printer",note:"note2",stock:"Yes",ship:"FedEx"},
{id:"67890",name:"Play Station",note:"note3",stock:"No", ship:"FedEx"},
{id:"76543",name:"Mobile Telephone",note:"note",stock:"Yes",ship:"ARAMEX"},
{id:"87654",name:"Server",note:"note2",stock:"Yes",ship:"TNT"},
{id:"98765",name:"Matrix Printer",note:"note3",stock:"No", ship:"FedEx"}
];
for(var i=0;i < mydata2.length;i++) {
$("#rowed5").jqGrid('addRowData',mydata2[i].id,mydata2[i]);
}
</script>
Scenario:
All ship will be displayed as initial load.
If the stock column changes to Yes, ship will display only FedEx, TNT.
If the stock column changes to No, ship will display only InTime, ARAMEX, ARAMEX123456789.
How can I change the options?
I solved it by trial and error. Want to share it, please refer to the below snippet. The changes are on onSelectRow function.
onSelectRow: function(id){
if(id && id!==lastsel2){
//$(this).saveRow(lastsel2, true);
$(this).restoreRow(lastsel2);
// get the selected stock column value before the editRow
var stockValue = $("#rowed5").jqGrid('getCell', id, 'stock');
if( stockValue == 'Yes') {
$("#rowed5").jqGrid('setColProp', 'ship', { editoptions: { value: 'FE:FedEx;TN:TNT'} });
} else if( stockValue == 'No') {
$("#rowed5").jqGrid('setColProp', 'ship', { editoptions: { value: 'IN:InTime;AR:ARAMEX;AR1:ARAMEX123456789'} });
}
$(this).editRow(id,true);
lastsel2=id;
$(this).scroll();
//resize combobox proportionate to column size
var rowSelectElements = $('[id^="' + id + '_"][role="select"]');
if(rowSelectElements.length > 0) {
$(rowSelectElements).each(function(index, element){
var name = $(element).attr('name');
var columnElement = $('#rowed5_' + name);
if(columnElement.length > 0) {
var columnWidth = $(columnElement).width();
$(element).width(columnWidth);
}
});
}
}
}