The Newbie Qs
The Newbie Qs

Reputation: 483

why can't my typo3 6.2 ajax action be found?

I am trying to hit an ajax action "ajaxfactsAction()" in my controller Factoids. But when the ajax call is made I get a 303 error and a redirect to another page.

This is what I have in my template that calls the ajax:

<f:section name="main">
<h1>I am</h1>
<f:form action="">
    <f:form.select id="topics" name="topics" options="{categories}" optionValueField="uid" optionLabelField="title"  additionalAttributes="{onchange: 'getFacts()'}"/>
    <f:form.hidden id="extraids" name="extraids" value="3,4,5" />
    <f:form.hidden id="number" name="number" value="3" />
</f:form>
<div>
<div class="factoid1"><f:render partial="Category/Factoid1"   /></div>
<div class="factoid2"><f:render partial="Category/Factoid2"   /></div>
<div class="factoid3"><f:render partial="Category/Factoid3"   /></div>
</div>
<f:flashMessages renderMode="div" />

<script type="text/javascript">
    var actionsPathFromViewHelperSetInTheView = '<f:uri.action action="ajaxfacts" controller="Factoid" />';
</script>


</f:section>

and this is the javascript:

function performAjaxCall(Topics, Extraids, Number) {
    alert("dddd");
    $.ajax({
        url: actionsPathFromViewHelperSetInTheView,
        data:{
            "tx_factoids_interests[uid]":Topics,
            "tx_factoids_interests[extraids]":Extraids,
            "tx_factoids_interests[number]":Number
        },
        success:function (data) {
            // do something with your json
            alert('Load was performed.');
        }
    });
}

function getFacts(){
    performAjaxCall($("#topics").val(), $("#extraids").val(), $("#number").val());   
}

and this is my action function:

/**
     * action ajaxfacts
     *
     * @return void
     */
    public function ajaxfactsAction() {
        echo __LINE__;
        die;
}

and my plugin in ext_localconf:

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
    'Seethroughweb.' . $_EXTKEY,
    'Interests',
    array(
        'Factoid' => 'interests, list, show, new, edit, create, update, ajaxfacts',

    ),
    // non-cacheable actions
    array(
        'Factoid' => 'interests, list, show, new, edit, create, update, ajaxfacts',

    )
);

What am I missing to make the action accessible?

The resulting uri looks like this :

xhttp://...xyz.com/index.php?id=111&tx_factoids_interests%5Baction%5D=ajaxfacts&tx_factoids_interests%5Bcontroller%5D=Factoid&cHash=0e805af8af888ebd7fec5e207f64b5f7&tx_factoids_interests%5Buid%5D=5&tx_factoids_interests%5Bextraids%5D=3%2C4%2C5&tx_factoids_interests%5Bnumber%5D=3

the page is is called from is accessible with the first part ie :

xhttp://....xyz.com/index.php?id=111

I am using Typo3 6.2, Thanks.

PS: javascript version two - made to work like the Arek's answer.

function performAjaxCall(Topics, Extraids, Number) {
    alert("performAjaxCall");
    $.ajax({
        url: $('form').attr('action'), // now we're using the url generated by Extbase/Fluid
        data: $('form').serialize(), // serializes the form

//        data:{
//            "tx_factoids_interests[uid]":Topics,
//          "tx_factoids_interests[extraids]":Extraids,
//          "tx_factoids_interests[number]":Number
//        },
        success:function (data) {
            // do something with your json
            alert('performAjaxCall Load was performed.');
        }
    });
    return false;
}

PPS: the request uri from this method now looks like this:

http://...xyz.com/undefinedindex.php?id=111&tx_factoids_interests%5Baction%5D=ajaxfacts&tx_factoids_interests%5Bcontroller%5D=Factoid&cHash=0e805af8af888ebd7fec5e207f64b5f7

and current javascript:

function performAjaxCall( Topics, Extraids, Divid) {
    //alert("performAjaxCall");
    $.ajax({
        type: "POST", 
        dataType: "json",

        url: $('base').attr('href') + $('#form1').attr('action'), // now we're using the url generated by Extbase/Fluid
        data: $('#form1').serialize(),

//      url: actionsPathFromViewHelperSetInTheView,
//        data:{
//            "tx_factoids_interests[uid]":Topics,
//          "tx_factoids_interests[extraids]":Extraids           
//        },

        success:function (data) {
            // do something with your json

            $.each( data, function( key, val ) {
                var items='';
                var id = '';
                $.each( val, function( ikey, ival ) {
                    if(ikey =='category') id = Divid +" #factoid"+ival; 
                    items +=  "<span class="+ikey+">" + ival + "</span><br/>" ;
                });
                $(id).html(items);

            });

//          $(".factoid1").html();
//          $(".factoid2").html();
//          $(".factoid3").html();
            //alert('performAjaxCall Load was performed.');
        }
    });
}

function getFacts(Divid){
    performAjaxCall( $(Divid+"topics").val(), $(Divid+"extraids").val(), Divid );    
    return false;
}   

and the current template:

 <div id="interests">
    <f:form action="ajaxfacts" controller="Factoid" id="form1">
        <f:form.select id="intereststopics" name="topics" options="{categories}" optionValueField="uid" optionLabelField="content"  additionalAttributes="{onchange: 'getFacts(\'#interests\')'}"/>
        <f:form.hidden id="interestsextraids" name="extraids" value="2,4,5" />

    </f:form>
    <div>
    <div id="factoid2" class="factoid1"></div>
    <div id="factoid4" class="factoid2"></div>
    <div id="factoid5" class="factoid3"></div>
    </div>
    </div>

PPPS: final code

function performAjaxCall( Topics, Extraids, Divid, Formid) {
      $.ajax({
        type: "POST", 
        dataType: "json",

        url: $(Formid).attr('action'), // now we're using the url generated by Extbase/Fluid
        data: $(Formid).serialize(),

        success:function (data) {

            $.each( data, function( key, val ) {
                var items='';
                var id = '';
                $.each( val, function( ikey, ival ) {
                    if(ikey =='category') id = Divid +" #factoid"+ival; 
                    $(id +" ."+ikey).html(ival);

                });

            });

        }
    });
}

function getFacts(Divid, Formid){
    performAjaxCall( $(Divid+"topics").val(), $(Divid+"extraids").val(), Divid, Formid );    
    return false;
}   

Upvotes: 1

Views: 570

Answers (1)

Arek van Schaijk
Arek van Schaijk

Reputation: 1442

You didn't set the <f:form action="">.

The calculated cHash is in your case based on the URL generated by <f:uri> which does not contain any information about the other properties you added in your JavaScript. Hereby you're running into the cHash error.

You can prevent that the pageNotFoundHandler is called on a cHash error by disabling $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFoundOnCHashError'] (Local Configuration).

For more information abount the cHash:

The mysteries of &cHash

The &cHash parameter of frontend plugins might have puzzled quite a few developers but this article will explain how it works and what to avoid in order to make great, reliable plugins with TYPO3.

Solution

Instead of making a custom url you need to use the action from the form generated by Extbase/Fluid.

So your form should look like:

<f:form action="ajaxfacts" controller="Factoid">

And your JavaScript should look like:

$(function() { 

    $('form').submit(function(e) {

        $.ajax({
            type: "POST",
            url: $('base').attr('href') + $('form').attr('action'), // now we're using the url generated by Extbase/Fluid
            data: $('form').serialize(), // serializes the form
            success:function (data) {
                // do something with your json
                alert('Load was performed.');
            }
        });

        return false;
    });

});

PPPS Final js code:

function performAjaxCall( Topics, Extraids, Divid, Formid) {

    $.ajax({
        type: "POST", 
        dataType: "json",


        url: $(Formid).attr('action'), // now we're using the url generated by Extbase/Fluid
        data: $(Formid).serialize(),

        success:function (data) {

            $.each( data, function( key, val ) {
                var items='';
                var id = '';
                $.each( val, function( ikey, ival ) {
                    if(ikey =='category') id = Divid +" #factoid"+ival; 
                    $(id +" ."+ikey).html(ival);
                    //items +=  "<span class="+ikey+">" + ival + "</span><br/>" ;
                });

            });

        }
    });
}

function getFacts(Divid, Formid){
    performAjaxCall( $(Divid+"topics").val(), $(Divid+"extraids").val(), Divid, Formid );    
    return false;
}   

Upvotes: 1

Related Questions