What is the best way to display lengthy content using a pair of HTML tags?

I am facing an issue with my Angular4 app where I have a <md-card-content> tag on part of my page. Inside this tag, I am trying to display some content within a <p> tag which has a maximum height of 20cm.

While this setup works fine for short content, it fails to accommodate longer content. Is there a way to dynamically create another <md-card-content> if the content exceeds 20cm in height? My goal is to replicate the behavior of Microsoft Word, moving to a new page when the current one is full!

Here is a snippet of my HTML code:

<md-card-content>
        <div fxLayout="row" fxLayoutAlign="center center" class="mt-1">
          <div class="template">
            <p class="head">Mail Number: {{mail_number}}</p> <br>
            <p class="head">Date: {{created_at| date:'yyyy MMM dd'}}</p>
            <p class="inner" id="mail">{{content}}</p>
            <p class="sign" *ngIf="!pageFull">Sincerely</p><br>
            <p class="sign" *ngIf="!pageFull">{{sender}}</p>
          </div>
        </div>
      </md-card-content>

Below is the relevant CSS code from my stylesheet:

.template{
  width: 600px;
  height: 1100px;
  border-width: 2px;
  border-style: solid;
  border-color: #e6e6e6;
  padding-top: 23mm;
  padding-left: 2cm;
  padding-right: 2.5cm;
}

p.head{
  line-height: 0.5px;
  padding-left: 120mm;
  font-size: 3;
}

p{
  line-height: 25px;
  word-spacing: 1px;
}

.inner{
  text-align: justify;
  padding-top: 21mm;
  padding-bottom: 10mm;
  white-space: pre-wrap;
  max-height: 20cm;
  width: 166mm;
  word-wrap: break-word;
}

p.sign{
  padding-left: 10mm;
  line-height: 0.5px;
}

Answer №1

To achieve this, you can apply maximum height constraints on the containers and then break down your initial paragraph into individual words.

Next, start adding one word at a time to your first paragraph until its height surpasses the maximum height of the container. Once this happens, the remaining words should be moved to the second paragraph.

Below is a simple snippet that demonstrates this concept:

window.onload = function() {

  let p1 = document.getElementById('content-1');
  let words = p1.innerHTML.split(' ');
  let maxHeight = +document.getElementById('container-1').style.maxHeight.replace('px', '');
  p1.innerHTML = words[0];
  
  let index = -1;
  for(let i = 1; i < words.length; i++) {
    p1.innerHTML += ' ' + words[i];

    if(p1.clientHeight > maxHeight && index === -1) {
      index = i;
    }
  }

  let p2 = document.getElementById('content-2');
  let p2words = words.splice(index, words.length - index);
  p2.innerHTML = p2words.join(' ');
}
#container-1, #container-2 {
  max-width: 300px;
  border: 1px solid lightgrey;
  margin: 12px 0;
}

#content-1, #content-2 {
  line-height: 20px;
  margin: 0;
}
<div id="container-1" style="max-height: 40px; overflow: hidden;">
  <p id="content-1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nulla nisi, facilisis posuere lectus rhoncus, posuere interdum ante. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In vitae pulvinar justo, in rutrum enim. Vivamus rutrum turpis non ante molestie auctor. Pellentesque ipsum lacus, ultrices non risus sit amet, porttitor aliquam risus. Pellentesque sit amet ante vitae dolor commodo elementum. Nunc congue iaculis lectus, at tempor purus nullam.</p>
</div>
<div id="container-2">
  <p id="content-2"></p>
</div>

EDIT Angular snippet

@ViewChild('container') container: ElementRef;
@ViewChild('contentOne') content1: ElementRef;
@ViewChild('contentTwo') content2: ElementRef;

ngOnInit() {

  let paragraph1: HTMLElement = this.content1.nativeElement;
  let words = paragraph1.innerHTML.split(' ');
  let maxHeight = (this.container.nativeElement as HTMLElement).style.maxHeight.replace('px', '');
  paragraph1.innerHTML = words[0];
  
  let index = -1;
  for(let i = 1; i < words.length; i++) {
    paragraph1.innerHTML += ' ' + words[i];

    if(paragraph1.clientHeight > maxHeight && index === -1) {
      index = i;
    }
  }

  let paragraph2: HTMLElement = this.content2.nativeElement;
  let leftoverWords = words.splice(index, words.length - index);
  paragraph2.innerHTML = leftoverWords.join(' ');
}
#container-1, #container-2 {
  max-width: 300px;
  border: 1px solid lightgrey;
  margin: 12px 0;
}

#content-1, #content-2 {
  line-height: 20px;
  margin: 0;
}
<div #container style="max-height: 40px; overflow: hidden;">
  <p #contentOne>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nulla nisi, facilisis posuere lectus rhoncus, posuere interdum ante. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In vitae pulvinar justo, in rutrum enim. Vivamus rutrum turpis non ante molestie auctor. Pellentesque ipsum lacus, ultrices non risus sit amet, porttitor aliquam risus. Pellentesque sit amet ante vitae dolor commodo elementum. Nunc congue iaculis lectus, at tempor purus nullam.</p>
</div>
<div id="container-2">
  <p #contentTwo></p>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issues with the functionality of Angular Material prebuilt themes are causing inconsistencies

After spending a considerable amount of time trying to understand Angular Material Themes, I decided to start by importing a prebuilt theme. However, I encountered some issues along the way. The theme doesn't seem to apply to all the tags as expected. ...

Display a jQuery loading window

Need help with displaying a loading div when making an ajax post request. I've tried the following code but it's not working. Can someone please assist in resolving this issue? $(document).ready(function() { $('a.pagerlink').click( ...

Creating a webpage that utilizes varying headers for each section can help to

When trying to print a multi-page webpage, I encounter an issue with the headers. How can I ensure that different headers appear on each page after the first one? Specifically, my problem arises when a label on the first page spans across to the second pa ...

jQuery Slider Showing Incorrect Images

My jQuery slider is acting strangely. It hides the first image, shows the second one, but then just repeats the cycle by showing the first image again instead of loading the third one. I'm puzzled about what could be causing this issue in my code. Do ...

Steps for inserting an image:

Looking for help adding a static header image to a simple HTML page that contains two div tags: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1 /DTD/xhtml1-strict.dtd"> <html> <head> ...

Updating the HTML class with JavaScript

My HTML class has two classes $(document).ready(function() { $(".container").hover(function() { $('.green').addClass('display-on'); }); $(".container").mouseleave(function() { $('.black&apos ...

Firebase Authentication error code "auth/invalid-email" occurs when the email address provided is not in a valid format, triggering the message "The email address is

Currently, I am working on integrating Firebase login and registration functionality into my Angular and Ionic 4 application. Registration of user accounts and password retrieval are functioning properly as I can see the accounts in my Firebase console. Ho ...

Update the 'checked' attribute of a radio button when the form is submitted

How do I dynamically change the content of an HTML table based on which radio button a user selects using jQuery? For example, when the page loads, I want the United Kingdom radio button to be checked and the table content to display as 'blue'. I ...

Rendering in Angular 2 is exclusively done through the use of arrow functions

Is Angular 2 only rendering using arrow functions, or am I missing something? this.service.getData(o).subscribe(res => { this.data = res.data this.view = res.view }); It actually renders my component, but this.service.getData(o).subscribe(functi ...

Bringing in typefaces to enhance your email signature

I am trying to design a unique email signature with a custom Adobe font. My email account is hosted by Strato, a German mail server. However, when I attempted to insert the signature using Apple Mail, I realized that the CSS <style> part was not bein ...

What is the best way to add custom styles to Material UI tabs in a React application?

I need help styling my material UI tabs within a react component. I am having trouble getting the styles applied correctly, specifically setting the background color and box shadow of the entire bar, as well as defining the indicator background color and u ...

specific css styles only for Safari and Internet Explorer

Imagine a scenario where I have a div with the class 'x': <div class = 'x' /> This div has some CSS properties and what's interesting is that it appears differently in Safari and the latest version of IE compared to other ...

Uploading files with Angular and NodeJS

I am attempting to achieve the following: When a client submits a form, they include their CV AngularJS sends all the form data (including CV) to the Node server Node then saves the CV on the server However, I am encountering difficulties with this proc ...

Are checkboxes embedded within labels?

There are two common ways that people code checkboxes on the web, and I'm wondering which one is considered correct. <input id="a" type="checkbox"/><label for="a">checkbox</label> <label for="b"><input id="b" type="checkbo ...

Preventing Component Reuse in Angular 2 RC2 version "2.0.0-rc.2 (2016-06-15)"

During my work with angular 2 RC1 version, I encountered a situation where I needed to implement navigation within nested structures. Specifically, I wanted to be able to navigate from one Component (A) to the same Component (A), but without Angular reusin ...

What could be causing the malfunction of this Bootstrap button dropdown?

Initially, I attempted using regular HTML for the dropdown button but encountered issues. As a result, I switched to jsfiddle to troubleshoot. Despite my efforts, the dropdown feature still refused to work. If you'd like to take a closer look, here&a ...

Executing a function in Angular depending on the values emitted by two distinct observables

As someone who is relatively new to Angular (6 months), I am facing a challenge with my code. Currently, I have two observables that are working independently of each other: this.siteService.siteChanged$ .pipe(takeUntil(this.disconnect$)) .subscribe(_ ...

Filling MatTables using asynchronous rows and promises

Is there a way to asynchronously populate the rows of a MatTable with data from a collection of objects? I have a list containing each object's URL and I want to fill in the data as it loads, even if the rows are initially empty. This is my approach: ...

The HTML 5 Validation is unsuccessful due to the presence of the "Attribute addthis:url not allowed on element a at this point." error

I am currently facing an issue on my MVC4 Project web page where I have implemented the ShareThis plugin to display share count for various posts. The code snippet looks like this: @{ string strShareThisURL = "addthis:url=\"" + mainURL +" ...

What is the best way to ensure that the table header is printed on every page when printing?

My table has a large number of dynamic rows, and when I try to print or preview it using the window.print() function, only the table header (thead) appears on the first page. How can I make sure that the table header appears on each printed page? <div ...