Код на идеал не претендует, но это работает
<?php
namespace application\widgets;
use webnula2\widgets\booster\TbActiveForm;
use webnula2\widgets\booster\TbBaseInputWidget;
/**
* Class GoogleMap
*
* @package application\widgets
*/
class GoogleMap extends TbBaseInputWidget
{
/**
* @var $options
*/
public $options;
/**
* @var $cs
*/
private $cs;
/**
*
*/
public function init()
{
parent::init();
$this->cs = \Yii::app()->getClientScript();
}
public function run()
{
$options = array();
if (empty($this->model[$this->attribute])) {
if (empty($this->options['mapCenter'])) {
$options['mapCenter'] = array('-8.36293738590362', '115.14429179101558');
}
if (empty($this->options['point'])) {
$options['point'] = $options['mapCenter'];
}
if (empty($this->options['mapZoom'])) {
$options['mapZoom'] = 10;
}
if (empty($this->options['mapType'])) {
$options['mapType'] = 'roadmap';
}
} else {
$options = $this->model[$this->attribute];
}
$id = \CHtml::activeId($this->model, $this->attribute);
$mapId = "GMapsID-" . $this->getId();
$searchControlId = 'pac-input-' . $this->getId();
$js = <<<JS
function getMarkerPosition(marker) {
return [marker.getPosition().lat(), marker.getPosition().lng()];
}
function initMap () {
var map;
var options = {
mapCenter: [{$options['mapCenter'][0]}, {$options['mapCenter'][1]}],
point: [{$options['point'][0]}, {$options['point'][1]}],
mapZoom: {$options['mapZoom']},
mapType: "{$options['mapType']}"
};
var latLng = new google.maps.LatLng(options.point[0], options.point[1]);
map = new google.maps.Map(document.getElementById('{$mapId}'), {
center: latLng,
zoom: options.mapZoom,
mapTypeId: options.mapType
});
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: true
});
var input = document.getElementById('{$searchControlId}');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
map.addListener('bounds_changed', function(){
searchBox.setBounds(map.getBounds());
});
var markers = [];
markers.push(marker);
searchBox.addListener('places_changed', function(){
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
markers.forEach(function(marker){
marker.setMap(null);
});
markers = [];
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place){
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
markers.push(new google.maps.Marker({
map: map,
//icon: icon,
title: place.name,
position: place.geometry.location,
draggable: true
}));
if (place.geometry.viewport){
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
googleMapSave();
});
/*google.maps.event.addListener(markers[0], 'drag', function(){
googleMapSave();
});
map.addListener('zoom_changed', function(){
googleMapSave();
});
map.addListener('maptypeid_changed', function(){
googleMapSave();
});*/
map.addListener('mouseout', function(){
googleMapSave();
});
function googleMapSave(){
options = {
mapCenter: getMarkerPosition(markers[0]),
point: getMarkerPosition(markers[0]),
mapZoom: map.getZoom(),
mapType: map.getMapTypeId()
};
$('#{$id}').val(JSON.stringify(options));
}
googleMapSave();
}
JS;
$css = <<<CSS
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#{$searchControlId} {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#{$searchControlId}:focus {
border-color: #4d90fe;
}
CSS;
$this->cs->registerScriptFile("https://maps.googleapis.com/maps/api/js?key=AIzaSyDTOzQmfoHuYz5coANmmLtSezC-yMxnv8A&libraries=places&callback=initMap", \CClientScript::POS_END);
$this->cs->registerScript($this->getId(), $js, \CClientScript::POS_HEAD);
$this->cs->registerCss($this->getId(), $css);
echo \CHtml::openTag('div', array('class' => 'map-container'));
echo \CHtml::openTag('input', array('id' => $searchControlId, 'class' => 'controls search-control', 'placeholder' => 'Search Box'));
echo \CHtml::openTag('div', array('style' => 'width: 100%;height:400px', 'id' => $mapId));
echo \CHtml::closeTag('div');
echo \CHtml::closeTag('div');
$this->model[$this->attribute] = \CJSON::encode($this->model[$this->attribute]);
echo \CHtml::activeHiddenField($this->model, $this->attribute);
}
}