11

I want to create custom modal popup widget and call on my .phtml file. How can I do that?

What will be the whole procedure for creating modal and accessing it from the .phtml file?

1

4 Answers 4

37

You should create a module first, then after create a requirejs-config.js file at app/code/Vendor/YourModule/view/frontend/requirejs-config.js

var config = {
    paths: {            
         'myjs': "Vendor_YourModule/js/myfile"
      },   
    shim: {
    'myjs': {
        deps: ['jquery']
    }
  }
} 

You need to create myfile.js in app/code/Vendor/YourModule/view/frontend/web/js/myfile.js

    require(
        [
            'jquery',
            'Magento_Ui/js/modal/modal'
        ],
        function(
            $,
            modal
        ) {
            var options = {
                type: 'popup',
                responsive: true,
                innerScroll: true,
                buttons: [{
                    text: $.mage.__('Continue'),
                    class: 'mymodal1',
                    click: function () {
                        this.closeModal();
                    }
                }]
            };

            var popup = modal(options, $('#popup-modal'));
            $("#click-me").on('click',function(){
                $("#popup-modal").modal("openModal");
            });
        }
    );

Then your phtml file should look like:

<div data-mage-init='{"myjs": {}}'>
    <a href="#" id="click-me">Click Me</a>
</div>


<div id="popup-modal" >
    yes I am the modal.
</div>
5
  • 2
    Worked Perfect! All the options that can be passed to the modal can be found here: devdocs.magento.com/guides/v2.3/javascript-dev-guide/widgets/… Jul 10, 2019 at 14:05
  • how to add resize and draggable facility in it. Nov 11, 2019 at 5:40
  • Before starting to this I just want to confirm, Is this popup will dynamic data.
    – Kim Na Na
    Jul 26, 2020 at 10:03
  • Is there a way to pass data from PHP into the script?
    – Black
    Nov 20, 2020 at 13:47
  • The modal applies "overlay: hidden" to the body and this removes the scrollbar as well. How can I replace this behavior with something like "document.addEventListener('wheel', preventScroll, { passive: false })" which prevent just the scrolling?
    – KaMZaTa
    Mar 4, 2021 at 17:07
15

You just need to add a container for the modal <div id="popup-modal"></div> and a small bit of javascript to initialise the modal like below:

<div id="popup-modal"><p>Hello World</p></div>

<script>
require(
[
    'jquery',
    'Magento_Ui/js/modal/modal'
],
function(
    $,
    modal
) {
    let options = {
        type: 'popup',
        responsive: true,
        innerScroll: true,
        title: 'Modal Title',
        modalClass: 'custom-modal',
        buttons: [{
            text: $.mage.__('Continue'),
            class: '',
            click: function () {
                this.closeModal();
            }
        }]
    };
    
    let $myModal = $('#popup-modal');
    let popup = modal(options, $myModal);
    
    //this opens the modal, you can use some click event or whatever you need to trigger the modal here
    $myModal.modal('openModal');
});
</script>

So the $myModal.modal('openModal'); will trigger the popup instantly however could be used like below to maybe trigger when clicking a button or link for example:

$(".open-modal").click(function() {
    $myModal.modal('openModal');
});
11
  • How can i call the same model from external javascript file? Jan 5, 2018 at 14:07
  • Just take that script out and add externally it will work the same.
    – harri
    Jan 5, 2018 at 14:08
  • I have tried the same, I placed my js file in web\js of my module also I have included the header tag in my layout.xml but cant access the modal. where I am wrong can you tell? Jan 5, 2018 at 14:13
  • Well i would first check that you can see your JS loaded in the page. Check that your modal markup present also. Then check for and errors in your console.
    – harri
    Jan 5, 2018 at 14:14
  • When I do "view page source" the file is included but on console it is giving error "404" Jan 5, 2018 at 14:18
5

I have used this, hope this will help you

 <button type="button" class="action" data-trigger="trigger">
    <span data-bind="i18n: 'Click Here'"></span>
</button>
<div data-bind="mageInit: {
        'Magento_Ui/js/modal/modal':{
            'type': 'popup',
            'title': 'Popup title',
            'trigger': '[data-trigger=trigger]',
            'responsive': true,
            'buttons': [{
                text: 'Submit',
                class: 'action'
            }]
        }}">
    <div class="content">
        Popup Content
    </div>
</div>
1
  • How I can make this popup dynamic
    – Kim Na Na
    Jul 26, 2020 at 10:12
0

Took the example from Magento 2.4 documentation, and modified slightly to hide the "click me!" opener link until the modal code has finished loading. Without this, there can be several seconds during page load where clicking the opener link does nothing.

Just add the below to your .phtml - you can refactor the inline style and script to separate files if you wish.

See here for more modal/popup examples and options: https://devdocs.magento.com/guides/v2.4/javascript-dev-guide/widgets/widget_modal.html

<style>
#modal-promo, #modal-promo-opener {display: none}
</style>

<a href="#" id="modal-promo-opener">
    <span><?= $block->escapeHtml(__('Click me')) ?></span>
</a>

<div id="modal-promo">
    <div class="modal-wrapper">
        <p><?= $block->escapeHtml(__('Modal content here...')) ?></p>
    </div>
</div>

<script type="text/javascript">
    require([
        "jquery",
        "Magento_Ui/js/modal/modal"
    ],function($, modal) {

        var options = {
            type: 'popup',
            responsive: true,
            buttons: []
        };

        var $modal = $('#modal-promo'), $opener = $('#modal-promo-opener');

        var popup = modal(options, $modal);
        $opener.click(function() {
            $modal.modal('openModal');
        });

        $opener.show();

    });
</script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.