How to space out list items

I am unable to get my nav to sit the way I like, the header is fine but ul just won't sit right.

I am unable to get my nav to sit the way I like, the header is fine but ul just won't sit right.

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

nav ul {
margin: 0;
padding: 0;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}

nav ul li {
list-style: none;
position: relative;
}
<div class="nav">
<h2>hackeryou</h2>
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
<li>Bootcamp</li>
<li>Part-Time</li>
</ul>
</nav>
</div>


I expect the h2 to stay left but I want everything else to move be more spaced out on the right.

Frontend vs Backend vs Fullstack Web Development - What should you learn?

Frontend vs Backend vs Fullstack Web Development - What should you learn?

Frontend vs Backend vs Fullstack Web Development - What should you learn? In Web Development, there's Frontend (JS, HTML, CSS), Backend (PHP, Node.js, DBs, ...) and Fullstack (Everything?) Development. What's the best one?

In Web Development, there's Frontend (JS, HTML, CSS), Backend (PHP, Node.js, DBs, ...) and Fullstack (Everything?) Development. What's the best one?
Limited Offer! Join the Full Node.js Course at 90% off: http://bit.ly/2O0oN6c
Exclusive Discount also available for these courses:

  • React.js: http://bit.ly/36Qm6ww
  • Angular: http://bit.ly/2X0yLZc
  • Vue.js: http://bit.ly/32xDUcj
  • MongoDB: http://bit.ly/34MsB1y
  • CSS: http://bit.ly/2NXtbCZ

How to Validate Phone Number with Javascript

How to Validate Phone Number with Javascript

The validating phone number is an important point while validating an HTML form. In this post we have discussed how to validate a phone number (in different format) using JavaScript

The validating phone number is an important point while validating an HTML form. In this page we have discussed how to validate a phone number (in different format) using JavaScript :

At first, we validate a phone number of 10 digits with no comma, no spaces, no punctuation and there will be no + sign in front the number. Simply the validation will remove all non-digits and permit only phone numbers with 10 digits. Here is the function.

function phonenumber(inputtxt)
{
  var phoneno = /^\d{10}$/;
  if((inputtxt.value.match(phoneno))
        {
      return true;
        }
      else
        {
        alert("message");
        return false;
        }
}

Flowchart:

Flowchart : JavaScript phone validation-1

To valid a phone number like
XXX-XXX-XXXX
XXX.XXX.XXXX
XXX XXX XXXX
use the following code.

function phonenumber(inputtxt)
{
  var phoneno = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
  if((inputtxt.value.match(phoneno))
        {
      return true;
        }
      else
        {
        alert("message");
        return false;
        }
}

Flowchart:

Flowchart : JavaScript - phone validation-2

If you want to use a + sign before the number in the following way
+XX-XXXX-XXXX
+XX.XXXX.XXXX
+XX XXXX XXXX
use the following code.


function phonenumber(inputtxt)
{
  var phoneno = /^\+?([0-9]{2})\)?[-. ]?([0-9]{4})[-. ]?([0-9]{4})$/;
  if((inputtxt.value.match(phoneno))
        {
      return true;
        }
      else
        {
        alert("message");
        return false;
        }
}

Flowchart:

Flowchart : JavaScript - phone validation-3

Following code blocks contain actual codes for the said validations. We have kept the CSS code part common for all the validations.

CSS Code

 li {list-style-type: none;
font-size: 16pt;
}
.mail {
margin: auto;
padding-top: 10px;
padding-bottom: 10px;
width: 400px;
background : #D8F1F8;
border: 1px soild silver;
}
.mail h2 {
margin-left: 38px;
}
input {
font-size: 20pt;
}
input:focus, textarea:focus{
background-color: lightyellow;
}
input submit {
font-size: 12pt;
}
.rq {
color: #FF0000;
font-size: 10pt;
}

Validate a 10 digit phone number

At first we validate a phone number of 10 digit. For example 1234567890, 0999990011, 8888855555 etc.

HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript form validation - checking non-empty</title>
<link rel='stylesheet' href='form-style.css' type='text/css' />      
</head><body onload='document.form1.text1.focus()'>
<div class="mail">
<h2>Input an Phone No.[xxxxxxxxxx] and Submit</h2>
<form name="form1" action="#">
<ul>
<li><input type='text' name='text1'/></li>
<li>&nbsp;</li>
<li class="submit"><input type="submit" name="submit" value="Submit" onclick="phonenumber(document.form1.text1)"/></li>
<li>&nbsp;</li>
</ul>
</form>
</div>
<script src="phoneno-all-numeric-validation.js"></script>
</body>
</html>

JavaScript Code

function phonenumber(inputtxt)
{
  var phoneno = /^\d{10}$/;
  if(inputtxt.value.match(phoneno))
  {
      return true;
  }
  else
  {
     alert("Not a valid Phone Number");
     return false;
  }
  }

Flowchart:

Flowchart : JavaScript - phone validation 10 digit

Validate North American phone numbers

Now, let's see how to validate a phone number, either in 222-055-9034, 321.789.4512 or 123 256 4587 formats.

HTML Code

<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<title>JavaScript form validation - checking non-empty</title>
<link rel='stylesheet' href='form-style.css' type='text/css' />      
</head>
<body onload='document.form1.text1.focus()'>
<div class="mail">
<h2>Input an Phone No.[xxx-xxx-xxxx, xxx.xxx.xxxx, xxx xxx xxxx] and Submit</h2>
<form name="form1" action="#"> 
<ul>
<li><input type='text' name='text1'/></li>
<li>&nbsp;</li>
<li class="submit"><input type="submit" name="submit" value="Submit" onclick="phonenumber(document.form1.text1)"/></li>
<li>&nbsp;</li>
</ul>
</form>
</div>
<script src="phoneno-international-format.js"></script>
</body>
</html>

JavaScript Code

function phonenumber(inputtxt)
{
  var phoneno = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
  if(inputtxt.value.match(phoneno))
     {
	   return true;      
	 }
   else
     {
	   alert("Not a valid Phone Number");
	   return false;
     }
}

Flowchart:

Flowchart : JavaScript - phone validation North America

Validate an international phone number with country code

Now, let's see how to validate a phone number with country code, either in +24-0455-9034, +21.3789.4512 or +23 1256 4587 format.

HTML Code

<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<title>JavaScript form validation - checking non-empty</title>
<link rel='stylesheet' href='form-style.css' type='text/css' />
</head>

<body onload='document.form1.text1.focus()'>
<div class="mail">
<h2>Input an Phone No.[+xx-xxxx-xxxx, +xx.xxxx.xxxx, +xx xxxx xxxx] and Submit</h2>
<form name="form1" action="#"> 
<ul>
<li><input type='text' name='text1'/></li>
<li>&nbsp;</li>
<li class="submit"><input type="submit" name="submit" value="Submit" onclick="phonenumber(document.form1.text1)"/></li>
<li>&nbsp;</li>
</ul>
</form>
</div>
<script src="phoneno-+international-format.js"></script>
</body>
</html>

JavaScript Code

function phonenumber(inputtxt)
{
  var phoneno = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
  if(inputtxt.value.match(phoneno))
     {
	   return true;
	 }
   else
     {
	   alert("Not a valid Phone Number");
	   return false;
     }
}

Thank you for visiting and reading !

How to Validate an IP address using Javascript

How to Validate an IP address using Javascript

IP address validation using javascript

IP address validation

Every computer connected to the Internet is identified by a unique four-part string, known as its Internet Protocol (IP) address. An IP address consists of four numbers (each between 0 and 255) separated by periods. The format of an IP address is a 32-bit numeric address written as four decimal numbers (called octets) separated by periods; each number can be written as 0 to 255 (e.g., 0.0.0.0 to 255.255.255.255).

Example of valid IP address

  • 115.42.150.37
  • 192.168.0.1
  • 110.234.52.124

Example of invalid IP address

  • 210.110 – must have 4 octets
  • 255 – must have 4 octets
  • y.y.y.y – the only digit has allowed
  • 255.0.0.y – the only digit has allowed
  • 666.10.10.20 – digit must between [0-255]
  • 4444.11.11.11 – digit must between [0-255]
  • 33.3333.33.3 – digit must between [0-255]

JavaScript code to validate an IP address

function ValidateIPaddress(ipaddress) 
{
 if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(myForm.emailAddr.value))
  {
    return (true)
  }
alert("You have entered an invalid IP address!")
return (false)
}

Explanation of the said Regular expression (IP address)

Regular Expression Pattern :

/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/

This is image title

Note: Last two parts of the regular expression is similar to above.

Syntax diagram - IP-address validation:

Syntax diagram - IP-address validation

Let apply the above JavaScript function in an HTML form.

HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript form validation - checking IP address/title>
<link rel='stylesheet' href='form-style.css' type='text/css' />
</head>
<body onload='document.form1.text1.focus()'>
<div class="mail">
<h2>Input an IP address and Submit</h2>
<form name="form1" action="#"> 
<ul>
<li><input type='text' name='text1'/></li>
<li>&nbsp;</li>
<li class="submit"><input type="submit" name="submit" value="Submit" onclick="ValidateIPaddress(document.form1.text1)"/></li>
<li>&nbsp;</li>
</ul>
</form>
</div>
<script src="ipaddress-validation.js"></script>
</body>
</html>

JavaScript Code

function ValidateIPaddress(inputText)
 {
 var ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
 if(inputText.value.match(ipformat))
 {
 document.form1.text1.focus();
 return true;
 }
 else
 {
 alert("You have entered an invalid IP address!");
 document.form1.text1.focus();return false;
 }
 }

Flowchart:

Flowchart : JavaScript - ipaddress validation

CSS Code

li {list-style-type: none;
font-size: 16pt;
}
.mail {
margin: auto;
padding-top: 10px;
padding-bottom: 10px;
width: 400px;
background : #D8F1F8;
border: 1px soild silver;
}
.mail h2 {
margin-left: 38px;
}
input {
font-size: 20pt;
}
input:focus, textarea:focus{
background-color: lightyellow;
}
input submit {
font-size: 12pt;
}
.rq {
color: #FF0000;
font-size: 10pt;
}

Thank for reading !

How to Creat Drag and Drop List with React and HTML

How to Creat Drag and Drop List with React and HTML

What goes into building a drag and drop component in the future?

Creating a Drag and Drop List

This is image title

What goes into building a drag and drop component in 2019?

The drag and drop interaction was invented in the 1970's by Jef Raskin as a part of the Macintosh project. That's 40 years ago! So how come that making things draggable on the web is still so painful? We were recently looking for answers since our component library needs to support a sortable list and slider.

HTML Drag and Drop API

There is an official HTML drag and drop API, it was introduced in the HTML5 standard and it comes with eight different events:

  • drag
  • dragend
  • dragenter
  • dragexit
  • dragleave
  • dragover
  • dragstart
  • drop

Here is a little pop quiz for you. What's the difference between dragexit and dragleave? Not sure? It takes some imagination to implement eight different events for something that could be described by three user actions:

  • pressing the mouse button
  • moving the mouse
  • releasing the mouse button

That is not the only strange thing about this API. Some other "glitches":

  • no support for touch devices (ugh)
  • limited styling options for dragged items
  • the API is wildly inconsistent across browsers

Yes, Internet Explorer 6 is the culprit here. If we don't want to settle with no mobile support and other shortcomings, what else we can do?

(The dragexit event is fired when an element is no longer the drag operation's immediate selection target. The dragleave event is fired when a dragged element or text selection leaves a valid drop target.)

Tracking Basic Actions

Fortunately, there are still good old mouse and touch events:

  • mousedown (touchstart)
  • mousemove (touchmove)
  • mouseup (touchend, touchcancel)

They also nicely translate into our three drag and drop actions.

Mouse/Finger Coordinates

Another information we need is the coordinates of the mouse/finger at any given point. That's very straightforward since all mouse/touch events pass them through. Mouse events:

  • event.clientX
  • event.clientY

Touch events:

  • event.touches[0].clientX
  • event.touches[0].clientY
Measuring Elements

We need to measure things. There is a great API with a horrible name. Let me introduce you Element.getBoundingClientRect. Call it on any element and it returns its dimensions and locations:

{
  "width": 500,
  "height": 100,
  "top": 674,
  "right": 800,
  "bottom": 774,
  "left": 1300
}
Positioning

As user "moves" an item around, we need to keep changing its position to actually create the illusion of moving. The first naive solution could look like this:

position: fixed;
top: 100px;
left: 200px;

As user moves the item, we apply position fixed and keep updating its top and left values. This works reasonably well. However, the better solution is using CSS transforms:

transform: translate(10px, 20px);
transition-duration: 1s;

It's GPU accelerated, requires less work from the browser and we can also combine it with transition-duration to animate it.

Other DOM APIs

There are many other useful DOM APIs to deal with scrolling, container manipulation or optimizing the browser workload:

window.getComputedStyle(ELement);
window.scrollTo(X, Y);
window.pageXOffset;
window.pageYOffset;
window.innerHeight;
Element.contains();
Element.scrollTop;
requestAnimationFrame(() => {});
ReactDOM.createPortal

There is also one very useful React API - Portals.

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

Why would we need such a thing? It's the only way to make the positioning of dragged items reliable.

render() {
  return ReactDOM.createPortal(
    <li>Dragged</li>,
    document.body
  );
}

In this example, we "portal" the dragged list item to the bottom of document body. This way the item has no parents and there are no inherited CSS properties that could impact its position (like CSS transforms). You can often see this technique being used for modals or notifications.

The Algorithm

We have all the tools and APIs we need. Now it's time to put it all into a single algorithm.

This is image title

user starts dragging the second item

User clicks on the second item and starts dragging it. We set its visibility to hidden so it preserves the current space occupied by the item and at the same time we portal it to the root. We give it an initial top and left position and as user keeps moving, we update the translate values.

This is image title

User reaches the boundary of the third item

The user reached the boundary of the third item so we want to move the third item to the second position. All we need to do is applying a negative translate Y value. We should also add the transition property to animate it.

So far we didn't change the DOM order of our items. That happens only after the user finishes the drop.

There are many ways how you could go about it but this algorithm is pretty straightforward and works.

Accessibility

What does it mean? You should be able to control our component only through the keyboard and screen reader. There is a set of keyboard shortcuts we implement:

  • tab and shift+tab to focus a item
  • space to lift or drop the item
  • j or arrow down to move the lifted item down
  • k or arrow up to move the lifted item up
  • escape to cancel the lift and return the item to its initial position

We also need to provide audible cues through the screen reader. First, we should describe each item so it's clear that you can move it:

<li aria-roledescription="This is a draggable item. Press space to lift.">
  Item 1
</li>

Then we provide additional messages as the user goes through the interaction:

<div aria-live="assertive" role="log" aria-atomic="true">
  You have lifted item at position 5. Press j to move it down...
</div>

This is called ARIA live region. Whatever you set its content to gets announced by the screen reader. Check this article for more details.

Little Things

There are some little things that you might now even notice but they make the whole interaction nicer. For example, the drop animation. There is none here:

This is image title

No drop animation

On the other hand, we use

transition: 0.3s cubic-bezier(0.2, 1, 0.1, 1);

bellow to make the item fly back which gives user a nice additional feedback:

This is image title

The drop is animated.

And there are many other small interactions like this to consider.

Testing

Any drag and drop library needs to rely on a multiple DOM APIs. If you want to write unit tests, you would have to mock out all of them. What are you even testing at that point? Focusing on end to end tests might be a better solution. With Puppeteer you can write short and descriptive tests. Here we are testing the whole interaction using the mouse:

test('dnd the first item to second position', async () => {
  await page.mouse.move(190, 111);
  await page.mouse.down();
  await page.mouse.move(190, 190);
  await page.mouse.up();
  expect(await getListItems(page)).toEqual([
    'Item 2',
    'Item 1',
    'Item 3',
    'Item 4',
    'Item 5',
    'Item 6',
  ]);
});

We just move the mouse around and check the order of DOM elements at the end. The test for keyboard is similar:

test('move the first item to second position', async () => {
  await page.keyboard.press('Tab');
  await page.keyboard.press('Space');
  await page.keyboard.press('ArrowDown');
  await page.keyboard.press('Space');
  expect(await getListItems(page)).toEqual([
    'Item 2',
    'Item 1',
    'Item 3',
    'Item 4',
    'Item 5',
    'Item 6',
  ]);
});
Gotchas

There is a class of bugs that regular tests might not cover. Since we deal with a lot of positioning it's quite easy to misplace some items by a few pixels. We can utilize visual regression testing with jest-image-snapshot. It takes an image (snapshot) of our functioning component, takes another one on the subsequent run and compares them pixel by pixel. If there is any difference, the test fails. Be aware that each OS renders fonts differently. You might need to use docker to keep the tests reliable.

Internet Explorer

Frankly, it would be surprising to open IE for the first time and see everything working. Fortunately, the issues are relatively minor:

  • transform: translate doesn't work for table rows
  • window.scrollBy doesn't exist
  • window.scrollY needs to be replaced by window.pageYOffset
  • window.scroll needs to be replaced window.scrollTo
Safari and Scrolling

The gesture for touch scrolling and drag and drop is exactly the same, so we need to disable the touch scrolling. Luckily for us there is a CSS property just for that:

touch-action: none;

and it works in all browsers. Except Safari. What do you do when CSS fails you? Use more JavaScript! We can e.preventDefault all touch events. However, don't forget to make your event listeners not passive:

document.addEventListener('touchstart', _, {passive: false});

since otherwise the e.preventDefault() calls are ignored by default. This also means you can't use React event system at all - use native events only.

Conclusion

Building a drag and drop web experience is involved but not impossible. You should never compromise on mobile support and accessibility. To ensure that, avoid the HTML5 API and go with mouse/touch events. For positioning, CSS transforms are the right choice. Browsers provide many great APIs like getBoundingClientRect for measuring things. And before you release anything, don't forget to write tests. Puppeteer makes it easy!

Thank for reading! Please share if you liked it!

How to export Angular page content to PDF with Kendo UI

How to export Angular page content to PDF with Kendo UI

In this tutorial, learn how to easily export pages with HTML content within your Angular application. This should be a complex task, but thanks to a Kendo UI component it is easy

If you've found yourself looking for an easy solution to smoothly export the HTML content from your Angular application to a PDF, then this is the appropriate post for you. We may need to export HTML content to PDF for several reasons, ranging from sharing it with others without necessarily accessing the internet to saving it just for documentation purposes.

Building a solution for a component like this could be time-consuming if you are building all by yourself. In this post, I will show you how to easily achieve this by leveraging the PDF export component provided by Kendo UI.

We will build an Angular application with some dummy content and add a Kendo UI button to export the content directly to PDF as shown here:

Install Angular CLI

Before creating an Angular application, you need to first install the Angular CLI if it doesn’t already exist on your machine. Open up a terminal and run the following command for that purpose:

npm install -g @angular/cli 

This will add the Angular CLI globally on your machine.

Creating Angular Application

You can now proceed to create a new app for the purpose of this post by running the command below to generate an application with the name kendo-angular-export-pdf:

ng new kendo-angular-export-pdf

Once the installation process is complete, change directory into the newly created project as shown below and start the application:

// change directory
cd kendo-angular-export-pdf
   
// start the application
ng serve

You may experience an error with the message below in your console:

ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,77): error TS1109: Expression expected.

This is a known issue on GitHub and it’s due to lack of compatibility between the current version of TypeScript on your machine and rxjs. The quick way to fix this is to delete the node_modules folder. Now, open the package.json file and within the dependencies object, edit the rxjs by removing ^ :

 "dependencies": {
   ...
   "rxjs": "6.0.0", // remove the `^`
   "zone.js": "^0.8.26"
 },

Save the file and run the npm install command again. Once the installation process is complete, you can now proceed to start the application with ng serve.

This will compile your application and start the development server. To view the default page of this Angular application, navigate to http://localhost:4200 from your favorite browser and you will see this:

Add PDF Export Component from Kendo UI

Next, we’ll need to add the PDF export component before we start using it in our application. To achieve that, we’ll use the ng add command to require and install the package as shown here:

ng add @progress/kendo-angular-pdf-export

This will import and add both PDFExportModule and BrowserAnimationsModule to the app.module.ts file:

// ./src/app/app/module.ts
   
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { PDFExportModule } from '@progress/kendo-angular-pdf-export';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
   
   
@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   PDFExportModule,
   BrowserAnimationsModule
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }
Use the Kendo PDF Export Component

After installing the PDF export package, you can now proceed to export content within our Angular application to PDF by placing it within the <kendo-pdf-export> component. Open ./src/app/app.component.html and replace its content with:

// ./src/app/app.component.html
   
<div class="pageWrapper">
 <div class="content">
   <kendo-pdf-export #pdf>
     <div class="size-a4">
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
     </div>
   </kendo-pdf-export>
   
   <div>
     <button kendo-button (click)="pdf.saveAs('demo-content.pdf')">
       Export As PDF
     </button>
   </div>
 </div>
</div>

Here, we have added dummy content and wrapped it with the <kendo-pdf-export></kendo-pdf-export> component. Next we added a button and attached a click event to it. Once the button is clicked, we called the saveAs() method in order to save the generated file. The file will be saved as the name passed as an argument to the saveAs() method.

Finally, to give the page some default styling, add the following content to ./src/app/app.component.css file:

// ./src/app/app.component.css
   
.pageWrapper {
 margin-top: 50px;
}
button {
   padding: 15px;
}
kendo-pdf-export {
 font-family: "DejaVu Sans", "Arial", sans-serif;
 font-size: 16px;
}
.content {
 width: 800px;
 margin: 0 auto;
 line-height: 20px;
}

Now proceed to start the application again by running ng serve from the terminal within the application’s directory. Once

the application is built and served on http://localhost:4200 you will see this:

The content displayed here is from our Angular application. To test the HTML content export functionality, click on the Kendo button with the text Export As PDF. Now open the downloaded PDF file:

Cool, right? This is the content of our page exported to PDF without much hassle. But with a close look at the PDF file, you will agree with me that something isn’t right. The content doesn’t look properly organized. We’ll change that by adding a little bit of margin in the next section.

Add Paper Size and Margin

The Kendo PDF export component API makes a provision for us to easily customize and specify the paper size of the PDF document. At the moment, it is set to the default auto which means that the paper size is determined by the content.

Let’s replace the content of ./src/app/app.component.html with:

// ./src/app/app.component.html
   
<div class="pageWrapper">
 <div class="content">
   <kendo-pdf-export #pdf paperSize="A4" margin="2cm">
     <div class="size-a4">
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
     </div>
   </kendo-pdf-export>
   
   <div>
     <button kendo-button (click)="pdf.saveAs('demo-content.pdf')">
       Export As PDF
     </button>
   </div>
 </div>
</div>

We have added two data attributes to the <kendo-pdf-export>, which are:

  • paperSize: We set this to A4.
  • margin: We set this to 2cm.

Check the page again and click on the Export As PDF button. Now proceed to open your downloaded PDF file and you will notice that it looks much better as shown below:

Conclusion

The Kendo PDF export component as shown here is a solution for exporting and handling HTML content to PDF. This comes in handy whenever you need to quickly save a page as a PDF document from your Angular application.

We have barely scratched the surface here, because there is so much more functionality provided by the Kendo UI team when exporting HTML content to PDF. Feel free to explore the API by checking the link here for more details.

Hopefully you have learned a lot from this post. Check the source code here on GitHub.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about Angular

Angular 8 (formerly Angular 2) - The Complete Guide

Angular & NodeJS - The MEAN Stack Guide

The Complete Node.js Developer Course (3rd Edition)

The Web Developer Bootcamp

Best 50 Angular Interview Questions for Frontend Developers in 2019

How to build a CRUD Web App with Angular 8.0

React vs Angular: An In-depth Comparison

React vs Angular vs Vue.js by Example

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Building CRUD Mobile App using Ionic 4, Angular 8

How to Build Mobile Apps with Angular, Ionic 4, and Spring Boot

Ionic 4 & Angular Tutorial For Beginners - Crash Course