Skip to content

Commit

Permalink
Add support for 'rows' column type
Browse files Browse the repository at this point in the history
  • Loading branch information
nickdekruijk committed Nov 25, 2019
1 parent f338ca3 commit 61292d8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/Controllers/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -468,4 +468,38 @@ public function pivot($columnId, $column)
}
return $response;
}

// Return the line input for a many to many (pivot) relationship
public function rows($columnId, $column)
{
$data = $this->getModelData($column);
$response = '<table class="rows" id="input_' . $columnId . '">';
$response .= '<tr class="template">';
foreach ($column['columns'] as $columnId2 => $opt) {
$response .= '<td>';
if (empty($opt['type'])) {
$opt['type'] = 'string';
}

if ($opt['type'] == 'string' || $opt['type'] == 'password' || $opt['type'] == 'date' || $opt['type'] == 'datetime' || $opt['type'] == 'number') {
$response .= '<input class="' . ($opt['type'] == 'date' ? 'datepicker' : '') . ($opt['type'] == 'datetime' ? 'datetimepicker' : '' ) . '" type="' . ($opt['type']=='string' || $opt['type'] == 'date' || $opt['type'] == 'datetime' ? 'text' : $opt['type']) . '" name="'. $columnId . '_' . $columnId2 . '[]" data-column="' . $columnId . '_' . $columnId2 . '" placeholder="' . $this->locale('placeholder', $opt, '') . '">';
} elseif ($opt['type'] == 'foreign') {
$response .= $this->foreign($columnId . '_' . $columnId2.'[]', $opt, false);
} else {
$response .= $opt['type'];
}
$response .= '</td>';
}
if ($this->can('delete')) {
$response .= '<td><button type="button" data-confirm="' . trans('admin::base.deleteconfirm') . '" class="pivot-delete button is-red"><i class="fa fa-trash"></i></button></td>';
}
$response .= '</tr>';
$response .= '<tr>';
foreach ($column['columns'] as $col => $opt) {
$response .= '<th>' . $this->locale('title', $opt, $col) . '</th>';
}
$response .= '</tr>';
$response .= '</table>';
return $response;
}
}
30 changes: 30 additions & 0 deletions src/Controllers/ModelController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,22 @@ private function save($model, Request $request)

$sync = [];
$morph = [];
$row = [];
foreach($this->columns() as $columnId => $column) {
if (isset($column['type']) && $column['type'] == 'pivot') {
$sync[$column['model']] = $request[$columnId];
if (!empty($column['morph'])) {
$morph[$column['model']] = $column['morph'];
}
} elseif (isset($column['type']) && $column['type'] == 'rows') {
$row[$column['model']]['self'] = $column['self'];
foreach($column['columns'] as $columnId2 => $opt) {
$r = $request[$columnId . '_' . $columnId2];
array_shift($r);
foreach($r as $key => $value) {
$row[$column['model']][$key][$columnId2] = $value;
}
}
} elseif (isset($column['type']) && $column['type'] == 'array') {
// If column is of type array json decode it
$model[$columnId] = json_decode($request[$columnId], true);
Expand Down Expand Up @@ -57,6 +67,21 @@ private function save($model, Request $request)

$model->save();

foreach($row as $foreign => $data) {
$fm = new $foreign;
$self = $data['self'];
unset($data['self']);
$fm::where($self, $model->id)->delete();
foreach($data as $row) {
$fm = new $foreign;
$fm->$self = $model->id;
foreach($row as $column => $value) {
$fm->$column = $value;
}
$fm->save();
}
}

foreach($sync as $foreign => $values) {
if (isset($morph[$foreign])) {
$model->morphToMany($foreign, $morph[$foreign])->sync($values);
Expand Down Expand Up @@ -114,6 +139,11 @@ public function show($slug, $id)
if ($column['type'] == 'array') {
$row[$columnId] = json_encode(json_decode($row[$columnId]), JSON_PRETTY_PRINT);
}
// If column type is rows return those rows
if ($column['type'] == 'rows') {
unset($row['"'.$columnId.'"']);
$row[$columnId] = $this->model()::findOrFail($id)->hasMany($column['model'])->get(array_keys($column['columns']))->toArray();
}
// If column type is pivot return matching ids
if ($column['type'] == 'pivot') {
unset($row['"'.$columnId.'"']);
Expand Down
11 changes: 11 additions & 0 deletions src/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,17 @@ nav li:hover > ul > li {max-height:40px}
#editview UL.input_images > .button.add:not(:first-child) {width:45px;height:90px;opacity:0.3}
#editview UL.input_images > .button.add:not(:first-child):hover {opacity:1}
#editview UL.input_images.image > .button.add:not(:first-child) {display:none}
#editview .content TABLE.rows {border-spacing:0;border-collapse:collapse;max-width:100%}
#editview .content TABLE.rows TR.template {display:none}
#editview .content TABLE.rows TR:last-child TH {display:none}
#editview .content TABLE.rows TH,
#editview .content TABLE.rows TD {font-weight:inherit;text-align:left;padding:0 0 3px 3px}
#editview .content TABLE.rows TH:first-child,
#editview .content TABLE.rows TD:first-child {padding-left:0}
#editview .content TABLE.rows SELECT {width:100%}
#editview .content TABLE.rows .button {padding:3px 7px 4px}
#editview .content TABLE.rows INPUT {padding:1px 4px 2px}

#editview .content TABLE.array {border-spacing:0;border-collapse:collapse}
#editview .content TABLE.array TD:first-child {color:rgba(0,0,0,0.5);padding-right:0.5em;font-size:0.95em}
#editview .content TABLE.array TD:first-child:first-letter {text-transform:uppercase}
Expand Down
25 changes: 25 additions & 0 deletions src/js/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ function modelShow(slug, id) {
$.ajax(slug + '/' + id, {
cache: false,
}).done(function (data, status, xhr) {
$('#editview .rows .data').remove();
for (i in data) {
if (i.substr(0, 7) == '_pivot.') {
$('#editview input[type=checkbox].pivot-' + i.substr(7)).prop('checked', false);
Expand All @@ -187,6 +188,11 @@ function modelShow(slug, id) {
});
} else if ($('#input_' + i).attr('type') == 'checkbox') {
$('#input_' + i).prop('checked', data[i] == true);
} else if ($('#input_' + i).is('TABLE') && $('#input_' + i).hasClass('rows')) {
var rowData = data[i];
for (n in rowData) {
modelAddLine(slug, $('#input_' + i), rowData[n], i)
}
} else {
$('#input_' + i).val(data[i]).change();
}
Expand Down Expand Up @@ -512,6 +518,22 @@ function hideColumns(t) {
}
}

function modelAddLine(slug, element, data, column) {
var tr = $(element).find('TR.template').clone().removeClass('template').addClass('data');
tr.appendTo($(element)).find('.pivot-delete').click(function () {
$(this).parent().parent().remove();
});
if (data) {
for (n in data) {
tr.find('INPUT[data-column='+column+'_'+n+']').val(data[n]);
tr.find('SELECT[data-column='+column+'_'+n+']').val(data[n]);
console.log(n,data[n]);
}
}
// Fix rendering bug that prevents TH from being shown after deleting
$(element).find('TH').hide().show();
}

function modelInit(slug) {
$('.datepicker').datepicker({
showButtonPanel: true,
Expand Down Expand Up @@ -543,6 +565,9 @@ function modelInit(slug) {
$('UL.input_images .button.add').click(function () {
modelAddMedia(slug, this);
});
$('DIV.rows .button.add').click(function () {
modelAddLine(slug, $(this).prev());
});
$('.header .search INPUT').keyup(function (e) {
modelSearch(this.value);
});
Expand Down
5 changes: 5 additions & 0 deletions src/views/model.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
{!! $lp->foreign($id, $column) !!}
@elseif ($column['type'] == 'pivot')
<div class="pivot">{!! $lp->pivot($id, $column) !!}</div>
@elseif ($column['type'] == 'rows')
<div class="rows">
{!! $lp->rows($id, $column) !!}
<button class="button add"><i class="fa fa-plus"></i></button>
</div>
@elseif ($column['type'] != 'boolean')
{{$column['type']}}
@endif
Expand Down

0 comments on commit 61292d8

Please sign in to comment.