Skip to content

Commit b4a1247

Browse files
author
Chepurnoy
committed
add editable widget
1 parent 4eab9db commit b4a1247

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

Editable.php

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
3+
namespace yii2mod\editable;
4+
5+
use kartik\helpers\Html;
6+
use yii\base\InvalidConfigException;
7+
use yii\db\ActiveRecordInterface;
8+
use yii\helpers\ArrayHelper;
9+
use yii\helpers\Json;
10+
use yii\helpers\Url;
11+
use yii\web\JsExpression;
12+
use yii\widgets\InputWidget;
13+
use yii2mod\editable\bundles\EditableAddressAsset;
14+
use yii2mod\editable\bundles\EditableBootstrapAsset;
15+
use yii2mod\editable\bundles\EditableComboDateAsset;
16+
use yii2mod\editable\bundles\EditableDatePickerAsset;
17+
use yii2mod\editable\bundles\EditableDateTimePickerAsset;
18+
19+
/**
20+
* Class Editable
21+
* @package yii2mod\editable
22+
*/
23+
class Editable extends InputWidget
24+
{
25+
/**
26+
* @var string the type of input. Type of input.
27+
*/
28+
public $type = 'text';
29+
30+
/**
31+
* @var string the Mode of editable, can be popup or inline.
32+
*/
33+
public $mode = 'inline';
34+
35+
/**
36+
* @var string|array Url for submit, e.g. '/post'.
37+
*/
38+
public $url;
39+
40+
/**
41+
* @var array the options for the X-editable.js plugin.
42+
*/
43+
public $pluginOptions = [];
44+
45+
/**
46+
* @var array the event handlers for the X-editable.js plugin.
47+
*/
48+
public $clientEvents = [];
49+
50+
51+
/**
52+
* Initializes the widget.
53+
*/
54+
public function init()
55+
{
56+
if ($this->url === null) {
57+
throw new InvalidConfigException("You must setup the 'Url' property.");
58+
}
59+
if (!isset($this->options['id'])) {
60+
$this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId();
61+
}
62+
63+
parent::init();
64+
}
65+
66+
/**
67+
* Executes the widget.
68+
*/
69+
public function run()
70+
{
71+
$linkText = $this->getLinkText();
72+
echo Html::a($linkText, null, $this->options);
73+
$this->registerClientScript();
74+
}
75+
76+
/**
77+
* Register client script
78+
*/
79+
protected function registerClientScript()
80+
{
81+
$view = $this->getView();
82+
switch ($this->type) {
83+
case 'address':
84+
EditableAddressAsset::register($view);
85+
break;
86+
case 'combodate':
87+
EditableComboDateAsset::register($view);
88+
break;
89+
case 'date':
90+
EditableDatePickerAsset::register($view);
91+
break;
92+
case 'datetime':
93+
EditableDateTimePickerAsset::register($view);
94+
break;
95+
default:
96+
EditableBootstrapAsset::register($view);
97+
}
98+
$id = ArrayHelper::remove($this->pluginOptions, 'selector', '#' . $this->options['id']);
99+
$id = preg_replace('/([.])/', '\\\\\\\$1', $id);
100+
101+
if ($this->hasActiveRecord() && $this->model->isNewRecord) {
102+
$this->pluginOptions['send'] = 'always'; // send to server without pk
103+
}
104+
$pluginOptions = $this->getPluginOptions();
105+
$js = "jQuery('$id').editable($pluginOptions);";
106+
$view->registerJs($js);
107+
if (!empty($this->clientEvents)) {
108+
$this->registerClientEvents($id);
109+
}
110+
}
111+
112+
/**
113+
* Return plugin options in json format
114+
* @return string
115+
*/
116+
public function getPluginOptions()
117+
{
118+
$pk = ArrayHelper::getValue($this->pluginOptions,
119+
'pk',
120+
$this->hasActiveRecord() ? $this->model->getPrimaryKey() : null
121+
);
122+
$this->pluginOptions['pk'] = $pk;
123+
$this->pluginOptions['url'] = $this->url instanceof JsExpression ? $this->url : Url::toRoute($this->url);
124+
$this->pluginOptions['type'] = $this->type;
125+
$this->pluginOptions['mode'] = $this->mode;
126+
$this->pluginOptions['name'] = $this->attribute ?: $this->name;
127+
128+
return Json::encode($this->pluginOptions);
129+
}
130+
131+
/**
132+
* Register client events
133+
* @param $id
134+
*/
135+
public function registerClientEvents($id)
136+
{
137+
$view = $this->getView();
138+
$js = [];
139+
foreach ($this->clientEvents as $event => $handler) {
140+
$js[] = "jQuery('$id').on('$event', $handler);";
141+
}
142+
$view->registerJs(implode("\n", $js));
143+
}
144+
145+
/**
146+
* Return link text
147+
* @return mixed|string
148+
*/
149+
protected function getLinkText()
150+
{
151+
$value = $this->value;
152+
if ($this->hasModel()) {
153+
$model = $this->model;
154+
if ($value !== null) {
155+
if (is_string($value)) {
156+
$linkText = ArrayHelper::getValue($model, $value);
157+
} else {
158+
$linkText = call_user_func($value, $model);
159+
}
160+
} else {
161+
$linkText = ArrayHelper::getValue($model, $this->attribute);
162+
}
163+
} else {
164+
$linkText = $value;
165+
}
166+
167+
return $linkText;
168+
}
169+
170+
/**
171+
* To ensure that `getPrimaryKey()` and `getIsNewRecord()` methods are implemented in model.
172+
* @return bool
173+
*/
174+
protected function hasActiveRecord()
175+
{
176+
return $this->hasModel() && $this->model instanceof ActiveRecordInterface;
177+
}
178+
}

0 commit comments

Comments
 (0)