How to call a computed property in dynamic style? - vue.js

I want to style Ant Design Vue button(inside a table row of Ant Design table) dynamically:
<template #status="{ text }">
<a-button ghost
:style="{'border-color': getColor(text) }">
</a-button>
</template>
And here is my computed propery(in script section):
const getColor = computed((status) => {
let color = '';
switch(status) {
case 'StatusA':
color = '#F97316';
break;
case 'StatusB':
color = '#EC4899';
break;
case 'StatusC':
color = '#8B5CF6'
break;
case 'StatusD':
color = '#16A34A';
break;
default:
color = "#5685EE";
}
return color;
})
But it is not working.
Error: This expression is not callable.Type 'String' has no call signatures
How do I do this?
Thanks.

Try to use computed property in options API by returning a function that takes the status as parameter:
setup(){
...
},
computed:{
getColor(){
return (status)=>{
let color = '';
switch(status) {
case 'StatusA':
color = '#F97316';
break;
case 'StatusB':
color = '#EC4899';
break;
case 'StatusC':
color = '#8B5CF6'
break;
case 'StatusD':
color = '#16A34A';
break;
default:
color = "#5685EE";
}
return color;
}
}
}
or just use function inside the setup :
const getColor = (status) => {
let color = '';
switch(status) {
case 'StatusA':
color = '#F97316';
break;
case 'StatusB':
color = '#EC4899';
break;
case 'StatusC':
color = '#8B5CF6'
break;
case 'StatusD':
color = '#16A34A';
break;
default:
color = "#5685EE";
}
return color;
}

Related

Array is not cloned, wrapped inside Proxy

Im executing this code inside vue created() method:
const width = window.innerWidth;
const columns = this.columns.slice()
let colVis = columns.map((element) => {
if(element.sClass == 'min-tv' && width < 2500) {
element.visible = false;
return element;
} else if(element.sClass == 'min-desktop-lg' && width < 1980) {
element.visible = false;
return element;
} else {
return element;
}
});
console.log(columns);
console.log(colVis);
For some reason both arrays returns same values (and this.columns too).
Everything is wraped inside Proxy - arrays and their values.
I cant understand whats going on and why i can't have clone of array?
I don't use computed, because it's initialization values (for Datatables colvis).
You should use filter to filter data from an array.
const width = window.innerWidth;
const columns = this.columns.slice()
let colVis = columns.map((element) => {
if(element.sClass == 'min-tv' && width < 2500) {
element.visible = false;
return element;
} else if(element.sClass == 'min-desktop-lg' && width < 1980) {
element.visible = false;
return element;
} else {
return element;
}
}).filter((element) => element.visible);
console.log(columns);
console.log(colVis);
It turns out to be vue bug.
Using inline window.innerWidth breaks its normal behavior.

How can I make Switch/Case only look at specific breakpoint?

I'm running a switch/case that looks at the Vuetify breakpoint, but instead of just taking the name and giving me the int I want, it always ends up taking whatever the highest number is for the "limitSize" variable.
This is for a news slider I'm working on where, depending on the breakpoint, it shows either one, two, or three elements in the slider. I've tried giving the variable a default value, but that didn't work. I'd preferably like it to go SM & down is 1, MD is 2 and LG & Up is 3, but I'm not sure what the right way to achieve that is. Any help would be greatly appreciated.
The following is the Switch/Case which sits inside a computed property. I've also attached an image of the current results of the code (Image is on MD window when I'd want 2)
VueJS
pageOfWhatsNews() {
var limitSize;
switch (this.$vuetify.breakpoint.name) {
case "xs":
limitSize = 1;
case "sm":
limitSize = 1;
case "md":
limitSize = 2;
case "lg":
limitSize = 3;
case "xl":
limitSize = 3;
}
var start = (this.currentPage - 1) * limitSize;
var end = (this.currentPage - 1) * limitSize + limitSize;
return this.whatsNews.slice(start, end);
}
Well, it's because you are missing break statements in between your switch cases. Look at the correct syntax of a switch-case block below:
Switch-Case Syntax
const expr = 'Papayas';
switch (expr) {
case 'Oranges':
console.log('Oranges are $0.59 a pound.');
break;
case 'Mangoes':
case 'Papayas':
console.log('Mangoes and papayas are $2.79 a pound.');
// expected output: "Mangoes and papayas are $2.79 a pound."
break;
default:
console.log(`Sorry, we are out of ${expr}.`);
}
Solution
function pageOfWhatsNews() {
var limitSize;
switch (this.$vuetify.breakpoint.name) {
case "xs":
limitSize = 1;
break;
case "sm":
limitSize = 1;
break;
case "md":
limitSize = 2;
break;
case "lg":
limitSize = 3;
break;
case "xl":
limitSize = 3;
break;
}
var start = (this.currentPage - 1) * limitSize;
var end = (this.currentPage - 1) * limitSize + limitSize;
console.log(limitSize);
// return this.whatsNews.slice(start, end);
}
// Just for demo
this.$vuetify = {breakpoint: {name: 'md'}};
pageOfWhatsNews();
Optimized Solution
I would also suggest you put cases of md, lg & xl breakpoints and rest of the breakpoints case fallback to the default case.
function pageOfWhatsNews() {
var limitSize;
switch (this.$vuetify.breakpoint.name) {
case "md":
limitSize = 2;
break;
case "lg":
limitSize = 3;
break;
case "xl":
limitSize = 3;
break;
default:
limitSize = 1;
}
var start = (this.currentPage - 1) * limitSize;
var end = (this.currentPage - 1) * limitSize + limitSize;
console.log(limitSize);
// return this.whatsNews.slice(start, end);
}
// Just for demo
this.$vuetify = {breakpoint: {name: 'sm'}};
pageOfWhatsNews();

Cannot set style of string variable

Method:
getTitleText(){
let mainTitle = "";
let getTitle = this.titleText;
let countGetTitle = getTitle.split(" ").length;
if(countGetTitle > 4){
mainTitle = getTitle.replace(/(\S+\s*){1,5}/, "$&\n");
console.log(typeof mainTitle)
mainTitle.style.fontSize = "30px"
}else{
mainTitle.style.fontSize = "40px"
}
return mainTitle;
},
error I found
[Vue warn]: Error in render: "TypeError: Cannot set property 'fontSize' of undefined"
found in
You're conflating String with HTMLElement. A String has no style property, so .style would be undefined, leading to the error you observed for fontSize. But it looks like you actually want to specify the font size for the HTML element that would contain that string.
One way to solve this is to return an object with one property for the title text, and another for the font size:
export default {
computed: {
getTitleText() {
let mainTitle = "";
let fontSize = "";
let getTitle = this.titleText;
let countGetTitle = getTitle.split(" ").length;
if(countGetTitle > 4) {
mainTitle = getTitle.replace(/(\S+\s*){1,5}/, "$&\n");
fontSize = "30px"
} else {
fontSize = "40px"
}
return {
text: mainTitle,
fontSize,
}
},
}
}
Then bind the result in your template:
<span :style="{ fontSize: getTitleText.fontSize }">{{ getTitleText.text }}</span>
demo

YADCF range_number - is it possible to add a preset select list to to/from range?

I want to add a select list to to/from fields of range_number so user can pick from set amounts to set range.
best option would be to use the custom function filtering filter_type: 'custom_func'
see showcase, first column , code sample and everything can be found on that page
{
column_number: 0,
filter_type: 'custom_func',
custom_func: myCustomFilterFunction,
...
(possible) custom func implementation
function myCustomFilterFunction(filterVal, columnVal) {
var found;
if (columnVal === '') {
return true;
}
switch (filterVal) {
case 'happy':
found = columnVal.search(/:-\]|:\)|Happy|JOY|:D/g);
break;
case 'sad':
found = columnVal.search(/:\(|Sad|:'\(/g);
break;
case 'angry':
found = columnVal.search(/!!!|Arr\.\.\./g);
break;
case 'lucky':
found = columnVal.search(/777|Bingo/g);
break;
case 'january':
found = columnVal.search(/01|Jan/g);
break;
default:
found = 1;
break;
}
if (found !== -1) {
return true;
}
return false;
}

Formatting radgrid exporting to PDF

I have a datatable dt, and want to make a PDF file from it. Everything is dynamic and it works but I can't format the layout such as alternate row background etc. Here is my code :
private void MakeGridExportToPDF(string strTitle, DataTable dt)
{
using (RadGrid grid = new RadGrid { AutoGenerateColumns = false, ShowHeader = true, })
{
grid.NeedDataSource += (object sender, GridNeedDataSourceEventArgs e) =>
{
grid.DataSource = dt;
};
// Add columns
dt.Columns.OfType<DataColumn>().ToList().ForEach(col =>
{
grid.MasterTableView.Columns.Add(new GridBoundColumn { DataField = col.ColumnName, HeaderText = col.Caption.ToCamel() });
});
GridExportSettings export = grid.ExportSettings;
export.OpenInNewWindow = true;
export.FileName = strTitle;
export.IgnorePaging = true;
GridPdfSettings pdf = export.Pdf;
pdf.PageHeight = Unit.Parse("210mm"); //
pdf.PageWidth = Unit.Parse(GetPageWidth(grid.MasterTableView.Columns.Count)); //
pdf.DefaultFontFamily = "Arial Unicode MS";
pdf.PageTopMargin = Unit.Parse("45mm");
grid.ItemCreated += (object sender, GridItemEventArgs e) =>
{
GridItem item = e.Item;
if (item is GridDataItem)
{
item.Style["vertical-align"] = "middle";
item.Style["text-align"] = "center";
}
switch (item.ItemType) //Mimic RadGrid appearance for the exported PDF file
{
case GridItemType.Item:
item.Style["background-color"] = "#DFDFDF";
item.Font.Italic = true;
break;
case GridItemType.AlternatingItem:
item.Style["background-color"] = "#FFFFFF";
break;
case GridItemType.Header:
item.Style["background-color"] = "#FFFFFF";
item.Style["Color"] = "#767676";
item.Font.Bold = true;
break;
case GridItemType.Footer:
item.Style["background-color"] = "#FFFFFF";
break;
}
};
this.smCSVFile.Controls.Add(grid);
grid.MasterTableView.ExportToPdf();
bDone = true;
}
}
What am I doing wrong. the ItemCreated is triggered when grid is created first but not when is exported and don't see any changes. Any help would be greatly appreciated.
My problem has been resolved by removing use(RadGrid grid .... and just make the Radgrid = new RadGrid { AutoGenerateColumns = false, ShowHeader = true, }