PDF preview for files
Learn how to create an alternative PDF view for file preview.
First, let's create a new file called FilePreview_pdf.vue
and copy the FilePreview
template and add a preview for the PDF using <embed>
:
vue
<!-- FilePreview_pdf.vue -->
<template>
<div
:class="classes.container"
v-show="visible"
v-bind="attrs"
tabindex="0"
role="button"
:aria-labelledby="ariaLabelledby"
:aria-placeholder="ariaPlaceholder"
:aria-describedby="`${el$.fieldId}-file-description`"
@keyup="handleKeyup"
>
<span :id="`${el$.fieldId}-file-description`" :class="classes.assistiveText" aria-hidden="">{{ form$.translations.vueform.a11y.file.description }}</span>
<div :class="classes.wrapper">
<div :class="classes.file">
<!-- Filename -->
<a :href="link" v-if="hasLink && clickable" :class="classes.filenameLink" target="_blank" rel="nofollow noopener">{{ filename }}</a>
<span v-else :class="classes.filenameStatic">{{ filename }}</span>
</div>
<div :class="classes.actions">
<!-- Remove -->
<div
v-if="canRemove"
:class="classes.remove"
@click.prevent="remove"
@keypress.enter.space="remove"
aria-roledescription="❎"
role="button"
tabindex="0"
>
<span :class="classes.removeIcon"></span>
</div>
<!-- Progress -->
<div v-if="uploading" :class="classes.percent">{{ progress }}%</div>
<!-- Error -->
<span v-if="hasError" :class="classes.warning">
<span :class="classes.warningIcon"></span>
</span>
<!-- Upload button -->
<div
v-if="canUploadTemp"
:class="classes.upload"
@click.prevent="upload"
tabindex="-1"
>{{ uploadText }}</div>
<!-- Success -->
<span v-else-if="el$.stage > 1" :class="classes.uploaded">
<span :class="classes.uploadedIcon"></span>
</span>
</div>
</div>
<!-- PDF preview -->
<div :class="classes.pdf_container">
<embed :src="preview" :class="classes.pdf" />
</div>
<!-- Upload progress -->
<div v-if="uploading" :class="classes.progressBar">
<div :class="classes.progress" :style="{ width: progress + '%' }"></div>
</div>
</div>
</template>
<script>
import tailwindTheme from '@vueform/vueform/dist/tailwind'
export default {
name: 'FilePreview_pdf',
data() {
return {
merge: false,
defaultClasses: {
// Insert default classes
...tailwindTheme.classes.FilePreview,
// Add pdf classes
pdf_container: 'my-4',
pdf: 'w-full h-[500px]',
}
}
}
}
</script>
vue
<!-- FilePreview_pdf.vue -->
<template>
<div
:class="classes.container"
v-show="visible"
v-bind="attrs"
tabindex="0"
role="button"
:aria-labelledby="ariaLabelledby"
:aria-placeholder="ariaPlaceholder"
:aria-describedby="`${el$.fieldId}-file-description`"
@keyup="handleKeyup"
>
<span :id="`${el$.fieldId}-file-description`" :class="classes.assistiveText" aria-hidden="">{{ form$.translations.vueform.a11y.file.description }}</span>
<div :class="classes.wrapper">
<div :class="classes.file">
<!-- Filename -->
<a :href="link" v-if="hasLink && clickable" :class="classes.filenameLink" target="_blank" rel="nofollow noopener">{{ filename }}</a>
<span v-else :class="classes.filenameStatic">{{ filename }}</span>
</div>
<div :class="classes.actions">
<!-- Remove -->
<div
v-if="canRemove"
:class="classes.remove"
@click.prevent="remove"
@keypress.enter.space="remove"
aria-roledescription="❎"
role="button"
tabindex="0"
>
<span :class="classes.removeIcon"></span>
</div>
<!-- Progress -->
<div v-if="uploading" :class="classes.percent">{{ progress }}%</div>
<!-- Error -->
<span v-if="hasError" :class="classes.warning">
<span :class="classes.warningIcon"></span>
</span>
<!-- Upload button -->
<div
v-if="canUploadTemp"
:class="classes.upload"
@click.prevent="upload"
tabindex="-1"
>{{ uploadText }}</div>
<!-- Success -->
<span v-else-if="el$.stage > 1" :class="classes.uploaded">
<span :class="classes.uploadedIcon"></span>
</span>
</div>
</div>
<!-- PDF preview -->
<div :class="classes.pdf_container">
<embed :src="preview" :class="classes.pdf" />
</div>
<!-- Upload progress -->
<div v-if="uploading" :class="classes.progressBar">
<div :class="classes.progress" :style="{ width: progress + '%' }"></div>
</div>
</div>
</template>
<script>
import vueformTheme from '@vueform/vueform/dist/vueform'
export default {
name: 'FilePreview_pdf',
data() {
return {
merge: false,
defaultClasses: {
// Insert default classes
...vueformTheme.templates.FilePreview.data().defaultClasses,
// Add pdf classes
pdf_container: 'vf-file-preview-pdf-container',
pdf: 'vf-file-preview-pdf',
}
}
}
}
</script>
<style>
.vf-file-preview-pdf-container {
margin: 1rem 0;
}
.vf-file-preview-pdf {
width: 100%;
height: 500px;
}
</style>
Changes made:
- we added a container and
<embed>
for the PDF preview - we used the
preview
prop that contains ourFile
object or the full path to the uploaded PDF - we renamed the component to
FilePreview_pdf
- we imported
tailwind
/vueform
theme and copiedFilePreview
's default classes - we added classes for our PDF preview
- we added
<style>
block with classes (Vueform Theme only)
The next step is to register the pdf
view in vueform.config.js
:
js
// vueform.config.js
import { defineConfig } from '@vueform/vueform'
import FilePreview_pdf from './FilePreview_pdf.vue'
export default defineConfig({
templates: {
FilePreview_pdf,
}
})
Once registered we can use it the following way:
vue
<FileElement
view="pdf"
accept="application/pdf"
/>