Many times we need to show some sort of information in modal overlay when customer comes to the site.
We can use it for many kind of purposes like newsletter subscription form, coupon codes or just some
general information.
In this article I’ll show you how to create the most basic functionality around this.
The challenge
When customer comes to our site, we want to show load specific static block content
into the modal overlay and show it only once to every customer.
Solution:
We should start by creating new module in Magento 2.
For that purpose start by creating app/code/Inchoo/ModalOverlay/registration.php
with following content:
<?php
/**
* @category Inchoo
* @package Inchoo_ModalOverlay
* @copyright Copyright (c) Inchoo (https://inchoo.net/)
*/
MagentoFrameworkComponentComponentRegistrar::register(
MagentoFrameworkComponentComponentRegistrar::MODULE,
'Inchoo_ModalOverlay',
__DIR__
);
Continue by creating app/code/Inchoo/ModalOverlay/etc/module.xml.
Put the following inside:
<?xml version="1.0"?>
<!--
@category Inchoo
@package Inchoo_ModalOverlay
@copyright Copyright (c) Inchoo (https://inchoo.net/)
-->
<config xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi_noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Inchoo_ModalOverlay" setup_version="1.0.0">
</module>
</config>
That will create a new module in Magento 2.
What we want to do now is to create block that will be shown in modal.
For that purpose, let’s continue by creating another file called
app/code/Inchoo/ModalOverlay/Block/ModalOverlay.php
This one should have the following content:
<?php
namespace InchooModalOverlayBlock;
use MagentoCmsApiBlockRepositoryInterface;
use MagentoCmsApiDataBlockInterface;
use MagentoFrameworkExceptionLocalizedException;
use MagentoFrameworkViewElementTemplate;
use MagentoFrameworkViewElementTemplateContext;
/**
* Class ModalOverlay
*
* @category Inchoo
* @package Inchoo_ModalOverlay
* @copyright Copyright (c) Inchoo (https://inchoo.net/)
*/
class ModalOverlay extends Template
{
/**
* @var BlockRepositoryInterface
*/
private $blockRepository;
/**
* ModalOverlay constructor.
*
* @param BlockRepositoryInterface $blockRepository
* @param Context $context
* @param array $data
*/
public function __construct(
BlockRepositoryInterface $blockRepository,
Context $context,
array $data = []
) {
$this->blockRepository = $blockRepository;
parent::__construct($context, $data);
}
/**
* Retrieve modal overlay content
*
* @param $identifier
* @return bool|string
*/
public function getContent($identifier)
{
try {
/** @var BlockInterface $block */
$block = $this->blockRepository->getById($identifier);
$content = $block->getContent();
} catch (LocalizedException $e) {
$content = false;
}
return $content;
}
}
Newly created block needs to have a template, so let’s create it and initialize our JavaScript app/code/Inchoo/ModalOverlay/view/frontend/templates/modal_overlay.phtml
<?php
/**
* @category Inchoo
* @package Inchoo_ModalOverlay
* @copyright Copyright (c) Inchoo (https://inchoo.net/)
*/
?>
<?php /** @var InchooModalOverlayBlockModalOverlay $block */ ?>
<?php if ($content = $block->getContent('this-should-be-renamed')) :?>
<div id="modal-overlay" style="display:none;">
<?php /* @noEscape */ echo $content ?>
</div>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"modal_overlay": {
"component": "Inchoo_ModalOverlay/js/modal_overlay"
}
}
}
}
}
</script>
<?php endif;?>
Let’s add previously created block into layout on every page.
For that purpose, create app/code/Inchoo/ModalOverlay/view/frontend/layout/default.xml and
put the following inside:
<?xml version="1.0"?>
<!--
@category Inchoo
@package Inchoo_ModalOverlay
@copyright Copyright (c) Inchoo (https://inchoo.net/)
-->
<page xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi_noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="InchooModalOverlayBlockModalOverlay"
template="Inchoo_ModalOverlay::modal_overlay.phtml"
name="modalOverlay"
as="modalOverlay"/>
</referenceContainer>
</body>
</page>
And finally, let’s add app/code/Inchoo/ModalOverlay/view/frontend/web/js/modal_overlay.js
with the following content:
/**
* @category Inchoo
* @package Inchoo_ModalOverlay
* @copyright Copyright (c) Inchoo (https://inchoo.net/)
*/
define([
'uiComponent',
'jquery',
'Magento_Ui/js/modal/modal',
'Magento_Customer/js/customer-data'
], function (Component, $, modal, storage) {
'use strict';
var cacheKey = 'modal-overlay';
var getData = function () {
return storage.get(cacheKey)();
};
var saveData = function (data) {
storage.set(cacheKey, data);
};
if ($.isEmptyObject(getData())) {
var modal_overlay = {
'modal_overlay': false
};
saveData(modal_overlay);
}
return Component.extend({
initialize: function () {
this._super();
var options = {
type: 'popup',
responsive: true,
innerScroll: false,
title: false,
buttons: false
};
var modal_overlay_element = $('#modal-overlay');
var popup = modal(options, modal_overlay_element);
modal_overlay_element.css("display", "block");
this.openModalOverlayModal();
},
openModalOverlayModal:function(){
var modalContainer = $("#modal-overlay");
if(this.getModalOverlay()) {
return false;
}
this.setModalOverlay(true);
modalContainer.modal('openModal');
},
setModalOverlay: function (data) {
var obj = getData();
obj.modal_overlay = data;
saveData(obj);
},
getModalOverlay: function () {
return getData().modal_overlay;
}
});
});
Conclusion
That is it. All that’s left is to create a static block and activate the module.
This should give you a basic module that you can modify however fits you best.
If you want to see how we can help you with these types of custom work on your Magento store, get in touch!