Zum Hauptinhalt springen Skip to page footer

Ajax Request mittels Extbase und Fluid

# Extensionname: hkfewo
# Pluginbezeichner: ajax

plugin.tx_hkfewo_ajax {
    settings {
        typeNum = 230130
    }
}


# PAGE object for Ajax call:
hkfewo_page = PAGE
hkfewo_page {
    typeNum = 230130

    config {
        disableAllHeaderCode = 1
        additionalHeaders = Content-type:application/html
        xhtml_cleaning = 0
        debug = 0
        no_cache = 1
        admPanel = 0
    }

    10 < tt_content.list.20.hkfewo_ajax
}
setup.typoscript

Dem Ajax-Request eine Adresse zuweisen, unter der auch getesetet werden kann

  PageTypeSuffix:
    type: PageType
    default: ''
    map:
      'ajax.html': 230130
config.yaml

In der ext_localconf das Plugin definieren

/**
 * Plugin- Ajax
 */
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
        'HkFewo',
        'Ajax',
        [
            \HK\HkFewo\Controller\AjaxController::class => 'getPrice',
        ],
        [
            \HK\HkFewo\Controller\AjaxController::class => 'getPrice',
        ]
);
ext_localconf.php

Im Fluid den Action-Link in einem versteckten Element erstellen, damit dieser über das Attr data-url ausgelesen werden kann

<a class="button ajaxButton getNewPrice" data-page="{page}" data-url="{f:uri.action(action: 'getPrice', controller: 'Ajax', pluginName: 'Ajax', pageType:'230130', arguments:'{posted: posted}')}"></a>

<div id="showPrice">
  <!-- Container, der das Ergebnis des Ajax-Requests anzeigen wird -->
</div>
FluidTemplate.html

Ajax-Request per jQuery

// fireAjaxEvent an ein jQuery Event (click, onload, change, ...) binden und darüber aufrufen.

function fireAjaxEvent () {
// den Action-Link aus dem versteckten Element holen
        var url = $(".ajaxButton.getNewPrice").attr('data-url');
        var format = 'html';
        var betten = parseInt(parseInt($("#buchungsanfrage-personen_erwachsene").val()) + parseInt($("#buchungsanfrage-personen_kinder_gross").val()));
   
        $.ajax
            ({
                type: "POST",
                url: url + "&tx_hkfewo_ajax%5Bposted%5D%5Bdate_von%5D=" + $("#date_von").val() + "&tx_hkfewo_ajax%5Bposted%5D%5Bdate_bis%5D=" + $("#date_bis").val() + "&tx_hkfewo_ajax%5BnewDate%5D%5Bdate_von%5D=" + $("#date_von").val() + "&tx_hkfewo_ajax%5BnewDate%5D%5Bdate_bis%5D=" + $("#date_bis").val() + "&tx_hkfewo_ajax%5Bbetten%5D=" + betten + "&tx_hkfewo_ajax%5Bhaustiere%5D=" + $("#buchungsanfrage-haustier").val() + "&tx_hkfewo_ajax%5Bservice1_zusatz%5D=" + $("#buchungsanfrage-service1_zusatz").val(),
                headers: {
                    'Cache-Control': 'no-cache, no-store, must-revalidate',
                    'Pragma': 'no-cache',
                    'Expires': '0'
                },
                dataType: format,
                success: function (result)
                {
					// Aufbereitetes Ergebnis aus Ajax-Template an Ziel-Container übergeben
                    $("#showPrice").html(result);
                },
                error: function (e)
                {
                    console.log('Error: ' + e);
                }
            });
    };    
ajax.js

Ajax-Controller, der die Berechnungen durchführt und die Werte per assign an das Ajax-FluidTemplate weitergibt

<?php

namespace HK\HkFewo\Controller;

use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use HK\HkFewo\Domain\Model\Objekt;

class AjaxController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

    /**
     * @var \HK\HkFewo\Domain\Repository\ObjektRepository
     * @TYPO3\CMS\Extbase\Annotation\Inject
     */
    protected $_ObjektRepository = null;

    /**
     * @var \HK\HkFewo\Domain\Repository\SaisonRepository
     * @TYPO3\CMS\Extbase\Annotation\Inject
     */
    protected $_SaisonRepository = null;

    /**
     * @var \HK\HkFewo\Domain\Repository\ObjektpreiseRepository
     * @TYPO3\CMS\Extbase\Annotation\Inject
     */
    protected $_ObjektpreiseRepository = null;

    /**
     * @var \HK\HkFewo\Domain\Repository\KonfigurationRepository
     * @TYPO3\CMS\Extbase\Annotation\Inject
     */
    protected $_KonfigurationRepository = null;

    protected function initializeAction() {
        parent::initializeAction();

        /** @var $querySettings QuerySettingsInterface */
        $querySettings = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
        $querySettings->setStoragePageIds([180]);

        $this->_ObjektRepository->setDefaultQuerySettings($querySettings);
        $this->_SaisonRepository->setDefaultQuerySettings($querySettings);
        $this->_ObjektpreiseRepository->setDefaultQuerySettings($querySettings);
        $this->_KonfigurationRepository->setDefaultQuerySettings($querySettings);
    }

    public function getPriceAction() {

        $posted = $this->request->getArgument('posted');

        if ($this->request->hasArgument('newDate')) {
            $newDate = $this->request->getArgument('newDate');
        }
        $objekt = $this->_ObjektRepository->findByUid(intval($posted['objekt']));
        
        $plannedStart = new \DateTime();
        $plannedEnd = new \DateTime();

        if ($newDate['date_von']) {
            $dateVon = $newDate['date_von'];
        } else {
            $dateVon = $posted['date_von'];
        }
        if ($newDate['date_bis']) {
            $dateBis = $newDate['date_bis'];
        } else {
            $dateBis = $posted['date_bis'];
        }
        if ($dateVon && $dateBis) {
            $planned_start = $dateVon;
            $planned_end = $dateBis;
            $plannedStart = \DateTime::createFromFormat('d.m.Y', $planned_start);
            $plannedEnd = \DateTime::createFromFormat('d.m.Y', $planned_end);
        }
        $plannedStart->setTime(0, 0, 0);
        $plannedEnd->setTime(0, 0, 0);

        $fullprice = 0;
        $alldays = 0;
        $pricePerDay = 0;
        if ($plannedEnd > $plannedStart) {
            $saisonartArrayDateRange = $this->_SaisonRepository->findByDateRange($plannedStart, $plannedEnd);
            $daysPerSaisonart = array_filter(array_count_values($saisonartArrayDateRange), function ($v) {
                return $v > 0;
            });
            $saisonprice = $objekt->getCurrentPreise()->processSaisonPreise();
            foreach ($daysPerSaisonart as $saisonart => $days) {
                $fullprice += ($days * $saisonprice[$saisonart]);
                $alldays += $days;
            }
            $pricePerDay = $fullprice / $alldays;
        }
        $price['fullprice'] = $fullprice;
        $price['alldays'] = $alldays;
        $price['pricePerDay'] = $pricePerDay;
        $price['daysPerSaisonart'] = $daysPerSaisonart;

        $gesamtpreis = $price['fullprice'];

        # Waeschekosten laden
        $waescheKosten = $this->_KonfigurationRepository->getValueAsFloat('waesche');
        if ($this->request->hasArgument('betten')) {
            $bettenMin = $objekt->getDetails()[0]->getSchlafplaetze();
            $bettenMax = $objekt->getDetails()[0]->getSchlafplaetzeBis() ? $objekt->getDetails()[0]->getSchlafplaetzeBis() : $objekt->getDetails()[0]->getSchlafplaetze();

            $betten = $this->request->getArgument('betten');
            if ($betten > $bettenMin) {
                $zusaetzlicheBetten = $betten - $bettenMin;
                $price['zusaetzlicheBetten'] = $zusaetzlicheBetten;
                $price['waeschekosten'] = $zusaetzlicheBetten * $waescheKosten;
                $gesamtpreis += $price['waeschekosten'];
            }
        }

        $haustierKosten = $this->_KonfigurationRepository->getValueAsFloat('haustier');
        if ($this->request->hasArgument('haustiere')) {
            $haustiere = $this->request->getArgument('haustiere');
            if ($haustiere > 0) {
                $price['haustiere'] = $haustiere;
                $price['haustierkosten'] = $haustiere * $haustierKosten;
                $gesamtpreis += $price['haustierkosten'];
            }
        }

        $kinderbettKosten = $this->_KonfigurationRepository->getValueAsFloat('kinderbett');
        if ($this->request->hasArgument('service1_zusatz')) {
            $kinderbetten = $this->request->getArgument('service1_zusatz');
            if ($kinderbetten > 0) {
                $price['kinderbetten'] = $kinderbetten;
                $price['kinderbettkosten'] = $kinderbetten * $kinderbettKosten;
                $gesamtpreis += $price['kinderbettkosten'];
            }
        }

        $price['gesamtpreis'] = $gesamtpreis;

        $this->view->assign('data', $price);
    }

}
AjaxController.php

Fluid-Plugin, das die per AjaxController ermittelten Werte über ein html-Template ausgiebt

<strong>Voraussichtlicher Preis: <f:format.currency currencySign="€" decimalSeparator="," thousandsSeparator=".">{data.gesamtpreis}</f:format.currency></strong> <br />
<f:format.currency currencySign="€" decimalSeparator="," thousandsSeparator=".">{data.fullprice}</f:format.currency> für {data.alldays} Nächte<br />
<f:if condition="{data.zusaetzlicheBetten} && {data.waeschekosten} > 0">
    {data.zusaetzlicheBetten} zusätzliche{f:if(condition:'{data.zusaetzlicheBetten}==1',then:'s')} Wäschepaket{f:if(condition:'{data.zusaetzlicheBetten}>1',then:'e')}: <f:format.currency currencySign="€" decimalSeparator="," thousandsSeparator=".">{data.waeschekosten}</f:format.currency></br />
</f:if>
<f:if condition="{data.kinderbetten} && {data.kinderbettkosten} > 0">
    {data.kinderbetten} Kinderbett{f:if(condition:'{data.kinderbetten}>1',then:'en')}: <f:format.currency currencySign="€" decimalSeparator="," thousandsSeparator=".">{data.kinderbettkosten}</f:format.currency><br />
</f:if>
<f:if condition="{data.haustiere} && {data.haustierkosten} > 0">
    {data.haustiere} Haustier{f:if(condition:'{data.haustiere}>1',then:'e')}: <f:format.currency currencySign="€" decimalSeparator="," thousandsSeparator=".">{data.haustierkosten}</f:format.currency><br />
</f:if>
FluidTemplateAjax.html