PHPackages                             madj2k/t3-ajax-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. madj2k/t3-ajax-api

ActiveTypo3-cms-extension[API Development](/categories/api)

madj2k/t3-ajax-api
==================

AJAX-API for usage with TYPO3, based on simple ViewHelpers and some JS

v10.4.5-stable(11mo ago)01329GPL-2.0+PHPPHP &gt;=7.4

Since Feb 22Pushed 10mo ago2 watchersCompare

[ Source](https://github.com/skroggel/typo3-ajax-api)[ Packagist](https://packagist.org/packages/madj2k/t3-ajax-api)[ Docs](https://www.steffenkroggel.dede)[ RSS](/packages/madj2k-t3-ajax-api/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (23)Used By (9)

ajax\_api
=========

[](#ajax_api)

What does it do?
----------------

[](#what-does-it-do)

It adds AJAX-functionality to your extensions in an easy and convenient way. There is no need to take care of AJAX request by yourself. Just code your extension and templates as usually – ajax\_api will take care of the rest

Setup
-----

[](#setup)

- Install the extension via composer
- Activate the extension in the backend
- The TypoScript-settings of ajax\_api will be activated automatically
- Now you need to activate the AJAX-Js via TypoScipt

```
plugin.tx_ajaxapi {
    settings {

        # cat=plugin.tx_ajaxapi//a; type=boolean; label=Include JS for AJAX-API (Version 2)?
        includeAjaxApiJs = 1
    }
}

```

- Don't forget to inherit you regular `page`-object to the `txAjaxApiPage`-object. This should happen after all other settings are done, so that both objects are identical.

```
txAjaxApiPage.10 < page.10

```

- You can test your setup by calling your website in a browser with `?type=250` appended to the URL. This should render your website with all contents, but without CSS or JavaScripts.

```
http://example.local/?type=250

```

Usage
-----

[](#usage)

### Basics

[](#basics)

First you will have to extend your `ActionContoller` from the `AjaxControllerAbstract`. This way the AJAX- functionality is added to your extension.

```
class YourController extends \Madj2k\AjaxApi\Controller\AjaxAbstractController
{
   [...]
}

```

Now that the basic functionality is available we can use it. This is best explained using an example.

### Example

[](#example)

Let's pretend you have an extension which:

- renders a list of elements
- a filter for this list
- a more-button for pagination

The Fluid-code may look like this:

```

        Value 1
        Value 2

            Item 1

            Item 3

            Item 3

        More

```

So we probably want to archive the following behavior:

- If the user filters the items of the list, the whole list should be refreshed via AJAX.
- If the user clicks the more button, further items should be added to the list via AJAX.
- In both cases the more-button should be updated via AJAX in order to have the correct page number as param.

In order to archive this behavior we have to use the AjaxWrapper-ViewHelper. This ViewHelper marks the sections in your HTML that are to be used for Ajax. With it you can also define which action should take place. The AjaxWrapper-ViewHelper expects the following params:

- ajaxId: This is the internal ID you define in order to distinguish the sections you use from each other. You don't have to take care for namespaces. Just make sure each ID is numeric and is used only once across all your templates, partials and layouts.
- ajaxAction: Here you define what will happen with the code inside the ViewHelper-Tag when loaded via Ajax. If you set the value to "replace" it will replace existing content, if you set the value to "append" it will be added at the end of the existing content, and if you set the value to "prepend" it will be added before the existing content.
- ajaxHelper: Well, here you simply set the AjaxHelper-Object.

First, lets take a look at the changed code before we try to explain why we did it this way:

```

            Value 1
            Value 2

        Send

                    Item 1

                    Item 3

                    Item 3

                More

```

This will be code rendered to the frontend like this:

```

            Value 1
            Value 2

        Send

            Item 1

            Item 3

            Item 3

        More

```

As you can see the AjaxWrapper-ViewHelpers will add some attributes to their first child elements. Note that these attributes will only be added to a defined set of valid HTML-tags (e.g. DIVs and FORMs). What did we do? We told the extension to:

- Completely refresh the innerHTML of the DIV with the id "773bc02ea02b903280d609bb6a883735afbd7f14-1" - **BECAUSE**: If the user filters the items of the list, the whole list should be refreshed via AJAX.
- Add items to the innerHTML of the DIV with the id "773bc02ea02b903280d609bb6a883735afbd7f14-2" - **BECAUSE:** If the user clicks the more button, further items should be added to the list via AJAX.
- Completely refresh the innerHTML of the DIV with id "773bc02ea02b903280d609bb6a883735afbd7f14-3" - **BECAUSE:** In both cases the more button should be updated via AJAX in order to have the correct page number as param.

What is still missing is an information about when these actions are to be executed. This is done by setting some params to the links and forms with the additionalParams-attribute. You can combine the following params with custom params for your extension.

```
additionalParams="{your_stuff: '{key: value}', ajax_api: '{key: ajaxHelper.key, cid: ajaxHelper.contentUid, idl: \'2,3\'}'}"

```

Let's take a look on the params and what they do:

- key: Just add `ajaxHelper.key` here. This is a internal generated key that is meant to prevent collisions between extensions and plugins.
- cid: Just add `ajaxHelper.contentUid` here. This is the uid of the current content element in order to include flexform settings.
- idl: This is the magical part. Here you add a list of Ajax-Ids that are to be updated via Ajax.

Let's integrate that into our example:

```

            Value 1
            Value 2

        Send

                    Item 1

                    Item 3

                    Item 3

```

This way the FORM with the param `idl=1` will take care of the AjaxWrapper with `id=1` and thus replace all the innerHTML of the first DIV when submitted. Therefore if the user filters the items, he will get a new list and a new more button.

The more- link with param `idl=2,3` will take care of the AjaxWrapper with `id=2` and `id=3`, when clicked. In case of the AjaxWrapper with `id=2` the new content will be added to the innerHTML of the first DIV (e. g. the second page of the list). In case of the AjaxWrapper with `id=3` the button itself will be replaced with an new one, which now contains the correct params to load the third page.

Lust but not least: don't forget to add the CSS-class `ajax` to all elements that are meant to trigger AJAX-events ;-)

That is basically all the magic.

### Advanced usage options

[](#advanced-usage-options)

#### On Submit

[](#on-submit)

By default, a form is always sent "on change". This behavior can be changed to "on submit" by using the additional class "ajax-submit-only"

```

```

#### Scroll to top

[](#scroll-to-top)

To scroll to top after submit use class "ajax-scroll-top"

#### Loading indicator

[](#loading-indicator)

As data-attribute you can specify the ID of the container that should be grayed out with "data-ajax-indicator-id"

### Special Case I: Execute Ajax-Call on page-load

[](#special-case-i-execute-ajax-call-on-page-load)

To achieve this you simply can add a template-tag to the website. The following example additionally checks for logged in users an ONLY executes the ajax call when one is logged in

```

    var txExampleAjaxUrl = "{f:uri.action(action:'loginInfo', absolute:'1', addQueryString: '1', additionalParams:'{ajax_api : \'{key: ajaxHelper.key, cid: ajaxHelper.contentUid, idl: \\\'1\\\'}\'}') -> f:format.raw()}";
    if (document.cookie.indexOf('fe_logged_in=') > -1) {
        document.getElementById('tx-example-login-info-ajax').setAttribute('data-ajax-url', txExampleAjaxUrl);
    }

```

If you combine this with a form, you can additionally check whether the form was submitted. This way, the ajax call is only triggered, when the form was not submitted. In that use-case it is also important to use the forward-method in case of an error in the controller, because the forward-methods keeps the POST-vars and thus prevents a further ajax-call.

```

        var txExampleAjaxUrl = "{f:uri.action(action:'loginInfo', absolute:'1', addQueryString: '1', additionalParams:'{ajax_api : \'{key: ajaxHelper.key, cid: ajaxHelper.contentUid, idl: \\\'1\\\'}\'}') -> f:format.raw()}";
        if (document.cookie.indexOf('fe_logged_in=') > -1) {
            document.getElementById('tx-example-login-info-ajax').setAttribute('data-ajax-url', txExampleAjaxUrl);
        }

```

### Special Case II: Execute Ajax-Call on page-load with specific viewport only

[](#special-case-ii-execute-ajax-call-on-page-load-with-specific-viewport-only)

In some cases it is helpful to bind the ajax-request on page-load to a specific viewport, e.h. to only trigger it on mobile devices. To archive this you can simply add the corresponding attribute `data-ajax-max-width`.

```

```

Additional hints
----------------

[](#additional-hints)

Since version v8.7.57-stable all requests are sent as "POST" to avoid the JS error "HTTP Error 414. The request URL is too long"

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance53

Moderate activity, may be stable

Popularity11

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 72.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~43 days

Recently: every ~58 days

Total

20

Last Release

348d ago

Major Versions

v9.5.1001-stable → v10.4.0-stable2024-04-19

### Community

Maintainers

![](https://www.gravatar.com/avatar/ca11ace9490b8fe0b145e7d32464fba5c8eddaa88d700b95d32241a226623e76?d=identicon)[SteffenKroggel](/maintainers/SteffenKroggel)

---

Top Contributors

[![skroggel](https://avatars.githubusercontent.com/u/8121847?v=4)](https://github.com/skroggel "skroggel (34 commits)")[![addorange](https://avatars.githubusercontent.com/u/1980618?v=4)](https://github.com/addorange "addorange (13 commits)")

---

Tags

apiajaxTYPO3 CMS

### Embed Badge

![Health badge](/badges/madj2k-t3-ajax-api/health.svg)

```
[![Health](https://phpackages.com/badges/madj2k-t3-ajax-api/health.svg)](https://phpackages.com/packages/madj2k-t3-ajax-api)
```

###  Alternatives

[pubnub/pubnub

This is the official PubNub PHP SDK repository.

1314.6M17](/packages/pubnub-pubnub)[agungsugiarto/codeigniter4-cors

Send CORS Headers in a CodeIgniter 4 application.

6524.6k2](/packages/agungsugiarto-codeigniter4-cors)[friendsoftypo3/interest

REST and CLI API for adding, updating, and deleting records in TYPO3. Tracks relations so records can be inserted in any order. Uses remote ID mapping so you don't have to keep track of what UID a record has gotten after import. Data is inserted using backend APIs as if a real human did it, so you can can inspect the record history and undo actions.

111.3k1](/packages/friendsoftypo3-interest)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
