-1

There is a field 'field_upload_artwork' that contains files. I am using them to build links to files and want to insert links after Apparel Printing in the last step of the form.

Now the markup in devtools of the browser looks like this:

<tbody>
<tr>
   <td>Apparel Printing</td>
   <td></td>
   <td #type="container" file_link="Array"></td>
   <td #type="container" file_link="Array"></td>
</tr>
</tbody>

Although it should be something like this (as I see):

<tbody>
<tr>
  <td>Apparel Printing</td>
  <td>
    <a href="".....>name_of_file.png</a>
  </td>
  <td>
    <a href="".....>name_of_file.png</a>
  </td>
</tr>
</tbody>

and this is how I build the table:

$files = [];
foreach ($quote_design->get('field_upload_artwork')->getValue() as $file) {
   if ($file = File::load($file['target_id'])) {
     $file_uri = $file->getFileUri();
     $file_link = [
       'title' => [
         '#type' => 'link',
         '#title' => $file->getFilename(),
         '#url' => $file_uri,
       ],
     ];
     $files[] = [
       '#type' => 'container',
       'file_link' => $file_link,
     ];
   }
}

$services_header = [
   'col0' => $this->t('Services'),
];
       // foreach ($files as $key => $file) {
       // $services_header['col' . $key] = '';
       // }

$services_row = [
   array_merge([$quote_design->get('field_service')->value, ''], $files),
];

$form['confirm_quote'][$key]['services_table'] = [
   '#type' => 'table',
   '#header' => $services_header,
   '#rows' => $services_row,
];

What am I doing wrong here? According to the idea, we need foreach, which I commented out. But if I uncomment it, then everything breaks down.

1
  • I’m not sure table cells can contain render arrays alone.
    – cilefen
    Oct 23, 2023 at 18:59

2 Answers 2

1

you should try this structure:

$rows[] = [
  'data' => [
    'label' => [
      'data' => [
        'link' => [
          '#type' => 'link',
          '#title' => 'link text',
          '#url' => Url::fromRoute('custom_module.route'),
        ],
      ],
    ],
  ],
];

which in my case looks like this:

      $services_header = [
        'col0' => $this->t('Services'),
      ];

      $services_rows = [
        [$quote_design->get('field_service')->value],
      ];

      foreach ($quote_design->get('field_upload_artwork')->getValue() as $file_key => $file_item) {
        if ($file_id = $file_item['target_id']) {
          $file = File::load($file_id);
          $file_url = $file->createFileUrl(FALSE);

          $services_header['col' . ($file_key + 1)] = '';

          $services_rows['data' . ($file_key + 1)] = [
            'label' => [
              'data' => [
                'link' => [
                  '#type' => 'link',
                  '#title' => 'Art Link',
                  '#url' => Url::fromUri($file_url),
                  '#attributes' => [
                    'class' => ['entity-quote-confirm-quote-services-table-link'],
                  ],
                ],
              ],
            ],
          ];
        }

      }

Also, I found this example (but I didn't use it):

use Drupal\Component\Render\FormattableMarkup;  
  $rows[] = array(

      array('data' => new FormattableMarkup('<a href=":link">@name</a>', 
        [':link' => $entry['link_url'], 
        '@name' => $entry['name']])
      ),
0

If using the table theme, the #rows array contents must follow some guidelines. #rows must be:

An array of the rows to be displayed. Each row is either an array of cell contents or an array of properties as described in table.html.twig Alternatively specify the data for the table as child elements of the table element. Table elements would contain rows elements that would in turn contain column elements. - https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Table.php/class/Table/10

So if #rows contains render arrays, they must be named child elements.

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.