Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Maison012's avatar

How to display new field from db to table Header?

Hello, i am working on a project with laravel + vue js. I have a table where i need to add columns dynamically from view form so i have created a form with vue js, and i can add a table field on db succesfouly. But i have a problem i dont know how to dislpay this field pn my table header when i add this field on db.

here is the vue table

<table class="table table-hover align-middle mb-0">
                    <thead class="">
                        <tr>
                            <th><input type="checkbox" class="form-check-input" v-model="selectAll" title="Select All"></th>
                            <th scope="col">Id</th>
                            <th scope="col">First Name</th>
                            <th scope="col">Last Name</th>
                            <th scope="col">Email</th>
                            <th scope="col">Phone</th>
                            <th scope="col">Status</th>
                            <th scope="col">Notes</th>
							//there should be added new field where i submit from form
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-show="leads.length" v-for="(lead, index) in leads" :key="lead.id">
                            <td>
                                <input type="checkbox" class="form-check-input" v-model="selected" :value="lead.id" />
                            </td>
                            <td :key="lead.id">{{index + 1}}</td>
                            <td>{{lead.first_name}}</td>
                            <td>{{lead.last_name}}</td>
                            <td>{{lead.primary_email}}</td>
                            <td>{{lead.primary_phone}}</td>
                            <td>{{lead.lead_status}}</td>
                            <td>{{lead.notes}}</td>
                        </tr>
                        <tr v-show="!leads.length">
                            <td colspan="12" class="text-center">Sorry :( No data found.</td>
                        </tr>
                    </tbody>
                </table>

this is form i use to add new field

<form @submit.prevent="addField()">
                    <div class="form-group">
                        <label for="exampleInputEmail1">Fields</label>
                        <input type="text" v-model="field" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Field">
                    </div>
                    <button type="submit" class="btn btn-primary">Submit</button>
                </form> 

//method to pass data on laravel controller

addField() {
            axios({
                method: 'POST',
                url: '/leads/addfield',
                data: {
                    field: this.field,
                }
            })
            .then(response => {
                console.log(response)
            })
        }

Also laravel controller

public function addField(Request $request)
    {
        $custom = $request->field;
        Schema::table('leads', function (Blueprint $table) use ($custom) {
            $table->string($custom);
        });
    }
0 likes
11 replies
lbecket's avatar

@leon012 I attempted to answer this when you asked the first time

Let the data structure determine the table layout. Don't hard-code your columns, but instead build them based on the values in your data object. If a field exists in your data, then it will exist in the table. If you remove it from the data, then vue is reactive and will remove it from the DOM. It shouldn't matter if you're doing this on the front-end or the back-end, just let the data structure determine your fields.

Maison012's avatar

@lbecket [UPDATED], Now i can fetch all headers data dynamically from db like this.

<tr>
    <th><input type="checkbox" class="form-check-input" v-model="selectAll" title="Select All"></th>
     <th  v-for="(header, index) in visibleHeaders" :key="index" scope="col">
          {{ header }}
      </th>
</tr>

return {
            headers: [],
            field: ' ',
            leads: [],
            selected: [],
        }

 computed: {
        visibleHeaders() {
            return this.headers.map(h => {
                return h.Field.replace("_", " ").toUpperCase()
            });
        },


methods: {
        getData() {
            axios.get('/leads/getleads')
            .then(response => {
                this.leads = response.data.leads
                this.headers = response.data.fields
                // console.log(response.data.leads)
            })
        },

        addField() {
            axios({
                method: 'POST',
                url: '/leads/addfield',
                data: {
                    field: this.field,
                }
            })
            .then(response => {
                console.log(response)
            })
        }
    }

Laravel controller

$query = "SHOW COLUMNS FROM $table_name";
$data = DB::select($query);
dd($data);
//Response
array::11 [
	0 => {#1331
    +"Field": "id"
    +"Type": "bigint unsigned"
    +"Null": "NO"
    +"Key": "PRI"
    +"Default": null
    +"Extra": "auto_increment"
  }
]

And this solution comes with anoter questions. If i will have an edit method , how can i display body content in same way as header?

Maison012's avatar

@lbecket Any idea how to fetch also body content similar like header.

If i cann add a header field there should be also a value for this field.

lbecket's avatar
lbecket
Best Answer
Level 39

@leon012 There are any number of ways that you can achieve this result. The easiest approach might be to manage the data structure on the back-end and return an array containing your headers and your data, which you would then assign to their respective data objects within your vue component.

So, structure your query based on whatever fields you intend to return. Then, take the resulting collection and isolate the keys. Return the keys and data together:

$queryResults = Lead::select('field_1', 'field_2')->get();
$headers = collect($queryResults->first())->keys();

return [
	'headers' => $headers,
	'rows' => $queryResults
];

Again, that's just one of many ways that this could be achieved, but let the data drive the component's structure.

Maison012's avatar

@lbecket Thanks for replying. Anyhow i have used another method:

public function getleads(Request $request)
    {
        $table_name = 'leads';
        // Through raw query
        $query = "SHOW COLUMNS FROM $table_name";
        $data = DB::select($query);

        $paginate = $request->perPage;
        $leads = Lead::paginate($paginate);

        if ($request->ajax()) {
            return response()->json([
                'leads' => $leads,
                'headers' => $data
            ], Response::HTTP_OK);
        }
    }

I dont know if it is the best mehod but it works :)

Sinnbeck's avatar

@Leon012 It is actually built into laravel

use Illuminate\Support\Facades\Schema; //top of file

$data = Schema::getColumnListing($table_name)
Maison012's avatar

@Sinnbeck this comes with an error

message: "explode() expects parameter 2 to be string, array given", exception: "ErrorException",…}
exception: "ErrorException"
file: "C:\Users\ag\Desktop\vue+laravel\main_panel\vendor\laravel\framework\src\Illuminate\Support\Str.php"
line: 612
message: "explode() expects parameter 2 to be string, array given"
trace: [{function: "handleError", class: "Illuminate\Foundation\Bootstrap\HandleExceptions", type: "->"},…]
Sinnbeck's avatar

@Leon012 What line triggers that error? I cannot recreate it

Does this work?

$data = Schema::getColumnListing($table_name)
dd($data);
Maison012's avatar

@Sinnbeck My mistake. It works, but in vue table header the fields they are confused. they are not in order .

headers:Array[9]
0:"created_at"
1:"first_name"
2:"id"
3:"last_name"
4:"lead_status"
5:"notes"
6:"primary_email"
7:"primary_phone"
8:"updated_at"

I think id should be first and other fields in order

Sinnbeck's avatar

@Leon012 Thats why I would personally use the method suggested by @lbecket as that ensures that the keys are in the same order as the query :) Or I would hard-code the column list in the order I want them to be shown.

Please or to participate in this conversation.