Создание виджетов в Yii2

Мне нравится Yii Framework тем, что это полностью обьектно-ориентированный инструмент для разработки веб-сайтов.

Недавно я искал виджет для работы с Google Place API, который бы мог предугадывать введенные клиентом даные. Картинка виджета показана вначале статьи.

Для создания виджетов в Yii2 не нужно знать многого и если вы любитель JavaScript и прочих фишек для розработки UI, тогда это статья для вас. Для создания виджета нужно зделать следующие шаги.

  1. Создадим папку для нашего виджета. Я назвал ее google. 

  1. Создадим в папке для виджета файл GoogleAsset.php и папку assets,  в которой будут лежать css и js файлы. Если вы не знаете, что такое Assets в Yii, то это класс для работы с стилями и JavaScript, а именно для того, что бы подключать эти файлы к вашим страницам. Содержимое файла GoogleAsset.php будет следующее.
namespace frontend\widgets\google;
use yii\web\AssetBundle;
class GoogleAsset extends AssetBundle
{
	public $sourcePath = '@frontend/widgets/google/assets';

	public $css = [
		'css/google.maps.css'
	];
	
	public $js = [
    	'https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=places',
	];

	public $depends = [
		'yii\web\YiiAsset',
		'yii\bootstrap\BootstrapAsset',
	];
}

Наш класс унаследован от класса AssetBungle имеет следующие атрибуты: $sourcePath - это путь к папке в которой лежат ваши файлы css и js; $css - список css файлов; $js - массив JavaScript файлов; $depends - ассеты от которых зависит даный.

  1. Создайте файл виджета. Я назвал его GooglePlaceAutoload.php. Он имеет следующее содержимое:
namespace frontend\widgets\google;
use frontend\widgets\google\GoogleAsset;
use yii\helpers\Html;
use yii\web\View;
use Yii;
/**
 * Description of Language
 *
 * @author aleksey
 */
class GooglePlaceAutoload extends \yii\bootstrap\Widget {
	public $model;
	public $attribute = 'google-map-input';
	public $location = [
		'lat' => '50.4501',
		'lng' => '30.5234',
	];

	public function init() {
		parent::init();
		$view = Yii::$app->getView();
		$this->registerAssets();
		$view->registerJs($this->getJs());
	}

	public function run() {
		$content = Html::label('Google maps location');		
		$text = isset($this->model) ? $this->model->{$this->attribute} : '';
		$content .= Html::input('text', $this->attribute, htmlspecialchars_decode($text),['id' => 'pac-input', 'class'=>'controls', 'placeholder' => "Enter a location"]);
		$content .= Html::tag('div', null, ['id'=>'map-canvas']);
		$output = Html::tag('div', $content,['id' => 'google_maps_div', 'style' => 'margin-bottom: 10px;']);
		return $output;
	}
	
	/**
	 * Registers the needed assets
	 */
	public function registerAssets()
	{
		$view = $this->getView();
		GoogleAsset::register($view);
	}
	
	private function getJs() {
             //Ваш js код должен быть здесь. 
             //Это ваше домашнее задание.))
	}
}

Класс GooglePlaceAutoload расширяет класс Widget и обязательно должен иметь функцию run(), которая должна возвращать текст или html-текст виджета, в моем случае я создаю html-контейнер для javasript гугла. Функция init() вызывается перед тем, как будет создан сам виджет и в ньом мы можем зарегестрировать наши ассеты через текущую вьюху(это обьект вьюхи из текущего layout). Функция getJs() возвращает js, собственно, для создания нашего виджета (этот javasrcipt я взял из примеров по API, не очень хотелось разбиратся в самом API)).  Атрибуты используются для настройки виджета. Я использовал переменную location для инициализации начального положения, которое будет отображатся на карте. Вам же флаг в руки и включите фантазию)).

  1. Последним шагом будет само использование нашего виджета, которое будет выгледеть примерно так:
use frontend\widgets\google\GooglePlaceAutoload;
echo GooglePlaceAutoload::widget(['location'=>['lat'=>50, 'lng'=>50]]); 

Вот и все! Виджет готов. Спасибо за внимание.

Тема: 
LikeMe: