-
Notifications
You must be signed in to change notification settings - Fork 0
/
FlexibleForm.php
executable file
·218 lines (186 loc) · 5.15 KB
/
FlexibleForm.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<?php
/**
*
* @author Novikov A
*
* The FlexibleForm widget renders form with field (CollapsableField) that could be
* configured as visible or not by end user. Also FlexibleForm supports templates feature
* that allow save the form configuration and fields values.
*
* You need to add widget module in your config file like following:
*
* 'modules' => [
* ...
* 'flexform' => [
* 'class' => 'vendor\novik\flexform\Module',
* ],
* ...
* ],
*
* Also you need to perform migration file located under the directory 'migrations' in widget root
*
* What you need to provide for full widget functionality:
*
* @var Model $formModel Form model instance, that keeps fields to be rendered by widget. (Nessesary)
* @var string $submitTitle - string form submit button title. (Optionaly)
*
* Than use this widget like ActiveForm widget, as it is a base class for this widget.
*
*/
namespace novikas\flexform;
use yii\widgets\ActiveForm;
use yii\base\InvalidConfigException;
use yii\db\Exception;
use yii\base\Model;
use yii\bootstrap\ButtonDropdown;
use yii\widgets\Pjax;
use yii\helpers\ArrayHelper;
use novikas\flexform\models\FlexformTemplate;
use novikas\flexform\models\FlexformField;
use novikas\flexform\assets\FlexibleFormAsset;
use novikas\interfaces\Templatable;
class FlexibleForm extends ActiveForm implements Templatable
{
use TemplateTrait;
const TEMPLATE_TYPE = self::TEMPLATE_FORM;
/**
*
* @var string field class
*/
public $fieldClass = 'vendor\novik\flexform\CollapsableField';
/**
* @var Model the data model that this form is associated with
*/
public $formModel;
/**
* @var array attributes that client code intent to display
*/
public $displayedAttributes = [];
/**
*
*/
public $submitTitle = 'Submit';
/**
* @var array template fields
*/
private $fieldNames = [];
/**
* @var Module instace of widget module
*/
protected $_module;
/**
*
* @var string class of the model
*/
private $modelClass;
/**
* (non-PHPdoc)
* @see \yii\widgets\ActiveForm::init()
*/
public function init()
{
Pjax::begin(['id' => 'flexform-widget-whole']);
Pjax::begin(['id' => 'flexform-widget']);
parent::init();
if( !isset( $this->formModel ) )
throw new InvalidConfigException("The \$formModel must be setup.");
$this->_module = Config::initModule( Module::classname() );
$this->modelClass = ( new \ReflectionClass( $this->formModel->className() ) )->getShortName();
$this->template_name = $this->modelClass;
$this->initTemplate( false );
$this->prepareModel();
}
/**
* (non-PHPdoc)
* @see \yii\widgets\ActiveForm::run()
*/
public function run()
{
parent::run();
Pjax::end();
if( !isset( $this->template ) )
{
$this->createDefaultTemplate();
}
echo $this->render('template/footer', ['formModel' => $this->formModel,
'templateController' => $this->_module->templateController,
'displayedAttributes' => $this->displayedAttributes,
'fieldNames' => $this->template->fields,
'submitTitle' => $this->submitTitle,
]);
Pjax::begin(['id' => 'template-panel-pjax']);
echo $this->templatesPanel();
Pjax::end();
Pjax::end();
FlexibleFormAsset::register( $this->view );
}
/**
* (non-PHPdoc)
*
* @see \yii\widgets\ActiveForm::field()
*/
public function field( $model, $attribute, $options = [] )
{
if( isset( $attribute ) )
$this->displayedAttributes[] = $attribute;
if( isset( $this->template ) )
{
$options['visible'] = in_array($attribute, $this->template->fields);
}
else
{
$options['visible'] = true;
}
return parent::field($model, $attribute, $options);
}
/**
* Fills the $formModel with saved values from template fields
* @return boolean true if $this->template is defined and false othervise.
*/
private function prepareModel()
{
if( isset( $this->template ) )
{
$attr = ArrayHelper::map( $this->template->flexFields, 'name', 'value' );
$str = 'store';
foreach ( $attr as $key => $value )
{
if( strpos($value, ',') )
{
$this->formModel->$key = explode( ',', $value );
}
else
{
$this->formModel->$key = $value;
}
}
return true;
}
return false;
}
public function getDisplayedAttributes()
{
return $this->displayedAttributes;
}
/**
* Generates button group which represents templates panel
* @return string generated html
*/
private function templatesPanel()
{
$html = "<div id = 'template-panel-container' class = 'btn-group btn-group-justified' data-toggle= 'buttons'>";
$userTemplatesList = FlexformTemplate::getUserFormTemplates( $this->modelClass );
foreach ( $userTemplatesList as $key => $value )
{
$html .= "<label class = 'btn btn-default template-panel current-template ".($value->current == 1?'active':'')
."' ><input type=radio name = 'currentFilter' value = $value->id "
.($value->current == 1?'checked':'').">$value->name</label>";
}
$html .="<label class = 'btn btn-default template-panel' id = 'new-template' value = $this->modelClass >
<span class = 'glyphicon glyphicon-plus'></span>
</label>";
$html .= "</div>";
return $html;
}
}
?>