horatius
horatius

Reputation: 814

How can I display the html email body in a scrollable table cell?

I am trying to build an email inbox browser in vuejs over .NET MVC backend. I am primarily receiving html emails which I want to display in a scrollable table cell.

Here's a sample email body.

html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style><!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0cm; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Calibri","sans-serif";} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:purple; text-decoration:underline;} span.EmailStyle17 {mso-style-type:personal-compose; font-family:"Calibri","sans-serif"; color:windowtext;} .MsoChpDefault {mso-style-type:export-only;} @page WordSection1 {size:612.0pt 792.0pt; margin:72.0pt 72.0pt 72.0pt 72.0pt;} div.WordSection1 {page:WordSection1;} -->
</style>
<!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1026" />     </xml><![endif]-->
<!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1" /> </o:shapelayout></xml><![endif]-->
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=WordSection1>
<p class=MsoNormal>
<o:p>Test Email &nbsp;</o:p></p>
</div>
</body>
</html>

Here's my vuejs component

import Vue from 'vue';
import { Component } from 'vue-property-decorator';

interface Email {
    to: string;
    from: string;
    subject: string;
    body: string;
}

@Component
export default class FetchDataComponent extends Vue {
    inboxEmails: Email[] = [];

    mounted() {
        fetch('api/Email/InboxEmails')
            .then(response => response.json() as Promise<Email[]>)
            .then(data => {
                this.inboxEmails = data;
            });
    }
}

And here's template.

<template>
    <div>
        <h1>Emails</h1>

        <p>The following emails are in your inbox</p>

        <table v-if="inboxEmails.length" class="table">
            <thead>
                <tr>
                    <th>To</th>
                    <th>From</th>
                    <th>Subject</th>
                    <th>Body</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="item in inboxEmails">
                    <td>{{ item.to }}</td>
                    <td>{{ item.from }}</td>
                    <td>{{ item.subject }}</td>
                    <td><div>{{ item.body }}</div></td>
                </tr>
            </tbody>
        </table>

        <p v-else><em>Loading...</em></p>
    </div>
</template>

<script src="./emails.ts"></script>

I understand that this is not a scrollable table cell. But I want to solve the display issue first before I put it into a scrollable table cell.

Upvotes: 0

Views: 786

Answers (1)

Sphinx
Sphinx

Reputation: 10729

It seems you'd to display the whole email message (<html>email body</html>), if so, uses <iframe :srcdoc="emailBody"> should be one solution.

Check MDN IFrame on the details of property=srcdoc, and the browser compatibility.

let testEmailBody = `<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style><!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0cm; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Calibri","sans-serif";} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:purple; text-decoration:underline;} span.EmailStyle17 {mso-style-type:personal-compose; font-family:"Calibri","sans-serif"; color:windowtext;} .MsoChpDefault {mso-style-type:export-only;} @page WordSection1 {size:612.0pt 792.0pt; margin:72.0pt 72.0pt 72.0pt 72.0pt;} div.WordSection1 {page:WordSection1;} -->
</style>
<!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="1026" />     </xml><![endif]-->
<!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1" /> </o:shapelayout></xml><![endif]-->
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=WordSection1>
<p class=MsoNormal>
<o:p>Test Email &nbsp;</o:p></p>
<p style="background-color:green;color:white">I am a test!</p>
</div>
</body>
</html>`
Vue.config.productionTip = false
app = new Vue({
  el: "#app",
  data: {
    emails: [
      {'from':'stackoverflow', 'to': '[email protected]', 'body': testEmailBody},
      {'from':'stackoverflow', 'to': '[email protected]', 'body': testEmailBody}
    ]
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <div>
    <table>
      <tr v-for="(email, index) in emails" :key="index">
        <td>{{email.from}}</td>
        <td>{{email.to}}</td>
        <td><iframe :srcdoc="email.body"></iframe></td>
      </tr>
    </table>
  </div>
</div>

Upvotes: 1

Related Questions