0
votes

I created a new extension with the extensionbuilder for TYPO3 9.5. In my extension, there is a 1:n relation. The n-elements are sort-able. The elements can easily be sorted in the backend flexform of the 1-element, by dragging the elements into the desired order and save the 1-element. I tried to find a solution how to get the same functionality in the frontend, so that a frontend-user can change the sorting of the elements. Is there a concept within extbase and fluid that I should follow to achieve the desired result? Or will I have to invent it on my own?

1
Could you please show at least the TCA and the relevant part of your model and controller that you have so far? - Jonas Eberle
Not the answer to your question, but a hint: It is more easy for you and the user if you use the sortable jquery plugin. - Stefan Padberg

1 Answers

0
votes

There is no real implemented concept. Because you used the Extension Builder I assume your table has a column with the name 'sorting'. I implemented a updateOrder Method in my Repository:

/**
 * @param int $uid1
 * @param int $uid2
 */
public function updateOrder($uid1, $uid2) {
    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
       ->getQueryBuilderForTable('your_table_name');

    $sorting = $queryBuilder        
      ->select("uid", "sorting")
      ->from("your_table_name")
      ->where($queryBuilder->expr()->in("uid", [$uid1, $uid2]))
      ->execute()->fetchAll();

    $queryBuilder
      ->update("your_table_name")
      ->set("sorting", $sorting[0]['sorting'])
      ->where($queryBuilder->expr()->eq("uid", $sorting[1]["uid"]))
      ->execute();
    $queryBuilder
      ->update("your_table_name")
      ->set("sorting", $sorting[1]["sorting"])
      ->where($queryBuilder->expr()->eq("uid", $sorting[0]["uid"]))
      ->execute();
}

and then I called this method by implementing a changeOrderAction in my Controller:

/**
 * action changeOrder
 *
 * @param int $uid1
 * @param int $uid2
 *
 * @return void
 * @throws StopActionException
 * @throws UnsupportedRequestTypeException
 */
public function changeOrderAction($uid1, $uid2) {
    $this->yourRepository->updateOrder($uid1, $uid2);

    $this->redirect("list");
}

Edit: Here's how i solved the Frontend (there's definitely room for improvement):

<f:for each="{objects}" as="object" iteration="iterator">
    <tr>
        <td><f:link.action action="show" arguments="{object : object}">{object.name}</f:link.action></td>
        <td><f:link.action action="edit" arguments="{object : object}">Edit</f:link.action></td>
        <td><f:link.action action="delete" arguments="{object : object}">Delete</f:link.action></td>
        <td>
            <div>
                <f:variable name="object_before_idx" value="{iterator.index - 1}"/>
                <f:variable name="object_before_uid" value="{objects.{object_before_idx}.uid}"/>
                <f:if condition="{objects.{object_before_idx}.uid}">
                    <f:then>
                        <f:link.action action="changeOrder" arguments="{uid1 : object.uid, uid2 : object_before_uid}">
                            Up
                        </f:link.action>
                    </f:then>
                </f:if>
            </div>
            <div>
                <f:variable name="object_after_idx" value="{iterator.index + 1}"/>
                <f:variable name="object_after_uid" value="{objects.{object_after_idx}.uid}"/>

                <f:if condition="{objects.{object_after_idx}.uid}">
                    <f:then>
                        <f:link.action action="changeOrder" arguments="{uid1 : object.uid, uid2 : object_after_uid}">
                            Down
                        </f:link.action>
                    </f:then>
                </f:if>
            </div>
        </td>
    </tr>
</f:for>