So i've been struggling for a week to make this happen!!!!
In short, my structure is as follows :
Address = new SimpleSchema({
location: {
type: Object
},
fullAddress: {
type: String
},
country: {
type: String
},
governorate: {
type: String
},
city: {
type: String
},
street: {
type: String
},
building: {
type: Number
}
});
Branch = new SimpleSchema({
address: {
type: Address
},
....
});
Companies = new Mongo.Collection('companies');
CompanySchema = new SimpleSchema({
branch: {
type: [Branch],
minCount: 1
},
....
});
Companies.attachSchema(CompanySchema);
As you can see, I have an array of branches, with all branch has an address & location.
I want to be able to show a map for each [Branch]/Address when calling autoform like:
{{> quickForm collection="Companies" type="insert" id="company_form"}}
Then, have some map click listener to place a marker, and then reverse geoDecode location to populate the address fields
I have tried following yogiben:autoform-map, but the package is incomplete (has MyLocation button issues zoom exceptions, and cannot show multiple maps per page) thus, cannot be used in production.
I am disparate...Please help!
So, I created my own solution, and I'll share it to benefit any one having the same issue.
I modified yogiben/meteor-autoform-map and added a pull request adding geoCoding feature along with a lot of other stuff.
The following is my current autoform configurations & handling:-
Schema
Location = new SimpleSchema({
location: {
type: Object,
autoform:{
type: 'map',
label: false,
afFieldInput: {
mapType: 'terrain',
defaultLat: 30.0444196,
defaultLng: 31.23571160000006,
geolocation: true,
autolocate: true,
searchBox: true,
language: function(){ return getUserLanguage(); },
direction: function(){ return (getUserLanguage() == 'ar')? 'rtl' : 'ltr'; },
zoom: 16,
key: Meteor.settings.public.google_maps_key,
googleMap: {
mapTypeControl: false
},
geoCoding: true,
geoCodingCallBack: 'reverseGeoCode',
animateMarker: true
}
}
},
placeId: {
type: String,
autoform: {
type: 'hidden'
},
autoValue: function(){
return '';
}
},
createdAt: {
type: Date,
autoValue: function(){
return new Date();
},
autoform: {
type: 'hidden'
}
}
});
Address = new SimpleSchema({
location: {
type: Location,
label: function(){
return (Session.get('lang') == 'ar')? 'الموقع على الخريطة' : 'Map Location';
}
},
country: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'الدولة' : 'Country';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'الدولة' : 'Country';
}
},
type: 'hidden'
}
},
governorate: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'المحافطة' : 'Governorate';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'المحافظة' : 'Governorate';
}
}
}
},
city: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'المدينة' : 'City';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'المدينة' : 'City';
}
}
}
},
district: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'الحي' : 'District';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'الحي' : 'District';
}
}
}
},
street: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'الشارع' : 'Street';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'اسم \ رقم الشارع' : 'Street Name / Number';
}
}
}
},
building: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'رقم المبنى' : 'Building Number';
},
regEx: /[\d+\-]/,
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'رقم المبنى' : 'Building Number';
}
},
}
},
createdAt: {
type: Date,
autoValue: function(){
return new Date();
},
autoform: {
type: 'hidden'
}
}
});
Branch = new SimpleSchema({
name: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'اسم الفرع' : 'Branch Name';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'اسم الفرع' : 'Branch Name';
}
}
}
},
address: {
type: Address,
label: function(){
return (Session.get('lang') == 'ar')? 'العنوان' : 'Address';
},
minCount: 1,
optional: false
},
createdAt: {
type: Date,
autoValue: function(){
return new Date();
},
autoform: {
type: 'hidden'
}
}
});
CompaniesSchema = new SimpleSchema({
name: {
type: String,
label: function(){
return (Session.get('lang') == 'ar')? 'اسم الشركة' : 'Company Name';
},
autoform: {
afFieldInput: {
placeholder: function(){
return (Session.get('lang') == 'ar')? 'اسم الشركة' : 'Company Name';
}
}
}
},
branches: {
type: [Branch],
label: function(){
return (Session.get('lang') == 'ar')? 'الفرع' : 'Branch';
}
},
createdAt: {
type: Date,
autoValue: function(){
return new Date();
},
autoform: {
type: 'hidden'
}
}
});
client/main.js
Meteor.startup(() => {
// ================================================================ //
// Functions that need to be global perior to Packages loading //
// ================================================================ //
// Get Initial/Current user language
getUserLanguage = function () {
return Session.get('lang') || Meteor.settings.public.defaultLang;
};
// Reverse Geocode location
// @param t => Template Instance - object
// @param geocoder => google.map.geocoder - object
// @param location => google.maps.LatLng - object
reverseGeoCode = function(t, geocoder, location){
var latlng = {lat: location.lat(), lng: location.lng()};
var geoCodingOpt = {
'location' : latlng,
'language' : Session.get('lang'),
'region' : 'eg'
};
geocoder.geocode(geoCodingOpt, function(results, status){
if(status === 'OK'){
if(results.length !== 0){
var address = results[0];
var cmp = address.address_components;
var pfx = t.data.name.replace(/.location/g,'');
var sel = '[name="' + pfx + '.' + 'xx' + '"]';
var selObj = {
placeId : sel.replace('xx', 'location.placeId'),
country : sel.replace('xx', 'country'),
governorate : sel.replace('xx', 'governorate'),
city : sel.replace('xx', 'city'),
district : sel.replace('xx', 'district'),
street : sel.replace('xx', 'street'),
building : sel.replace('xx', 'building')
};
// Address Container DOM element
$addressElm = $(t.firstNode.closest('.autoform-array-item'));
// Place ID
$addressElm.find(selObj.placeId).val(address.place_id);
// Country
$addressElm.find(selObj.country).val(cmp[5].long_name);
// Governorate
$addressElm.find(selObj.governorate).val(cmp[4].long_name);
// City
$addressElm.find(selObj.city).val(cmp[3].long_name);
// District
$addressElm.find(selObj.district).val(cmp[2].long_name);
// Street
$addressElm.find(selObj.street).val(cmp[1].long_name);
// Building
$addressElm.find(selObj.building).val(cmp[0].long_name);
// Clear DOM refference for Garbage Collection
$addressElm.prevObject = null;
$addressElm = null;
}
}
});
}
});
Hope that helps anyone.
Feel free to inquire any elaborations