"A is not defined" inside of <aui:script> block

red_sky picture red_sky · Jul 3, 2013 · Viewed 7.3k times · Source

I'm trying to extend some functionality of an existing Liferay portlet. As part of this, I would like to use Alloy UI to modify the value of a field in the portlet. There's a pre-existing <aui:script> block where I would like to define my custom function. I went ahead and tried using A.one('element'), but I am receiving the error "A is not defined." A.one() is used elsewhere in the same .jsp file, though not in an <aui:script> block, and it functions as expected.

I have tried Googling this problem to no avail. One solution that I tried was to include the "use" statement in the element block, but this made all of the functions in that block undefined when called from the jsp.

What I mean by the "use" statement is this:

<aui:script use="aui-node,aui-base">
    // ... script
</aui:script>

Here's a rough outline of what I'm trying to do:

<aui:script>
    function save(){
        // This is where I'm getting the 'A is not defined' error.
        var titleNode = A.one('input[name=title]');

        if (titleNode) {
            // do stuff with titleNode
            var titleVal = titleNode.val();
            var titleSubstr = titleVal.substring(0, titleSubstr.lastIndexOf('/'));
            titleNode.val(titleSubstr);
        }

        // other save-related code here
    }

    function otherFunction() {
        // some other functionality
    }
</aui:script>

Answer

GKlimov picture GKlimov · Jul 4, 2013

<aui:script> tag outputs

AUI().use(function(A) {
}

only if you provide dependencies via use attribute. Like

<aui:script use="aui-base">
    // your code here
</aui:script>

If you do so, you'll have

<script type="text/javascript">
    AUI().use('aui-base', function(A) {
        // your code here
    }
</script>

as a result. But in this case, all functions you declare inside will not be global. To make them global call

Liferay.provide(window, 'functionName', function() {
    // function body
});

inside <aui:script/>

Also <aui:script use="aui-base"/> is better than manually calling AUI().use(function(A) {}) if client can have IE <= 7, that doesn't work correctly with AUI().use(). In case of IE 6,7 <aui:script use="aui-base> will output AUI().ready('aui-base', function(A) {}); which will work in old browsers.