I am using map() function to return an array for my data and display they in a dynamically way for my table in vue js. I get an error when i use paginate method : map() is not a function.
Here is the vue table with function
<thead class="">
<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>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-show="leads.length" v-for="(column, index) in visibileColumn" :key="index">
<td>
<input type="checkbox" class="form-check-input" v-model="selected" :value="column.id" />
</td>
<td v-for="atr in column">{{atr}}</td>
<td>
<a class="btn btn-sm btn-info">View</a>
<button type="button" class="btn btn-sm btn-secondary" data-mdb-toggle="modal" data-mdb-target="#editUserModal" >Edit</button>
<button type="button" class="btn btn-sm btn-danger" >Delete</button>
</td>
</tr>
<tr v-show="!leads.length">
<td colspan="12" class="text-center">Sorry :( No data found.</td>
</tr>
</tbody>
//script
data() {
return {
headers: [],
leads: [],
field: '',
}
},
computed: {
visibleHeaders() {
return this.headers.map(h => {
return h.Field.replace("_", " ").toUpperCase()
});
},
visibileColumn() {
return this.leads.map(c => {
// console.log(c)
return c
})
},
},
methods: {
getData() {
axios.get('/leads/getleads')
.then(response => {
this.leads = response.data.leads
this.headers = response.data.headers
// console.log(response.data.leads)
})
},
}
And laravel controller function
public function getleads(Request $request)
{
$table_name = 'leads';
// Through raw query
$query = "SHOW COLUMNS FROM $table_name";
$data = DB::select($query);
if ($request->ajax()) {
return response()->json([
'leads' => Lead::paginate(10),
'headers' => $data
], Response::HTTP_OK);
}
}
if i use 'leads' => Lead::get(), this method works fine but when i use paginate(10) i get an error
app.js:34778 [Vue warn]: Error in render: "TypeError: this.leads.map is not a function"
the paginate method returns an object with data field and other fields explained here, so you should do :
this.leads = response.data.leads.data
Related
I am working on a project (vue + laravel) where i need to fetch all table structure from db. So my table will be dynamically with all field(table header) and record. Now i need to do a filter(search) for each visible column. I have tryed some way but it does not work for me, I just dont know how to pass only column value for each option select value.
Collapse content is the option who will show on filter click and there should display the option for each column
<table class="table table-hover align-middle mb-0" :class="smallTable.smTable">
<thead class="">
<tr>
<th><input type="checkbox" class="form-check-input" v-model="selectAll" title="Select All"></th>
<th v-for="(header, i) in visibleHeaders" :key="i" scope="col">
{{ header.name }}
</th>
<th v-if="actionHide">ACTION</th>
</tr>
</thead>
<!-- Collapsed content ./ -->
<thead class="collapse" id="collapseFilter">
<tr>
<th></th>
<th v-for="(header, i) in visibleHeaders" :key="i">
<div class="filter-table col-12 d-flex">
<select id="" class="form-select" >
<option v-for="(lead, i) in leads" >{{lead}}</option>
</select>
</div>
</th>
</tr>
</thead>
<!-- ./ Collapse contet -->
<tbody>
<tr v-show="leads.length" v-for="(lead, i) in leads" :key="i">
<td>
<input type="checkbox" class="form-check-input" v-model="selected" :value="lead.id" />
</td>
<td v-for="(field, j) in lead" :key="j">
<span v-if="field == 'new'" class="badge badge-primary">
{{ field }}
</span>
<span v-else-if="field == 'contract'" class="badge badge-success">
{{ field }}
</span>
<span v-else>
{{ field }}
</span>
</td>
<td >
<button #click="editLead(lead.id)" type="button" class="btn btn-sm btn-secondary" data-mdb-toggle="modal" data-mdb-target="#editLeadModal" >
<i class="fa-solid fa-eye"></i>
</button>
</td>
</tr>
<tr v-show="!leads.length">
<td colspan="12" class="text-center">Sorry :( No data found.</td>
</tr>
</table>
data() {
return {
headers: [],
leads: [],
fields: [],
}
}
mounted() {
axios.get('/leads/getfields')
.then(response => {
this.fields = response.data.map(field => {
return {
name: field,
visible: true,
}
});
}
this.getData();
});
}
getData() {
this.headers = this.fields.map(item => {
if (item.visible) {
return item.name;
}
});
axios.post('/leads/getleads?page=' + this.pagination.current_page, {
perPage: this.displayRecord,
fields: this.headers,
})
.then(response => {
this.leads = response.data.data;
this.pagination = response.data.meta
});
},
I would like to insert a button in every row of a table and when I click on this button, it redirect me to another page with the data of the single table row using Laravel
How can I do this?
This is my form:
<html>
<table class="table">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">USERNAME</th>
<th scope="col">MAC ADDRESS</th>
</tr>
</thead>
<tbody>
#foreach ($data as $item)
<tr>
<th scope="row">{{$item->id}}</th>
<td>{{$item->username}}</td>
<td>{{$item->mac_addr}}</td>
<td>
<form action="{{url('singleDevice')}}" method="get">
<button class="btn btn-primary" type="submit">Select</button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
</body>
</html>
This is my controller:
class DeviceController extends Controller
{
public function index()
{
$data=Device::all();
return view('device', compact("data"));
}
public function create()
{
return view('registrationDevice');
}
public function store(Request $request)
{
$input = new Device;
//On left field name in DB and on right field name in Form/view
$input -> username = $request->username;
$input -> mac_addr = $request->mac_address;
$input->save();
return redirect('registrationDevice')->with('message', 'DATA SAVED');
}
public function show(Device $device)
{
return view('singleDevice');
}
}
Thanks in advance
Change your form like :
<tbody>
#foreach ($data as $item)
<tr>
<th scope="row">{{$item->id}}</th>
<td>{{$item->username}}</td>
<td>{{$item->mac_addr}}</td>
<td>
Select
</td>
</tr>
#endforeach
</tbody>
If you want to use route name, you can change by :
<td>
Select
</td>
Change your route like :
Route::get('/singleDevice/{deviceID}', [DeviceController::class, 'show'])->name('show');
Change your show function of the controller like:
public function show($deviceID)
{
$device = Device::firstWhere('id', $deviceID);
return view('singleDevice', compact("device"));
}
Why do you need a form? use the link
<form action="{{url('singleDevice')}}" method="get">
<button class="btn btn-primary" type="submit">Select</button>
</form>
replace with
Select
and configure the URL in the router as /singleDevice/{device}
Route::get('/singleDevice/{device}', [DeviceController::class, 'show'])->name('show');
You also can use this as you have already used form in your code
<form action="{{ route('show', $item->id) }}" method="get">
<button class="btn btn-primary" type="submit">Select</button>
</form>
public function show(Device $device)
{
return view('singleDevice');
}
For Route you can pass $device:
Route::get('/singleDevice/{$device}', [DeviceController::class, 'show'])->name('show');
i try to fetch data from an array returned with vuejs script. i displayed data in script and everything is well. in created function, the value array is empty. but with template. the array is empty and not returned null.
export default {
name: 'attribute-values',
props: ['attributeid'],
data() {
return {
values: [],
value: '',
price: '',
currentId: '',
valueTest:'',
addValue: true,
key: 0
}
},
methods: {
loadValues() {
let attributeId = this.attributeid;
var self = this;
self.valueTest='a test';
axios.post('/admin/attributes/get-values', {
id: attributeId
}).then (function(response){
self.values = response.data;
console.log(self.values);
this.values=self.values;
}).catch(function (error) {
console.log(error);
});
console.log(this.values);
}
},
created :function() {
this.loadValues();
}
}
and this is the template
<tr v-if="values.length==0"><td>No items founds</td></tr>
<tr v-for="valuee in values" :key="valuee.id">
<td style="width: 25%" class="text-center">{{ valuee.id }}</td>
<td style="width: 25%" class="text-center">{{ valuee.value }}</td>
<td style="width: 25%" class="text-center">{{ valuee.price }}</td>
<td style="width: 25%" class="text-center">
<button class="btn btn-sm btn-primary">
<i class="fa fa-edit"></i>
</button>
<button class="btn btn-sm btn-danger">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
this is the output of the array returned from created function:
I'm developing a web application where I want to populate some field if I type computer_number I want to populate staff_old_name field that will select from staffs table.
This is what I've tried:
Template
<div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Computer Number</th>
<th>Old Name</th>
<th>New Name</th>
<th>Remarks</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(staff, index) in staffs">
<td>
<span v-if="staff.editmode"><input class="form-control" v-model="staff.computer_number"/></span>
<span v-else>{{staff.computer_number}}</span>
</td>
<td>
<span v-if="staff.editmode"><input class="form-control" v-model="staff.old_name"/></span>
<span v-else>{{staff.old_name}}</span>
</td>
<td>
<span v-if="staff.editmode"><input class="form-control" v-model="staff.new_name"/></span>
<span v-else>{{staff.new_name}}</span>
</td>
<td>
<span v-if="staff.editmode"><input class="form-control" v-model="staff.remarks"/></span>
<span v-else>{{staff.remarks}}</span>
</td>
<td>
<span v-if="!staff.editmode"><button class="btn btn-info" type="button" #click="edit(staff)">Edit</button></span>
<span v-else><button class="btn btn-success" type="button" #click="save(staff)">Save</button></span>
<span><button type="button" class="btn btn-danger" #click="remove(index)"><i class="fa fa-trash"></i></button></span>
</td>
</tr>
</tbody>
</table>
<div class="box-footer">
<button class="btn btn-info" type="button" #click="cloneLast">Add Row</button>
</div>
</div>
Script
export default {
data() {
return {
staffs: [],
data_results: []
}
},
computed:{
autoComplete(){
this.data_results = [];
if(this.computer_number.length > 2){
axios.get('/api/staffs/autocomplete',{params: {computer_number: this.computer_number}}).then(response => {
console.log(response);
this.data_results = response.data;
});
}
}
},
methods: {
edit :function(obj){
this.$set(obj, 'editmode', true);
},
save : function(obj){
this.$set(obj, 'editmode', false);
},
remove: function(obj){
this.staffs.splice(obj,1);
},
cloneLast:function(obj){
//var lastObj = this.staffs[this.staffs.length-1];
//lastObj = JSON.parse(JSON.stringify(lastObj));
obj.editmode = true;
this.staffs.push(obj);
},
},
created() {
axios.get('/staff-names')
.then(response => this.staffs = response.data);
},
}
when I type the computer number I want the staff_old_name field populated base on staff name which is stored in staffs table.
I am creating a form in which you add cities on the basis of countries you get from dynamic drop-down. I am able to get the category_id (foreign key) in Vuejs but I don't how to pass it to the laravel back-end. I want to create a subcategory object with name and category_id. category_id is foreign key. I am unable to get category_id and it is passing NULL to db.
**Category = Country**
**Subcategory = City**
<template id="add-post">
<div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>City Name</th>
<th>Country id</th>
</tr>
</thead>
<tbody>
<tr v-for="(subcategory, index) in citylist" :key="subcategory.id">
<td>{{ index + 1 }}</td>
<td>{{ subcategory.name }}</td>
<td>{{ subcategory.category_id }}</td>
</tr>
</tbody>
</table>
<h3>Add City</h3>
<form v-on:submit.prevent = "createPost">
<select v-model="countryid" name="country" class="form-control" #change="myFunction()">
<option countryid disabled>Select Country</option>
<option v-for="category in categories" v-bind:value='category.id' v-text="category.name">{{category.name}}</option>
</select>
<div class="form-group">
<label for="add-name">Name</label>
<input v-model="subcategory.name" class="form-control" required />
</div>
<button type="submit" class="btn btn-xs btn-primary">Add City</button>
<!-- <button v-on:click="setPostId()">click</button> -->
<router-link class="btn btn-xs btn-warning" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<script>
export default {
data: function () {
return {
categories: [],
category: '',
countryid:'',
subcategories: [],
subcategory: {name: '', category_id: ''}
};
},
mounted(){
this.loadCategories()
},
created: function() {
let uri = 'http://localhost:8000/cities/';
Axios.get(uri).then((response) => {
this.subcategories = response.data;
});
},
computed: {
citylist: function(){
if(this.subcategories.length) {
return this.subcategories;
}
}
},
methods: {
myFunction: function() {
console.log(this.countryid)
},
loadCategories(){
axios.get('/api/categories')
.then(response => this.categories = response.data)
.catch(error => console.log(error))
},
createPost: function() {
let uri = 'http://localhost:8000/addsubcategory/';
Axios.post(uri, this.subcategory).then((response) => {
this.$router.push({name: 'City'})
})
}
}
}
</script>
you can make drop down
<select v-model="fruit" id="deptList">
<option v-for="company_master in company_masters.data" v-bind:value="company_master.CompanyId"> {{company_master.CompanyName}}
</option>
</select>
and call the data with axios like
axios.get("api/company_master").then(response => (this.company_masters = response.data));
also define
company_masters:[],
fruit:'',