Skip to content

Commit c7e5e48

Browse files
committed
Change template of build ListRenderer - avoid table tag
1 parent 6f2e302 commit c7e5e48

File tree

1 file changed

+98
-55
lines changed

1 file changed

+98
-55
lines changed

src/renderers/ListRenderer.php

Lines changed: 98 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88

99
namespace unclead\multipleinput\renderers;
1010

11+
use unclead\multipleinput\assets\MultipleInputAsset;
12+
use unclead\multipleinput\assets\MultipleInputSortableAsset;
1113
use yii\base\InvalidConfigException;
1214
use yii\db\ActiveRecordInterface;
1315
use yii\helpers\ArrayHelper;
1416
use yii\helpers\Html;
1517
use unclead\multipleinput\components\BaseColumn;
18+
use yii\helpers\Json;
1619

1720
/**
1821
* Class ListRenderer
@@ -22,6 +25,7 @@ class ListRenderer extends BaseRenderer
2225
{
2326
/**
2427
* @return mixed
28+
* @throws InvalidConfigException
2529
*/
2630
protected function internalRender()
2731
{
@@ -35,10 +39,10 @@ protected function internalRender()
3539
Html::addCssClass($options, 'multiple-input-list list-renderer');
3640

3741
if ($this->isBootstrapTheme()) {
38-
Html::addCssClass($options, 'table form-horizontal');
42+
Html::addCssClass($options, 'form-horizontal');
3943
}
4044

41-
$content = Html::tag('table', implode("\n", $content), $options);
45+
$content = Html::tag('div', implode("\n", $content), $options);
4246

4347
return Html::tag('div', $content, [
4448
'id' => $this->id,
@@ -53,24 +57,17 @@ protected function internalRender()
5357
*/
5458
public function renderHeader()
5559
{
56-
if ($this->min !== 0 || !$this->isAddButtonPositionHeader()) {
60+
if (!$this->isAddButtonPositionHeader()) {
5761
return '';
5862
}
5963

60-
$button = $this->isAddButtonPositionHeader() ? $this->renderAddButton() : '';
61-
62-
$content = [];
63-
$content[] = Html::tag('td', ' ');
64-
65-
if ($this->cloneButton) {
66-
$content[] = Html::tag('td', ' ');
67-
}
68-
69-
$content[] = Html::tag('td', $button, [
70-
'class' => 'list-cell__button',
71-
]);
64+
$options = ['class' => 'list-cell__button'];
65+
$layoutConfig = array_merge([
66+
'buttonAddClass' => $this->isBootstrapTheme() ? 'col-sm-offset-9 col-sm-3' : '',
67+
], $this->layoutConfig);
68+
Html::addCssClass($options, $layoutConfig['buttonAddClass']);
7269

73-
return Html::tag('thead', Html::tag('tr', implode("\n", $content)));
70+
return Html::tag('div', $this->renderAddButton(), $options);
7471
}
7572

7673
/**
@@ -84,13 +81,13 @@ public function renderFooter()
8481
return '';
8582
}
8683

87-
$cells = [];
88-
$cells[] = Html::tag('td', ' ');
89-
$cells[] = Html::tag('td', $this->renderAddButton(), [
90-
'class' => 'list-cell__button'
91-
]);
84+
$options = ['class' => 'list-cell__button'];
85+
$layoutConfig = array_merge([
86+
'buttonAddClass' => $this->isBootstrapTheme() ? 'col-sm-offset-9 col-sm-3' : '',
87+
], $this->layoutConfig);
88+
Html::addCssClass($options, $layoutConfig['buttonAddClass']);
9289

93-
return Html::tag('tfoot', Html::tag('tr', implode("\n", $cells)));
90+
return Html::tag('div', $this->renderAddButton(), $options);
9491
}
9592

9693
/**
@@ -122,7 +119,7 @@ protected function renderBody()
122119
}
123120
}
124121

125-
return Html::tag('tbody', implode("\n", $rows));
122+
return implode("\n", $rows);
126123
}
127124

128125
/**
@@ -131,29 +128,18 @@ protected function renderBody()
131128
* @param int $index
132129
* @param ActiveRecordInterface|array $item
133130
* @return mixed
134-
* @throws InvalidConfigException
135131
*/
136132
private function renderRowContent($index = null, $item = null)
137133
{
138134
$elements = [];
135+
$columnIndex = 0;
139136
foreach ($this->columns as $column) {
140137
/* @var $column BaseColumn */
141138
$column->setModel($item);
142-
$elements[] = $this->renderCellContent($column, $index);
143-
}
144-
145-
$content = [];
146-
$content[] = Html::tag('td', implode("\n", $elements));
147-
if ($this->max !== $this->min) {
148-
$content[] = $this->renderActionColumn($index);
149-
}
150-
151-
if ($this->cloneButton) {
152-
$content[] = $this->renderCloneColumn();
139+
$elements[] = $this->renderCellContent($column, $index, $columnIndex++);
153140
}
154141

155-
$content = Html::tag('tr', implode("\n", $content), $this->prepareRowOptions($index, $item));
156-
142+
$content = Html::tag('div', implode("\n", $elements), $this->prepareRowOptions($index, $item));
157143
if ($index !== null) {
158144
$content = str_replace('{' . $this->getIndexPlaceholder() . '}', $index, $content);
159145
}
@@ -186,25 +172,42 @@ protected function prepareRowOptions($index, $item)
186172
*
187173
* @param BaseColumn $column
188174
* @param int|null $index
175+
* @param int|null $columnIndex
189176
* @return string
177+
* @throws \Exception
190178
*/
191-
public function renderCellContent($column, $index)
179+
public function renderCellContent($column, $index, $columnIndex = null)
192180
{
193-
$id = $column->getElementId($index);
194-
$name = $column->getElementName($index);
195-
$input = $column->renderInput($name, [
196-
'id' => $id
181+
$id = $column->getElementId($index);
182+
$name = $column->getElementName($index);
183+
184+
/**
185+
* This class inherits iconMap from BaseRenderer
186+
* If the input to be rendered is a drag column, we give it the appropriate icon class
187+
* via the $options array
188+
*/
189+
$options = ['id' => $id];
190+
if (substr($id, -4) === 'drag') {
191+
$options = ArrayHelper::merge($options, ['class' => $this->iconMap['drag-handle']]);
192+
}
193+
$input = $column->renderInput($name, $options, [
194+
'id' => $id,
195+
'name' => $name,
196+
'indexPlaceholder' => $this->getIndexPlaceholder(),
197+
'index' => $index,
198+
'columnIndex' => $columnIndex,
199+
'context' => $this->context,
197200
]);
198201

199202
if ($column->isHiddenInput()) {
200203
return $input;
201204
}
202205

203206
$layoutConfig = array_merge([
204-
'offsetClass' => $this->isBootstrapTheme() ? 'col-sm-offset-3' : '',
205-
'labelClass' => $this->isBootstrapTheme() ? 'col-sm-3' : '',
206-
'wrapperClass' => $this->isBootstrapTheme() ? 'col-sm-6' : '',
207-
'errorClass' => $this->isBootstrapTheme() ? 'col-sm-offset-3 col-sm-6' : '',
207+
'offsetClass' => $this->isBootstrapTheme() ? 'col-sm-offset-3' : '',
208+
'labelClass' => $this->isBootstrapTheme() ? 'col-sm-3' : '',
209+
'wrapperClass' => $this->isBootstrapTheme() ? 'col-sm-6' : '',
210+
'errorClass' => $this->isBootstrapTheme() ? 'col-sm-offset-3 col-sm-6' : '',
208211
], $this->layoutConfig);
209212

210213
Html::addCssClass($column->errorOptions, $layoutConfig['errorClass']);
@@ -240,7 +243,7 @@ public function renderCellContent($column, $index)
240243
}
241244

242245
$options = array_merge_recursive($options, $columnOptions);
243-
246+
244247
$content = Html::beginTag('div', $options);
245248

246249
if (empty($column->title)) {
@@ -256,6 +259,16 @@ public function renderCellContent($column, $index)
256259

257260
$content .= Html::tag('div', $input, $wrapperOptions);
258261

262+
// first line
263+
if ($columnIndex == 0) {
264+
if ($this->max !== $this->min) {
265+
$content .= $this->renderActionColumn($index);
266+
}
267+
if ($this->cloneButton) {
268+
$content .= $this->renderCloneColumn();
269+
}
270+
}
271+
259272
if ($column->enableError) {
260273
$content .= "\n" . $column->renderError($error);
261274
}
@@ -271,28 +284,35 @@ public function renderCellContent($column, $index)
271284
* @param null|int $index
272285
* @param null|ActiveRecordInterface|array $item
273286
* @return string
274-
* @throws \Exception
275287
*/
276288
private function renderActionColumn($index = null, $item = null)
277289
{
278290
$content = $this->getActionButton($index) . $this->getExtraButtons($index, $item);
279291

280-
return Html::tag('td', $content, [
281-
'class' => 'list-cell__button',
282-
]);
292+
$options = ['class' => 'list-cell__button'];
293+
$layoutConfig = array_merge([
294+
'buttonActionClass' => $this->isBootstrapTheme() ? 'col-sm-offset-0 col-sm-2' : '',
295+
], $this->layoutConfig);
296+
Html::addCssClass($options, $layoutConfig['buttonActionClass']);
297+
298+
return Html::tag('div', $content, $options);
283299
}
284300

285301
/**
286302
* Renders the clone column.
287303
*
288304
* @return string
289-
* @throws \Exception
290305
*/
291306
private function renderCloneColumn()
292307
{
293-
return Html::tag('td', $this->renderCloneButton(), [
294-
'class' => 'list-cell__button',
295-
]);
308+
309+
$options = ['class' => 'list-cell__button'];
310+
$layoutConfig = array_merge([
311+
'buttonCloneClass' => $this->isBootstrapTheme() ? 'col-sm-offset-0 col-sm-1' : '',
312+
], $this->layoutConfig);
313+
Html::addCssClass($options, $layoutConfig['buttonCloneClass']);
314+
315+
return Html::tag('div', $this->renderCloneButton(), $options);
296316
}
297317

298318
private function getActionButton($index)
@@ -364,4 +384,27 @@ protected function prepareTemplate()
364384
{
365385
return $this->renderRowContent();
366386
}
387+
388+
/**
389+
* Returns an array of JQuery sortable plugin options for ListRenderer
390+
* @return array
391+
*/
392+
protected function getJsSortableOptions()
393+
{
394+
return [
395+
'containerSelector' => '.list-renderer',
396+
'itemSelector' => '.multiple-input-list__item',
397+
'placeholder' => '<div class="placeholder"></div>',
398+
'handle' => '.drag-handle',
399+
'onDrop' => new \yii\web\JsExpression("
400+
function(item, container, _super, event) {
401+
_super(item, container, _super, event);
402+
403+
var wrapper = item.closest('.multiple-input').first();
404+
event = $.Event('afterDropRow');
405+
wrapper.trigger(event, [item]);
406+
}
407+
")
408+
];
409+
}
367410
}

0 commit comments

Comments
 (0)