How do I append a table row at the end on an element click in VueJS? - vue.js

I am trying to have two rows available on the table, but the user may need more rows to enter more data part of a form that will be submitted. I am having a hard time making this work. Can someone help with this? I am trying to add a row when the user clicks on the little plus icon at the end of the last TR > TD.
<template>
<table id="myTable">
<tbody>
<tr v-for="(content1, content2, content3, content4, index) in tableRows">
<td scope="row" data-label="">{{content1}}</td>
<td data-label="Filename">{{content2}}</td>
<td data-label="Image Title">{{content3}}</td>
<td data-label="Caption">{{content4}}></td>
<td class="addrow" data-label="Add"><a class="add-link"><span #click="insert_Row()" class="plus-icon">+</span></a></td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data: {
tableRows: ['D2',"<input type='text'>", "<input type='text'>", "<input type='text'>"],
counter: 2
},
methods: {
insert_Row() {
this.counter++;
this.tableRows.push("D " +this.counter);
}
}
}
</script>
<style lang="scss">
td,
th {
padding: .4rem;
&.addrow {
border: 0 none;
width: 2.3rem;
padding: 1.7rem 0 0 0;
vertical-align: middle;
text-align: center;
}
}
td .plus-icon {
border:1px solid cornflowerblue;
background-color: cornflowerblue;
color: #fff;
text-align: center;
padding: 0 .7rem;
box-sizing: border-box;
border-radius: 50%;
transition: all ease-in-out .4s;
&:hover, &:focus {
border:1px solid #182241;
background-color: #182241;
}
}
</style>
I am trying to have two rows available on the table, but the user may need more rows to enter more data part of a form that will be submitted. I am having a hard time making this work. Can someone help with this? I am trying to add a row when the user clicks on the little plus icon at the end of the last TR > TD.* <template>
<table id="myTable">
<tbody>
<tr v-for="(content1, content2, content3, content4, index) in tableRows">
<td scope="row" data-label="">{{content1}}</td>
<td data-label="Filename">{{content2}}</td>
<td data-label="Image Title">{{content3}}</td>
<td data-label="Caption">{{content4}}></td>
<td class="addrow" data-label="Add">
<a class="add-link">
<span #click="insert_Row()" class="plus-icon">+</span>
</a>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data: {
tableRows: ['D2', " < input type = 'text' > ", " < input type = 'text' > ", " < input type = 'text' > "], counter: 2 }, methods: { insert_Row() { this.counter++; this.tableRows.push("
D " +this.counter); } } }
</script>
<style lang="scss">
td,
th {
padding: .4rem;
&.addrow {
border: 0 none;
width: 2.3rem;
padding: 1.7rem 0 0 0;
vertical-align: middle;
text-align: center;
}
}
td .plus-icon {
border: 1px solid cornflowerblue;
background-color: cornflowerblue;
color: #fff;
text-align: center;
padding: 0 .7rem;
box-sizing: border-box;
border-radius: 50%;
transition: all ease-in-out .4s;
&:hover,
&:focus {
border: 1px solid #182241;
background-color: #182241;
}
}
</style> ``` Okay now, after a good response, I have edited the code. It now looks like this. ``` <template>
<table id="myTable">
<tbody>
<tr>
<td scope="row" data-label="">D1</td>
<td data-label="Filename">
<input type="text">
</td>
<td data-label="Image Title">
<input type="text">
</td>
<td data-label="Caption">
<input type="text">
</td>
<td class="addrow" data-label="Add"></td>
</tr>
<tr>
<td scope="row" data-label="">D2</td>
<td data-label="Filename">
<input type="text">
</td>
<td data-label="Image Title">
<input type="text">
</td>
<td data-label="Caption">
<input type="text">
</td>
<td class="addrow" data-label="Add"></td>
</tr>
<tr v-for="(item, index) in tableRows" :key="item.id">
<td scope="row" data-label="">D{{item.id}}</td>
<td data-label="Filename">
<input type="text" v-model="item.Filename">
</td>
<td data-label="Image Title">
<input type="text" v-model="item.ImageTitle">
</td>
<td data-label="Caption">
<input type="text" v-model="item.Caption">
</td>
<td class="addrow" data-label="Add">
<a class="add-link">
<span #click.stop="insert_Row" class="plus-icon">+</span>
</a>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data() {
return {
tableRows: [{
"id": 3,
"Filename": "",
"ImageTitle": "",
"Caption": ""
}]
}
},
methods: {
insert_Row() {
this.tableRows.push({
"id": this.tableRows.length + 3,
"Filename": "",
"ImageTitle": "",
"Caption": ""
})
}
}
}
</script>
<style lang="scss">
td,
th {
padding: .4rem;
&.addrow {
border: 0 none;
width: 2.3rem;
padding: 1.7rem 0 0 0;
vertical-align: middle;
text-align: center;
}
}
td .plus-icon {
border: 1px solid cornflowerblue;
background-color: cornflowerblue;
color: #fff;
text-align: center;
padding: 0 .7rem;
box-sizing: border-box;
border-radius: 50%;
transition: all ease-in-out .4s;
&:hover,
&:focus {
border: 1px solid #182241;
background-color: #182241;
}
}
</style>
I want to only have the icon plus on the last row cell. I wish to hide or remove the others, but also, I edited the code to start with 3 rows instead of one.

Your data should be reactive.
You should bind your data to the html inputs.
You need to rethink your code a lot. Here is an example of how you could get started: Vue SFC Playground

Related

Dynamic HTML table in React Native PDF

listData below is a dynamic array of data. I'm trying to print the data in to a PDF using expo-print.
How can I dynamically populate required number of table rows based on the array length and print each result in a seperate row?
"listdata": [
"OAG0001",
"RAA0012",
"RAA0098",
"RAB0023",
"UAE0014"
]
What I've tried so far below obviously prints the total array in to a single table row.
const printLoadOutData = () => {
setPrintLoadoutLoader(true);
const dataLoadOutToprint = `
<html>
<header>
</header>
<title></title>
<style>
table, th, td {
border:1px solid black;
}
</style>
<body>
<table >
<tr>
<td>"${listData}"</td>
</tr>
</table>
</body>
</html >`;
Print.printAsync({
html: dataLoadOutToprint,
width: 3508,
height: 2480,
orientation: Print.Orientation.landscape
})
.then(() => {
setPrintLoadoutLoader(false);
})
.catch(() => {
setPrintLoadoutLoader(false);
})
}
You need to do something like this:
const listdata = [
"OAG0001",
"RAA0012",
"RAA0098",
"RAB0023",
"UAE0014"
];
const htmltable = () => {
let t = '';
for (let i in listdata) {
const item = listdata[i];
t = t +
`<tr>
<td>${item}</td>
</tr>`
}
return t;
}
Html content be like:
const htmlContent =
`<html>
<header></header>
<title></title>
<style>
table, th, td {
border:1px solid black;
}
</style>
<body>
<table>
${htmltable()}
</table>
</body>
</html>`;
Print function:
const print = () => {
Print.printAsync({
html: htmlContent,
width: 3508,
height: 2480,
orientation: Print.Orientation.landscape
}).then(() => {
setPrintLoadoutLoader(false);
}).catch(() => {
setPrintLoadoutLoader(false);
})
}
Using expo-print for react native
import * as Print from "expo-print";
import { shareAsync } from "expo-sharing";
htmltable = () => {
let t = '';
for (let i in this.state.data) {
const item = this.state.data[i];
t = t +
`<tr>
<td style="border: 1px solid #000000;text-align: center;padding: 8px">${item.p_sku}<br/></td>
<td style="border: 1px solid #000000;text-align: center;padding: 8px">${item.p_name}<br/></td>
<td style="border: 1px solid #000000;text-align: center;padding: 8px">${item.p_price}<br/></td>
<td style="border: 1px solid #000000;text-align: center;padding: 8px">${item.p_quantity}<br/></td>
<td style="border: 1px solid #000000;text-align: center;padding: 8px">${item.p_incl_tax_total}<br/></td>
</tr>`
}
return t;
}
in render-> use like this
<TouchableOpacity
style={styles.buttonstyle}
onPress={async () => {
const { uri } = await Print.printToFileAsync({
html: `
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
</head>
<body style="text-align: center;">
<h1>Order: ${Constant.ORDER_ID}</h1>
<p>
<strong>Order Date: ${this.state.Orderdate}</strong><br/>
<strong>Order Total: ${this.state.OrderTotal}</strong><br/>
<strong>Status: ${this.state.OrderStatus}</strong>
<br/>
<br/>
<table style="width:100%">
<tr>
<th style="text-align:left"><strong>Shipping Address</strong></th>
<th style="text-align:left"><strong>Billing Address</strong></th>
</tr>
<tr>
<td>Name: ${this.state.shippingname}<br/></td>
<td>Name: ${this.state.billingname}<br/></td>
</tr>
<tr>
<td>Total : ${this.state.OrderTotal}<br/></td>
<td>Email: ${this.state.Billingemail}<br/></td>
</tr>
<tr>
<td>Email: ${this.state.shippingemail}<br/></td>
<td>Ph: ${this.state.Billingphone}<br/></td>
</tr>
<tr>
<td>Ph: ${this.state.shippingphone}<br/></td>
<td>Fax: ${this.state.Billingfax}<br/></td>
</tr>
<tr>
<td>Fax: ${this.state.shippingfax}<br/></td>
<td>Company: ${this.state.Billingcompany}<br/></td>
</tr>
<tr>
<td>Company: ${this.state.shippingcompany}<br/></td>
<td>Address: ${this.state.Billingaddress}<br/></td>
</tr>
<tr>
<td>Address: ${this.state.shippingaddress}<br/></td>
</tr>
</table>
<table style="width:100%">
<tr>
<th style="text-align:left"><strong>Payment</strong></th>
<th style="text-align:left"><strong>Shipping</strong></th>
</tr>
<tr>
<td>Payment method: ${this.state.PaymentMethod}<br/></td>
<td>Shipping method: ${this.state.ShippingMethod}<br/></td>
</tr>
</table><br/><br/>
<strong>Products: </strong><br/>
<table style="width:100%;border-collapse: collapse">
<tr>
<th style="border: 1px solid #000000;text-align: center;padding: 8px"><strong>SKU</strong></th>
<th style="border: 1px solid #000000;text-align: center;padding: 8px"><strong>Name</strong></th>
<th style="border: 1px solid #000000;text-align: center;padding: 8px"><strong>Price</strong></th>
<th style="border: 1px solid #000000;text-align: center;padding: 8px"><strong>Quantity</strong></th>
<th style="border: 1px solid #000000;text-align: center;padding: 8px"><strong>Total</strong></th>
</tr>
${this.htmltable()}
</table>
<br/>
<br/>
<table style="width:30%;border-collapse: collapse">
<tr>
<th style="border: 1px solid #000000;text-align: left;padding: 8px"><strong>Sub-Total: ${this.state.OrderSubtotalExclTax}</strong></th>
</tr>
<tr><th style="border: 1px solid #000000;text-align: left;padding: 8px"><strong>Shipping: ${this.state.OrderTax}</strong></th>
</tr>
<tr><th style="border: 1px solid #000000;text-align: left;padding: 8px"><strong>Tax: ${this.state.OrderTax}</strong></th>
</tr>
<tr><th style="border: 1px solid #000000;text-align: left;padding: 8px"><strong>Order Total: ${this.state.OrderTotal}</strong></th>
</tr>
</table>
</p>
</body>
</html>
`,
});
// console.log("File has been saved to:", uri);
await shareAsync(uri, { UTI: ".pdf", mimeType: "application/pdf" });
}}
>
<Text
style={{
color: "white",
fontWeight: "bold",
fontSize: 16,
textTransform: "uppercase",
letterSpacing: 1,
}}
>
Print
</Text>
</TouchableOpacity>

Create Pricing Table using HTML, CSS

I tried to create a responsive pricing table, but not working.
I tried below way but it's not working. I tried to google but I can't figure out the useful links.
Please suggest me to do this right away.
.table tr.hide-table-padding td {
padding: 0;
}
.expand-button {
position: relative;
}
.accordion-toggle .expand-button:after {
position: absolute;
left:.75rem;
top: 50%;
transform: translate(0, -50%);
content: '-';
}
.accordion-toggle.collapsed .expand-button:after {
content: '+';
}
</style>
<style type="text/css">/* Chart.js */
#-webkit-keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}#keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}.chartjs-render-monitor{-webkit-animation:chartjs-render-animation 0.001s;animation:chartjs-render-animation 0.001s;}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Heading</th>
<th scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr class="accordion-toggle collapsed" id="accordion1" data-toggle="collapse" data-parent="#accordion1" href="#collapseOne">
<td class="expand-button"></td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
</div>
Please suggest me to create the same as.
Try using width: 100% to fill the screen horizontally:
.table tr.hide-table-padding td {
padding: 0;
}
.table {
width: 100%;
}
.expand-button {
position: relative;
}
.accordion-toggle .expand-button:after {
position: absolute;
left: .75rem;
top: 50%;
transform: translate(0, -50%);
content: '-';
}
.accordion-toggle.collapsed .expand-button:after {
content: '+';
}
</style><style type="text/css">
/* Chart.js */
#-webkit-keyframes chartjs-render-animation {
from {
opacity: 0.99
}
to {
opacity: 1
}
}
#keyframes chartjs-render-animation {
from {
opacity: 0.99
}
to {
opacity: 1
}
}
.chartjs-render-monitor {
-webkit-animation: chartjs-render-animation 0.001s;
animation: chartjs-render-animation 0.001s;
}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Heading</th>
<th scope="col">Heading</th>
</tr>
</thead>
<tbody>
<tr class="accordion-toggle collapsed" id="accordion1" data-toggle="collapse" data-parent="#accordion1" href="#collapseOne">
<td class="expand-button"></td>
<td>Cell</td>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
</div>

td center aligned without space, borders and padding

Problem
i've to do a little html email just for test. The problem is that right now i cannot reset all the space between this 5 tds.
I need them in the center of the table.
Tries
I already tried, as suggested in many posts:
border spacing
border collapse
reset all in css ( html, body, p etc )
display: inline-table
display: inline-block
This is only the interested row of a bigger table, the other rows works perfectly.
i don't know what i could try to fix this.
Expectation
five square near to each other in the center of the
Code
<table id="bodyTable" width="100%" bgcolor="#efefef" border="0" cellspacing="0" cellpadding="0" style="margin: 0 auto; font-family: Museo, Helvetica, Arial, sans-serif">
<tr>
<td>
<table align="center" border="0" cellspacing="0" cellpadding="0" style="max-width: 600px">
<tr>
<tr>
<td>
<table width="600px" border="0" cellspacing="0" cellpadding="0" bgcolor="#efefef">
<tr>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/y48sqQs/Goglueplus-Logo.png" alt="twitterButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px;" src="https://i.ibb.co/m5nZrrg/facebook-Mini-Button.png" alt="facebookButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/cxLcQcQ/Instagram-Logo.png" alt="googlePlusButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/rxT4vzx/Linkedin-Button.png" alt="linkedinButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/3FCYZ4z/twitter-Button.png" alt="instagramButton">
</td>
</tr>
</table>
</td>
</tr>
</tr>
</table>
</td>
</tr>
</table>
CSS RESET
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100% !important;
-ms-text-size-adjust: 100% !important;
-webkit-font-smoothing: antialiased !important;
}
img {
border: 0 none !important;
display: block;
height: auto;
line-height: 100%;
outline: none !important;
text-decoration: none;
}
a img {
border: 0 none;
}
table, td {
border-collapse: collapse;
border: 0 none;
}
td, a, span {
mso-line-height-rule: exactly;
}
p {
Margin: 0px !important;
Padding: 0px !important;
}
#bodyTable{
height: 100% !important;
margin: 0;
padding: 0;
width: 100% !important;
-webkit-text-size-adjust: 100% !important;
-ms-text-size-adjust: 100% !important;
-webkit-font-smoothing: antialiased !important;
}
In the Html, your table width is 600px. Try 300px for centering them.
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100% !important;
-ms-text-size-adjust: 100% !important;
-webkit-font-smoothing: antialiased !important;
}
img {
border: 0 none !important;
display: block;
height: auto;
line-height: 100%;
outline: none !important;
text-decoration: none;
}
a img {
border: 0 none;
}
table,
td {
border-collapse: collapse;
border: 0 none;
}
td,
a,
span {
mso-line-height-rule: exactly;
}
p {
Margin: 0px !important;
Padding: 0px !important;
}
#bodyTable {
height: 100% !important;
margin: 0;
padding: 0;
width: 100% !important;
-webkit-text-size-adjust: 100% !important;
-ms-text-size-adjust: 100% !important;
-webkit-font-smoothing: antialiased !important;
}
<table id="bodyTable" width="100%" bgcolor="#efefef" border="0" cellspacing="0" cellpadding="0" style="margin: 0 auto; font-family: Museo, Helvetica, Arial, sans-serif">
<tr>
<td>
<table align="center" border="0" cellspacing="0" cellpadding="0" style="max-width: 600px">
<tr>
<tr>
<td>
<table width="300px" border="0" cellspacing="0" cellpadding="0" bgcolor="#efefef">
<tr>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/y48sqQs/Goglueplus-Logo.png" alt="twitterButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px;" src="https://i.ibb.co/m5nZrrg/facebook-Mini-Button.png" alt="facebookButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/cxLcQcQ/Instagram-Logo.png" alt="googlePlusButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/rxT4vzx/Linkedin-Button.png" alt="linkedinButton">
</td>
<td align="center">
<img style="height: 30px; padding: 10px" src="https://i.ibb.co/3FCYZ4z/twitter-Button.png" alt="instagramButton">
</td>
</tr>
</table>
</td>
</tr>
</tr>
</table>

Vuejs2 - Not able to apply property values from data object for the dynamically added table rows

I want to append dynamic rows to the table. Iam able to add dynamic rows but the property values defined inside the data object and css style not applied for those newly added rows. 1st row of the table(already defined one) shows the property value and its css also working fine
billing.vue
<template>
<b-card id="showBill">
<div class="table-responsive col-md-6">
<table class="table table-striped table-bordered table-sm" id="tbl">
<thead>
<tr>
<th>Charges</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td><select class="form-control input-sm form-control3"> <option v-for="option in chargesOpt" v-bind:value="option.value" :key="option.value"> {{ option.text }} </option></select></td>
<td><input type="text" class=" form-control input-sm form-control3"></td>
</tr>
</tbody>
<tfoot>
<tr class="table-secondary">
<th>Total Amount</th>
<th style="text-align:right;">0.00</th>
</tr>
</tfoot>
</table>
</div>
<div class="col-md-6">
<button type="button" class="btn btn-success" #click="addRow">Add</button>
</div>
</b-card>
</template>
<script>
export default {
data () {
return {
chargesOpt:[
{ value: '', text: 'Select'},
{ value: '1', text: 'Maintanence'},
{ value: '2', text: 'Extra'}
]
}
},
methods:{
addRow()
{
var table = document.getElementById("tbl");
var rowCount = table.rows.length-1;
var row = table.insertRow(rowCount);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
cell1.innerHTML = cell1.innerHTML +'<select class="form-control input-sm form-control3"> <option v-for="option in chargesOpt" v-bind:value="option.value" :key="option.value"> {{ option.text }} </option></select>';
cell2.innerHTML = cell2.innerHTML +'<input type="text" class=" form-control input-sm form-control3"/>';
}
}
}
</script>
<style lang="scss" scoped>
#import '../../../node_modules/bootstrap/dist/css/bootstrap.min.css';
.is-danger{
color: RED;
}
.form-control{display:block;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out
}
.input-sm{
border: 1px solid #ccc;
padding: 5px 8px;
color: #616161;
background: #fff;
box-shadow: none !important;
width: 100%;
font-size: 0.85em;
font-weight: 300;
height: 40px;
border-radius: 0;
-webkit-appearance: none;
resize: none;
}
.input-sm {
font-size: 14px;
height: 35px;
}
.form-control3 { /* For Vacancy List Table Input Fields */
padding-bottom: 0px;
padding-top: 0px;
background-color: transparent!important;
background: transparent !important;
border: 1px solid transparent !important;
border-radius: 5px;
box-shadow: none !important;
}
.form-control3:focus {
border: 1px solid #03a9f4 !important;
background: #fff !important;
box-shadow: none !important;
}
.form-control3{
height: 30px;
}
.form-control3,{
padding-bottom: 0px;
padding-top: 0px;
}
</style>
You could do something like:
<tr v-for="charge in charges">
<td>
<select class="form-control input-sm form-control3" v-model="charge.opt">
<option v-for="option in chargesOpt" v-bind:value="option.value" :key="option.value">{{ option.text }}</option>
</select>
</td>
<td>
<input type="text" class=" form-control input-sm form-control3" v-model="charge.value">
</td>
</tr>
...
export default {
data() {
return {
chargesOpt: [
{value: '', text: 'Select'},
{value: '1', text: 'Maintanence'},
{value: '2', text: 'Extra'}
],
charges: []
}
},
mounted() {
this.addRow();
},
methods: {
addRow() {
this.charges.push({
value: '',
opt: ''
});
}
}
}
By using v-for on the table row and pushing a new object on to the charges array, vue will take care of creating the new row for you.

jsfiddle: same code different result on same browser

This shows the working jfiddle (Click the color-picker)
http://jsfiddle.net/xztoqtd7/
This shows the non-working jfiddle (Click the color-picker)
http://jsfiddle.net/p7dm051z/
They should both change the color of the second row cells, but only one of them does that. Code:
HTML
<table>
<tr>
<td>
<input type="color" id="colorpicker1" />
</td>
<td>
<input type="color" id="colorpicker2" />
</td>
</tr>
<tr>
<td id="one">ipsum</td>
<td id="two">lorem</td>
</tr>
</table>
CSS
table {
border-collapse: collapse;
background: #000;
border-top: 1px solid #777;
border-left: 1px solid #777;
}
table tr td {
border-right: 1px solid #777;
border-bottom: 1px solid #777;
color: #fff;
text-align: center;
}
input {
border: 0;
padding: 0;
margin: 0;
}
JS
$("#colorpicker1").on("change", function() {
$("#one").css("color", $("#colorpicker1").val());
});
$("#colorpicker2").on("change", function() {
$("#two").css("color", $("#colorpicker2").val());
});
Why is the result different?