Skip to content

Commit 68f46da

Browse files
author
Eugene Tupikov
committed
#16 fix render of dropDown and similar inputs
1 parent b5cacc1 commit 68f46da

File tree

4 files changed

+81
-94
lines changed

4 files changed

+81
-94
lines changed

src/MultipleInput.php

Lines changed: 67 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ class MultipleInput extends InputWidget
5858
protected $template;
5959

6060
/**
61-
* @var array js templates collected from js which has been registered during rendering of widgets
61+
* @var array js templates collected from js which has been registered during rendering of widget
6262
*/
6363
protected $jsTemplates = [];
6464

6565
/**
6666
* @var string
6767
*/
68-
protected $replacementKeys;
68+
private $replacementKeys;
6969

7070
/**
7171
* Initialization.
@@ -194,79 +194,100 @@ protected function renderBody()
194194
$rows = [];
195195
if (!empty($this->data)) {
196196
foreach ($this->data as $index => $data) {
197-
$rows[] = $this->renderRow($index, $data);
197+
$rows[] = $this->renderRowContent($index, $data);
198198
}
199199
} else {
200-
$rows[] = $this->renderRow(0);
200+
$rows[] = $this->renderRowContent(0);
201201
}
202202
return Html::tag('tbody', implode("\n", $rows));
203203
}
204204

205-
private function getRowTemplate()
205+
/**
206+
* Renders the row content.
207+
*
208+
* @param int $index
209+
* @param ActiveRecord|array $data
210+
* @return mixed
211+
* @throws InvalidConfigException
212+
*/
213+
private function renderRowContent($index = null, $data = null)
206214
{
207-
if (empty($this->template)) {
208-
$cells = [];
209-
$hiddenInputs = [];
210-
foreach ($this->columns as $columnIndex => $column) {
211-
/* @var $column MultipleInputColumn */
215+
$cells = [];
216+
$hiddenInputs = [];
217+
foreach ($this->columns as $columnIndex => $column) {
218+
/* @var $column MultipleInputColumn */
219+
if (is_null($index)) {
212220
$value = 'multiple-' . $column->name . '-value';
213221
$this->replacementKeys[$value] = $column->defaultValue;
214222
$value = '{' . $value . '}';
215-
216-
if ($column->isHiddenInput()) {
217-
$hiddenInputs[] = $column->renderCellContent($value);
218-
} else {
219-
$cells[] = $column->renderCellContent($value);
220-
}
221-
}
222-
if (is_null($this->limit) || $this->limit > 1) {
223-
$cells[] = $this->renderActionColumn();
223+
} else {
224+
$value = $column->prepareValue($data);
224225
}
225226

226-
if (!empty($hiddenInputs)) {
227-
$hiddenInputs = implode("\n", $hiddenInputs);
228-
$cells[0] = preg_replace('/^(<td[^>]+>)(.*)(<\/td>)$/', '${1}' . $hiddenInputs . '$2$3', $cells[0]);
227+
if ($column->isHiddenInput()) {
228+
$hiddenInputs[] = $column->renderCellContent($value, $index);
229+
} else {
230+
$cells[] = $column->renderCellContent($value, $index);
229231
}
232+
}
233+
if (is_null($this->limit) || $this->limit > 1) {
234+
$cells[] = $this->renderActionColumn($index);
235+
}
230236

231-
$this->template = Html::tag('tr', implode("\n", $cells), [
232-
'class' => 'multiple-input-list__item',
233-
]);
237+
if (!empty($hiddenInputs)) {
238+
$hiddenInputs = implode("\n", $hiddenInputs);
239+
$cells[0] = preg_replace('/^(<td[^>]+>)(.*)(<\/td>)$/', '${1}' . $hiddenInputs . '$2$3', $cells[0]);
240+
}
234241

235-
if (is_array($this->getView()->js) && array_key_exists(View::POS_READY, $this->getView()->js)) {
236-
$this->collectJsTemplates();
237-
}
242+
$content = Html::tag('tr', implode("\n", $cells), [
243+
'class' => 'multiple-input-list__item',
244+
]);
245+
246+
if (is_null($index)) {
247+
$this->collectJsTemplates();
238248
}
239249

240-
return $this->template;
250+
return $content;
241251
}
242252

243253
private function collectJsTemplates()
244254
{
255+
if (is_array($this->getView()->js) && array_key_exists(View::POS_READY, $this->getView()->js)) {
245256
$this->jsTemplates = [];
246257
foreach ($this->getView()->js[View::POS_READY] as $key => $js) {
247-
if (preg_match('/\(.#[^)]+{multiple-index}[^)]+\)/', $js) === 1) {
248-
$this->jsTemplates[] = $js;
249-
unset($this->getView()->js[View::POS_READY][$key]);
258+
if (preg_match('/^.*' . $this->options['id'] . '-{multiple-index}.*$/', $js) === 1) {
259+
$this->jsTemplates[] = $js;
260+
unset($this->getView()->js[View::POS_READY][$key]);
261+
}
250262
}
251263
}
252264
}
253265

254266
/**
255267
* Renders the action column.
256268
*
269+
* @param null|int $index
257270
* @return string
258271
* @throws \Exception
259272
*/
260-
private function renderActionColumn()
273+
private function renderActionColumn($index = null)
261274
{
275+
if (is_null($index)) {
276+
$action = '{multiple-btn-action}';
277+
$type = '{multiple-btn-type}';
278+
} else {
279+
$action = $index == 0 ? self::ACTION_ADD : self::ACTION_REMOVE;
280+
$type = $index == 0 ? 'btn-default' : 'btn-danger';
281+
}
282+
262283
$button = Button::widget(
263284
[
264285
'tagName' => 'div',
265286
'encodeLabel' => false,
266-
'label' => Html::tag('i', null, ['class' => 'glyphicon glyphicon-{multiple-btn-action}']),
287+
'label' => Html::tag('i', null, ['class' => 'glyphicon glyphicon-' . $action]),
267288
'options' => [
268-
'id' => $this->getElementId('button'),
269-
'class' => "{multiple-btn-type} multiple-input-list__btn btn js-input-{multiple-btn-action}",
289+
'id' => $this->getElementId('button', $index),
290+
'class' => $type . ' multiple-input-list__btn btn js-input-' . $action,
270291
]
271292
]
272293
);
@@ -275,51 +296,21 @@ private function renderActionColumn()
275296
]);
276297
}
277298

278-
/**
279-
* Renders the row.
280-
*
281-
* @param int $index
282-
* @param ActiveRecord|array $data
283-
* @return mixed
284-
* @throws InvalidConfigException
285-
*/
286-
private function renderRow($index, $data = null)
287-
{
288-
$btnAction = $index == 0 ? self::ACTION_ADD : self::ACTION_REMOVE;
289-
$btnType = $index == 0 ? 'btn-default' : 'btn-danger';
290-
$search = ['{multiple-index}', '{multiple-btn-action}', '{multiple-btn-type}'];
291-
$replace = [$index, $btnAction, $btnType];
292-
293-
foreach ($this->columns as $column) {
294-
/* @var $column MultipleInputColumn */
295-
$search[] = '{multiple-' . $column->name . '-value}';
296-
$replace[] = $column->prepareValue($data);
297-
}
298-
299-
$row = str_replace($search, $replace, $this->getRowTemplate());
300-
301-
foreach ($this->jsTemplates as $js) {
302-
$this->getView()->registerJs(strtr($js, ['{multiple-index}' => $index]), View::POS_READY);
303-
}
304-
return $row;
305-
}
306299

307300
/**
308301
* Returns element's name.
309302
*
310-
* @param string $name
311-
* @param string $index
303+
* @param string $name the name of cell element
304+
* @param int|null $index
312305
* @return string
313306
*/
314-
public function getElementName($name, $index = null)
307+
public function getElementName($name, $index)
315308
{
316-
if ($index === null) {
309+
if (is_null($index)) {
317310
$index = '{multiple-index}';
318311
}
319312
return $this->getInputNamePrefix($name) . (
320-
count($this->columns) > 1
321-
? '[' . $index . '][' . $name . ']'
322-
: '[' . $name . '][' . $index . ']'
313+
count($this->columns) > 1 ? '[' . $index . '][' . $name . ']' : '[' . $name . '][' . $index . ']'
323314
);
324315
}
325316

@@ -343,12 +334,13 @@ private function getInputNamePrefix($name)
343334
/**
344335
* Returns element id.
345336
*
346-
* @param $name
337+
* @param string $name
338+
* @param null|int $index
347339
* @return mixed
348340
*/
349-
public function getElementId($name)
341+
public function getElementId($name, $index = null)
350342
{
351-
return $this->normalize($this->getElementName($name));
343+
return $this->normalize($this->getElementName($name, $index));
352344
}
353345

354346
/**
@@ -371,7 +363,7 @@ public function registerClientScript()
371363
$options = Json::encode(
372364
[
373365
'id' => $this->getId(),
374-
'template' => $this->getRowTemplate(),
366+
'template' => $this->renderRowContent(),
375367
'jsTemplates' => $this->jsTemplates,
376368
'btnAction' => self::ACTION_REMOVE,
377369
'btnType' => 'btn-danger',

src/MultipleInputColumn.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,23 +147,24 @@ public function prepareValue($data)
147147
$value = $this->defaultValue;
148148
}
149149
}
150-
return is_array($value) ? Json::encode($value) : $value;
150+
return $value;
151151
}
152152

153153
/**
154154
* Renders the cell content.
155155
*
156-
* @param string $value placeholder of the input's value
156+
* @param string $value
157+
* @param int|null $index
157158
* @return string
158159
* @throws InvalidConfigException
159160
*/
160-
public function renderCellContent($value)
161+
public function renderCellContent($value, $index)
161162
{
162163
$type = $this->type;
163-
$name = $this->widget->getElementName($this->name);
164+
$name = $this->widget->getElementName($this->name, $index);
164165

165166
$options = $this->options;
166-
$options['id'] = $this->widget->getElementId($this->name);
167+
$options['id'] = $this->widget->getElementId($this->name, $index);
167168
Html::addCssClass($options, 'form-control');
168169

169170
switch ($this->type) {
@@ -174,8 +175,7 @@ public function renderCellContent($value)
174175
case self::TYPE_LISTBOX:
175176
case self::TYPE_CHECKBOX_LIST:
176177
case self::TYPE_RADIO_LIST:
177-
$options['data-selected-option'] = $value;
178-
$input = Html::$type($name, null, $this->items, $options);
178+
$input = Html::$type($name, $value, $this->items, $options);
179179
break;
180180
case self::TYPE_STATIC:
181181
$input = Html::tag('p', $value, ['class' => 'form-control-static']);

src/assets/src/js/jquery.multipleInput.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,11 @@
7575
methods.addAttribute.apply(this);
7676
});
7777
wrapper.data('multipleInput').currentIndex = wrapper.find('.multiple-input-list__item').length;
78-
79-
$('[data-selected-option]').each(function (k, v) {
80-
var $ele = $(v);
81-
$ele.val($ele.data('selected-option')).removeAttr('data-selected-option');
82-
});
8378
clearInterval(intervalID);
8479
}
8580
}, 100);
8681

87-
88-
8982
wrapper.trigger('init');
90-
9183
},
9284

9385
addInput: function () {
@@ -159,9 +151,12 @@
159151
},
160152

161153
removeAttribute: function () {
162-
var id = $(this).attr('id');
163-
var form = $('#' + $(this).attr('id')).closest('form');
164-
form.yiiActiveForm('remove', id);
154+
var id = $(this).attr('id'),
155+
form = $('#' + $(this).attr('id')).closest('form');
156+
157+
if (form.length !== 0) {
158+
form.yiiActiveForm('remove', id);
159+
}
165160
}
166161

167162
};

src/assets/src/js/jquery.multipleInput.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)