Magento 2 Add Block with JS – How to Call It from CMS

blocksjavascriptmagento2phtml

I have simple code

<div class="container">
<h1>count</h1>

<div class="timer"></div>
</div>
<script src="http://code.jquery.com/jquery-1.12.1.min.js"></script>
<script src="circular-countdown.js"></script>

<script>
$('.timer').circularCountDown({
  size: 500,
  borderSize: 10,
  colorCircle: 'gray',
  background: 'white',
  fontFamily: 'sans-serif',
  fontColor: '#333333',
  fontSize: 16,
  delayToFadeIn: 0,
  delayToFadeOut: 0,
  reverseLoading: false,
  reverseRotation: false,
  duration: {
      hours: 0,
      minutes: 0,
      seconds: 1000
  },
  beforeStart: function(){},
  end: function(){}
});
</script>

and try to show this counter in front-end . I create count.phtml in app/design/frontend/vendorname/module/Magento_Theme/templates/html

<div class="container">
<h1>Test</h1>
<div class="timer"></div>
</div>
<script>
$('.timer').circularCountDown({
  size: 500,
  borderSize: 10,
  colorCircle: 'gray',
  background: 'white',
  fontFamily: 'sans-serif',
  fontColor: '#333333',
  fontSize: 16,
  delayToFadeIn: 0,
  delayToFadeOut: 0,
  reverseLoading: false,
  reverseRotation: false,
  duration: {
      hours: 0,
      minutes: 0,
      seconds: 1000
  },
  beforeStart: function(){},
  end: function(){}
});
</script>

then edit layout file default_head_blocks.xml and add

<script src="circular-countdown.js"></script>

after that I call this block from CMS:

{{block class="Magento\Framework\View\Element\Template" name="count_file" template="Magento_Theme::html/count.phtml"}} 

script not run, I understand i cant run script from .phtml file directly so what i should do ? thanks

Best Answer

You might find issue with trying to run these files in the head of the page. Magento 2 is very picky about javascript load order, and in many cases wont load your scripts correctly. This will lead to endless amounts of console error. Mostly "jquery is not defined..." but there are loads others that will be kicked.

You are much better off using the built in require js system to loaded your scripts. I assume you are using this circular js module, but any js module should work in the same way. Download this file and place it in your theme:

app/design/frontend/{vendor_namespace}/{theme}/Magento_Theme/web/js/circular-countdown.js

You will need to wrap the code in a define statement like this:

define([
    'jquery'
], function($) {

    // the code for the js module goes here

    };
    return CircularCountDown;
});

From there you want to set up a require js config file for easy and reliable use in your theme:

app/design/frontend/{vendor_namespace}/{theme}/requirejs-config.js

with this code in it:

var config = {
    map: {
        '*': {
            circularCountDown: 'Magento_Theme/js/circular-countdown'
        }
    }
};

You will notice that the path defined here is the same as the file you placed above, omitting the web directory and the .js on the end of the file. Why? I don't know, it's just the Magento convention and a way to keep end users guessing at what the hell they were thinking when they did this. But all the same, you are now free to set up a template and run the JS in conjunction with the html markup:

app/design/frontend/{vendor_namespace}/{theme}/Magento_Theme/templates/circular.phtml

with this code:

<div class="container">
    <h1>Test</h1>
    <div class="timer" style="min-height: 300px;"></div>
</div>
<script>
    require([
        'jquery',
        'circularCountDown',
        'domReady!'
    ], function($) {
        $('.timer').circularCountDown({
            size: 200,
            borderSize: 10,
            colorCircle: 'gray',
            background: 'white',
            fontFamily: 'sans-serif',
            fontColor: '#333333',
            fontSize: 16,
            delayToFadeIn: 0,
            delayToFadeOut: 0,
            reverseLoading: false,
            reverseRotation: false,
            duration: {
                hours: 0,
                minutes: 0,
                seconds: 60
            },
            beforeStart: function(){},
            end: function(){}
        });
    });
</script>

Note that i did change a few things for my testing, but what you want to take away from this is the use of the require and the passing in of the needed files jquery, circularCountDown and domReady!. Without domReady! i was getting circularCountDown is not a function errors so it's worth keeping around. This template is now ready to get used anywhere it's called on the site. For my testing i just called it into the homepage.

{{block class="Magento\Framework\View\Element\Template" name="count_file" template="Magento_Theme::circular.phtml"}}

enter image description here

Related Topic