Automatically tally up the pages and showcase the page numbers for seamless printing

I've been tackling a challenge in my Vue.js application, specifically with generating invoices and accurately numbering the pages. An issue arose when printing the invoice – each page was labeled "Page 1 of 20" irrespective of its actual position in the document. This inconsistency has left me perplexed, and I'm struggling to find a resolution. Any suggestions or troubleshooting insights would be greatly welcomed. Below is the problematic code snippet:

<template>
  <div style="background-color: lightgray" >
    <div style="background-color: white;margin: auto;width: 29.7cm" id="printable-content">
      <!-- Invoice content goes here -->
    </div>
  </div>

  <div class="invoice">
    <!-- Invoice content continues here -->

    <!-- Page number -->
    <span class="page-number"> <span class="page-counter"></span></span>
  </div>


</template>
<script>

export default {
  data() {
    return {
      pageNumber: 1, // Initial page number
      items: [
        {name: "Item 1", quantity: 2, price: 10, vat: 20, price_in: 1200, totalt: 2000},
        {name: "Item 2 with a long name that needs to be truncated", quantity: 1, price: 20},
        {name: "Item 3", quantity: 3, price: 15},
        <!-- More item objects -->
      ]
    };

    
  },
 
  methods: {
  limitNameLength(name) {
    const maxLength = 20;
    return name.length > maxLength ? name.substring(0, maxLength) + '...' : name;
  },
  updatePageCounter(totalPages) {
    const currentPage = this.pageNumber;
    this.$nextTick(() => {
      const pageCounterElement = document.querySelector('.page-counter');
      if (pageCounterElement) {
        document.querySelector('.page-counter').textContent = currentPage;
        pageCounterElement.textContent = `Page ${currentPage} of ${totalPages}`;
      }
    });
  },
},

mounted() {
    const totalPages = 20;
    this.updatePageCounter(totalPages);
  },


};

</script>

<style lang="scss">
thead td, tfoot td {
  padding: 20px;
}

tbody tr td {
  padding: 5px 20px;
}


.rejectBreak {
  page-break-after: always;
}

@media print {
  .page-footer {
    position: fixed;
    bottom: 0;
    right: 0;
    left: 0;
    padding: 10px;
    background-color: white;
    border-top: 1px solid lightgray;
    text-align: right;
  }

  tfoot {
    display: table-footer-group;
  }

  button {
    display: none;
  }

  body {
    margin: 0;
  }

  tfoot .tfootHolder {
    display: none;
  }
  .tfoot {
    display: block !important;
    padding: 20px;
    position: fixed;
    bottom: 0;
    width: 29.7cm;

  }
  .page-footer-space {
    height: 300px;
  }

  @page {
    size: A4;
  }

  <!-- Additional print styles -->

</style>

Despite extensive Vue.js coding, the page counting functionality remains faulty.

Answer №1

When working with Vue, it is recommended to use the ref attribute instead of document.querySelector for selecting elements (specifically in Vue 3):

<template>
<div ref="myDiv">lorem ipsum</div>
</template>

<script>
const myDiv = ref(null); // Start by initializing as null and ensure the variable name matches the ref attribute on the div.
</script>

In Vue 2, the approach would be:

<template>
<div ref="myDiv">lorem ipsum</div>
</template>

<script>
export default {
  mounted() {
    this.$refs.myDiv.innerHTML = 'Page number…';
  }
}
</script>

Additionally, there may be uncertainties around using $nextTick while in the print dialog.

One suggestion is to iterate through your invoices and adjust the height of each invoice <div> based on the paper size you are printing on:

<div class="page" v-for="(invoice, index) in invoices" :key="invoice">
  <span>Page {{ index + 1 }}</span>
</div>

<style>
@media print {
  .page {
    height: 793px; /* approximately 1 A4 page */
    break-after: always; /* enforce page break */
  }
}
</style>

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

Use vue.js to add a block of content after every sixth iteration in a loop

Currently, I have a list of offer cards rendering through a loop. I am adding a row div every 3rd column (bootstrap) element. Now, I need to also add another column element (banner block) for every 6th element in order to achieve a layout like the one show ...

Ways to split JSON information into several pages?

I am currently facing an issue with my HTML code. It works perfectly fine for a small JSON file, displaying the data in an HTML table as expected. However, when I try to load a larger JSON file with around 15,000 rows of data, my page becomes unresponsiv ...

Tips for utilizing the "g" element in SVG within CoffeeScript to rotate an object in D3

I'm experimenting with creating a design similar to the following SVG code snippet: <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example rect02 - rounded rectangles&l ...

Removing a single object from an array of objects using MongooseJS

Hello to all the MongooseJS experts out there! I'm a newcomer to MongooseJS, and I've been trying to solve this problem for the past two days but haven't found a solution yet. Thank you in advance for any help! The Issue with My Delete me ...

Having trouble executing 'vue ui' in npm with nodejs vue/cli

Trying to set up Vue tool chain on a fresh Win10pro system has been quite challenging, as I kept encountering various errors that seem to stem from the same source. Upon running vue ui, the following error message pops up: @vue/cli 4.5.15 PS C:\U ...

Error encountered during Ajax request - two files being transmitted instead of one

Can someone assist me with a basic ajax call for a login button? I need help with the form submission and sending the request to a php file to handle the login action. However, I am encountering an issue where two files are being sent instead of one when ...

Failure of Ajax to populate dropdowns in Internet Explorer

I've been grappling with some code for the past couple of days and I'm stuck. I really need some help. Here's what I'm trying to achieve: Manually fill the first dropdown menu Retrieve the selected value from the first dropdown, use i ...

what is the method to extract the value of a JSON object nested within another JSON object

Can someone please assist me? "_attachments": { "kiran.jpg": { "content_type": "image/jpeg", "revpos": 6, "digest": "md5-mEsoX4ljN1iJlF2bX1Lw2g==", "length": 4601, "stub": true } } I ...

Do you know where I can locate the HTML and CSS pertaining to the search results page

I'm looking for a way to present search results on my website that resembles the Google search results, creating a familiar interface for users. Is there anyone who knows where I can obtain the HTML and CSS code that produces the same style as Google& ...

Exploring additional parameters within express.js

I'm currently working on creating an email sender that includes all necessary components such as 'from', 'to', 'subject', 'textBody', etc. However, I am facing a challenge in setting optional parameters in expre ...

I am having trouble with Fullcalendar not loading my JSON data to display events

I've been experimenting with the fullcalendar JavaScript library, but I'm struggling to load data from my MySQL database onto the calendar. When I test my db-connect.php file, it does return the first entry in the table, yet the calendar remains ...

How to efficiently utilize images with the VueJS Bootstrap carousel technique

My issue revolves around a specific requirement. Obtaining a list of images from the backend. The goal is to pass these image names to the carousel for image display. Showcased below is the code snippet I am working with. <template> <div cla ...

Error Alert: LocalStorage is undefined in this context - NextJS

Having trouble retrieving access and refresh tokens from local storage. Each attempt results in a 500: Internal Server Error, with an error indicating LocalStorage is undefined. Research suggests that LocalStorage may not be compatible with rendering with ...

Comparison between JSON Serializers and .NET Serialized Classes for Retrieving jQuery AJAX Result Data

What is the best method for transferring data from a .NET (C#, VB.NET) Web Service to the client-side using JQuery AJAX? A) Utilizing Newtonsoft JSON serialization, for example: <WebInvoke(Method:="*", ResponseFormat:=WebMessageFormat.Json, UriTemplat ...

The setInterval function continues executing even after the page has been changed

I'm encountering an issue with my function where it continues to run even after the page has changed, resulting in an error. How can I go about stopping this behavior? Thank you! componentDidMount() { var current = 0; var slides = document.g ...

Despite my efforts to include the necessary key, I am still encountering an error with the item list in

Below is an example of a list container: import { List, ListItemText, ListItem } from '@mui/material'; import FooterItem from './FooterItem'; const FooterList = ({ title, items }) => { return ( <List> ...

The JSON response is displaying [object object] instead of an array

I am currently facing an issue with my Sencha touch app where the json data I am feeding into it is not returning the image URLs as expected. Instead, it is showing me "[object Object]" when I console.log the "images" property. Here is a snippet of the js ...

Convert a solo row into individual columns within a grid format

My goal is to design a grid layout where each row can be divided into columns independently, similar to the example shown below: https://i.stack.imgur.com/VFPFq.png Here's the code snippet I have been experimenting with: .container { position ...

Encountering silence: React JS fetch call left unanswered by Sinatra server

Exploring the realms of Sinatra and React JS, I am venturing into making a GET call from my React website to a Sinatra server in order to display plain text. The Sinatra Server script: require 'sinatra' set :root, 'lib/app' before d ...

Will my variables become unbound when a new object is created?

Currently, I am developing a component within my Angular application where I am binding an object: CustomComponent.js angular.module("app").component( "customComponent", { controller: function() { var ctrl = this; ctrl.createInstance ...