0
votes

I've run into a little Problem with my TYPO3 Extension I created with the Extension Builder. The Extension generates a Calendar and shows a list of upcoming events. Calendar with listed events

code list.html

<div id="dncalendar-container"></div>

        <f:flashMessages />

        <div  class="tx_tbpartnereventcal">

            <f:for each="{events}" as="event">
                <f:link.action class="event-cont" action="show" controller="Events" arguments="{events : event}" target="popup">
                    <span class="event-title">{event.title}</span> <span class="event-date"><f:format.date format="Y-m-d">{event.date}</f:format.date></span><br>
                </f:link.action>
            </f:for>
        </div>

        <!--<f:debug>{_all}</f:debug>-->

        <f:format.raw>{scriptDates}</f:format.raw>
        <script type="text/javascript">
         //script to generate calendar
        </script>

the list is created via the standard listAction in the controller and the elements can be clicked to show detailed information about each event.

However, when clicking on a linked Listitem, it reloads the pluginarea with the deatailed information as a new page. I would prefer it if the div.tx_tbpartnereventcal would just change the content of itself to the detailed information.

I have no idea however, how to get that working with ajax in TYPO3 or if there is another way.

Code controller action list and show:

/**
 * action list
 *
 * @return void
 */
public function listAction()
{
    $events = $this->eventsRepository->findAll();
    $this->view->assign('events', $events);


    /* get all events and turn into json for js calendar */
    $allNotes ='';
    /** @var Event $event */
    foreach ($events as $event) {
        $tempArr=array("date"=>$event->getDate()->format("Y-m-d"), "note" =>$event->getTitle(), "description" => $event->getLink(), "optional"=> "stuff");
        $allNotes .= json_encode($tempArr).",";
    }

    /* create script to use data in js in .html */
    $script = "
    <script>
        var jsondate = [".$allNotes."];
    </script>
    ";

    /* send js script to list.html to insert into js calendar */
    $this->view->assign('scriptDates', $script);
}


/**
* action show
* 
* @param \TBPartnerNet\TbPartnerTerminkalender\Domain\Model\Events $events
* @return void
*/
 public function showAction(\TBPartnerNet\TbPartnerTerminkalender\Domain\Model\Events $events)
{
   $this->view->assign('events', $events);
}

Am thankfull for any help!

1
I wanted to reply with some JavaScript code. But I should know first: do you want a jQuery or plain JavaScript solution?Jonas Eberle
I'd prefer jqueryAlex S.
And your TYPO3 version, please (in case you want to introduce an AJAX endpoint)Jonas Eberle
currently using 8.7.19Alex S.

1 Answers

0
votes

There are basically 3 ways to achieve client-side dynamic on that element:

1) Introduce a kind of web service that produces the data to show (as JSON):

  • requires an AJAX endpoint in TYPO3 and client-side (JavaScript) building of the template (plain JavaScript or simple [e.g. mustache] or other [e.g. angular, vue] template-libraries).

2) Introduce a kind of web service that produces the HTML of the plugin:

  • requires an AJAX endpoint in TYPO3 and some JavaScript

3) Fetch the whole page (HTML) by AJAX and only replace your calendar part in the DOM:

  • requires no changes to TYPO3 but a little JavaScript

    code example:

# register click handler for the date links on parent element (which will
# not change, thus you do not have to reregister the events after replacing the links)
$('.tx_tbpartnereventcal').on(
  'click',
  '.event-cont',
  function(ev) {
    ev.preventDefault()
    # https://api.jquery.com/jQuery.ajax/
    $.ajax(
      [
         url: ev.target.href
      ]
    ).done(
      function(data) {
        var $newPage = $(data),
            newPluginHtml = $newPage.find(.tx_tbpartnereventcal).html()

        $('.tx_tbpartnereventcal').html(newPluginHtml)
        # you notice a JavaScript to generate the calendar - 
        # maybe you could call it here
      }
    )
  }
)

3) is easiest to implement from your current point but of course is not the most performant way.

For 1) and 2) you need an AJAX endpoint. For v8 and below this is unelegant: Either the so-called pageType-approach or a helper extension like helhum/typoscript-rendering or the so-called eID-approach (not recommended!). For v9 we have middlewares which makes providing web services a lot cleaner.