How to draw diagonal lines with SCRIPT in PDF - javascript

I'm using laravel-dompdf package for generating pdf.
I could draw a diagonal line using rotate of the CSS.
As you can see, my document have a lot of diagonal lines, so I want to draw a line with scripts.
Controller
public function downloadPDF () {
$pdf = PDF::loadView('test', [
'users' => $users //$users is array
])->setPaper('a4', 'portrait');
return $pdf->download("test.pdf");
}
View(test.blade.php)
<!DOCTYPE html>
<html>
...
<body>
<table>
<tbody>
<tr>
<th>{{-- Draw diagonal line here --}}</th>
<th>Name</th>
<th>TEL</th>
</tr>
#foreach($users as $key=>$user)
<tr>
<td>{{ $key }}</td>
<td>{{ $user['name'] }}</td>
<td>{{ $user['tel'] }}</td>
</tr>
#endforeach
</tbody>
</table>
</body>
</html>
Below is a sample pdf format.
How can draw diagonal lines with script?

I could use line function of Dompdf\Adapter\CPDFclass.
As PDF rendering interface, CPDF provide to enable php script on blade, using set_option("enable_php", true)
line function
line($x1, $y1, $x2, $y2, $color, $width, $style = [])
Controller
public function downloadPDF () {
$pdf = PDF::getDomPDF()->set_option("enable_php", true)->loadView('test', [
'users' => $users //$users is array
])->setPaper('a4', 'portrait');
return $pdf->download("test.pdf");
}
<script type="text/php">
if (isset($pdf)) {
$pdf->page_script('
$pdf->line(100, 100, 200, 200, array(0,0,0), 0.7);
');
}
</script>

Related

I cant seem to pass value from controller to view, Laravel 8

I can't seem to parse data that i got from db on controller to view, i have tried multiple solutions that i got from similiar question but none seem to work.
i simply want to show my employee list on my admin page.
Here's my login controller
The login function works just fine, its just doenst seem to parse the data i got from db to view
public function postLogin(Request $request){
$list = "";
$list = \DB::table('users')->where('role','1')->get();
if(Auth::attempt($request -> only('username','password'))){
if (Auth::user()->role == '0') {
return view('admin',['daftar' => $list]);
}else if (Auth::user()->role == '1') {
return redirect('/EPage');
}
}
return redirect('/');
}
Here's my admin blade view
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">email</th>
<th scope="col">phone</th>
</tr>
</thead>
<tbody>
<tr>
#foreach($list as $lists)
<th scope="row">1</th>
<td>{{ $lists->name }}</td>
<td>{{ $lists->email }}</td>
<td>{{ $lists->phone }}</td>
#endforeach
</tr>
</tbody>
Please help me understand my mistake, Thank you in advance.
i'm expecting the admin page with show user list with role equals to 1
After i tinker here and there, i finally found that i forgot to put an "s" on my user(s) table name. silly mistake but crucial hahaha
it seems previously the variable that i parse are actually empty.
Here are my final controller that worked
public function postLogin(Request $request){
if(Auth::attempt($request -> only('username','password'))){
if (Auth::user()->role == '0') {
$daftar = \DB::table('users')->where('role',1)->get();
return view('admin',['daftar' => $daftar]);
}else if (Auth::user()->role == '1') {
return redirect('/EPage');
}
}
return redirect('/');
}
and here's my blade view
<tbody>
#foreach($daftar as $lists)
<tr>
<th scope="row">1</th>
<td>{{ $lists->name }}</td>
<td>{{ $lists->email }}</td>
<td>{{ $lists->Phone }}</td>
</tr>
#endforeach
</tbody>
also thanks to waqar for correcting my previous mistakes
You can send list data with view using compact like:
public function postLogin(Request $request){
$list = "";
$list = \DB::table('users')->where('role','1')->get();
if(Auth::attempt($request -> only('username','password'))){
if (Auth::user()->role == '0') {
return view('admin',compact('list'));
}else if (Auth::user()->role == '1') {
return redirect('/EPage');
}
}
return redirect('/');
}
then you can use $list on your blade easily.

An animation in Angular to switch rows in a table

I have an HTML file that displays a voting chart for musical songs using Angular. Each time I press the refresh button, the chart data is updated by making a GET request. I am trying to create an animation that shows the changes in the table when the data is updated. For example, when the third most voted track becomes the first most voted track after the update, I want the third row to visually move up in the table and the first and second rows to move down. Can someone help me figure out how to achieve this animation?
<button onclick="reloadData()">REFRESH</button>
<table>
<thead>
<tr>
<th>Rank</th>
<th>Track</th>
<th>Artist</th>
<th>Percentage</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let track of votedTracks; let i = index">
<td>{{ i + 1 }}</td>
<td class="track-name">{{ track.name }}</td>
<td class="artist-name">{{ track.artist }}</td>
<td class="percentage">{{ track.percentage | number : "1.0-2" }}%</td>
</tr>
</tbody>
</table>
I have tried to create a custom animation using the Angular animation module, but the rows are not moving as expected. I'm expecting the rows to move up or down in the table when the data is updated and the ranking of the tracks changes. Last time it showed only the first row and than it gave me the error:
> ERROR Error: Unexpected synthetic property #moveRow found. Please make sure that:
> Either `BrowserAnimationsModule` or `NoopAnimationsModule` are imported in your application.
> There is corresponding configuration for the animation named `#moveRow` defined in the `animations` field of the `#Component` decorator (see https://angular.io/api/core/Component#animations).
Import the BrowserAnimationsModule in your app.module.ts file.
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
You also need to add [#moveRow] to the <tr>, like so:
<tr *ngFor="let track of votedTracks; let i = index" [#moveRow]>
All together it would something like this:
#Component({
animations: [
trigger('moveRow', [
state('in', style({transform: 'translateY(0)'})),
transition('void => *', [
style({transform: 'translateY(-100%)'}),
animate(200)
]),
transition('* => void', [
animate(200, style({transform: 'translateY(100%)'}))
])
])
],
// ... etc
})
<tbody>
<tr *ngFor="let track of votedTracks; let i = index" [#moveRow]="i">
<td>{{ i + 1 }}</td>
<td class="track-name">{{ track.name }}</td>
<td class="artist-name">{{ track.artist }}</td>
<td class="percentage">{{ track.percentage | number : "1.0-2" }}%</td>
</tr>
</tbody>
Then in your reloadData() method you need to use ngZone.run() method because the change detection doesn't run automatically from an async data source... you would have something like this:
reloadData() {
this.http.get('/api/voted-tracks').subscribe(data => {
this.ngZone.run(() => {
this.votedTracks = data;
});
});
}

Create a select from list and put it in table

I'm writing a web application using Java and Spring.
From the controller, I send to the view a list called materials
#RequestMapping(value = "/advanced")
public String advancedCalculation(Model model) {
model.addAttribute("materials", materialService.getMaterials());
model.addAttribute("calcForm", new CalculationForm());
return "advanced";
}
materials is a list of objects called MaterialDTO:
public class MaterialDTO extends DTO {
/* Constructors */
public MaterialDTO() { super(); }
public MaterialDTO(Integer id, String name) { super(id, name); }
}
From the client side I have to make tables with buttons to add rows to such tables. Something like:
<table id="1">
<thead>
... 2 columns ...
</thead>
<tbody>
<tr>
<td>HERE I NEED THE SELECTOR</td>
<td>column 2</td>
</tr>
</tbody>
</table>
.
.
.
<table id=N>
<thead>
... M columns ...
</thead>
<tbody>
<tr>
<td>HERE I NEED THE SELECTOR</td>
<td>column 2</td>
...
<td>column M</td>
</tr>
</tbody>
</table>
That selector is the same for all tables, so I wanted to create it from the materials list once and use it where I need it. With this last I'm having problems ...
/* Making select */
var materialsList = new Array();
var sel = $('<select>');
<c:forEach items="${materials}" var="material">
var material = new Object();
material.id = '${material.id}';
material.name = '${material.name}';
materialsList.push(material);
</c:forEach>
$(materialsList).each(function() {
sel.append($('<option>').attr('value', this.id).text(this.name));
});
That's when I try to add it as HTML and it fails
function add_to_table_1() {
$('#1')
.append('<tr><td>' + sel.html() + '</td><td><input type="text" id="e"></input></td><td><input type="text" id="S"></input></td><td><input type="itext" id="r"></input></td><td><button onclick="delete_row(this)">Borrar</button></td></tr>');
}
And instead of the selector appears "[object Object]". How can I fix this?
Try this:
$(sel).wrap('<div></div>').parent().html();
This will fix your select not displaying with your options. Remember .html() only returns innerHTML. The outer html, <select></select>, will not display with it. You have to wrap first.
Alternative:
$(sel)[0].outerHTML

ng-repeat filter not applied

I have a simple code that pulls some data in intervals and prints into a table. I'd like to filter the table rows but any filters that I'm trying to apply are ignored. What am I missing? This is basically a plain copy from AngularJS docs page.
The only difference here seems to be that I'm using a controller and the example code does not.
Example Plunkr.
HTML template:
<table>
<thead>
<tr>
<th>Pages</th>
<th>Last action</th>
<th>Total time</th>
</tr>
<tr>
<th><input ng-model="search.count"></th>
<th><input ng-model="search.last"></th>
<th><input ng-model="search.time"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in adminCtrl.rows | filter:search ">
<td>{{ row.count }}</td>
<td>{{ row.last }}</td>
<td>{{ row.time }}</td>
</tr>
</tbody>
</table>
Controller:
(function(){
var app = angular.module('admin', []);
app.controller('AdminController', ['$interval', '$http', function($interval, $http){
var admin = this;
admin.rows = [];
var timer = undefined;
function updateRows() {
$http.get('test.json').success(function(data) {
admin.rows = data;
});
}
admin.stopTimer = function() {
if (angular.isDefined(timer)) {
$interval.cancel(timer);
timer = undefined;
}
};
admin.startTimer = function(delay) {
if (!angular.isDefined(delay)) {
// Default interval 10 seconds.
delay = 10000;
}
if (!angular.isDefined(timer)) {
timer = $interval(updateRows, delay);
}
};
admin.isTimerRunning = function() {
return angular.isDefined(timer);
}
// Initialize rows.
updateRows();
// Start the interval timer.
admin.startTimer();
}]);
})();
the filter is only apply in array where your data is an object. simply convert the data to array should work. if you happend to use lo-dash, that's a easy job to do :
function updateRows() {
$http.get('test.json').success(function(data) {
admin.rows = _.toArray(data);
});
}
It's because your ng-repeat is repeating over an object and not an array, here is your adminCtrl.rows:
{"a":{"count":14,"last":"Lorem ipsum","time":45},"b":{"count":5,"last":"Some title","time":13}}
Make it an array:
[{"count":14,"last":"Lorem ipsum","time":45},{"count":5,"last":"Some title","time":13}}]
If you want to use filter over an object, you'll have to roll your own using a
.filter("MY_FILTER", function(){
...
});

How to handle an empty result set in tempojs?

The documentation is not quite clear on this, or I may not be understanding how to implement this in the HTML, but how do you handle a template in tempojs that has an empty list/array of items coming from JSON output? Is there a template directive that can be used to display something when the data list is empty (i.e. like the else empty in normal conditional code)?
Here's an example:
Javascript:
$(function() {
/*var data = [
{id:'1',name:'Test One',coordinates:'12.0012,-122.92'}
];*/
var data = [];
Tempo.prepare('userLocs').render(data);
});
HTML:
...
<tbody id="userLocs">
<tr data-template>
<td>{{name}}</td>
<td>{{coordinates}}</td>
<td>Delete</td>
</tr>
<tr data-template-fallback>
<td colspan="3">Javascript is not available.</td>
</tr>
</tbody>
...

Categories