I have pretty simple table of users here with only 4 cols, and i want to show a button for each user depending on his status 'isActive'. If user is active i want to show button with text 'disable' and vice versa. I am little bit stuck with this because i dont have an idea how can i show these buttons, because i am using vuexy template for this project(admin panel). Is there a way to do this with JSX?
Please take a look at code, i am getting data from mysql with nodejs. Ask me if you need more info. Thanks.
<template>
<div>
<div class="container">
<b-card-text class="mb-2">
<div
v-if="showLoginError"
class="text-center bg-danger colors-container rounded text-white width-360 height-50 d-flex align-items-center justify-content-center mr-1 ml-50 my-1 shadow"
>
<span>{{ loginError }}</span>
</div>
</b-card-text>
<b-card-text class="mb-2">
<div
v-if="showSuccessMessage"
class="text-center bg-success colors-container rounded text-white width-360 height-50 d-flex align-items-center justify-content-center mr-1 ml-50 my-1 shadow"
>
<span>{{ successMessage }}</span>
</div>
</b-card-text>
<section id="card-actions" class="input-section">
<b-row>
<b-col cols="8">
<b-card-actions ref="cardAction">
<validation-observer ref="simpleRules">
<b-form>
<b-row>
<b-col md="6">
<b-form-group>
<validation-provider
#default="{ errors }"
name="First Name"
rules="required"
>
<b-form-input
v-model="name"
:state="errors.length > 0 ? false:null"
placeholder="Twitter username"
/>
</validation-provider>
</b-form-group>
</b-col>
<b-col cols="12">
<b-button
variant="primary"
type="submit"
#click.prevent="validationForm"
>
Submit
</b-button>
</b-col>
</b-row>
</b-form>
</validation-observer>
</b-card-actions>
</b-col>
</b-row>
</section>
// This is table
<b-table responsive="sm" :items="items"/>
</div>
</div>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate'
import {
BFormInput, BFormGroup, BForm, BRow, BCol, BButton, BTable,
} from 'bootstrap-vue'
import { required } from '#validations'
import axios from 'axios'
import { getUserToken } from '#/auth/auth'
export default {
components: {
ValidationProvider,
ValidationObserver,
BFormInput,
BFormGroup,
BForm,
BRow,
BCol,
BButton,
BTable,
},
data() {
return {
name: '',
successMessage: '',
showSuccessMessage: false,
loginError: '',
showLoginError: false,
required,
items: [],
}
},
beforeMount() {
this.getAllUsers()
},
methods: {
getAllUsers() {
const API_URL = `${this.$server}/api/twitter/allusers`
const params = {
token: getUserToken(),
}
axios.post(API_URL, null, { params }).then(res => {
if (res.data) {
res.data.forEach(element => {
let isActive = 'active'
if (element.isActive === 0) {
isActive = 'disabled'
}
const arr = {
twitter_name: element.twitter_name,
twitter_username: element.twitter_username,
twitter_id: element.twitter_id,
userActive: isActive,
}
this.items.push(arr)
})
}
})
},
validationForm() {
const API_URL = `${this.$server}/api/twitter/adduser`
const params = {
twitter_username: this.name,
token: getUserToken(),
}
axios.post(API_URL, null, { params }).then(res => {
if (res.data.success) {
this.successMessage = res.data.message
this.showSuccessMessage = true
// Hide message after 5sec
setTimeout(() => {
this.successMessage = ''
this.showSuccessMessage = false
}, 5000)
} else {
this.loginError = res.data.message
this.showLoginError = true
// Hide message after 5sec
setTimeout(() => {
this.loginError = ''
this.showLoginError = false
}, 5000)
}
})
},
},
}
</script>
I'm a little bit confused, where do you want to show your button ?
If it's in the table, you can use the custom templation of Bootstrap-Vue, you'll find the doc here with an example : https://bootstrap-vue.org/docs/components/table#custom-data-rendering
EDIT: here an example for your case
<b-table responsive="sm" :items="items">
<template #cell(userActive)="data">
<b-button v-if="data.userActive">Disabled</b-button>
<b-button v-else>Enabled</b-button>
</template>
</b-table>
Related
hi,what i want the result is once i click the icon it will update the database status from 0 to 1, icon color change to green and click again it will go back from 1 to 0 and icon color change from green to grey in bootstrap vue
<b-card v-else style="border:none;" >
<b-row v-for="(data,index) in my_name" :key="index" class=" p-3 bg-light" style="margin-bottom: 30px;" >
<b-col cols="12">
<b-row>
<b-col class="font-weight-bold">{{data.name}}<br><span class="font-weight-normal" style="color:#817F7F;"> </b-col>
<b-col class="mt-3 mb-0 view-more d-flex align-items-center justify-content-end" #click="changeStatus(data.id)">
<b-icon v-if="data.status=='done'" icon="check-circle-fill" font-scale="2" variant="success"></b-icon>
<b-icon v-else icon="check-circle-fill" font-scale="2" variant="secondary" ></b-icon>
</b-col>
</b-row>
</b-col>
</b-row>
</b-card>
export default {
data: () => ({
my_name:[],
}),
created(){
},
methods: {
changeStatus(id) {
axios.post('/api/name/update_my_name',{id,id}).then(res => res.data).then(res => {
if(this.res.data.status =='0'){
this.res.data.status == '1'
}
else{
this.res.data.status == '0'
}
})
.catch((error) => {
let error_msg = error.res.data.message;
this.$bvToast.toast(error_msg,{ variant:'danger', noCloseButton: true, solid:true})
this.loading = false;
});
},
}
So in your current implementation you changing the icon based on data.status which is my_name[index].data.staus. But when changing the data after api fetched, you assigning this.res.data.status = 0 or 1 which not relevant to what you binding on screen. So should change to:
HTML: Adding index to the click handler
<b-col class="mt-3 mb-0 view-more d-flex align-items-center justify-content-end" #click="changeStatus(data.id, index)">
<b-icon v-if="data.status=='done'" icon="check-circle-fill" font-scale="2" variant="success"></b-icon>
<b-icon v-else icon="check-circle-fill" font-scale="2" variant="secondary"></b-icon>
</b-col>
In the Viewmodel (I do not refactor your code) something like:
changeStatus(id, index) {
axios.post('/api/name/update_my_name',{id,id}).then(res => {
if(this.my_name[index].data.status =='0'){
this.my_name[index].data.status == '1'
} else {
this.my_name[index].data.status == '0'
}
})
.catch((error) => {
let error_msg = error.res.data.message;
this.$bvToast.toast(error_msg,{ variant:'danger', noCloseButton: true, solid:true})
this.loading = false;
});
}
I want to hide the buttons on the back of the modal window. When I open the modal window, the buttons on the back are visible in the modal window. I have tried use opasity etc.
Here is my code for modal form.
Modal form :
<template>
<popup-modal-spr style="opacity: $modal-backdrop-opacity; filter: alpha(opacity=50); background: rgba(0, 0, 0, 0.8); overflow: hidden;" ref="popup">
<confirm-dialogue-info ref="confirmDialogueInfo"></confirm-dialogue-info>
<h2 style="margin-top: 0">{{ titleListAllCustomers }}</h2>
<b-form-radio-group
v-model="selectedRadioTypeCustomerSearch"
:options="RadioModelTypeCustomerSearch"
value-field="itemTypeCustomerSerarch"
text-field="nameTypeCustomerSerarch"
disabled-field="notEnabled"
/>
<b-form-group
id="labelNameCustomerSearch"
content-cols-sm
description="Наименование клиента"
label="Наименование клиента"
label-for="NameCustomerSearch"
>
<b-form-input id="NameCustomerSearch" v-model="NameCustomerSearch" size="sm"></b-form-input>
</b-form-group>
<b-form-group
id="labelInnCustomerSearch"
content-cols-sm
description="ИНН клиента"
label="ИНН клиента"
label-for="InnCustomerSearch"
>
<b-form-input id="InnCustomerSearch" v-model="InnCustomerSearch" size="sm"></b-form-input>
</b-form-group>
<b-button
id="btnSearchCustomer" name="btnSearchCustomer"
#click="RefreshData"
variant="primary">
Поиск
</b-button>
<b-form-group align="center">
<b-container fluid>
<b-col>
<label>Фильтрация выгруженного списка :</label>
</b-col>
<b-col>
<b-input-group size="sm">
<b-form-input
id="filter-input"
v-model="filter"
type="search"
placeholder="Введите для фильтрации списка"
></b-form-input>
<b-input-group-append>
<b-button :disabled="!filter" #click="filter = ''">Очистить</b-button>
</b-input-group-append>
</b-input-group>
</b-col>
</b-container>
</b-form-group>
<div class="overflow-auto">
<b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
aria-controls="list-All-Customers"
></b-pagination>
<p class="mt-3">Текущая страница: {{ currentPage }}</p>
<!-- <b-button #click="RefreshData" variant="primary">Обновить</b-button> -->
<b-button #click="_confirm" variant="danger">Закрыть</b-button>
<b-table
:items="ListAllCustomers"
:fields="fields"
:per-page="perPage"
:current-page="currentPage"
:filter="filter"
:filter-included-fields="filterOn"
#filtered="onFiltered"
small
id="list-All-Customers"
ref="listAllCustomerssselect">
<template v-slot:cell(actions)="{item:{customerID}}">
<b-button size="sm" #click="_confirm(customerID)" variant="info" class="mr-2" >Выбрать</b-button>
</template>
</b-table>
</div>
</popup-modal-spr>
</template>
<script>
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import PopupModalSpr from './PopupModalSpr.vue'
Vue.use(VueAxios,axios);
axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
axios.defaults.headers.common['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS, PUT, PATCH, DELETE';
axios.defaults.headers.common['Access-Control-Allow-Headers'] = 'Origin,Content-Type,X-Requested-With,Accept,Authorization';
axios.defaults.headers.common['Authorization'] = "Bearer "+sessionStorage.authHash;
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
import ConfirmDialogueInfo from '/src/components/ConfirmDialogueInfo.vue'
export default {
name: 'ConfirmDialogue',
components: { PopupModalSpr,ConfirmDialogueInfo },
data() {
return{
NameCustomerSearch:"",
InnCustomerSearch:"",
selectedRadioTypeCustomerSearch: 0,
RadioModelTypeCustomerSearch: [
{ itemTypeCustomerSerarch: 0, nameTypeCustomerSerarch: 'Все' },
{ itemTypeCustomerSerarch: 1, nameTypeCustomerSerarch: 'Физ.' },
{ itemTypeCustomerSerarch: 2, nameTypeCustomerSerarch: 'Юр.' },
],
rows:0,
perPage: 15,
currentPage: 1,
titleListAllCustomers:undefined,
resolvePromise: undefined,
rejectPromise: undefined,
filter: null,
filterOn: [],
ListAllCustomers:[],
fields: [
{
key: 'customerID',
label:"ИД клиента",
},
{
key: 'nameCustomer',
label:"Название клиента",
},
{
key: 'actions',
label:"Действие",
},
],
}
},
methods:
{
onFiltered(filteredItems) {
// Trigger pagination to update the number of buttons/pages due to filtering
this.totalRows = filteredItems.length
this.currentPage = 1
},
rows() {
this.rows=this.ListAllCustomers.length
return this.rows
},
show(opts = {}) {
this.titleListAllCustomers = opts.title
// this.RefreshData();
this.$refs.popup.open()
// Return promise so the caller can get results
return new Promise((resolve, reject) => {
this.resolvePromise = resolve
this.rejectPromise = reject
})
},
_confirm(item) {
this.$refs.popup.close()
const SelectedCustomers= this.ListAllCustomers.filter(i=>i.customerID == item);
this.resolvePromise(SelectedCustomers[0])
},
_cancel() {
this.$refs.popup.close()
this.resolvePromise(false)
},
RefreshData() {
this.isBusy = !this.isBusy
const HeaderBearer="Bearer "+sessionStorage.authHash
axios.post
(
`/api/SprsObGets/GetCustomers`,
{
TypeCustomer:this.selectedRadioTypeCustomerSearch,
NameCustomer:this.NameCustomerSearch,
IdentificationNumberCustomer:this.InnCustomerSearch,
},
{
headers:
{
"Authorization": HeaderBearer
},
mode: 'no-cors',
credentials: 'include'
}
)
.then((result)=>{
this.ListAllCustomers = result.data;
this.rows=this.ListAllCustomers.length;
console.warn(result.data);
})
.catch(err => {
if(err.response.status==401)
{
sessionStorage.loginIn = false;
sessionStorage.setItem("UsersMenuItems", JSON.stringify("")) ,
sessionStorage.authHash = "",
sessionStorage.setItem("ObInfoSys", JSON.stringify("")),
sessionStorage.setItem("UsersData", JSON.stringify("")),
this.$router.push({
path: '/Auth'
});
}
else{
this.$refs.confirmDialogueInfo.show({
title: 'Ошибка',
message: err.response.data.errorText,
cancelButton: 'ОК',
});
}
})
this.isBusy = !this.isBusy
}
},
}
</script>
I want to hide the buttons on the back of the modal window. When I open the modal window, the buttons on the back are visible in the modal window. I have tried use opasity etc.
Here is my code for modal form.
I need your help solving a problem ...
I'm new to vue and I can't use modal bootstrap-vue.
I need to load a form with the data into my "MODAL" so that I can change it, but I can't load this data by the user ID inside the modal form.
<PageTitle icon="fa fa-cogs" main="Administração" sub="Feriados" />
<b-table hover striped :items="feriados" :fields="fields" small class="mt-0 mb-0">
<template slot="actions" slot-scope="data">
<b-button variant="warning" #click="loadFeriado(data.item)" class="mr-2" size="sm">
<i class="fa fa-pencil"></i>
</b-button>
<b-button variant="info" #click="viewFeriado" class="mr-2" size="sm">
<i class="fa fa-pencil"> Editar</i>
</b-button>
</template>
</b-table>
<div>
<b-modal ref="showFeriado"
title="Visualizar Feriado"
size="xl"
#shown="loadFeriado"
#hidden="reset"
#ok="save"
ok-variant="primary"
cancel-title="Cancelar">
<div>
<input id="feriado-id" type="hidden" v-model="feriado.id"/>
<b-row class="mt-0 mb-0">
<b-col md="6" sm="12">
<b-form-group
label="Data do Feriado:"
label-for="feriado-data"
label-size="sm"
class="mt-0 mb-0">
<v-date-picker v-model="feriado.data" />
</b-form-group>
</b-col>
<b-col md="6" sm="12">
<b-form-group label="Nome:" label-for="feriado-descricao" label-size="sm">
<b-form-input id="feriado-descricao" type="text"
size="sm"
v-model="feriado.descricao" required
:readonly="mode === 'remove'"
placeholder="Informe o nome do Feriado..." />
</b-form-group>
</b-col>
</b-row>
</div>
</b-modal>
</div>
</div>
</template>
<script>
import PageTitle from '../template/PageTitle'
import axios from 'axios'
import { baseApiUrl, showError, userKey } from '#/global'
import moment from 'moment'
export default {
name: 'FeriadoAdmin',
components: {
PageTitle,
moment,
},
data: function() {
return {
mode: 'save',
feriado: {},
feriados: [],
fields: [
{ key: 'id', label: 'Número', sortable: true },
{
key: 'descricao',
label: 'Descrição',
sortable: true
},
{
key: 'data',
label: 'Data',
sortable: true,
formatter: (value, key, item) => {
return moment.utc(value).format('DD/MM/YYYY')
}
},
{
key: 'actions',
label: 'Status'
}
]
}
},
methods: {
viewFeriado () {
this.$refs.showFeriado.show()
},
loadFeriados() {
axios.get(`${baseApiUrl}/feriados`)
.then((list) => {
this.feriados = list.data
})
},
loadFeriado(feriado) {
this.feriado = {
...feriado,
data: moment.utc(feriado.data).toDate()
}
//console.log(feriado)
}
},
mounted() {
this.loadFeriados()
}
}
</script>
<style>
</style>
This console error occurs when attempting to load data into the modal form:
Why my b-table displays all columns of my table even I only selected some?
Here is my server-side code that calls the selected columns. Also, it worked if I use bootstrap only not bootstrap-vue.
router.get('/users', function(req, res) {
/* Get the person who has the latest date */
let getUser = "SELECT DISTINCT(MEMB.MEMB_N), MAX(PrintDate) AS PrintDate, MEMB.* \
FROM MEMB LEFT JOIN VD_Print ON MEMB.MEMB_N = VD_Print.MEMB_N GROUP BY MEMB.LAST_M \
ORDER BY PrintDate DESC LIMIT 100;"
myDB.query(getUser, function(err, rows) {
if (err) {
console.log(err);
} else {
console.log(rows);
res.send(rows);
}
});
});
And this one is on my client-side which is vuejs
<template>
<section>
<div class="sidebar"></div>
<div>
<b-form-input class="searchBar" placeholder="Search Here"></b-form-input>
</div>
<div>
<b-table class="table" striped hover :items="results"></b-table>
</div>
<b-button class="printBtn">PRINT</b-button>
</section>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
results: [],
};
},
mounted() {
this.getUsers();
},
methods: {
getUsers: function() {
axios
.get("http://localhost:9000/api/users/")
.then(response => (this.results = response.data))
.catch(error => alert(error));
}
}
};
</script>
My JSON looks like this:
You need to define the your column name in field definition of b-table. If you multiple filed in response but you want to display some fields.
Please below code and working demo.
CODE SNIPPET
export default {
data() {
return {
selectAll: false,
records: [],
perPage: 10,
currentPage: 1,
pageOptions: [5, 10, 15],
column: [{
key: "name",
sortable: true,
label: "Log File Name"
}, {
key: "lastModified",
sortable: true,
label: "Last Modified Date",
class: "text-right options-column"
}]
};
}
}
<template>
<div>
<div v-if="!hasRecords" style="text-align: center"><br><br>LOADING DATA...</div>
<div style="padding: 15px;" v-if="hasRecords">
<b-table :items="records" :fields="column" striped hover :current-page="currentPage" :per-page="perPage">
</b-table>
<b-row>
<b-col md="6" class="my-1">
<b-pagination :total-rows="totalRows" :per-page="perPage" v-model="currentPage" class="my-0" />
</b-col>
<b-col md="6" class="my-1">
<b-form-group horizontal label="Per page" class="mb-0">
<b-form-select :options="pageOptions" v-model="perPage" />
</b-form-group>
</b-col>
</b-row>
</div>
</div>
</template>
i want to do filter and pagination in my view-candidates page..i want to display the candidates depending on the name and experience and expected ctc..i want to display the candidates..
Can anyone help me how to do that in vuejs...
Here is my view-candidates.blade.php
<div class="container">
<div class="row">
<el-row :gutter="12">
<el-col>
<p>View Candidates</p>
</el-col>
</el-row>
<el-row :gutter="12">
<template v-for="c in candidates">
<el-col :span="6">
<Candidate :c="c" :key="c.id"></Candidate>
</el-col>
</template>
</el-row>
</div>
here is my view-candidates.js page:
import Candidate from './components/Candidate.vue';
const app = new Vue({
el: '#app',
data() {
return {
candidates: window.data.candidates,
sortKey : 'first_name'
}
},
components: { Candidate },
});
here is my candidate.vue page:
<template>
<ElCard>
<div slot="header">
<strong>
{{c.first_name.toUpperCase() + ' ' + c.last_name.toUpperCase()}}
<br />
<small>{{c.role}} - {{c.experience}} Years</small>
</strong>
</div>
<p><strong>{{c.contact_no}} : {{c.email}}</strong></p>
<p>
<strong>Currently at:</strong> {{c.current_location}}
<br />
<strong>Ready to move:</strong> {{c.desired_location}}
</p>
<ElButton type="primary" size="small" #click="ResumeDialog = true">VIEW RESUME</ElButton>
<ElDialog class="text-left" :title="c.first_name.toUpperCase() + ' ' + c.last_name.toUpperCase()" v-model="ResumeDialog">
<p><strong>{{c.role}} - {{c.experience}} Years</strong></p>
<p>
<strong>Currently at:</strong> {{c.current_location}}
<br />
<strong>Ready to move:</strong> {{c.desired_location}}
</p>
<p>{{c.resume}}</p>
<br />
<p><strong>{{c.contact_no}} : {{c.email}}</strong></p>
</ElDialog>
</ElCard>
//script
import { Button as ElButton, Dialog as ElDialog, Card as ElCard } from 'element-ui';
import axios from 'axios';
export default {
props: ['c'],
data() {
return {
ResumeDialog: false,
}
},
components: { ElButton, ElDialog, ElCard },
}
Can anyone help me how to do that..
TIA..
In your view-candidates.js it should be like that:
import Candidate from './components/Candidate.vue';
const app = new Vue({
el: '#app',
data() {
return {
sortKey : 'first_name',
page: 0,
itemsPerPage: 4,
}
},
components: { Candidate },
methods: {
//custom method bound to page buttons
setPage(page) {
this.page = page-1;
this.paginedCandidates = this.paginate()
},
paginate() {
return this.filteredCandidates.slice(this.page*this.itemsPerPage, this.itemsPerPage * this.page + this.itemsPerPage)
},
},
computed: {
//compute number of pages, we always round up (ceil)
numPages() {
return Math.ceil(this.filteredCandidates.length/this.itemsPerPage);
},
filteredCandidates() {
//filter out all candidates that have experience less than 10
const filtered = window.data.candidates.filter((candidate) => {
//e.g.
if(candidate.experience < 10) {
return false;
}
return true;
})
return filtered;
},
paginedCandidates() {
return this.paginate()
}
}
});
And you render the buttons in the template:
<div class="container">
<div class="row">
<el-row :gutter="12">
<el-col>
<p>View Candidates</p>
</el-col>
</el-row>
<el-row :gutter="12">
<template v-for="c in paginedCandidates">
<el-col :span="6">
<Candidate :c="c" :key="c.id"></Candidate>
</el-col>
</template>
</el-row>
<el-row>
<!-- setPage is our method defined in methods object -->
<button v-for="n in numPages" #click="setPage(n)">#{{ n }}</button>
</el-row>
</div>
I believe this should do the magic. Probably you'll have to adjust it a little bit to your needs.