Drupal Answers Asked by Kenny83 on October 26, 2021
I have a form that displays a TableSelect
which is populated by a user-specific database query. This query can sometimes return over 1000 results so I’m paging the query and adding a '#type' => 'pager'
to the form. Here’s the code:
<?php
namespace Drupalmy_moduleForm;
use DrupalCoreFormFormBase;
use DrupalCoreFormFormStateInterface;
class ReconcilePaymentsForm extends FormBase {
// create() and __construct() methods for dependency
// injection removed for brevity, as well as getFormId()
public function buildForm(array $form, FormStateInterface $form_state) {
$query = $this->db->select('payments', 'p');
$query->join('invoices', 'i', 'p.iid = i.iid');
$query->fields('p', [ 'iid', 'source', 'date', 'amount', 'reconciled' ])
->condition('i.uid', Drupal::currentUser()->id())->isNotNull('p.date');
->orderBy('p.date', 'DESC');
if (!($showAll = $this->tempStore->get('show_all'))) {
$query->condition($query->orConditionGroup()->condition(
'p.reconciled', '0')->isNull('p.reconciled'));
}
$payments = $query->extend('DrupalCoreDatabaseQuery\' .
'PagerSelectExtender')->limit(50)->execute()->fetchAll();
foreach ($payments as &$payment) {
// code to contruct the #options array with
// the correct format, removed for brevity
}
$form['payments'] = [
'#type' => 'tableselect',
'#header' => [
'iid' => $this->t('Invoice #'),
'source' => $this->t('Payment Source'),
'date' => $this->t('Payment Date'),
'amount' => $this->t('Amount')
],
'#options' => $payments
];
$form['pager'] = [ '#type' => 'pager' ];
$form['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#value' => $this->t($showAll ? 'Update' : 'Reconcile')
],
'show_all' => [
'#type' => 'submit',
'#value' => $this->t($showAll ? 'Hide Reconciled' : 'Show All Payments')
]
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$op = (string)$values['op'];
if ($op === 'Show All Payments') {
$form_state->setRebuild();
$this->tempStore->set('show_all', true);
return $form;
}
if ($op === 'Hide Reconciled') {
$form_state->setRebuild();
$this->tempStore->set('show_all', false);
return $form;
}
$reconciled = $unreconciled = [];
foreach ($values['payments'] as $key => $value) {
if ($value) {
$reconciled[] = $value;
} else {
$unreconciled[] = $key;
}
}
$reconciled = implode(', ', $reconciled) ?: '0';
$unreconciled = implode(', ', $unreconciled) ?: '0';
$query = 'UPDATE payments SET reconciled = (CASE WHEN pid IN (' .
$unreconciled . ") THEN 0 WHEN pid IN ($reconciled) THEN " .
time() . ' ELSE reconciled END)';
$this->db->query($query);
return $form;
}
}
The idea is that a user will go to this page with their bank statement in front of them, and tick off each payment that they have actually received. If they want to see all payments that have been made through the site (not just reconciled ones), then they click the Show All Payments
button and get an even-bigger table. They can then uncheck a reconciled payment if they wish to notify us that they haven’t actually received that payment, and previously reconciled it in error. Or they can continue to check off the unreconciled ones to update those.
All of this functionality works flawlessly, except that when switching between "show all" mode and "show reconciled" mode, the pager is not being rebuilt. Everything else is; the table is updated with the correct rows and everything seems hunky dory until they scroll to the bottom of the page and see a much-bigger or smaller pager than they should.
Any help would be very much appreciated. Thanks! 🙂
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP