Html2Canvas Iteration in HTML table - laravel

Good day! I have this dynamic table which data is coming from database.
<table class="ui table" style="margin-top: 1em;border:1" id = "tbl">
<thead>
<tr>
<th class="four wide">FirstName</th>
<th class="four wide">LastName</th>
</tr>
</thead>
<tbody>
#foreach ($data as $name)
<tr>
<td>{!! $name !!} </td>
</tr>
#endforeach
</tbody>
</table>
What i want to do is get every row of table and screenshot that row using HTML2Canvas then the image will save to JSPDF. I only have this code of html2canvas which is capturing the whole table.
var w = document.getElementById("tbl").offsetWidth;
var h = document.getElementById("tbl").offsetHeight;
html2canvas(document.getElementById("tbl"), {
dpi: 300, // Set to 300 DPI
scale: 3, // Adjusts your resolution
onrendered: function(canvas) {
var img = canvas.toDataURL("image/jpeg", 1);
var doc = new jsPDF('P', 'px', [w, h]);
doc.addImage(img, 'JPEG', 15, 40, w, h);
doc.save('sample-file.pdf');
}
});
How will I be able to do that? I have iteration from html table to javascript but keep getting error. here is the iteration code.
for (let row of tbl.rows) {
for(let cell of row.cells) {
console.log(cell.innerText)
}
}
Thankyou in Advance

Related

data not displaying in table in vuejs

i have created vue file to display data in frontend. but i'm unable to print 2 tables on same page at same time. only table 2 is displaying data , in first table it shows data for 2 seconds and than disappears. what i'm doing wrong? please help. i am super new in vuejs and have not much knowledge.
here is my index.vue file,
Table 1
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and this is function code,
async fetchData1() {
this.$store.state.operations.loading = true;
let currentPage = this.pagination ? this.pagination.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/calldata?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
table 2
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and here is the function for table 2
async fetchData2() {
this.Loading2 = true
let currentPage = this.Pagination2 ? this.Pagination2.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/datacall/data2?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
this.Loading2 = false;
and this are the controller functions
public function index(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',1)->latest()->paginate($request->perPage));
}
public function index2(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',0)->latest()->paginate($request->perPage));
}
And Route ,
Route::get('/calldata/data2', [DataController::class, 'index2']);
Route::apiResource('calldata', DataController::class);
Observation : You are updating same variable which is items for both the tables. Hence, it is overriding the latest items with the old items array.
Solution : Here is the implementation as per my comment.
new Vue({
el: '#app',
data: {
table1Items: null,
table2Items: null
},
mounted() {
this.fetchData1();
this.fetchData2();
},
methods: {
fetchData1() {
this.table1Items = [{
id: 1,
name: 'table 1 alpha'
}, {
id: 2,
name: 'table 1 beta'
}]
},
fetchData2() {
this.table2Items = [{
id: 1,
name: 'table 2 alpha'
}, {
id: 2,
name: 'table 2 beta'
}]
}
}
})
table, th, td {
border: 1px solid black;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table1Items" v-for="(data, i) in table1Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table2Items" v-for="(data, i) in table2Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
</div>
you are using same property which is items for both. so second request will changed first items. so in both table same data will visible. you have to store in different state property for different data rendering.
solution :
make another action fetchData2.
call another mutation setItems2. add state propery item2: []. and setItems2 value from this mutation.
render second table like this.
<tr
v-show="items2.length"
v-for="(data, i) in items2"
:key="i">
<td></td>
<td></td>
</tr>
For code quailty:
give proper and related variable name . don't use items1 and items2 like that.
never used v-if/v-show and v-for in same element.for more info
use template first in this senerio.
use the item's unique id instead of the index in the key.
if you take the items default value as [], instead of null, then you only required to check items.length instead of items && items.length. so always use list default value []
if both requests are not dependent on each other then you should use Promise.all() for fetching data concurrently. which saved tremendous time and also in this case you don't require two loading property.

Splitting data into rows and columns in VueJS

I have some data and I am trying to figure out how I can display it in table format in rows and columns in Vue Js. The display should be as shown:
this is my code but only displays in one column only but need to split the data into rows and columns
<table>
<tbody>
<tr v-for="product in products">
<td>{{product.item_name}}</td>
</tr>
</tbody>
</table>
Using this function you can sort the initial array to be in three sections: (Make it a vue method).
function sortList(list, rows) {
const sortedList = [];
let rowIndex = 0;
for (i = 0; i < rows; i++) {
sortedList[i] = [];
}
list.forEach(item => {
sortedList[rowIndex++].push(item);
if ((rowIndex + 1) === rows) {
rowIndex = 0;
}
});
return sortedList;
}
Then you can set:
this.products = this.sortList(list, 3);
list being the initial array and 3 being the number of rows you want.
Then in the template you can do:
<table>
<tbody>
<tr v-for="row in products">
<td v-for="item in row">{{ item.item_name }}</td>
</tr>
</tbody>
</table>

How can I insert array using ajax laravel?

Help please ,I recover my data in frontend use jquery and I can display in console, now I want to insert these data in the database we are using ajax and laravel, here is my table.
Hi,help please ,I recover my data in frontend use jquery :
<table class="table table-bordered" id="mytable">
<tr>
<th>Archive</th>
<th><input type="checkbox" id="check_all"></th>
<th>S.No.</th>
<th>matricule</th>
<th>nom & prenom</th>
<th>salaire net</th>
<th>nbre de jour </th>
<th>prime</th>
</tr>
#if($salaries->count())
#foreach($salaries as $key => $salarie)
<tr id="tr_{{$salarie->id}}">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="{{$salarie->id}}"></td>
<td>{{ ++$key }}</td>
<td class="mat">{{ $salarie->matricule }}</td>
<td class="name">{{ $salarie->nom }} {{ $salarie->prenom }}</td>
<td class="salaireValue">{{ $salarie->salairenet }}</td>
<td ><input type="text" name="nbreJ" class="form-control" value="{{$data['nbr']}}"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
#endforeach
#endif
</table>
This is my code jquery which allows to recover my data
<script type="text/javascript">
$(document).ready(function () {
$('#check_all').on('click', function(e) {
if($(this).is(':checked',true))
{
$(".checkbox").prop('checked', true);
} else {
$(".checkbox").prop('checked',false);
}
});
$('.checkbox').on('click',function(){
if($('.checkbox:checked').length == $('.checkbox').length){
$('#check_all').prop('checked',true);
}else{
$('#check_all').prop('checked',false);
}
});
//get value
$('.add-all').on('click', function() {
var allChecked = $('.checkbox:checked');
for (var i = 0; i < allChecked.length; i++) {
var currentHtml = $(allChecked[i]).parent().siblings('.salaireValue')[0];
var currentHtml1 = $(allChecked[i]).parent().siblings('.name')[0];
var currentHtml2 = $(allChecked[i]).parent().siblings('.mat')[0];
var currentHtml3 = $(allChecked[i]).parent().siblings('.datea')[0];
var result = parseInt($(currentHtml)[0].innerText);
var result1 = $(currentHtml1)[0].innerText;
var result2 = parseInt($(currentHtml2)[0].innerText);
console.log(result);
console.log(result1);
console.log(result2);
}
});
});
</script>
This my controller I do not know how to write the function.
public function addMultiple(Request $request){
dd(request());
}
route
Route::post('mensuel', ['as'=>'salarie.multiple-add','uses'=>'SalarieController#addMultiple']);

laravel vue send array to backend

I want to send array of id's to backend with one button from vuejs table but i get error 500.
Logic
Check the check boxes
Collect the id's
Send id's to back-end when click on button
update the view
Code
template
<table class="table table-dark table-hover table-bordered table-striped">
<thead>
<tr>
<th class="text-center" width="50">
//the button
<button class="btn btn-outline-danger" #click="withdraw(index)">Withdraw</button>
</th>
<th class="text-center" width="50">#</th>
<th class="text-center">Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="(income,index) in incomes" v-bind:key="index">
<td class="text-center">
//check box input
<input v-if="income.withdraw == '0'" type="checkbox" :id="income.id" :value="income.amount" v-model="checkedNumbers">
</td>
<td class="text-center">{{index+1}}</td>
<td class="text-center">Rp. {{formatPrice(income.amount)}}</td>
</tr>
<tr>
<td colspan="2"></td>
<td>
<span>Withdraw for today, Sum: <br> Rp. {{ formatPrice(sum) }}</span>
</td>
</tr>
</tbody>
</table>
script
export default {
data() {
return {
incomes: [],
checkedNumbers: [],
}
},
computed: {
sum() {
return this.checkedNumbers.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
},
methods: {
withdraw(index) {
let checkedids = this.incomes[index]
axios.post(`/api/withdrawbutton/`+checkedids).then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
}
}
}
route
Route::post('withdrawbutton/{id}', 'IncomeController#withdrawbutton');
controller
public function withdrawbutton($id)
{
$dowithdraw = Income::where('id', $id)->get();
$dowithdraw->withdraw = '1';
$dowithdraw->save();
return response()->json($dowithdraw,200);
}
Any idea where is my mistake and how to fix it?
......................................................................................................................
Don't send the list as a GET parameter, send it as a POST:
let params = {}
params.ids = this.checkedNumbers
axios.post(`/api/withdrawbutton/`, params)
.then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
Controller
public function withdrawbutton(Request $request)
{
$dowithdraws = Income::whereIn('id', $request->input('ids', []));
$dowithdraws->update(['withdraw' => '1']);
return response()->json($dowithdraws->get(), 200);
}
Route
Route::post('withdrawbutton/', 'IncomeController#withdrawbutton');
And I don't think you need to update anything in the front because you already have them checked (if you want to keep them checked)

Line break in cell jquery-bootgrid

There is a way to make visible a <br> inside a cell using jquery-bootgrid? Because the render of <br> is not visible.
What I understand is that you want to add a line break in your data, something like this,
In the features column I am passing an array and it displays each Item in a separate row using <br>
For this you can create a custom converter,
http://www.jquery-bootgrid.com/Documentation#converters
You can create the converter when initializing the BootGrid Table
var dt = $('#myTable').bootgrid({
//.......... Other Options
converters: {
listDisplay: {
from: function(value) {
return value;
},
to: function(value) {
// Here you can customise value - I have an Array which I join using <br>
value.sort();
value = value.join("<br/>");
return value;
}
}
}
});
Then all you have to do in the Table HTML is set the data-type on the Column heading
<table id="myTable">
<thead>
<tr>
<th data-column-id="Id" data-visible="false" data-identifier="true" data-type="numeric">Id</th>
<th data-column-id="SelectedFeaturesNames" data-type="listDisplay">Features</th>
<!-- Note the data-type on the Features <th> is listDisplay -->
</tr>
</thead>
<tbody></tbody>
</table>
Did it work using that method?
Yes #Dawood Awan ! It worked for me
PHP:
<td>
<?php
$test = ['b', 'a', 'c'];
echo json_encode($test);
?>
</td>
JS:
to: function(value) {
value = JSON.parse(value); //convert received json to js array.
value.sort();
value = value.join("<br/>");
return value;
}

Resources