Magento 2: Calling module script, controller, template (app/code/vendor/module) from design (app/design/frontend/vendor)

magento.stackexchange https://magento.stackexchange.com/questions/286550

Frage

First of all, I am kind of new in Magento then sorry if my question looks stupid.

I would like to use a template, controller, block, and the script from my module (app/code) into the header of my website made in design (app/design), but for the script, I have an error.

Also, a point which might be important I am using theme infortis (Ultimo).

I made a module in app/code/Vendor/ZipCode with module.xml, routes.xml, registration.php, ziptemplate.phtml (my template), index.php(my controller), ajax.js, Ziplist.php(my block) and zipcode_zipcode_index.xml.

Then for have this module in my header I overide the design in app/design/frontend/Vendor/vendor/Magento_Theme/layout by coping the default.xml from ultimo of infortis and modify so I have app/design/frontend/Vendor/vendor/Magento_Theme/layout/default.xml with added:

<referenceContainer name="container_header_top_central_1">
                    <block class="Vendor\ZipCode\Block\Ziplist" name="zipForm" template="Vendor_ZipCode::ziptemplate.phtml"></block>
</referenceContainer>

For testing Ajax I took from a Stack tutorial this in my template(app/code/Vendor/ZipCode/view/frontend/templates/ziptemplate.phtml) :

<input type='button' id='zip_btn' name='zip_btn'>
<style>  
.hideme{display:none;}
</style>
<script type="text/x-magento-init">
        {
            "*": {
                "Vendor_ZipCode/web/js/ajax": {
                    "AjaxUrl": "<?php echo $block->getAjaxUrl(); ?>"
                }
            }
        }
</script>
<div id='test' class="hideme">
    <select>
      <% _.each(posts, function(text,value) { %>
         <option value="<%= value %>"><%= text %></option>
      <% }) %> 
     </select>
</div>

this in my controller (app/code/Vendor/ZipCode/Controller/Zipcode/index.php) :

<?php 
namespace Vendor\ZipCode\Controller\Zipcode;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
class Index extends Action
{
    public function __construct(
        Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
    ) {

        $this->resultJsonFactory = $resultJsonFactory;
        parent::__construct($context);
    }


    public function execute()
    {
        $result = $this->resultJsonFactory->create();
        if ($this->getRequest()->isAjax()) 
        {
            $test=Array
            (
                'Firstname' => 'What is your firstname',
                'Email' => 'What is your emailId',
                'Lastname' => 'What is your lastname',
                'Country' => 'Your Country'
            );
            return $result->setData($test);
        }
    }
} 

and this in my script (app/code/Vendor/ZipCode/view/frontend/web/js/ajax.js):

define([
    'jquery',
    'underscore',
    'mage/template',
    'jquery/list-filter'
    ], function (
        $,
        _,
        template
    ) {
        function main(config, element) {
            var $element = $(element);
            var zipurl = config.AjaxUrl;
            console.log('test');
            $(document).on('click','#zip_btn',function() {
                    var param = 'ajax=1';
                        $.ajax({
                            showLoader: true,
                            url: zipurl,
                            data: param,
                            type: "POST",
                            dataType: 'json'
                        }).done(function (data) {
                            $('#test').removeClass('hideme');
                            var html = template('#test', {posts:data}); 
                            $('#test').html(html);
                        });
                });
        };
    console.log('test');
    return main;
});

and then I have the following error in the webconsole :

Loading failed for the with source “http://dev.mywebsitename.com/pub/static/version1566807153/frontend/Vendor/vendor/en_US/Vendor_ZipCode/web/js/ajax.js”. dev.mywebsitename.com:1 Error: Script error for: Vendor_ZipCode/web/js/ajax http://requirejs.org/docs/errors.html#scripterror

If I understand correctly this error Magento search the script in the design but it is on the module, how can I deal with it (with by preference keeping the script on the module)?
Does someone had the same issue and deal with it?
Thank you in advance.

PS: In case of minus please tell me why so that I can improve my post.

EDIT (full code):
for other part of my module code :
-app/code/Vendor/ZipCode/etc/module.xml :

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Vendor_ZipCode" setup_version="2.0.0">
            <sequence>
                <module name="Magento_Theme"/>
            </sequence>
        </module>
    </config>

app/code/Vendor/Zipcode/etc/frontend/routes.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="zipcode" frontName="zipcode">
            <module name="Vendor_ZipCode" />
        </route>
    </router>
</config>

for app/code/Vendor/ZipCode/registration.php :

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_ZipCode',
    __DIR__
);

For app/code/Vendor/ZipCode/Block/Ziplist.php:

<?php
namespace Vendor\ZipCode\Block;
use Magento\Framework\View\Element\Template;

class Ziplist extends \Magento\Framework\View\Element\Template
{
    public function __construct(Template\Context $context,array $data = array())
    {
        parent::__construct($context, $data);
        $this->setData('zip','');
    }

    public function setZipcode($zipcode)
    {
        //$_zipcode = $this->getData('zip');
        $this->setData('zip',$zipcode);
    }
}

for app/code/Vendor/ZipCode/view/frontend/layout/zipcode_zipcode_index.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="page.wrapper">
            <block class="Infortis\Base\Block\Html\Header" name="base-header-container" before="-" template="html/header.phtml">
                <referenceContainer name="container_header_top_central_1">
                    <block class="Vendor\ZipCode\Block\Ziplist" name="zipForm" template="Vendor_ZipCode::ziptemplate.phtml"></block>
                    </referenceBlock>
                </referenceContainer>
            </block>
        </referenceContainer> <!-- end: page.wrapper -->
    </body>
</page>
War es hilfreich?

Lösung

You need to add require js config in your module for frontend

Vendor/ZipCode/view/frontend/requirejs-config.js

with below content

    var config = {
    map: {
        '*': {
            customNavigation: 'Vendor_ZipCode/js/ajax',
        }
    }
};

AND put your JS file in Vendor/ZipCode/view/frontend/web/js with below code.

define([
    'jquery',
    'underscore',
    'mage/template',
    'jquery/list-filter'
], function (
    $,
    _,
    template
) {
    'use strict';
    $.widget('mage.ajaxCall', {
        init: function (options) {
            var $element = $(options.element);
            var zipurl = options.AjaxUrl;
            console.log('test');
            $(document).on('click', '#zip_btn', function () {
                var param = 'ajax=1';
                $.ajax({
                    showLoader: true,
                    url: zipurl,
                    data: param,
                    type: "POST",
                    dataType: 'json'
                }).done(function (data) {
                    $('#test').removeClass('hideme');
                    var html = template('#test', {posts: data});
                    $('#test').html(html);
                });
            });
        }
    });
    return $.mage.ajaxCall;
});

You need update in your phtml file as below

<input type='button' id='zip_btn' name='zip_btn'>
<style>  
.hideme{display:none;}
</style>
<script type="text/x-magento-init">
        {
            "*": {
                "Vendor_ZipCode/js/ajax": {
                    "AjaxUrl": "<?php echo $block->getAjaxUrl(); ?>"
                }
            }
        }
</script>
<div id='test' class="hideme">
    <select>
      <% _.each(posts, function(text,value) { %>
         <option value="<%= value %>"><%= text %></option>
      <% }) %> 
     </select>
</div>

Andere Tipps

You tell that your script is in:

app/code/Vendor/ZipCode/view/web/js/ajax.js

...but is has to be in

app/code/Vendor/ZipCode/view/**frontend**/web/js/ajax.js

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top