0

Hi i need an example on how to implement a simple on / off toggler in a Joomla 4/5 Custom Component's list view. I've tried the following code but i did not get any reaction in the model / idk how to forward it from controller:

The Project: Basic structure of a listview of items and edit of items Models are called "RegistrationsModel" and "RegistrationModel".

In the listview of RegistrationModels I've rendered the following (in development):

...
<td class="text-center">
   <?php
      $task = $item->payment_status == 1 ? 'setunpaid' : 'setpaid';
      $class = $item->payment_status == 1 ? 'fas fa-check-circle text-success' : 'fas fa-times-circle text-danger';
      $label = $item->payment_status == 0 ? 'SET_PAID' : 'SET_UNPAID';
      $action = Text::_($label);
      echo '<a href="#" onclick="return Joomla.listItemTask(\'cb' . $i . '\',\'' . 'registration.' . $task . '\')" title="' . $action . '">';
        echo '<i class="' . $class . ' fa-lg" title="' . Text::_($label) . '"></i>';
      echo '</a>';
   ?>
</td>
...

Controllers are called "RegistrationsController" (extends AdminController) and "RegistrationController" (extends FormController). The RegistrationModel extends the AdminModel

In the model I've placed these methods:

...
public function setpaid(){
        error_log('setPaid called');
    }

    public function setunpaid(){
        error_log('setUnpaid called');
    }
...

My RegistrationController:

class RegistrationController extends FormController
{
    protected $view_list = 'registrations';
    protected $default_view = 'registration';

    public function setpaid($data = null)
    {
        error_log(print_r($data, true));
        error_log('setpaid in controller');
        return true;
    }

    public function setunpaid($data = null)
    {
        error_log(print_r($data, true));
        error_log('setunpaid in controller');
        return true;
    }
}

In the controller the log gets called, but: How can i forward the call from the controller to the model / identify the item in the model? "$data" is empty / null in Controller...

And (maybe solved automatically) when clicking the icon the list view disapears and shows a blank view now.

Thanks for guiding me into the right direction

*** Edit: *** Thanks to Sharky's answer below the Controller looks now like this:

public function setpaid()
    {
        $ids = (array) $this->input->get('cid', [], 'int');
        $this->setPaymentStatus($ids, 1);
    }

    public function setunpaid()
    {
        $ids = (array) $this->input->get('cid', [], 'int');
        $this->setPaymentStatus($ids, 0);
    }

    protected function setPaymentStatus($ids, $status)
    {
        $model = $this->getModel('Registration');
        $model->setPaymentStatus($ids, $status);
    }

And in the Model:

public function setPaymentStatus($arrayOfIds, $status): void
    {
        $db = $this->getDbo();
        $query = $db->getQuery(true);
        $query->update($db->quoteName('#__com_componentname_registrations'));
        $query->set($db->quoteName('payment_status') . ' = ' . $status);
        $query->where($db->quoteName('id') . ' IN (' . implode(',', $arrayOfIds) . ')');
        $db->setQuery($query);
        $db->execute();
    }

When clicking on the icon it sets the new value - but the page got reloaded and the table is then gone, what did I have to write to block this behavior / to reload the list with the filters still set?

Edit 2: Ok got it now, I modified my setPayment Method in the Controller:

protected function setPaymentStatus($ids, $status)
    {
        $model = $this->getModel('Registration');
        $model->setPaymentStatus($ids, $status);

        // Force a re-rendering of the listview and keep filter and current page thanks to input
        $url = 'index.php?option=com_componentname&view=registrations';
        $this->setRedirect(Route::_($url, false));

    }

Thanks to the input Joomla keeps the filter / listposition so the redirect itself is enough now.

1 Answer 1

2

Controller task methods in Joomla do not accept any arguments. They should read data from Joomla\Input\Input object. The key to read depends on your HTML markup. It is the name of the element with ID passed to Joomla.listItemTask(). In core components it's usually cid:

public function setpaid()
{
    $ids = (array) $this->input->get('cid', [], 'int');
    ...
}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.