How to reload data in material table when state changes? - material-table

I am trying to re-render material-table when my state (props.office, props.department) changes. The data seems to reload but the page number stays the same, for example if I was on page 2 and the state changed, it calls for data for page 2 instead of calling data for page 1. Here's the code to elaborate on what I am trying to do:
function PastMaterialTable(props) {
const [isLoading, setIsLoading] = useState(true);
const tableRef = React.createRef()
useEffect(() => {
tableRef.current.onQueryChange();
},[props.office, props.department])
function questionSearch(query) {
setIsLoading(true);
return new Promise((resolve, reject) => {
let url = "https://reqres.in/api/users?";
url += "per_page=" + query.pageSize;
url += "&page=" + (query.page + 1);
url += "&office=" + (props.office + 1);
url += "&department=" + (props.department + 1);
console.log("fetching data for office: " + props.office + ", department: " + props.department + " and questions of type: " + "past" + " query pagesize: " + query.pageSize + " query page: " + (query.page+1));
fetch(url)
.then(response => response.json())
.then(result => {
setIsLoading(false);
resolve({
data: result.data,
page: result.page - 1,
totalCount: result.total
});
});
})
}
return (
<MaterialTable
tableRef= {tableRef}
columns={[
{ title: "Question", field: "id", width: 400 },
{ title: "Category", field: "first_name", width: 100 },
{ title: "Date", field: "last_name", width: 100 }
]}
data={questionSearch}
isLoading={isLoading}
options={{
showFirstLastPageButtons: false,
showEmptyDataSourceMessage: true,
toolbar: false,
pageSize: 10,
pageSizeOptions:[10],
sorting: false
}}
onRowClick={handleQuestionPopup}
/>
);
}
Any input on how I can reset my query will be appreciated

Related

How do i pass data to a function under data in vuejs

I tried to reference this.items in the function in taskList.cls.cls
the main idea is to run a task in vue-terminal then pass the result of the post request to this.items but it's returning undefined
data() {
return {
//this is the data i want to pass the post response to
items: [],
query: '',
taskList: {
// your tasks
cls: {
description: 'Clear Terminal',
cls: this, async(pushToList) {
const p = new Promise(resolve => {
this.query = 'SELECT * FROM notifications'
const token = localStorage.getItem('token')
axios.post('/query', {'query': this.query}, {
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
}
}).then(res => {
//i want to reference
**this.items = res.data.data.result**
//
pushToList({type: 'system', label: 'Running query', message: 'Please wait!!'})
}).catch(err => {
console.log(err)
})
setTimeout(() => {
resolve({type: 'success', label: 'Success', message: 'Success!'})
this.test = "worked"
}, 2000)
})
return p
}
}
},
commandList: {
// your commands
}
}
},
Don't do that, call api on "mount()".

Datatable.Net - Search by columns is not rendering

I'm using jQuery datatable.net to render a table (server-side). Everything including filtering is working fine. I elected to implement searching by column and I just can't seem to get it to render the values. When I type in a value, the "Processing" window displays and immediately goes away (which tells me that the search string is being processed) however the search results are not being displayed.
My datatable script is as follows:
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
$('#contacts tfoot th').each(function () {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
var contactlist = $('#contacts').DataTable({
responsive: true,
destroy: true,
orderMulti: true,
processing: true,
serverSide: true,
stateSave: true,
stateSaveCallback: function (settings, data) {
localStorage.setItem('DataTables_' + settings.sInstance, JSON.stringify(data))
},
stateLoadCallback: function (settings) {
return JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance))
},
oLanguage: {
sSearch: ""
},
pagingType: "full_numbers",
filter: true,
rowId: "id",
order: [[1, "asc"]],
ajax: {
url: "/Contact/GetContactList",
type: "POST",
datatype: "json"
},
columnDefs: [{
targets: [0],
visible: false,
searchable: false
}],
"columns": [
{ data: "id", name: "Id", autoWidth: true},
{ data: "firstName", name: "FirstName", autoWidth: true },
{ data: "lastName", name: "LastName", autoWidth: true },
{ data: "company", name: "Company", autoWidth: true },
{
data: null,
name: "Phone",
autoWidth: true,
defaultContent: "",
render: function (data, type, row) {
var cell = "";
var office = "";
var other = "";
if (row.phoneCell != null) {
cell = "<i class='fas fa-mobile-alt'></i><a href='tel:" + row.phoneCell + "'> " + "<small>" + row.phoneCell + "</small></a>";
}
if (row.phoneOffice != null) {
if (cell != "") { office = "<br />"; }
office = office + "<i class='fas fa-building'></i><a href='tel:" + row.phoneOffice + "'> " + "<small>" + row.phoneOffice + "</small></a>";
}
if (row.phoneOther != null) {
if (office != "") { other = "<br />"; }
other = other + "<i class='fas fa-phone-square-alt'></i><a href='tel:" + row.phoneOther + "'> " + "<small>" + row.phoneOther + "</small></a>";
}
return cell + office + other;
}
},
{
data: "webSite",
name: "WebSite",
autoWidth: true,
defaultContent: "",
render: function (data, type, row) {
if (row.webSite != null) {
return "<i class='fas fa-globe-americas'></i><a href='" + row.webSite + "' target='_blank'> " + "<small>" + row.webSite + "</small></a>";
}
}
},
{ data: "campaign", name: "Campaign", autoWidth: true, defaultContent: "" },
],
initComplete: function () {
var r = $('#contacts tfoot tr');
r.find('th').each(function () {
$(this).css('padding', 8);
});
$('#contacts thead').append(r);
$('#search_0').css('text-align', 'center');
var api = this.api();
api.columns().every(function () {
var that = this;
$('input', this.footer()).on('keyup change', function () {
if (that.search() !== this.value) {
that.search(this.value);
that.draw();
}
});
});
}
});
$('.dataTables_filter input[type="search"]').
attr('placeholder', 'Filter by first/last name or company ...').
css({ 'width': '350px', 'display': 'inline-block' });
$('#contacts tbody').on('click', 'tr', function () {
debugger;
var currentRowData = contactlist.row(this).data();
var id = currentRowData.id;
var url = "#Url.Action("View", "Contact")?id=" + id;
window.open(url,"_parent");
});
});
</script>
Any idea what I'm doing wrong?
Thanks.
-- Val

How can I put sign (%) on data in ChartJS?

I want to add the sign (%) next to the value. The problem is when I concatenate sign (%) the pie chart is not showing data: vm.distributed_per_day.map(item => (item.Amount / sum * 100).toFixed(2) + '%'). How can I add the sign (%) to my pie chart? Can somebody help me with my problem? Here's my code
retrieveDistributedPerDayByPie : function() {
var self = this;
var sum = 0;
axios.post(this.urlRoot + this.api + "retrieve_transaction_per_day.php")
.then(response => {
console.log(response);
vm.distributed_per_day = response.data
var ctxChart = self.$refs.myChart2.getContext('2d');
for(var i = 0; i < this.distributed_per_day.length; i++) {
sum += parseFloat(this.distributed_per_day[i].Amount);
}
var myChart2 = new Chart(ctxChart, {
type: 'pie',
data: {
labels: vm.distributed_per_day.map(item => item.Day),
datasets: [{
label: 'Total Amount',
data: vm.distributed_per_day.map(item => (item.Amount / sum * 100).toFixed(2) + '%'),
backgroundColor: this.poolColors(vm.distributed_per_day.length),
borderColor: '#eee',
borderWidth: 2
}]
},
reponsive : true,
options: {
title : {
display : true,
text : "Distributed Reports per Day",
fontFamily: "sans-serif",
fontSize: 18,
},
legend: {
display: false
},
tooltips: {
enabled: true
}
}
});
}).catch(e => {
console.log(e)
});
},
This works on a bar chart, haven't tried it on a pie chart. Hope it works for you.
yAxes: [
{
ticks: {
callback: function (value, index, values) {
return value + " %";
}
}
}
]
This solution worked for me.
tooltips: {
mode: 'label',
callbacks: {
label: function (tooltipItem, data) {
var indice = tooltipItem.index;
return data.labels[indice] + ': ' + data.datasets[0].data[indice] + '%';
}
}
}

Different color for each bar in a bar graph in ChartJS and VueJS

I want each color of the bar is different depending on the data I have in the database. The problem is when I used the codes below it only change the first bar the rest is not. How can I change each bar? Can somebody help me with my problem? Here's my code below
dynamicColor : function() {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
return "rgba(" + r + "," + g + "," + b + ", 0.5)";
},
poolColors : function(a) {
var pool = [];
for(var i = 0; i < a; i++) {
pool.push(this.dynamicColor());
}
return pool;
},
retrieveDistributedPerDayByLine : function() {
var self = this;
axios.post(this.urlRoot + this.api + "retrieve_transaction_per_day.php")
.then(response => {
console.log(response);
vm.distributed_per_day = response.data
var ctxChart = self.$refs.myChart.getContext('2d');
var myChart = new Chart(ctxChart, {
type: 'bar',
data: {
labels: vm.distributed_per_day.map(item => item.Day),
datasets: [{
label: 'Total Amount',
data: vm.distributed_per_day.map(item => item.Amount),
backgroundColor: [
this.poolColors(vm.distributed_per_day.length)
],
borderColor: [
this.poolColors(vm.distributed_per_day.length)
],
borderWidth: 1
}]
},
reponsive: true,
options: {
title : {
display : true,
text : "Distrubuted Reports per Day",
fontFamily: "sans-serif",
fontSize: 18
},
legend: {
display: false
},
tooltips: {
enabled: true,
padding: 10
}
}
});
}).catch(e => {
console.log(e)
});
},
the this.poolColors method is returning an array so you are passing an array inside an array hence it is considered as one element ... it should be like this :
backgroundColor: this.poolColors(vm.distributed_per_day.length),
borderColor: this.poolColors(vm.distributed_per_day.length)

Reset Vue Bootstrap Table

i am using vue-bootstrap4-table in my application i have a custom input though which i search and populate the data,now i need to build a feature in which their is a cross button inside the search field and on clicking on it it should reset the table to empty state here is my code
<template>
<auto-complete
#autocomplete-result-selected="setCustomer"
placeholder="Enter Customer name"
:selected="selectedCustomer"
:styles="{width: 'calc(100% - 10px)'}"
index="locations"
attribute="name"
>
<template slot-scope="{ hit }">
<span>
{{ hit.customer.company && hit.customer.company + ' - ' }}{{ hit.customer.fname }}
{{ hit.customer.lname }}
</span>
</template>
</auto-complete>
<i class="fas fa-times" #click="clearTable()" v-show="selectedCustomer"></i>
</div>
</div>
</template>
<script>
import http from "../../helpers/api.js";
import AutoComplete from "../autocomplete/Autocomplete";
import axios from "axios";
import VueBootstrap4Table from "vue-bootstrap4-table";
export default {
components: {
"auto-complete": AutoComplete,
VueBootstrap4Table
},
computed: {},
data() {
return {
value: "",
selectedCustomer: "",
selectedFirstName: "",
selectedLastName: "",
selectedFields: [
{ name: "Invoice", value: "invoices" },
{
name: "Estimate",
value: "workorder_estimates"
}
],
filters: [
{ is_checked: true, value: "invoices", name: "Invoice" },
{ is_checked: true, value: "workorder_estimates", name: "Estimate" }
],
selectedFilters: [],
estimateChecked: false,
invoiceChecked: false,
config: {
card_mode: false,
show_refresh_button: false,
show_reset_button: false,
global_search: {
placeholder: "Enter custom Search text",
visibility: false,
case_sensitive: false
},
pagination: true,
pagination_info: false,
per_page: 10,
rows_selectable: true,
server_mode: true,
preservePageOnDataChange: true,
selected_rows_info:true
},
classes: {},
rows: [],
columns: [
{
label: "TYPE",
name: "type"
},
{
label: "ID",
name: "distinction_id"
},
{
label: "CUSTOMER NAME",
name: "full_name"
},
{
label: "SERVICE DATE",
name: "service_date"
},
{
label: "ADDRESS",
name: "address1"
},
{
label: "CREATE DATE",
name: "created_at"
}
],
queryParams: {
sort: [],
filters: [],
global_search: "",
per_page: 10,
page: 1
},
selected_rows: [],
total_rows: 0
};
},
methods: {
onNameSearch() {
this.selectedFilters = ["invoices", "workorder_estimates"];
this.fetchData();
},
clearTable(){
this.rows=[];
console.log(this.config.selected_rows_info);
this.config.selected_rows_info=false;
},
onChangeQuery(queryParams) {
console.log(queryParams);
this.queryParams = queryParams;
this.fetchData();
},
onRowClick(payload) {
console.log(payload);
},
setCustomer(selectedResult) {
this.selectedCustomer = selectedResult.customer.company
? `${selectedResult.customer.company + " - "}${
selectedResult.customer.fname
} ${selectedResult.customer.lname}`
: `${selectedResult.customer.fname} ${selectedResult.customer.lname}`;
this.selectedFirstName = selectedResult.customer.fname;
this.selectedLastName = selectedResult.customer.lname;
},
changeCheck(event, index, value) {
var checked = event.target.checked;
switch (value) {
case "invoices":
if (checked) {
this.selectedFields.push({ name: "Invoice", value: "invoices" });
this.invoiceChecked = true;
var data = this.filters[index];
data.is_checked = true;
Vue.set(this.filters, data, index);
} else {
var index = this.selectedFields.findIndex(
item => item.value === value
);
this.selectedFields.splice(index, 1);
this.invoiceChecked = false;
var data = this.filters[index];
data.is_checked = false;
Vue.set(this.filters, data, index);
}
break;
case "workorder_estimates":
if (checked) {
this.selectedFields.push({
name: "Estimate",
value: "workorder_estimates"
});
var data = this.filters[index];
data.is_checked = true;
Vue.set(this.filters, data, index);
} else {
var index = this.selectedFields.findIndex(
item => item.value === value
);
this.selectedFields.splice(index, 1);
this.estimateChecked = false;
var data = this.filters[index];
data.is_checked = false;
Vue.set(this.filters, data, index);
}
break;
}
},
removeFilter(index, value) {
switch (value) {
case "workorder_estimates":
this.selectedFields.splice(index, 1);
this.estimateChecked = false;
var i = this.filters.findIndex(item => item.value === value);
var data = this.filters[i];
data.is_checked = false;
Vue.set(this.filters, data, i);
break;
case "invoices":
this.selectedFields.splice(index, 1);
this.invoiceChecked = false;
var i = this.filters.findIndex(item => item.value === value);
var data = this.filters[i];
data.is_checked = false;
Vue.set(this.filters, data, i);
break;
}
},
updateFilters() {
this.selectedFilters = [];
this.selectedFields.forEach(element => {
this.selectedFilters.push(element.value);
});
if(this.selectedFilters.length == 0){
this.selectedFilters = ['invoices', 'workorder_estimates'];
}
this.fetchData();
},
async fetchData() {
var final = [];
try {
var result = await http.post("/estimate-invoice-search", {
type: this.selectedFilters,
search: {
value: this.selectedFirstName + " " + this.selectedLastName
},
per_page: this.queryParams.per_page,
page: this.queryParams.page,
sort: this.queryParams.sort
});
this.total_rows = result.recordsFiltered;
result.data.forEach(element => {
element.full_name = element.first_name + " " + element.last_name;
final.push(element);
});
this.rows = final;
} catch (error) {
console.log(error);
}
}
},
mounted() {}
};
</script>
now the method named clearTable here i want to reset my table to the point lie we see on page refresh in the method i used this.rows=[]; this clears all the rows which is exactly what i want but the text which shows the number of rows is still their and i cant seem to remove it please view the below image for clarification
i read the documentation on link but cant seem to find a solution for hiding the text, is their any way?
It looks like you're using total_rows as the variable for the number of rows in your template here:
<span>{{total_rows}}</span> Result(s)
The only spot in code that you set this value is in fetchData() where you set:
this.total_rows = result.recordsFiltered;
You can either:
1) Make total_rows a computed property (recommended) that returns the length of rows (I believe rows is always the same length as total_rows from your code)
-or-
2) Just set this.total_rows = 0; in your clearTable() function