How to remove the whole column in vue table? - vue.js

I have a problem in removing the whole column and its corresponding row in vue-table.
Here is my code.
<b-table :fields="fields" :items="data">
<template slot="action" slot-scope="data" v-if="authorize = 1">
</template>
</b-table>
export default{
data(){
authorize: 0,
data: [],
fields: [
{key: 'id', label: '#'},
{key: 'name', label: 'Name'},
{key: 'action', label: 'Action'}
],
}
}
In this case, When I use v-if inside the <template> it only removes the corresponding row of the column.
This is the result of the code above
| # | Name | Action |
----------------------------------------
| 1 | John Doe | |
| 2 | Chicharon Ni Mang Juan | |
| 3 | Lumanog | |
My Problem is, I want to remove the column itself like this.
| # | Name |
------------------------------
| 1 | John Doe |
| 2 | Chicharon Ni Mang Juan |
| 3 | Lumanog |
#Regards,

With vue-tables-2 I don't think there's any other choice but to have conditional for different column sets, like in computed. For example:
computed: {
fields: function() {
let fields = [{key: 'id', label: '#'}, {key: 'name', label: 'Name'}]
if (this.authorize === 1) {
fields.push({key: 'action', label: 'Action'})
}
return fields
}
}

I just found a simple solution by not using the table on this way:
<b-table :fields="fields" :items="data">
<template slot="action" slot-scope="data" v-if="authorize = 1">
</template>
</b-table>
I just used this simple html table:
<table class="table" style="width:100%">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th v-if="authorize == 1">Action</th>
</tr>
</thead>
<tbody>
<tr v-for="user in data">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td v-if="authorize == 1">
<button variant="primary">Delete</button>
</td>
</tr>
</tbody>
</table>
Here, I can easily manipulate to remove/show the column and its data.
Thanks!

Related

Get all the data from an Array

I have an API which was developed using Laravel and i am trying to pass the data into vue js to display it.
The data is like this
electData: Object
category: Array[3]
0: Object
cat_desc: modified
category_id: 95
cost: 56
kwh_used: 99
1: Object
cat_desc: modified
category_id: 95
cost: 56
kwh_used: 99
2: Object
cat_desc: modified
category_id: 95
cost: 56
kwh_used: 99
And i tried to render it by using v-for
<tr>
<td class="clickOption" #click="first">{{ (electCats.category[0].cat_desc) }}</td>
<td>{{ electCats.category[0].kwh_used }}</td>
<td>£{{ electCats.category[0].cost }}</td>
</tr>
The above code display the first object in the array.
My question is that how do i get the 2nd, 3rd etc in the array because when i do this
<tr>
<td class="clickOption" #click="second">{{ (electCats.category[1].cat_desc) }}</td>
<td>{{ electCats.category[1].kwh_used }}</td>
<td>£{{ electCats.category[1].cost }}</td>
</tr>
I get error [Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'cat_desc')"
How can i avoid this error?
[Vue warn]: Error in render: "TypeError: Cannot read properties of
undefined (reading 'cat_desc')"
As per the error, It seems you are trying to access an object from category array which is not available.
Working Demo :
const app = new Vue({
el: '#app',
data() {
return {
electData: {
category: [{
cat_desc: 'Description 1',
category_id: 1,
cost: 51,
kwh_used: 97
}, {
cat_desc: 'Description 2',
category_id: 2,
cost: 52,
kwh_used: 98
}, {
cat_desc: 'Description 3',
category_id: 3,
cost: 53,
kwh_used: 99
}]
},
filteredData: []
}
},
methods: {
getCategoryDetails(categoryId) {
this.filteredData = this.electData.category.filter((obj) => obj.category_id === categoryId)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button v-for="category in electData.category" :key="category.category_id" style="border: 1px solid black" #click="getCategoryDetails(category.category_id)">
{{ category.category_id }}
</button>
<table>
<tr v-for="category in filteredData" :key="category.category_id">
<td>{{ (category.cat_desc) }}</td>
<td>{{ category.kwh_used }}</td>
<td>£{{ category.cost }}</td>
</tr>
</table>
</div>
I would v-for on the <tr> element, something like:
<tr v-for "(category, index) in electCats.category" :key="index" >
<td class="clickOption" #click="categoryClick(index)">{{ (category.cat_desc) }}</td>
<td>{{ category.kwh_used }}</td>
<td>£{{ category.cost }}</td>
</tr>
Where categoryClick() is the function induced by clicking a row. You probably want to pass a parameter into the #click-induced function, perhaps the index, so that the function knows which element you have clicked on.

How to display column data under a specific column in react bootstrap table

I am create a React Bootstrap Table using data from an array. There can be 4 or 5 columns depending on the array, 3 or 4 of them with data from the array and I want the final column 'Admin' to always contain 2 button. So in the below example there are 4 players and a time taken from the array, but in the array there are 6 players, so the first row is full, and the second row only has 2 players. This is what I am currently getting
Time | player1 | player 2 | player 3 | player4 | Admin
_____________________________________________________________________________________
10:00 | Joe B | Mike A | John S | Paul W | button 1, button 2
______________________________________________________________________________________
10:10 | Karl A | Sean F | button 1, button 2 | |
I want the 2 buttons to always be in the Admin column, even if other columns are not populated.
Time | player1 | player 2 | player 3 | player4 | Admin
_____________________________________________________________________________________
10:00 | Joe B | Mike A | John S | Paul W | button 1, button 2
______________________________________________________________________________________
10:10 | Karl A | Sean F | | | button 1, button 2
Code for the tables,
<Table striped bordered hover responsive>
<thead>
<tr>
<th >Tee time</th>
<th >Player 1</th>
<th>Player 2</th>
<th>Player 3</th>
{teeTimes[0] !== undefined && teeTimes[0].noOfSlots === 4 &&
<th>Player 4</th>}
{props.loggedInUser.role === 'ADMIN' &&
<th id='admin'>Admin</th>}
</tr>
</thead>
{teeTimes.map((teetime =>
<tbody key={teetime.id}>
<tr>
<td>{teetime.teeTime}</td>
{teetime.entrants.map((entrant) =>
<td>{entrant.member['firstName']} {entrant.member['surname']} ({entrant.member['handicap']})</td>
)}
{props.loggedInUser.role === 'ADMIN' &&
<td headers='admin'>
<button className="btn btn-danger m-2" onClick={() => deleteTeeSheet(teetime.id)}>delete</button>
<button className="btn btn-warning m-2" onClick={() => handleShowEditTeeTime(teetime.id)}>Update</button>
</td>}
</tr>
</tbody>
))}
</Table>
Is there a way to tell the table that the buttons <td> should always be under the admin <th>

vue.js - How to split array of objects and display in two different columns

I have two columns with name and age.The jason returns the following object.I would to return the value under name and age column.
Students: {
details: [
{ John: 21 },
{ Brian: 22 },
{ Ryan: 21 },
<tbody>
<tr v-for= "(item,index) in Students.details" :key="index" >
<td ">
{{item --(should display name)}}
</td>
<td">
{{item --(should display age)}}
</td >
</tr>
</tbody>
This could work out:
<tbody>
<tr v-for= "(item, index) in Students.details" :key="index" >
<td>
{{Object.keys(item)[0]}}
</td>
<td>
{{item[Object.keys(item)[0]]}}
</td >
</tr>
</tbody>
There are many ways to solve your problem, but I suggest to arrange the data first to a simpler form then render them. For example, use computed to change the form first.
computed: {
dataArray() {
return Object.keys(this.Students).map(name => {
return {
name: name,
age: this.Students[name]
}
})
}
}
// you can get an array [{name: "John", age: 21}, {name: "Brian", age: 22}, ...]
Then in the template just show the data:
<tr v-for= "item in dataArray" :key="item.name">
<td>
{{ item.name }}
</td>
<td>
{{ item.age }}
</td >
</tr>

how to have Vuex mapState with computed properties in vuejs

I'm trying to learn Vuex and tried adding the mapState with local computed property in my Vuejs 2.0 application on top of Laravel 5.4, now while adding so I'm getting following error:
Syntax Error: Unexpected token, expected , (379:32)
377 | },
378 | mapState({
> 379 | contactStore: state => state.contactStore
| ^
380 | })
381 | }
382 | }
Here is my component:
<template>
<div class="row">
<div class="table-responsive">
<table class="table table-striped">
<tbody>
<tr>
<th class="text-left">Contact Name</th>
<th class="text-left">Company Name</th>
<th class="text-left">City</th>
<th class="text-left">Email</th>
<th class="text-left">Mobile</th>
<th class="text-left">Type</th>
<th class="text-left">SubType</th>
<th class="text-left">Profile</th>
</tr>
<tr v-for="(item, index) in tableFilter">
<td class="text-left"><a #click="showModal(item)" data-toggle="modal" data-target="#showContactModal">{{ item.first_name+' '+item.last_name }}</a></td>
<td class="text-left">{{ item.company.name }}</td>
<td class="text-left">{{ item.city }}</td>
<td class="text-left">{{ item.email }}</td>
<td class="text-left">{{ item.mobile }}</td>
<td class="text-left"><span class="badge badge-info">{{ item.company.type }}</span></td>
<td class="text-left"><span class="badge badge-info">{{ item.company.sub_type }}</span></td>
<td class="text-left"><span class="badge badge-info">{{ item.profile }}</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
data(){
return {
id: '',
search: '',
model: []
}
},
computed: {
tableFilter: function () {
const searchTerm = this.search.toLowerCase();
if(this.model)
{
return this.model.filter((item) =>
(item.first_name.toLowerCase().includes(searchTerm)
|| (item.last_name !==null && item.last_name.toLowerCase().includes(searchTerm))
|| (item.company.name !==null && item.company.name.toLowerCase().includes(searchTerm))
);
}
},
mapState({
contactStore: state => state.contactStore
})
}
}
</script>
I'm trying to replace table filter computed property with the current contact_list state, how can I achieve this or I'm doing some mistake, even if I do ...mapState({}) it is showing me same type of error:
Syntax Error: Unexpected token (378:8)
376 | }
377 | },
> 378 | ...mapState({
| ^
379 | contactStore: state => state.contactStore
380 | })
381 | }
what can be done guide me. Thanks
You are getting this error because the babel is not working on your vue file. The laravel-mix library should do this for you, but if you are manually configuring the file using a webpack.config.js file, you will have to attach a babel loader to the vue loader.
I answered this question on another thread... https://stackoverflow.com/a/49581031/1718887

table header not getting aligned with table contents while using scrollX = true

I've a dataTable where I have to display the contents fetched from the database. But the problem is , I have to display the contents inside a div. While using "scrollX": true, the table header does not align with the table contents.
It gets displayed like this:
| S.No | Name | Reg. No. | Course |
| 1 | Balamurugan | 211311106078 | BE. Electronics and Communication |
| 2 | Sai Krishna S | 211311107098 | BE. Computer Science |
But it should be like this:
| S.No | Name | Reg. No. | Course |
| 1 | Balamurugan | 211311106078 | BE. Electronics and Communication|
| 2 | Sai Krishna S | 211311107098 | BE. Computer Science |
This is how I tried:
<?php
include("includes/config.php");
$report = $_GET["report"];
$title = $_GET["title"];
$pagetitle = $title;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php include("includes/inc-head.php"); ?>
</head>
<body role="document">
<?php include("includes/inc-header.php"); ?>
<div class="panel-body form-horizontal">
<div class="panel panel-default">
<div class="panel-heading">
<?php echo $title; ?>
<input type="hidden" id="input_report" name="input_report" value="<?php echo $report; ?>">
<div id="toolbar" name="toolbar" class="btn-group pull-right">
<button id="full_view" name="full_view" type="button" class="btn btn-info btn-sm" onclick="window.open('fullview-for-dashboard.php');">
Full View
</button>
</div>
</div>
<div class="panel-body form-horizontal">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="table_dashboard" class="table table-colstriped table-bordered table-hover hide">
<thead>
<tr>
<th></th>
<th>Total Mark</th>
<th>Total Percentage</th>
<th>Name of the Student</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="table_profit" class="table table-bordered table-colstriped table-hover hide">
<thead>
<tr>
<th>S. No</th>
<th>Name</th>
<th>Reg. No.</th>
<th>Chain Name</th>
<th>Course</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript" language="javascript">
jQuery(document).ready(function(){
jQuery.ajaxSetup({cache: false});
var input_report = jQuery("#input_report").val();
var table_id = "#table_" + input_report;
jQuery(table_id).removeClass("hide").addClass("show");
jQuery(table_id).dataTable({
dom: "<'row'<'col-sm-12'Bftri>>" + "<'row'<'col-sm-4'l><'col-sm-8'p>>",
"sAjaxSource": "db.php?repor_name=" + input_report,
"bDestroy": true,
"scrollX": true,
"bInfo": true,
select: true,
buttons: [{
extend: 'collection',
text: 'Export',
buttons:[
{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'LEGAL',
text: '<i class="fa fa-file-pdf-o">&nbsp&nbsp&nbsp&nbsp&nbspPDF</i>',
titleAttr: 'PDF'
},
{
extend: 'excelHtml5',
orientation: 'landscape',
pageSize: 'LEGAL',
text: '<i class="fa fa-file-excel-o">&nbsp&nbsp&nbsp&nbsp&nbspEXCEL</i>',
titleAttr: 'Excel'
},
{
extend: 'csvHtml5',
orientation: 'landscape',
pageSize: 'LEGAL',
text: '<i class="fa fa-file-text-o">&nbsp&nbsp&nbsp&nbsp&nbspCSV</i>',
titleAttr: 'CSV'
},
{
extend: 'copyHtml5',
orientation: 'landscape',
pageSize: 'LEGAL',
text: '<i class="fa fa-files-o">&nbsp&nbsp&nbsp&nbsp&nbspCOPY</i>',
titleAttr: 'Copy'
}
]
},
{
extend: 'print',
orientation: 'landscape',
pageSize: 'LEGAL'
}
]
});
});
</script>
</body>
</html>
What should I add along with this, so that the table will be displayed properly?
I had the same issue. Seems like it's caused by the way how resizing is handled in the product.
I was able to fix by triggering resize event:
$(window).trigger('resize');
In the source of DataTables you can find the code:
var bindResize = function () {
$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
_fnAdjustColumnSizing( oSettings );
} ) );
It binds _fnAdjustColumnSizing to resize, but sometime resize isn't triggered.
Update:
Try to set a table width in scrollX parameter:
$('#table').dataTable({
...
scrollX: '100%',
...
});
You need a reference to the DataTable:
var table = $('#table').DataTable();
Then, you need some combination of this:
table.draw();
table.columns.adjust();
table.scroller.measure();
You may need to defer the code for reasons...
setTimeout(function() {
table.draw();
table.columns.adjust();
table.scroller.measure();
}, 1);