How to divide a column to have multiple rows in b-table in bootstrap vue? - vue-cli

I am creating SPA using vue. I have JSON array :
[
{
date: new Date(2076, 5, 10),
customer: {id: 0,name: "Foo bar",tol: "Some tol",city: "Some City",},
items: [
{code: "gs",name: "Generic Shoes",cost: 500,quantity: 5},
{code: "nf",name: "North Facing Jacket",cost: 5000,quantity: 5},
{code: "lp",name: "Lee Vice Jeans Pant",cost: 1500,quantity: 15}
],
}
]
which now contains one object that has date, customer and items primarily. I want to make table that will contain date, customer and items as fields, and each row of table will contain multiple row of items.
Something like this :
,
This thing has only one row, but as you can imagine there might be multiple row for multiple {date, customer, items[]}.
This was best I was able to do :
<b-container>
<b-table responsive="true" striped hover :items="DraftList" :fields="fields">
<template slot="[date]" slot-scope="data">{{data.value|formatDate}}</template>
<template slot="[customer]" slot-scope="data">{{data.value.name}}</template>
<template slot="[items]" slot-scope="data">{{data.value}}</template>
</b-table>
</b-container>
<script>
import { mapState } from "vuex";
export default {
data() {
return {
fields: [
{ key: "date", sortable: true },
{
key: "customer",
label: "Customer's Name",
sortable: true
},
{
key: "items",
label: "Item List",
sortable: true
}
]
};
},
computed: {
...mapState(["DraftList"])
},
mounted() {},
filters: {
formatDate: date => {
if (date instanceof Date) {
let month = "" + (date.getMonth() + 1);
let day = "" + date.getDate();
let year = date.getFullYear();
if (month.length < 2) month = "0" + month;
if (day.length < 2) day = "0" + day;
return [year, month, day].join("-");
}
return null;
}
}
};
</script>
I am stuck, what should I do now? I cannot properly term my searches either.

Solved it using v-for and rowspan
<b-table-simple responsive="true" hover outlined>
<colgroup>
<col />
<col />
</colgroup>
<colgroup>
<col />
<col />
<col />
</colgroup>
<colgroup>
<col />
<col />
</colgroup>
<b-thead head-variant="light">
<b-tr>
<b-th rowspan="2">Date</b-th>
<b-th rowspan="2">Customer's Name</b-th>
<b-th colspan="4">Items</b-th>
</b-tr>
<b-tr>
<b-th>code</b-th>
<b-th>Name</b-th>
<b-th>Cost</b-th>
<b-th>Quantity</b-th>
</b-tr>
</b-thead>
<b-tbody v-for="(draft,index) in DraftList" :key="index">
<b-tr>
<b-td :rowspan="draft.items.length+1">{{draft.date|formatDate}}</b-td>
<b-td :rowspan="draft.items.length+1">{{draft.customer.name}}</b-td>
</b-tr>
<b-tr v-for="(item, itemIndex) in draft.items" :key="itemIndex">
<b-td>{{item.code}}</b-td>
<b-td>{{item.name}}</b-td>
<b-td>{{item.cost}}</b-td>
<b-td>{{item.quantity}}</b-td>
</b-tr>
</b-tbody>
</b-table-simple>

Related

Material-UI - TypeScript - Autocomplete with getOptionLabel and renderOption

I am trying to display member and company using MUI Autocomplete.
I have suggestion array to show as options
[
{
"__typename": "Member",
"id": "ckwa91sfy0sd241b4l8rekas9jx",
"name": "my name 2",
"companyName": ""
},
{
"__typename": "Member",
"id": "ckwac4ijl25dsd80b4l8fpsrc64o",
"name": "my name",
"companyName": ""
},
{
"__typename": "Member",
"id": "ckwa8z6z7004dsd2b4l81m6ras9c",
"name": "my name 1",
"companyName": "A COMPANY"
}
]
I use this to display
<Autocomplete
id="free-solo-demo"
freeSolo
options={
suggestion &&
suggestion.map(
(suggestion: any) =>
suggestion.name
)
}
onChange={(event, value) =>
HandleUserProfile(value)
}
renderInput={(params) => (
<TextField
{...params}
placeholder="Search..."
onChange={handleChange}
/>
)}
/>
By using this I am getting options if only I search with member name.
I want to search with both company and member and need to customize UI of option.
I tried this
<Autocomplete
id="free-solo-demo"
freeSolo
options={suggestion}
getOptionLabel={(option) => `${option.name} ${option.companyName}`}
renderOption={(option)=>{
return <h1>{`${option.name}: ${option.companyName}`}</h1>
}}
onChange={(event, value) =>
HandleUserProfile(value)
}
renderInput={(params) => (
<TextField
{...params}
placeholder="Search..."
onChange={handleChange}
/>
)}
/>
but It is not working.
it shows error TypeScript error in ... Property 'name' does not exist on type 'never'. TS2339
First, you should make sure the name field doesn't have any duplicated values, that's why you should use the mandatory id field to select one.
And also you need to build a custom filter function or use createFilterOptions hook from Autocomplete component.
https://mui.com/components/autocomplete/#custom-filter
import Autocomplete, { createFilterOptions } from '#mui/material/Autocomplete';
...
const filterOptions = createFilterOptions({
stringify: ({ name, companyName }) => `${name} ${companyName}`
});
<Autocomplete
options={suggestion}
getOptionLabel={option => option.name}
filterOptions={filterOptions}
...
/>;

Tabulator's output of print function does not include table footer column calculation and text alignments

I am using Tabulator version 4.3 and trying to print a table (which has columnCalcs: both) using print function. I have set printCopyStyle:true, but the output of print does not include footer row (column calculation at the bottom of the table); also alignment of numbers which is set to right does not appear right aligned. The footer and alignment both appear correctly in the Tabulator table, but not in print copy.
Please check jsfiddle here.
Are these features not available or am I missing something?
const tabledata = [{
dep: "A",
name: "Oli Bob",
score: 100
},
{
dep: "A",
name: "Jamie Newhart",
score: 120
},
{
dep: "D",
name: "Gemma Jane",
score: 90
},
{
dep: "D",
name: "James Newman",
score: 100
},
];
const table = new Tabulator("#example-table", {
height: "250px",
data: tabledata,
groupBy: "dep",
columnCalcs: "both",
printAsHtml: true,
printCopyStyle: true,
columns: [{
title: "Name",
field: "name",
width: 200
},
{
title: "Score",
field: "score",
align: "right",
bottomCalc: "sum"
},
],
});
<head>
<link href="https://unpkg.com/tabulator-tables#4.3.0/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.3.0/dist/js/tabulator.min.js"></script>
</head>
<body>
<button type="button" id="report-print" onclick="table.print();">Print </button>
<div id="example-table"></div>
</body>

[Vue warn]: Error in render: “TypeError: Cannot read property ‘sex’ of undefined”

I'm doing a v-for on a parent altoke-layers component, and a v-for on its son component altoke-flyers.
send the array a_c that stores the query, from the father to the son,
this works, but I have error alert in console:
please community, help me understand what I'm doing wrong.
this is the console response
vue.js:597 [Vue warn]: Error in render: "TypeError: Cannot read property 'sex' of undefined"
found in
---> <AltokeFlyers>
<AltokeCapas>
<Root>
-------------------------------------------
warn # vue.js:597
vue.js:1743 TypeError: Cannot read property 'sex' of undefined
at Proxy.eval (eval at createFunction (vue.js:10667), <anonymous>:3:234)
at VueComponent.Vue._render (vue.js:4535)
at VueComponent.updateComponent (vue.js:2788)
at Watcher.get (vue.js:3140)
at new Watcher (vue.js:3129)
at mountComponent (vue.js:2795)
at VueComponent.Vue.$mount (vue.js:8527)
at VueComponent.Vue.$mount (vue.js:10926)
at init (vue.js:4131)
at createComponent (vue.js:5595)
this fraction of code in the html where the parent component is tagged (father)
<altoke-capas v-for="(ab, nb) in a_b"
:key="nb++"
:ab="ab"
:a_c="a_c"
v-bind:id="'Slide' + nb"
v-bind:for="'Slide' + nb"
></altoke-capas>
vue.js code
Vue.component('altoke-flyers',{
props: ['ac'],
template: `
<div>
<div class="isquierda">izquierda</div>
<div class="list">
<label class="img" for="Slide6" >
<div v-html="ac.sex" class="lege"></div>
<img v-bind:src="'./files/ski/webcompleta/files/media/img/img/flyers/' + ac.qui + '/124-186.jpg'">
</label>
</div>
<div class="derecha">derecha</div>
</div>
`
})
Vue.component('altoke-capas',{
props: ['ab', 'a_c'],
template: `
<label class="Slide">
<altoke-flyers v-for="(ac, nc) in a_c"
:key="nc++"
:ac="ac"
v-if="ab.a > 0"
v-bind:class="'content ' + ab.b"
></altoke-flyers>
<altoke-flyers
v-if="ab.a > 0"
v-bind:class="'content ' + ab.c"
></altoke-flyers>
</label>
`
})
var app = new Vue({
el:'.altoke',
data: {
mostrar: false,
a_a: [
{ a: "", b: "pel", m: 0, n: false },
{ a: "Inicio", b: "home", m: 1, n: true },
{ a: "Pedidos", b: "comment", m: 1, n: false },
{ a: "Reporte", b: "bullhorn", m: 1, n: false },
{ a: "Generos", b: "list-alt", m: 1, n: false},
{ a: "Nosotros", b: "chalkboard-teacher", m: 1, n: false},
{ a: "", b: "pel", m: 1, n: false },
{ a: "", b: "pel", m: 1, n: false },
],
a_b: [
{ a: "1", b: "pels", c: "sers", m: 0, n: false },
{ a: "0", b: "", c: "", m: 1, n: true },
{ a: "0", b: "", c: "", m: 1, n: false },
{ a: "0", b: "", c: "", m: 1, n: false },
{ a: "0", b: "", c: "", m: 1, n: false},
{ a: "0", b: "", c: "", m: 1, n: false},
],
a_c:[],
},
created: function(){
if (localStorage.getItem('vlist')){
try {
this.a_c = JSON.parse(localStorage.getItem('vlist'));
} catch(e) {
localStorage.removeItem('vlist');
}
} else {
this.get_contacts();
}
},
methods:{
get_contacts: function(){
//const options = { method: 'post', body: 'foo=bar&test=1' }
fetch("./files/icl/master.php")
.then(response=>response.json())
.then(json=>{localStorage.setItem('vlist', JSON.stringify(this.a_c=json.contactos))})
}
},
})
Good day, I've been somewhat busy and worried about this problem, which apparently was not a big deal.
I sent the necessary variables to the child component,
Vue.component('altoke-capas',{
props: ['ab', 'a_c'],
template: `
<label class="Slide">
<altoke-flyers v-for="(ac, nc) in a_c"
:key="nc++"
:ac="ac"
-------->
:sex="ac.sex"
:qui="ac.qui"
-------->
v-if="ab.a > 0"
v-bind:class="'content ' + ab.b"
></altoke-flyers>
<altoke-flyers
v-if="ab.a > 0"
v-bind:class="'content ' + ab.c"
></altoke-flyers>
</label>
`
})
and in this I added the props that would use them.
Vue.component('altoke-flyers',{
props: {
------>
sex: String,
qui: String,
------>
},
template: `
<div>
<div class="isquierda">izquierda</div>
<div class="list">
<label class="img" for="Slide6" >
|
| |
<div v-html="sex" class="lege"></div> |
<img v-bind:src="'./files/ski/webcompleta/files/media/img/img/flyers/' + qui + '/124-186.jpg'">
</label>
</div>
<div class="derecha">derecha</div>
</div>
`
})

how does foreach works in react-redux

I am making a nodejs app which can fetch flights from the KIWI api, it returns a json list, and since you parameters like from and to, it should return a list of flights.
I can successfully get that, but when I want to display everything I dont know how to do it.
This is my render:
render(){
return (
<table className="table table-hover">
<thead>
<tr>
<th>Flight #</th>
<th>From</th>
<th>To</th>
</tr>
</thead>
<tbody>
{this.props.flights.map(this.renderFlights)}
</tbody>
</table>
);
}
and
renderFlights(flightData){
// add key to make them unique
return(
<tr>
<td>{flightData.data[0].id}</td>
<td>{flightData.data[0].mapIdfrom}</td>
<td>{flightData.data[0].mapIdto}</td>
</tr>
);
}
{this.props.flights.map(this.renderFlights)} just maps the first one in the array, I know that I have to use foreach, but I dont know how I can use this to print everything in the list, flight id plus the from and to, so when u fetch the flights u get around 15, and I want to be able to display all the 15 flights can someone help me out here?
this returns undefined for forEach:
<tbody>
{
this.props.flights.array.forEach(element => {
this.renderFlights
})
}
</tbody>
I found your API and test interface here: https://skypickerbookingapi1.docs.apiary.io/#reference/check-flights/checkflights/check_flights?console=1
So it seems that you are getting this object for your response:
{
"server_time": 1516568910,
"flights_checked": false,
"extra_fee": 0,
// blah blah,
"flights": [
// first flight
{
"bags_recheck_required": false,
"dtime_unix": 1524646800,
"extra": "",
"atime_unix": 1524651600,
"priority_boarding": {
"currency": null,
"price": null,
"is_possible": false
},
"price": 313,
"currency": "NOK",
"price_new": 313,
// blah blah
},
// second flight
{
"bags_recheck_required": true,
"dtime_unix": 1524683400,
"extra": "",
"atime_unix": 1524691800,
"priority_boarding": {
"currency": null,
"price": null,
"is_possible": false
},
"price": 1560,
"currency": "NOK",
"price_new": 1560,
// blah blah
},
// more and more flights
So I'm guessing that your "this.props.flights" is referring to the "flights" property of the above object.
Now, you need to use "map", not "foreach":
this.props.flights.map(this.renderFlights) //this is correct
And your callback function should be:
renderFlights(one_single_flight){
// add key to make them unique
return(
<tr>
<td>{one_single_flight.id}</td>
<td>{one_single_flight.src_country}</td>
<td>{one_single_flight.dst_country}</td>
</tr>
);
}
}
This is how I was able to get the result I wanted:
renderFlights(flightData){
const result = flightData._results;
var rows = [];
for (var i = 0; i < result; i++) {
rows.push(
<tr key={i} >
<td>{flightData.data[i].mapIdfrom}</td>,
<td>{flightData.data[i].mapIdto}</td>,
</tr>
);
}
return <tbody>{rows}</tbody>;
}
This prints all the available flights for some certain date.

VizChart on dialog in SAP UI5

I am trying to add a Viz chart on my Dialog Box in SAP UI5, but nothings gets displayed. Here is my code, can someone please help! I added a dialog box on a press which is working fine. Even i put alerts in various part just to check if the code is running proper. There is no error, still i dont see the chart in dialog box.
pressTemp: function() {
var oView = this.getView();
var oDialog = oView.byId("helloSiteDialog");
// create dialog lazily
if (!oDialog) {
// create dialog via fragment factory
oDialog = sap.ui.xmlfragment(oView.getId(), "Hari_At_Work.view.HelloSiteDialog", this);
var oVizFrame = this.getView().byId("idVizFrame");
oVizFrame.destroyDataset();
oVizFrame.destroyFeeds();
console.log("chart here");
//New dataset
oVizFrame.setDataset(new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
name: 'Timeline',
value: "{Country}"
}],
measures: [{
name: 'Value',
value: '{revenue}'
}],
data : {
path : "/businessData"
}
}));
alert("Dataset found");
//Add feeds
oVizFrame.addFeed(new sap.viz.ui5.controls.common.feeds.FeedItem({
uid: "categoryAxis",
type: "Dimension",
values: ["Timeline"]
}));
oVizFrame.addFeed(new sap.viz.ui5.controls.common.feeds.FeedItem({
uid: "valueAxis",
type: "Measure",
values: ["Value"]
}));
// oVizFrame.setModel(sap.ui.getCore().getModel());
var oModel = new sap.ui.model.json.JSONModel({
businessData: [{
Country: "Canada",
revenue: 410.87,
profit: -141.25,
population: 34789000
}, {
Country: "China",
revenue: 338.29,
profit: 133.82,
population: 1339724852
}, {
Country: "France",
revenue: 487.66,
profit: 348.76,
population: 65350000
}, {
Country: "Germany",
revenue: 470.23,
profit: 217.29,
population: 81799600
}, {
Country: "India",
revenue: 170.93,
profit: 117.00,
population: 1210193422
}, {
Country: "United States",
revenue: 905.08,
profit: 609.16,
population: 313490000
}]
});
oVizFrame.setModel(oModel);
alert("Model found");
oView.addDependent(oDialog);
}
oDialog.open();
// oVizFrame.invalidate();
},
My Fragment XML code:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:l="sap.ui.layout" xmlns:viz.feeds="sap.viz.ui5.controls.common.feeds"
xmlns:viz.data="sap.viz.ui5.data" xmlns:viz="sap.viz.ui5.controls" xmlns:fb="sap.ui.comp.filterbar">
<Dialog id="helloSiteDialog" title="Temperature Trend">
<viz:VizFrame id="idVizFrame" uiConfig="{applicationSet:'fiori'}"
height='100%' width="100%" vizType='column'>
<viz:dataset>
<viz.data:FlattenedDataset data="{/businessData}">
<viz.data:dimensions>
<viz.data:DimensionDefinition name="Name"
value="{Country}" />
</viz.data:dimensions>
<viz.data:measures>
<viz.data:MeasureDefinition name="Revenue"
value="{revenue}" />
<viz.data:MeasureDefinition name="Cost"
value="{Cost}" />
</viz.data:measures>
</viz.data:FlattenedDataset>
</viz:dataset>
<viz:feeds>
<viz.feeds:FeedItem id='valueAxisFeed' uid="valueAxis" type="Measure"
values="Revenue" />
<viz.feeds:FeedItem id='categoryAxisFeed' uid="categoryAxis" type="Dimension"
values="Name" />
</viz:feeds>
</viz:VizFrame>
<beginButton>
<Button text="Close" press="onCloseSiteDialog"/>
</beginButton>
</Dialog>
One Solution for a map inside a dialog box can be
<d:Dialog> <html:div id='map' style='width: 100%; height: 500px;'> Add you map content here </html:div> </d:Dialog>
Also paste view and fragment code..I have tried your code.The map is showing for me see sample in plunkr.Are you getting any error in console?
Plunk of vizframe
I have used popover.so change in code is only
oDialog.openBy(btn);

Resources