Skip to main content
Component states for PDFs

Learn how to configure export of e-Detailers to PDF

eWizard Team avatar
Written by eWizard Team
Updated over a year ago

eWizard PDF Export service allows you to export presentations as a PDF document. In the resulting PDF, each slide transforms into a separate page. However, the slide may contain some interactive elements, for example, a popup in which content is initially hidden and appears upon a click. All slide states are displayed upon its Activate feature since it allows for including more than one state into the resulting PDF.


TIP: Hidden slides, subslides, and chapters are exported into PDF.


PDF Export Service API

Activate

The component instance must have the activate method. The PDF Export service iterates through all slide components and calls the activate method of each component. This method must execute a logic that reveals the component's content (for example, the function to open a popup, to rotate carousel items and others). For new state generating, the activate method must change the component's props or data. The PDF Export service checks if props or data were changed during activation, and makes a slide screenshot.

Example:

<template>
<div class="example-component">
<p>The image bellow will be visible on the second screenshot</p>
<wiz-image v-if="isVisible"></wiz-image>
</div>
</template><script>
import wizImage from "wiz-image"
export default {
name: "example-component",
components: {
wizImage
},
data() {
return {
isVisible: false
};
},
methods: {
activate() {
this.isVisible = true;
}
},
};
</script>

Deactivate

After the component activation, along with all its with nested components, the PDF Export service calls the deactivate method of the component instance. Let's briefly consider the following example: we have a wiz-popup component with nested wiz-tab-group component in the slide. The service activates the popup to make the state with popup opened. Then the service activates the tab-group and generates states with each tab opened. The final step calls the deactivate method of the popup to hide it. In case this slide contains any other popup with content, the first popup is deactivated and hidden in the rest of the states.

The deactivate function must be defined as a method of the component instance

Example:

methods: {
deactivate() {
this.isVisible = true;
}
}

PDF Export settings

In the process of an e-Detailer export to PDF, states of all common e-Detailer's components are generated into a single slide. This slide is defined in the .ewizard/settings.json file. Define the ID of the preferable slide in the slideWithCommonLayout field of the screenshoter object:

"screenshoter": {
"slideWithCommonLayout": "customSlideId"
}

In case the settings are missing, the screenshoter makes common components states in the first slide.

beforeScreenshot hook

When you navigate to the slide with the custom animation effect, it takes a certain amount of time before you see the actual element after animation effect ends. The beforeScreenshot hook provides possibility to ignore delay in the custom animation effect on the slide before taking the screenshot of the slide. This feature is useful when you export your e-Detailer to PDF.

To add the beforeScreenshot hook to the slide Vue instance:

// ./slides/slide_name/index.vuecreated() {
this.timerId = setTimeout(() => {
this.setStartValue();
}, 500);
}, 
beforeScreenshot() {
clearTimeout(this.timerId);
this.setStartValue();
},

Consider the following example where the slider animation starts with the delay of 10,000 ms.

// ./slides/slider1/index.vue<template>
<wiz-slide class="editable-block">
<wiz-text :text="$t('title')" id="title"></wiz-text><!--    <transition name="fade">-->
<div class="container" v-if="show">
<wiz-text :text="value.toString()" class="counter"></wiz-text>
<wiz-text class="label" :text="$t('text')"></wiz-text>
<div v-if="show" @slideswipe.stop @chapterswipe.stop class="slider-wrapper">
<wiz-slider type="horizontal" :value.sync="value" :step="1" :min-value="0" :max-value="100" class="default slider" @change="submitMonitoring"></wiz-slider>
</div>
</div><!--    </transition>-->
</wiz-slide>
</template>
<script>
import wizSlider from 'wiz-slider';export default {
components: {
wizSlider,
},
data() {
return {
counter: '0',
show: false,
value: 0,
};
},
mounted() {
setTimeout(() => this.show = true, 10000);
},
beforeScreenshot() {
return new Promise(resolve => {
this.show = true;
setTimeout(() => resolve('test'), 500);
});
},
methods: {
submitMonitoring() {
this.$monitoring.submit('slider1', this.value);
}
},
};
</script>
<style scoped>
</style><style scoped editor>
#title {
height: auto;
}
</style>

If you don't use the beforeScreenshot hook, the screenshoter service takes the slide screenshot without the slider due to delay in the animation effect. The beforeScreenshot hook sets the start value for the screenshoter service to 500 ms or you can set any other delay value.

To check how the screenshoter service works with the beforeScreenshot hook:

1) Add the 10,000 ms delay before the animation effect starts on the slide.

// ./slides.slider1/index.vuemounted() {
setTimeout(() => this.show = true, 10000);
},

2) Take the slide thumbnail screenshot.

wiz thumbs -s slider1

3) View the slide thumbnail screenshot without the slider.

4) Add the beforeScreenshot hook.

// ./slides/slider1/index.vuemounted() {
setTimeout(() => this.show = true, 10000);
},
beforeScreenshot() {
return new Promise(resolve => {
this.show = true;
setTimeout(() => resolve('test'), 500);
});
},

5) Take the slide thumbnail screenshot.

wiz thumbs -s slider1

6) View the slide thumbnail screenshot with the slider.

nextState

Use the nextState method to check if there are states available for screenshots. This is useful when exporting PDFs of components that have multiple windows, or windows that could exceed the slide limit, such as wiz-slider or wiz-scroller.

Usage examples

You can specify the conditions on how to change the state in the if clause of the method. For example:

To check all states in the wiz-scroller component:

<!-- ./slides/scroller1/index.vue --><template>
<wiz-slide class="editable-block">
<wiz-scroller id="wiz-scroller-e363" class="default" :scrollpanelopts="[{'__label':'options','initialScrollY':'50%','initialScrollX':'10px','scrollingX':true,'scrollingY':true,'__id':'7-scrollpanelopts-0'}]" :railopts="[{'__label': 'Options', 'background': '#00ff03', 'gutterOfEnds': 10, 'opacity': 0, '__id': '7-railopts-0'}]" :baropts="[{'__label':'Options','background':'hwb(195, 0%, 0%)','disable':true,'opacity':50,'keepShow':true,'__id':'7-baropts-0'}]">
<wiz-text :text="$t('text2')" id="wiz-text-4769"></wiz-text>
<wiz-image id="wiz-image-8e03" class="default" src="./media/images/my_image.jpg"></wiz-image>
</wiz-scroller>
<wiz-text id="wiz-text-b070" class="default" :text="$t('wiz_text_c124')"></wiz-text>
</wiz-slide>
</template><script>
export default {
components: {},
methods: {
async nextState() {
if (this.isAvailableSwitchStatesForScreenshot) {
const { scrollingX, scrollingY } = this.ops.scrollPanel;
const { v, h } = this.getScrollProcess();const dy = this._getOneScreenHeightDistance();
const dx = this._getOneScreenWidthDistance();
this.scrollBy({ dy: `${dy}`, dx: `${dx}` });if ((scrollingY && v !== 1 && dy > 0) || (scrollingX && h !== 1 && dx > 0)) {
return {
done: false,
value: undefined,
};
}
}
return {
done: true,
value: undefined,
};
},
}
};
</script>

In this example, eWizard.js checks the height of the screen and scrolls one screen down while the function from the if clause returns done: false.

To check all states in the wiz-slider component:

<!-- ./slides/slider1/index.vue --><template>
<wiz-slide class="editable-block">
<wiz-slider
id="slider1"
ref="slider1"
class="pa"
v-bind="sliderOptions"
:component-name="'Slider 1'"
@slideswipe.native.stop=""
@change="setDifference"
></wiz-slider>
<wiz-text id="wiz-text-b070" class="default" :text="$t('wiz_text_c124')"></wiz-text>
</wiz-slide>
</template><script>
export default {
components: {},
methods: {
async nextState() {
if (this.screenshoterStateCounter === 0) {
this.screenshoterStateCounter = 1;
this.sliderOptions.value = this.sliderOptions.max;
this.setDifference(this.sliderOptions.max);
return {
done: false,
value: undefined,
};
}return {
done: true,
value: undefined,
};
},
getSliderValue(value) {
this.currentSliderValue = value;
},
calcDifference() {
this.difference = +this.sliderOptions.max - +this.currentSliderValue;
},
setDifference(value) {
this.getSliderValue(value);
this.calcDifference();
const vueSliderProcess = this.$refs.slider1.$el.getElementsByClassName("vue-slider-process")[0];
const graph = this.$refs.graph.$el;
vueSliderProcess.style.setProperty("--difference", `${this.difference}%`);
graph.style.setProperty("--difference", `${this.difference}%`);
},
},
};
</script>

In this example, eWizard.js screenshots every state while the function from the if clause returns done: false.

Did this answer your question?