Embed
Print layout can be embedded with an iframe inside another page or modal
Getting started
When embedding print layout built-in print controls and copyrights footer are hidden and the parent container is expected to take control of printing
To use Embedded mode transfer query parameter in the URL
mode=embed
Custom layout variables
Every built-in layout supports overriding Bootstrap 4 variables with its own custom values. This is especially important for the embedded print layout, since it runs inside another layout and must visually match its host — things like border radius on cards, modals, and buttons should look identical.Print from container
By calling window.print() on the iframe's contentWindow you can manually invoke print
Cross-Origin Embedding
When the parent and iframe are on different domains or subdomains (e.g.app.example.com
and
print.example.com
), browsers block direct access to the iframe's
contentWindow
for security reasons.
In this case, use
postMessage
to communicate between the parent and the iframe instead of calling
contentWindow.print()
directly.
Modal
When embedding in a modal:
- Remove the default modal body padding by adding .p-0 to .modal-body
- Set a minimum height on .modal-body using .min-vh-sm-50 , .min-vh-sm-75 , etc.
- Apply the following utility classes to the iframe: .d-block .border-0 .w-100 .h-100
Lazy Loading
Instead of setting the iframe's
src
immediately, lazy load it the first time the modal opens.
This avoids an unnecessary network request if the user never opens the print dialog.
Use Bootstrap's
show.bs.modal
event with
.one()
to load the iframe only once on first open.
See the example below for implementation.
.row
.col-24.col-sm-auto
=button_tag 'print modal', class: 'btn btn-light', 'data-toggle': "modal", 'data-target': "#modal-print", type: 'button'
.col-24.col-sm-auto.mt-2.mt-sm-0
=button_tag 'print modal lg', class: 'btn btn-light', 'data-toggle': "modal", 'data-modal-dialog-class': 'modal-lg', 'data-target': "#modal-print", type: 'button'
.col-24.col-sm-auto.mt-2.mt-sm-0
=button_tag 'print modal xl', class: 'btn btn-light', 'data-toggle': "modal", 'data-modal-dialog-class': 'modal-xl', 'data-target': "#modal-print", type: 'button'
.col-24.col-sm-auto.mt-2.mt-sm-0
=button_tag 'print modal full screen', class: 'btn btn-light', 'data-toggle': "modal", 'data-modal-dialog-class': 'modal-fs', 'data-target': "#modal-print", type: 'button'
.modal#modal-print{tabindex: '-1'}
.modal-dialog
.modal-content
.modal-header
%h5.modal-title='Full screen modal'
=button_tag class: 'close', 'data-dismiss': 'modal', type: 'button' do
%span ×
.modal-body.p-0.min-vh-sm-50
%iframe.d-block.border-0.h-100.w-100{'data-src': print_path(ignore_environment_header: true, mode: 'embedded')}
.modal-footer
=button_tag 'cancel', type: 'button', class: 'btn btn-link', 'data-dismiss': "modal"
=link_to 'javascript: $("#modal-print iframe")[0].contentWindow.print();', class: 'btn btn-primary' do
%i.far.fa-fw.fa-print
Print
:javascript
$('#modal-print').one('show.bs.modal', function (e) {
let iframe = $(e.target).find('iframe[data-src]'); // first time modal is shown
iframe.attr('src', iframe.data('src'));
})
On this page