add option to upload file when creating a table

master
Ondřej Hruška 6 years ago
parent 7ae41b368e
commit 13b22f7cb4
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 43
      app/Http/Controllers/TableController.php
  2. 1
      app/Models/Row.php
  3. 36
      resources/assets/js/components/ColumnEditor.vue
  4. 15
      resources/views/table/create.blade.php
  5. 2
      resources/views/table/propose/add-rows-csv.blade.php

@ -81,16 +81,17 @@ class TableController extends Controller
*/
public function create()
{
$exampleData =
"Mercenaria mercenaria,hard clam,40\n" .
"Magallana gigas,pacific oyster,30\n" .
"Patella vulgata,common limpet,20";
$exampleData = "";
// "Mercenaria mercenaria,hard clam,40\n" .
// "Magallana gigas,pacific oyster,30\n" .
// "Patella vulgata,common limpet,20";
$columns = Column::columnsFromJson([
// fake 'id' to satisfy the check in Column constructor
['id' => 1, 'name' => 'latin', 'type' => 'string', 'title' => 'Latin Name'],
['id' => 2, 'name' => 'common', 'type' => 'string', 'title' => 'Common Name'],
['id' => 3, 'name' => 'lifespan', 'type' => 'int', 'title' => 'Lifespan (years)']
['id' => 1, 'name' => 'column_1', 'type' => 'string', 'title' => 'First Column'],
// ['id' => 1, 'name' => 'latin', 'type' => 'string', 'title' => 'Latin Name'],
// ['id' => 2, 'name' => 'common', 'type' => 'string', 'title' => 'Common Name'],
// ['id' => 3, 'name' => 'lifespan', 'type' => 'int', 'title' => 'Lifespan (years)']
]);
return view('table.create', [
@ -210,7 +211,33 @@ class TableController extends Controller
}
// --- DATA ---
$dataCsvLines = Utils::csvToArray($input->data);
$fname = 'csv-file';
$dataCsvLines = [];
if ($request->hasFile($fname)) {
try {
$file = $request->file($fname);
if ($file->isValid() && $file->isReadable()) {
$handle = $file->openFile();
$dataCsvLines = Utils::csvToArray($handle);
if (empty($dataCsvLines)) throw new \Exception("Failed to parse CSV file.");
$handle = null;
} else {
throw new \Exception("File not valid.");
}
} catch (\Exception $e) {
return $this->backWithErrors(['csv-file' => $e->getMessage()]);
}
}
else if ($input->data) {
try {
$text = trim($input->data);
if (!empty($text)) {
$dataCsvLines = Utils::csvToArray($text);
}
} catch (\Exception $e) {
return $this->backWithErrors(['data' => $e->getMessage()]);
}
}
// Preparing data to insert into the Rows table
$rowsToInsert = null;

@ -83,6 +83,7 @@ class Row extends BaseModel
*/
public static function allocateRowIDs($count)
{
if ($count == 0) return null;
$last = \DB::selectOne("SELECT multi_nextval('global_row_id_seq', ?) AS last_id;", [$count])->last_id;
return [$last - $count + 1, $last];
}

@ -63,6 +63,9 @@ Complex animated column editor for the table edit page
<input v-model="col.name"
:class="['form-control', { 'is-invalid': col._errors && col._errors['name'] }]"
:title="(col._errors && col._errors['name']) ? col._errors['name'][0] : null"
:ref="`edit-${i}-name`"
@keydown.down="verticalTab(i, 'name', 1)"
@keydown.up="verticalTab(i, 'name', -1)"
type="text">
</td>
@ -81,6 +84,9 @@ Complex animated column editor for the table edit page
<input v-model="col.title"
:title="(col._errors && col._errors['title']) ? col._errors['title'][0] : null"
:class="['form-control', { 'is-invalid': col._errors && col._errors['title'] }]"
:ref="`edit-${i}-title`"
@keydown.down="verticalTab(i, 'title', 1)"
@keydown.up="verticalTab(i, 'title', -1)"
type="text">
</td>
</template>
@ -141,7 +147,7 @@ Complex animated column editor for the table edit page
@media screen and (min-width: 625px) {
table.new-table {
margin-left: -53px;
margin-left: -66px;
}
}
@ -471,6 +477,34 @@ export default {
for (const [key, value] of Object.entries(col._loadvals)) {
col[key] = value
}
},
/**
* Move to next or prev editable cell vertically
*
* @param index
* @param field
* @param dir - +1 down, -1 up
*/
verticalTab (index, field, dir) {
if (dir == -1) {
// up
for(let i = index-1; i>= 0; i--) {
if (this.columns[i]._editing || this.newTable) {
this.$refs[`edit-${i}-${field}`][0].focus()
break;
}
}
}
else {
// down
for(let i = index+1; i < this.columns.length; i++) {
if (this.columns[i]._editing || this.newTable) {
this.$refs[`edit-${i}-${field}`][0].focus()
break;
}
}
}
}
}
}

@ -4,6 +4,7 @@
@section('content')
<form method="POST" action="{{route('table.storeNew')}}" class="row justify-content-center"
enctype="multipart/form-data"
aria-label="New Table">
@csrf
@ -57,11 +58,15 @@
</div>
</div>
{!! Widget::textarea('data', 'Initial data')->value($exampleData)->height('12em')
->help('
Initial table data in CSV format, columns corresponding to the
specification you entered above. This is optional; you can fill the table
later, e.g. by uploading a CSV file.') !!}
{!! Widget::par('
Initialize the table with pasted CSV lines or an uploaded CSV file,
using the column order you defined above. This is optional, you can always
fill or modify the table later.
', 'text-muted') !!}
{!! Widget::textarea('data', 'CSV as text')->value($exampleData)->height('12em') !!}
{!! Widget::file('csv-file', 'CSV file')->accept("text/csv") !!}
<div class="row form-group">
<div class="col-md-7 offset-md-3">

@ -23,7 +23,7 @@
}
@endphp
{!! Widget::par('Append rows from pasted CSV lines or uploaded CSV file') !!}
{!! Widget::par('Append rows from pasted CSV lines or an uploaded CSV file') !!}
{{-- TODO interactive widget to select which cols are included, and in which order --}}
{!! Widget::labeledPar('Columns', implode(', ', $cols), '', false) !!}

Loading…
Cancel
Save