data change doesn't reflect in vue application - vue.js

In my Vue application I am trying to create a simple table with changeable column sequence. In the data structure I keep all column data with its thead. I use compute to calculate rows from column data using matrix transposion. However any change I do to dynamicTable.columns doesn't reflect in the view.
function transpose(a)
{
return a[0].map(function (_, c) { return a.map(function (r) { return r[c]; }); });
// or in more modern dialect
// return a[0].map((_, c) => a.map(r => r[c]));
}
var tData = {
columns:[
{thead:'isbn',
tdata:[1,2]},
{thead:'name',
tdata:['rose','flower']},
{thead:'price',
tdata:['10','15']},
{thead:'author',
tdata:['john','jane']},
{thead:'page count',
tdata:['396','149']},
{thead:'print date',
tdata:['2001', '1996']}
]
}
var dynamicTable = new Vue({
el: '#dynamicTable',
data: tData,
computed:{
rows: function(){
arr = [];
this.columns.forEach(function(element){
arr.push(element.tdata);
});
return transpose(arr)
}
}
})
For example I want to change the order of isbn column with price,
a=dynamicTable.columns[0]
b=dynamicTable.columns[2]
dynamicTable.columns[0]=b
dynamicTable.columns[1]=a
data changes but changes are not reflected. What is the problem here?

As mentioned in the documentation, this is a JavaScript limitation. Direct changes to an array are not detected by Vue.
One workaround for this, is to use Vue.set(), as instructed in the link.

Related

use vue.js with chartist.js to create a chart that track balance progress

I'm doing some training to better learn how to use vue.js and electron. I've decided to make a simple app to track the profit/loose of a trading day. I will calculate the difference between the end balance and the start balance of every day with a subtraction operation. After some trouble I'm able to get the result of the operation on the DOM using the computed function of vue. What I want to do is to use chartist.js to create a simple chart that will track the results after it is calculated. I'm not sure how to proceed, what I want is to have on the chart every end balance with the calculated difference with the previous amount showed. Can anyone help me with an example?
My actual vue.js code
let app = new Vue({
el: '#app',
data: {
s: '',
e: '',
},
computed: {
tot(){
return Number(this.e) - Number(this.s);
}
}
});
Sample data:
DAY INIT. BALANCE FINAL BALANCE
20/03/2020 2,309.99 2,332.25
23/03/2020 2,332.25 2,343.30
24/03/2020 2,343,30 2,424.62 (+81,32€)
25/03/2020 2,424.62 2,519.56 (+94,94€)
26/03/2020 2,519.56 2,544.46 (+24,90€)
27/03/2020 1,346.00
You just need two convert your data into two arrays, dates for your x-axis and values for your y-axis.
data () {
return {
input: [
['23/03/2020', '2,309.99', '2,332.25'],
['24/03/2020', '2,343,30', '2,424.62'],
['25/03/2020', '2,424.62', '2,519.56']
],
}
},
computed: {
dates () {
return this.input.map(x=>x[0])
},
values () {
return this.input.map(
x => parseFloat(x[2].replace(',','')) -
parseFloat(x[1].replace(',',''))
)
}
}
example with vue-chartjs: https://jsfiddle.net/ellisdod/9vz2qukj/6/

PivotTable.JS Callback implementation problem

I have implemented PivotTable.JS in Filemaker and it works great. I've added the callback code and that function seems to be working when I click on a cell. When click on the cell I get the dialog "Message from webpage", I assume I still need to add some code to show the records that makes up the content of the click cell. What would be the approach to show the records, unfortunately I am not java script savvy.
$("#output").pivotUI(
$.pivotUtilities.tipsData, {
cols: ["Quarter Latest"],
rows: ["Customer"],
vals: ["Wt Forecast"],
aggregatorName: "Sum",
rendererName: "Table",
renderers: $.extend(
$.pivotUtilities.renderers,
$.pivotUtilities.c3_renderers,
$.pivotUtilities.export_renderers
),
rendererOptions: {
table: {
clickCallback: function(e, value, filters, pivotData){
var names = [];
pivotData.forEachMatchingRecord(filters,
function(record){ names.push(record.Name); });
alert(names.join("\n"));
}
}
}
});
I guess the problem is that you are pushing into the array 'names' a field 'Name' that is not available in your recordset.
You can access de complete json returned on the clickCallBack by making a small change to your code.
$("#output").pivotUI(
$.pivotUtilities.tipsData, {
cols: ["Quarter Latest"],
rows: ["Customer"],
vals: ["Wt Forecast"],
aggregatorName: "Sum",
rendererName: "Table",
renderers: $.extend(
$.pivotUtilities.renderers,
$.pivotUtilities.c3_renderers,
$.pivotUtilities.export_renderers
),
rendererOptions: {
table: {
clickCallback: function(e, value, filters, pivotData){
var fullData = [];
pivotData.forEachMatchingRecord(filters,
function(record){ fullData.push(record); });
console.log(fullData);
}
}
}
});
Perhaps you can later pass that JSON to another function and build a table.

BookshelfJS - 'withRelated' through relational table returns empty results

I've been trying to structure the relations in my database for more efficient querying and joins but after following the guides for '.belongsToMany', '.through' and '.belongsTo' I'm now getting empty results.
I've got a Sound model and a Keyword model which I want to model with a many-to-many relationship (each Sound can have multiple Keywords, and each Keyword can be related to multiple sounds). Based on the documentation '.belongsToMany' would be the relation to use here.
I've set up my models as follows, using a 'sound_keyword' relational table/SoundKeyword relational model (where each entry has it's own unique 'id', a 'soundID', and a 'keywordID'):
var Sound = bookshelf.Model.extend({
tableName: 'sounds',
keywords: function () {
return this.belongsToMany(Keyword, 'sound_keyword', 'id', 'id').through(SoundKeyword, 'id', 'soundID');
},
});
var Keyword = bookshelf.Model.extend({
tableName: 'keywords',
sounds: function () {
return this.belongsToMany(Sound, 'sound_keyword', 'id', 'id').through(SoundKeyword, 'id', 'keywordID');
}
});
where:
var SoundKeyword = bookshelf.Model.extend({
tableName: 'sound_keyword',
sound: function () {
return this.belongsTo(Sound, 'soundID');
},
keyword: function () {
return this.belongsTo(Keyword, 'keywordID');
}
});
From what I've read in the docs and the BookshelfJS GitHub page the above seems to be correct. Despite this when I run the following query I'm getting an empty result set (the Sound in question is related to 3 Keywords in the DB):
var results = await Sound
.where('id', soundID)
.fetch({
withRelated: ['keywords']
})
.then((result) => {
console.log(JSON.stringify(result.related('keywords')));
})
Where am I going wrong with this? Are the relationships not set up correctly (Possibly wrong foreign keys?)? Am I fetching related models incorrectly?
Happy to provide the Knex setup as needed.
UPDATED EDIT:
I had been using the Model-Registry Plugin from the start and had forgotten about it. As it turns out, while the below syntax is correct, it prefers syntax similar to the following (i.e. lowercase 'model', dropping the '.extends' and putting model names in quotes):
var Sound = bookshelf.model('Sound',{
tableName: 'sounds',
keywords: function () {
return this.belongsToMany('Keyword', 'sound_keyword', 'soundID', 'keywordID');
},
});
var Keyword = bookshelf.model('Keyword',{
tableName: 'keywords',
sounds: function () {
return this.belongsToMany('Sound', 'sound_keyword', 'keywordID', 'soundID');
}
});
Hope this can be of help to others.
Seems like removing the '.through' relation and changing the IDs in the '.belongsToMany' call did the trick (as below), though I'm not entirely sure why (the docs seem to imply belongsToMany and .through work well together - possibly redundant?)
var Sound = bookshelf.Model.extend({
tableName: 'sounds',
keywords: function () {
return this.belongsToMany(Keyword, 'sound_keyword', 'soundID', 'keywordID');
},
});
var Keyword = bookshelf.Model.extend({
tableName: 'keywords',
sounds: function () {
return this.belongsToMany(Sound, 'sound_keyword', 'keywordID', 'soundID');
}
});
I did try my original code with soundID and keywordId instead of 'id' (as below), but without the .through relation and that gave the same empty results.

Filter other columns based on first columns

I'm using jquery data tables and I'm assigning an array of values to the initialization of the data table. The table basically looks like this.
based on an an radio button I would like to limit the items that are display in the table and the items that are searched in the table.
For my example it would be based on the "Chart column". I want to limit the table to only show the items that are based on chart "D" or Chart "S". Here is how I'm initializing the table.
if (!$.fn.DataTable.isDataTable( '#fundLookUptbl' ) ) {
fundTable = $('#fundLookUptbl').DataTable( {
data: funds,
columns: [
{ "mData": "chart" },
{ "mData": "fund" },
{ "mData": "orgDefault" },
{ "mData": "progDefault" }
]
} );
var filteredData = fundTable
.columns( [0, 1] )
.data()
.eq( 0 )
.filter( function ( value, index ) {
return value = 'D' ? true : false;
} );
}
This is obviously not working, and the filterData variable is a lousy attempt on trying to make it work. I'm having a hard time understanding the API's. So the question is , How can initialize the table to only show the items that are based on a given chart. I know that I can remove the items of the array but i don't want to do that since I would simple like to be able to switch between chart "D" and "S" but still continue to search through the other columns.
I believe that filtering the column would solve your problem.
table.column(0).search('Bruno').draw()
So you could just filter the column when the radio button selection change
Here is a fiddle example
I´m not sure to be understanding what you want to do but here are some options:
One way is selecting by default value example "s". You can use a dropdown is easier to handled .Then select with jQuery the dafault value "s" on that dropdown and add a function
$("#DropdownId").change(function () {
var chart=$("#DropdownId").val();
});
$.ajax({
url: "url")",//url to reload page with new value
type: "POST",
data: {chart:chart},
success: function (data) {
}
});
});
on this way the filter is on backend. If you want to do something on the row depending of a column value you shoud to add something like this
"fnRowCallback": function (nRow, mData, iDisplayIndex, iDisplayIndexFull) {
if (mData["chart"] =="s") {
return nRow;
}
},
Datatables: custom function inside of fnRowCallback.
Good luck
fundTable.order( [0, 'asc'] );
Try that or look at this particular page for reference:
https://datatables.net/reference/api/order%28%29
Basically orders in pair of columnIndex in either asc(ending) or desc(ending) order.

Dojo gridx: using "onAfterRow" disables "onCellWidgetCreated"?

When creating a gridx, I use the following column definition to insert an Edit button in to the last cell of each row:
var editColumn = { field : 'Edit', name : '', widgetsInCell: true,
onCellWidgetCreated: function(cellWidget, column){
var btn = new Button({
label : "Edit",
onClick : function() {
console.log('Do stuff here');
});
btn.placeAt(cellWidget.domNode);
}
};
columns.push(editColumn);
var grid = new Grid({
cacheClass : Cache,
store : store,
structure : columns,
modules: ["gridx/modules/CellWidget"]
}, 'gridNode');
grid.body.onAfterRow = function(row){
...do stuff on the row here
};
Whne I include the onAfterRow function the row processing happens but the OnCellWidgetCreated does not. Each function seems wo work in absence of the other. Any suggestions on how I can: (1) format the rows according to row data AND (2) insert the button widgets in the last cell of each row?
Ok, solved it. Rather than assign the grid.body.onAfterRow, the way that worked for me was:
aspect.after(grid.body,'onAfterRow',function(row){
key = row.id;
if ('anulada' in row.grid.store.get(key)){
if(row.grid.store.get(key).anulada == true){
row.node().style.color = 'gray';
}
}
},true);
You need to require "dojo/aspect".