0

I have a function that returns a render array for a table;

  private function _files_table($job_id){
    $files = $this->_query("
      select *
      from JC_Documents_Recent_Revisions
      where Job_ID=".$this->sqs($job_id).";
    ");

    $rows = array_map(function($row){
      return [
        (string)$row['Job_ID'],
        $row['Document_Name'],
        $row['Document_Type'],
        $row['File_Name'],
        ($row['Uploaded_Date'] != NULL ? $row['Uploaded_Date']->format("Y-m-d H:i") : 'Unknown Date'),
        $row['Uploaded_By'],
        new FormattableMarkup('<a href=":link">show</a>', [':link' => (Url::fromRoute('JobFileUpload.Serve', ['file_id' => (int)$row['FileID']]))->toString()]),
        new FormattableMarkup('<a href=":link">revise</a>', [':link' => (Url::fromRoute('JobFileUpload.Revise', ['file_id' => (int)$row['FileID']]))->toString()]),
        new FormattableMarkup('<a href=":link">delete</a>', [':link' => (Url::fromRoute('JobFileUpload.Delete', ['document_id' => (int)$row['DocumentID']]))->toString()])
      ];
    }, $files);

    $header = [
      t('Job ID'),
      t('Document Name'),
      t('Document Type'),
      t('File Name'),
      t('Uploaded Date'),
      t('Uploaded By'),
      t('Download'),
      t('Revise'),
      t('Delete')
    ];

    return [
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $rows
    ];
  }

and two occasions where I wish to render the table. The first is in buildForm:

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $job_id=NULL) {
    $jobs = $this->_query("
      select *
      from Active_Job_List;
    ");

    $formatted_jobs = [];
    $len = count($jobs);
    for($i=0; $i<$len; $i++){
      $formatted_jobs[$jobs[$i]['Job_ID']] = $jobs[$i]['Job_Name'];
    }
    natsort($formatted_jobs);

    $form['job_id'] = [
      '#weight' => 1,
      '#title' => t('Job'),
      '#type' => 'select',
      '#options' => $formatted_jobs,
      '#ajax' => [
        'callback' => '::showFiles',
        'wrapper' => 'ajax-wrapper'
      ],
      '#required' => TRUE,
      '#default_value' => $job_id
    ];

    $form['jobfiles'] = $this->_files_table($job_id);
    $form['jobfiles']['#weight'] = 2;

    if($job_id != null){
      $form['newfile'] =  [
        '#weight' => 3,
        '#title' => t('Upload new file'),
        '#type' => 'link',
        '#url' => Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id])
      ];
    }

    return $form;
  }

The second is in showFiles:

  public function showFiles(array &$form, FormStateInterface $form_state) {
    $job_id = $form_state->getValue('job_id');

    $output = $this->_files_table((int)$job_id);
    // $output['link'] = new FormattableMarkup('<a href=":link">Upload a new file...</a>', [':link' => (Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]))->toString()]);

    $renderer = \Drupal::service('renderer');

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#ajax-wrapper', $renderer->render($output)));

    return $response;
  }

The buildForm method works just fine, and I get a table with the files in it. But when I call the same render array function on an output for the AjaxResponse (in ::showFiles), I don't even get an error, and the table does not show up. Anyone got an idea of what I'm doing wrong here?

0

I think the problem was not specifying an id attribute for my table when I first render it, so there was nothing to replace.

This seems to work:

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $job_id=NULL) {
    $jobs = $this->_query("
      select *
      from Active_Job_List;
    ");

    $formatted_jobs = [];
    $len = count($jobs);
    for($i=0; $i<$len; $i++){
      $formatted_jobs[$jobs[$i]['Job_ID']] = $jobs[$i]['Job_Name'];
    }
    natsort($formatted_jobs);

    $form['job_id'] = [
      '#weight' => 1,
      '#title' => t('Job'),
      '#type' => 'select',
      '#options' => $formatted_jobs,
      '#ajax' => [
        'callback' => '::showFiles',
        'wrapper' => 'ajax-wrapper'
      ],
      '#required' => TRUE,
      '#default_value' => $job_id
    ];

    $form['jobfiles'] = $this->_files_table($job_id);
    $form['jobfiles']['#weight'] = 2;

    if($job_id != null){
      $form['newfile'] =  [
        '#weight' => 3,
        '#title' => t('Upload new file'),
        '#type' => 'link',
        '#url' => Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]),
        '#attributes' => [
          'id' => ['new-file']
        ]
      ];
    }

    return $form;
  }

  public function showFiles(array &$form, FormStateInterface $form_state) {
    $job_id = $form_state->getValue('job_id');
    // $form_state->setRedirectUrl(Url::fromRoute('JobFileUpload.OverviewWithJobId', ['job_id' => $job_id]));

    $table = $this->_files_table((int)$job_id);
    $link = [
      '#type' => 'markup',
      '#markup' => new FormattableMarkup('<a href=":link">Upload a new file...</a>', [':link' => (Url::fromRoute('JobFileUpload.UploadForm', ['job_id' => $job_id]))->toString()
      ])
    ];
    $renderer = \Drupal::service('renderer');

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#ajax-wrapper', $renderer->render($table)));
    $response->addCommand(new HtmlCommand('#new-file', $renderer->render($link)));

    return $response;  
  }

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .