Magento 2 – Fix JS Function Not Working from Template File

javascriptjquerymagento2

I have created a js file in my custom module: components.js which contains the following code:

require([
    'jquery',
    'jquery/ui'
], function($) {
    function checkFormValues(inputs, radio) {
        var empty = false;
        $(inputs).each(function () {
            if ($(this).val() == '') {
                empty = true;
                return false;
            }
        });
    $.each(radio, function(index, value) {
        if (!$("input[name='" + value + "']:checked").val()) {
            empty = true;
        }
    });
    return empty;
}

function checkEnableSubmit(inputs, radio, button) {
    if (checkFormValues(inputs, radio)) {
        $(button).attr('disabled', 'disabled');
    } else {
        $(button).removeAttr('disabled');
    }
}
});

I am then requiring the js file in my template file via requirejs and referencing the functions, however the console outputs error

<script>
require([
    'jquery',
    'jquery/ui',
    'ms.ux'
], function($, ui, ux) {
    checkEnableSubmit('.form-service-plan input', ['plan_code', 'is_scb'], '.js-submit');
    $('.form-service-plan input').change(function () {
        checkEnableSubmit('.form-service-plan input', ['plan_code', 'is_scb'], '.js-submit');
    });
});
</script>

which outputs:

Uncaught ReferenceError: checkEnableSubmit is not defined

The components.js file is loading fine, so I believe the issue is with js function declarations but am not sure how to resolve.

Update:

I was able to get functions to work if i removed the requirejs wrapper and change $ to jQuery in components.js.

function checkFormValues(inputs, radio) {
    var empty = false;
    jQuery(inputs).each(function () {
        if (jQuery(this).val() == '') {
            empty = true;
            return false;
        }
    });

    jQuery.each(radio, function(index, value) {
        if (!jQuery("input[name='" + value + "']:checked").val()) {
            empty = true;
        }
    });
    return empty;
}

function checkEnableSubmit(inputs, radio, button) {
    if (checkFormValues(inputs, radio)) {
        jQuery(button).attr('disabled', 'disabled');
    } else {
        jQuery(button).removeAttr('disabled');
    }
}

Should I not use requirejs wrapper for any shared functions or libraries?

Best Answer

When you are defining a module to be reused you need to use define rather than require.

About define

With define you register a module in require.js that you can then depend on in other module definitions or require statements.

About require

With require you "just" load/use a module or javascript file that can be loaded by require.js. For examples have a look at the documentation.

Example

require([
    'jquery',
    'jquery/ui'
], function($) {
    ...
});

Should be

define([
    'jquery',
    'jquery/ui'
], function($) {
    ...
});
Related Topic