ILIAS  trunk Revision v11.0_alpha-1715-g7fc467680fb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
Renderer.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
29 use ILIAS\Data\URI;
33 
35 {
39  public function render(Component\Component $component, RendererInterface $default_renderer): string
40  {
41  if ($component instanceof Component\Table\Presentation) {
42  return $this->renderPresentationTable($component, $default_renderer);
43  }
44  if ($component instanceof Component\Table\PresentationRow) {
45  return $this->renderPresentationRow($component, $default_renderer);
46  }
47  if ($component instanceof Component\Table\Data) {
48  return $this->renderDataTable($component, $default_renderer);
49  }
50  if ($component instanceof Component\Table\DataRow
51  && !$component instanceof Component\Table\OrderingRow
52  ) {
53  return $this->renderDataRow($component, $default_renderer);
54  }
55  if ($component instanceof Component\Table\Ordering) {
56  return $this->renderOrderingTable($component, $default_renderer);
57  }
58  if ($component instanceof Component\Table\OrderingRow) {
59  return $this->renderOrderingRow($component, $default_renderer);
60  }
61  $this->cannotHandleComponent($component);
62  }
63 
64  protected function renderPresentationTable(
65  Component\Table\Presentation $component,
66  RendererInterface $default_renderer
67  ): string {
68  $tpl = $this->getTemplate("tpl.presentationtable.html", true, true);
69  $tpl->setVariable("TITLE", $component->getTitle());
70  $expcollapsebtns = [];
71  if ($sig_ta = $component->getExpandCollapseAllSignal()) {
72  $sig_ta_expand = clone $sig_ta;
73  $sig_ta_expand->addOption('expand', true);
74  $expcollapsebtns[] = $this->getUIFactory()->button()
75  ->standard($this->txt('presentation_table_expand'), '')
76  ->withOnClick($sig_ta_expand);
77  $sig_ta_collapse = clone $sig_ta;
78  $sig_ta_collapse->addOption('expand', false);
79  $expcollapsebtns[] = $this->getUIFactory()->button()
80  ->standard($this->txt('presentation_table_collapse'), '')
81  ->withOnClick($sig_ta_collapse);
82  $component = $component->withAdditionalOnLoadCode(
83  static fn($id) => "
84  il.UI.table.presentation.init('{$id}');
85  $(document).on('$sig_ta', function(event, signal_data) { il.UI.table.presentation.get('$id').expandAll(signal_data); return false; });
86  "
87  );
88  }
89 
90  $tpl->setVariable("EXPANDCOLLAPSEALL", $default_renderer->render($expcollapsebtns));
91 
92  $vcs = $component->getViewControls();
93  if ($vcs) {
94  $tpl->setVariable("VC", $default_renderer->render($vcs));
95  }
96 
97  $id = $this->bindJavaScript($component);
98  $tpl->setVariable("ID", $id);
99 
100  $row_mapping = $component->getRowMapping();
101  $data = $component->getData();
102  $component_id = $id;
103 
104  if (empty($data)) {
105  $this->renderEmptyPresentationRow($tpl, $default_renderer, $this->txt('ui_table_no_records'));
106  return $tpl->get();
107  }
108 
109  foreach ($data as $record) {
110  $row = $row_mapping(
111  new PresentationRow($component->getSignalGenerator(), $component_id),
112  $record,
113  $this->getUIFactory(),
114  $component->getEnvironment()
115  );
116 
117  $tpl->setCurrentBlock("row");
118  $tpl->setVariable("ROW", $default_renderer->render($row));
119  $tpl->parseCurrentBlock();
120  }
121 
122  return $tpl->get();
123  }
124 
125  protected function renderPresentationRow(
126  Component\Table\PresentationRow $component,
127  RendererInterface $default_renderer
128  ): string {
129  $f = $this->getUIFactory();
130  $tpl = $this->getTemplate("tpl.presentationrow.html", true, true);
131 
132  $component = $this->registerSignals($component->withResetSignals());
133  $sig_show = $component->getShowSignal();
134  $sig_hide = $component->getCloseSignal();
135  $sig_toggle = $component->getToggleSignal();
136  $id = $this->bindJavaScript($component);
137 
138  $expander = $f->symbol()->glyph()->expand("#")
139  ->withOnClick($sig_show);
140  $collapser = $f->symbol()->glyph()->collapse("#")
141  ->withOnClick($sig_hide);
142  $shy_expander = $f->button()->shy($this->txt("presentation_table_more"), "#")
143  ->withOnClick($sig_show);
144 
145  $tpl->setVariable("ID", $id);
146  $tpl->setVariable("EXPANDER", $default_renderer->render($expander));
147  $tpl->setVariable("COLLAPSER", $default_renderer->render($collapser));
148  $tpl->setVariable("SHY_EXPANDER", $default_renderer->render($shy_expander));
149 
150  if ($symbol = $component->getLeadingSymbol()) {
151  $tpl->setVariable("SYMBOL", $default_renderer->render($symbol));
152  }
153  $tpl->setVariable("HEADLINE", $component->getHeadline());
154  $tpl->setVariable("TOGGLE_SIGNAL", $sig_toggle);
155  $subheadline = $component->getSubheadline();
156  if ($subheadline) {
157  $tpl->setVariable("SUBHEADLINE", $subheadline);
158  }
159 
160  foreach ($component->getImportantFields() as $label => $value) {
161  $tpl->setCurrentBlock("important_field");
162  if (is_string($label)) {
163  $tpl->setVariable("IMPORTANT_FIELD_LABEL", $label);
164  }
165  $tpl->setVariable("IMPORTANT_FIELD_VALUE", $value);
166  $tpl->parseCurrentBlock();
167  }
168 
169  $tpl->setVariable("DESCLIST", $default_renderer->render($component->getContent()));
170 
171  $further_fields_headline = $component->getFurtherFieldsHeadline();
172  $further_fields = $component->getFurtherFields();
173 
174  if (count($further_fields) > 0) {
175  $tpl->touchBlock("has_further_fields");
176 
177  if ($further_fields_headline) {
178  $tpl->setVariable("FURTHER_FIELDS_HEADLINE", $further_fields_headline);
179  }
180 
181  foreach ($further_fields as $label => $value) {
182  $tpl->setCurrentBlock("further_field");
183  if (is_string($label)) {
184  $tpl->setVariable("FIELD_LABEL", $label);
185  }
186  $tpl->setVariable("FIELD_VALUE", $value);
187  $tpl->parseCurrentBlock();
188  }
189  }
190 
191  $action = $component->getAction();
192  if (!is_null($action)) {
193  $tpl->setCurrentBlock("button");
194  $tpl->setVariable("BUTTON", $default_renderer->render($action));
195  $tpl->parseCurrentBlock();
196  }
197 
198  return $tpl->get();
199  }
200 
201  public function renderDataTable(Component\Table\Data $component, RendererInterface $default_renderer): string
202  {
203  $tpl = $this->getTemplate("tpl.datatable.html", true, true);
204  $component = $this->registerActions($component);
205 
206  [$component, $view_controls] = $component->applyViewControls(
207  $component->getFilter() ?? [],
208  $component->getAdditionalParameters()
209  );
210 
211  $rows = $component->getDataRetrieval()->getRows(
212  $component->getRowBuilder(),
213  array_keys($component->getVisibleColumns()),
214  $component->getRange(),
215  $component->getOrder(),
216  $component->getFilter(),
217  $component->getAdditionalParameters()
218  );
219 
220  $id = $this->bindJavaScript($component);
221  $tpl->setVariable('ID', $id);
222  $tpl->setVariable('TITLE', $component->getTitle());
223  $tpl->setVariable('COL_COUNT', (string) $component->getColumnCount());
224  $tpl->setVariable('VIEW_CONTROLS', $default_renderer->render($view_controls));
225 
226  $sortation_signal = null;
227  // if the generator is empty, and thus invalid, we render an empty row.
228  if (!$rows->valid()) {
229  $this->renderFullWidthDataCell($component, $tpl, $this->txt('ui_table_no_records'));
230  } else {
231  $this->renderActionsHeader($default_renderer, $component, $tpl);
232  $this->appendTableRows($tpl, $rows, $default_renderer);
233 
234  if ($component->hasMultiActions()) {
235  $multi_actions = $component->getMultiActions();
236  $modal = $this->buildMultiActionsAllObjectsModal($multi_actions, $id);
237  $multi_actions_dropdown = $this->buildMultiActionsDropdown(
238  $multi_actions,
239  $component->getMultiActionSignal(),
240  $modal->getShowSignal()
241  );
242  $total_number_of_cols = count($component->getVisibleColumns()) + 2; // + selection column and action dropdown column
243  $tpl->setVariable('COLUMN_COUNT', (string) $total_number_of_cols);
244  $tpl->setVariable('MULTI_ACTION_TRIGGERER', $default_renderer->render($multi_actions_dropdown));
245  $tpl->setVariable('MULTI_ACTION_ALL_MODAL', $default_renderer->render($modal));
246  }
247 
248  $sortation_view_control = array_filter(
249  $view_controls->getInputs(),
250  static fn($i): bool => $i instanceof Component\Input\ViewControl\Sortation
251  );
252  if ($sortation_view_control) {
253  $sortation_signal = array_shift($sortation_view_control)->getInternalSignal();
254  $sortation_signal->addOption('parent_container', $id);
255  }
256  }
257 
258  $this->renderTableHeader($default_renderer, $component, $tpl, $sortation_signal);
259  return $tpl->get();
260  }
261 
262  protected function renderTableHeader(
263  RendererInterface $default_renderer,
264  Component\Table\Data $component,
265  Template $tpl,
266  ?Component\Signal $sortation_signal
267  ): void {
268  $order = $component->getOrder();
269  $glyph_factory = $this->getUIFactory()->symbol()->glyph();
270  $sort_col = key($order->get());
271  $sort_direction = current($order->get());
272  $columns = $component->getVisibleColumns();
273 
274  foreach ($columns as $col_id => $col) {
275  $param_sort_direction = Order::ASC;
276  $col_title = $col->getTitle();
277  if ($col_id === $sort_col) {
278  if ($sort_direction === Order::ASC) {
279  $sortation = $this->txt('order_option_generic_ascending');
280  $sortation_glyph = $glyph_factory->sortAscending("#");
281  $param_sort_direction = Order::DESC;
282  }
283  if ($sort_direction === Order::DESC) {
284  $sortation = $this->txt('order_option_generic_descending');
285  $sortation_glyph = $glyph_factory->sortDescending("#");
286  }
287  }
288 
289  $tpl->setCurrentBlock('header_cell');
290  $tpl->setVariable('COL_INDEX', (string) $col->getIndex());
291 
292  if ($col->isSortable() && !is_null($sortation_signal)) {
293  $sort_signal = clone $sortation_signal;
294  $sort_signal->addOption('value', "$col_id:$param_sort_direction");
295  $col_title = $default_renderer->render(
296  $this->getUIFactory()->button()->shy($col_title, $sort_signal)
297  );
298 
299  if ($col_id === $sort_col) {
300  $sortation_glyph = $default_renderer->render($sortation_glyph->withOnClick($sort_signal));
301  $tpl->setVariable('COL_SORTATION', $sortation);
302  $tpl->setVariable('COL_SORTATION_GLYPH', $sortation_glyph);
303  }
304  }
305 
306  $tpl->setVariable('COL_TITLE', $col_title);
307  $tpl->setVariable('COL_TYPE', strtolower($col->getType()));
308  $tpl->parseCurrentBlock();
309  }
310  }
311 
312  protected function renderActionsHeader(
313  RendererInterface $default_renderer,
314  Component\Table\Table $component,
315  Template $tpl
316  ): void {
317  if ($component->hasSingleActions()) {
318  $tpl->setVariable('COL_INDEX_ACTION', (string) count($component->getColumns()));
319  $tpl->setVariable('COL_TITLE_ACTION', $this->txt('actions'));
320  }
321 
322  if ($component->hasMultiActions()) {
323  $glyph_factory = $this->getUIFactory()->symbol()->glyph();
324  $signal = $component->getSelectionSignal();
325  $sig_all = clone $signal;
326  $sig_all->addOption('select', true);
327  $select_all = $glyph_factory->add()->withOnClick($sig_all);
328  $signal->addOption('select', false);
329  $select_none = $glyph_factory->close()->withOnClick($signal);
330  $tpl->setVariable('SELECTION_CONTROL_SELECT', $default_renderer->render($select_all));
331  $tpl->setVariable('SELECTION_CONTROL_DESELECT', $default_renderer->render($select_none));
332  }
333  }
334 
339  protected function renderFullWidthDataCell(Component\Table\Data $component, Template $tpl, string $content): void
340  {
341  $cell_tpl = $this->getTemplate('tpl.datacell.html', true, true);
342  $cell_tpl->setCurrentBlock('cell');
343  $cell_tpl->setVariable('CELL_CONTENT', $content);
344  $cell_tpl->setVariable('COL_SPAN', count($component->getVisibleColumns()));
345  $cell_tpl->setVariable('COL_TYPE', 'full-width');
346  $cell_tpl->setVariable('COL_INDEX', '1');
347  $cell_tpl->parseCurrentBlock();
348 
349  $tpl->setCurrentBlock('row');
350  $tpl->setVariable('ALTERNATION', 'even');
351  $tpl->setVariable('CELLS', $cell_tpl->get());
352  $tpl->parseCurrentBlock();
353  }
354 
355  protected function registerActions(Component\Table\Table $component): Component\Table\Table
356  {
357  $opt_action_id = Action::OPT_ACTIONID;
358  $opt_row_id = Action::OPT_ROWID;
359 
360  $component = $component
361  ->withAdditionalOnLoadCode(
362  static fn($id): string =>
363  "il.UI.table.data.init('{$id}','{$opt_action_id}','{$opt_row_id}');"
364  )
365  ->withAdditionalOnLoadCode($this->getAsyncActionHandler($component->getAsyncActionSignal()))
366  ->withAdditionalOnLoadCode($this->getMultiActionHandler($component->getMultiActionSignal()))
367  ->withAdditionalOnLoadCode($this->getSelectionHandler($component->getSelectionSignal()));
368 
369  $actions = [];
370  foreach ($component->getAllActions() as $action_id => $action) {
371  $component = $component->withAdditionalOnLoadCode($this->getActionRegistration((string) $action_id, $action));
372  if ($action->isAsync()) {
373  $signal = clone $component->getAsyncActionSignal();
374  $signal->addOption(Action::OPT_ACTIONID, $action_id);
375  $action = $action->withSignalTarget($signal);
376  }
377  $actions[$action_id] = $action;
378  }
379  $component = $component->withActions($actions);
380 
381  if ($component->hasMultiActions()) {
382  $component = $component->withAdditionalOnLoadCode(
383  static fn($id): string => "il.UI.table.data.get('{$id}').selectAll(false);"
384  );
385  }
386 
387  return $component;
388  }
389 
390  protected function appendTableRows(
391  Template $tpl,
392  \Generator|array $rows,
393  RendererInterface $default_renderer
394  ): void {
395  $alternate = 'even';
396  foreach ($rows as $row) {
397  $row_contents = $default_renderer->render($row);
398  $alternate = ($alternate === 'odd') ? 'even' : 'odd';
399  $tpl->setCurrentBlock('row');
400  $tpl->setVariable('ALTERNATION', $alternate);
401  $tpl->setVariable('CELLS', $row_contents);
402  $tpl->parseCurrentBlock();
403  }
404  }
405 
406  protected function renderEmptyPresentationRow(Template $tpl, RendererInterface $default_renderer, string $content): void
407  {
408  $row_tpl = $this->getTemplate('tpl.presentationrow_empty.html', true, true);
409  $row_tpl->setVariable('CONTENT', $content);
410  $tpl->setVariable('ROW', $row_tpl->get());
411  }
412 
417  array $actions,
418  string $table_id
419  ): \ILIAS\UI\Component\Modal\RoundTrip {
420  $f = $this->getUIFactory();
421 
422  $msg = $f->messageBox()->confirmation($this->txt('datatable_multiactionmodal_msg'));
423 
424  $select = $f->input()->field()->select(
425  $this->txt('datatable_multiactionmodal_actionlabel'),
426  array_map(
427  static fn($action): string => $action->getLabel(),
428  $actions
429  ),
430  ""
431  )->withRequired(true);
432  $submit = $f->button()->primary($this->txt('datatable_multiactionmodal_apply'), '')
433  ->withOnLoadCode(
434  static fn($id): string => "$('#{$id}').click(function() { il.UI.table.data.get('{$table_id}').doActionForAll(this); return false; });"
435  );
436  $modal = $f->modal()
437  ->roundtrip($this->txt('datatable_multiactionmodal_title'), [$msg, $select])
438  ->withActionButtons([$submit]);
439  return $modal;
440  }
441 
445  protected function buildMultiActionsDropdown(
446  array $actions,
447  Component\Signal $action_signal,
448  Component\Signal $modal_signal,
450  if ($actions === []) {
451  return null;
452  }
453  $f = $this->getUIFactory();
454  $glyph = $f->symbol()->glyph()->bulletlist();
455  $buttons = [];
456  $all_obj_buttons = [];
457  foreach ($actions as $action_id => $act) {
458  $signal = clone $action_signal;
459  $signal->addOption(Action::OPT_ACTIONID, $action_id);
460  $buttons[] = $f->button()->shy($act->getLabel(), $signal);
461  }
462 
463  $buttons[] = $f->divider()->horizontal();
464  $buttons[] = $f->button()->shy($this->txt('datatable_multiactionmodal_listentry'), '#')->withOnClick($modal_signal);
465 
466  return $f->dropdown()->standard($buttons)->withLabel($this->txt('datatable_multiaction_label'));
467  }
468 
469  protected function getAsyncActionHandler(Component\Signal $action_signal): \Closure
470  {
471  return static function ($id) use ($action_signal): string {
472  return "
473  $(document).on('{$action_signal}', function(event, signal_data) {
474  il.UI.table.data.get('{$id}').doSingleAction(signal_data);
475  return false;
476  });";
477  };
478  }
479  protected function getMultiActionHandler(Component\Signal $action_signal): \Closure
480  {
481  return static function ($id) use ($action_signal): string {
482  return "
483  $(document).on('{$action_signal}', function(event, signal_data) {
484  il.UI.table.data.get('{$id}').doMultiAction(signal_data);
485  return false;
486  });";
487  };
488  }
489 
490  protected function getSelectionHandler(Component\Signal $selection_signal): \Closure
491  {
492  return static function ($id) use ($selection_signal): string {
493  return "
494  $(document).on('{$selection_signal}', function(event, signal_data) {
495  il.UI.table.data.get('{$id}').selectAll(signal_data.options.select);
496  return false;
497  });
498  ";
499  };
500  }
501 
502  protected function getActionRegistration(
503  string $action_id,
504  Action $action
505  ): \Closure {
506  $async = $action->isAsync() ? 'true' : 'false';
507  $url_builder_js = $action->getURLBuilderJS();
508  $tokens_js = $action->getURLBuilderTokensJS();
509 
510  return static function ($id) use ($action_id, $async, $url_builder_js, $tokens_js): string {
511  return "
512  il.UI.table.data.get('{$id}').registerAction('{$action_id}', {$async}, {$url_builder_js}, {$tokens_js});
513  ";
514  };
515  }
516 
517  public function renderDataRow(Component\Table\DataRow $component, RendererInterface $default_renderer): string
518  {
519  $cell_tpl = $this->getTemplate("tpl.datacell.html", true, true);
520  $this->fillCells($component, $cell_tpl, $default_renderer);
521 
522 
523  return $cell_tpl->get();
524  }
525 
526  public function renderOrderingRow(Component\Table\OrderingRow $component, RendererInterface $default_renderer): string
527  {
528  $cell_tpl = $this->getTemplate("tpl.orderingcell.html", true, true);
529  $this->fillCells($component, $cell_tpl, $default_renderer);
530 
531  $drag_handle = $this->getUIFactory()->symbol()->glyph()->dragHandle();
532  $drag_handle = $default_renderer->render($drag_handle);
533  $cell_tpl->setVariable('DRAG_HANDLE', $drag_handle);
534 
535  if ($component->isOrderingDisabled()) {
536  return $cell_tpl->get();
537  }
538 
539  $namesource = new class () implements NameSource {
540  public function getNewName(): string
541  {
542  return '';
543  }
544  public function getNewDedicatedName(string $dedicated_name): string
545  {
546  return $dedicated_name;
547  }
548  };
549 
550  $numeric_label = $this->txt("ui_table_order");
551  $input = $this->getUIFactory()->input()->field()->numeric($numeric_label)
552  ->withDedicatedName($component->getId())
553  ->withNameFrom($namesource)
554  ->withValue($component->getPosition() * 10);
555  $cell_tpl->setVariable('ORDER_INPUT', $default_renderer->render($input));
556 
557  return $cell_tpl->get();
558  }
559 
560 
561  protected function fillCells(
562  Component\Table\DataRow $row,
563  Template $cell_tpl,
564  RendererInterface $default_renderer
565  ) {
566  $cols = $row->getColumns();
567  foreach ($cols as $col_id => $column) {
568  if ($column->isHighlighted()) {
569  $cell_tpl->touchBlock('highlighted');
570  }
571  $cell_tpl->setCurrentBlock('cell');
572  $cell_tpl->setVariable('COL_TYPE', strtolower($column->getType()));
573  $cell_tpl->setVariable('COL_INDEX', $column->getIndex());
574  $cell_content = $row->getCellContent($col_id);
575  if ($cell_content instanceof Component\Component) {
576  $cell_content = $default_renderer->render($cell_content);
577  }
578  $cell_tpl->setVariable('CELL_CONTENT', $cell_content);
579  $cell_tpl->setVariable('CELL_COL_TITLE', $row->getColumns()[$col_id]->getTitle());
580  $cell_tpl->parseCurrentBlock();
581  }
582 
583  if ($row->tableHasMultiActions()) {
584  $cell_tpl->setVariable('ROW_ID', $row->getId());
585  }
586  if ($row->tableHasSingleActions()) {
587  $row_actions_dropdown = $this->getSingleActionsForRow(
588  $row->getId(),
589  $row->getActions()
590  );
591  $cell_tpl->setVariable('ACTION_CONTENT', $default_renderer->render($row_actions_dropdown));
592  }
593  }
594 
598  protected function getSingleActionsForRow(string $row_id, array $actions): \ILIAS\UI\Component\Dropdown\Standard
599  {
600  $f = $this->getUIFactory();
601  $buttons = [];
602  foreach ($actions as $act) {
603  $act = $act->withRowId($row_id);
604  $target = $act->getTarget();
605  if ($target instanceof URI) {
606  $target = (string) $target;
607  }
608  $buttons[] = $f->button()->shy($act->getLabel(), $target);
609  }
610  return $f->dropdown()->standard($buttons);
611  }
612 
613 
614  public function renderOrderingTable(Component\Table\Ordering $component, RendererInterface $default_renderer): string
615  {
616  $tpl = $this->getTemplate("tpl.orderingtable.html", true, true);
617  $component = $this->registerActions($component);
618 
619  [$component, $view_controls] = $component->applyViewControls();
620 
621  $rows = $component->getDataBinding()->getRows(
622  $component->getRowBuilder(),
623  array_keys($component->getVisibleColumns()),
624  );
625 
626 
627  if (!$component->isOrderingDisabled()) {
628  $component = $component->withAdditionalOnLoadCode(
629  static fn($id): string => "il.UI.table.ordering.init('{$id}');"
630  );
631  }
632 
633  $tableid = $this->bindJavaScript($component) ?? $this->createId();
634  $total_number_of_cols = count($component->getVisibleColumns());
635 
636  if (!$component->isOrderingDisabled()) {
637  $total_number_of_cols = $total_number_of_cols + 1;
638  $submit = $this->getUIFactory()->button()->standard($this->txt('sorting_save'), "")
639  ->withOnLoadCode(static fn($id) => "document.getElementById('$id').addEventListener('click',
640  function() {document.querySelector('#$tableid form.c-table-ordering__form').submit();return false;});");
641 
642  $tpl->setVariable('FORM_BUTTONS', $default_renderer->render($submit));
643  $tpl->setVariable('POS_INPUT_TITLE', $this->txt('table_posinput_col_title'));
644  }
645 
646  $tpl->setVariable('ID', $tableid);
647  $tpl->setVariable('TARGET_URL', $component->getTargetURL() ? $component->getTargetURL()->__toString() : '#');
648  $tpl->setVariable('TITLE', $component->getTitle());
649  $tpl->setVariable('COL_COUNT', (string) $component->getColumnCount());
650  $tpl->setVariable('VIEW_CONTROLS', $default_renderer->render($view_controls));
651 
652 
653  $columns = $component->getVisibleColumns();
654  foreach ($columns as $col_id => $col) {
655  $col_title = $col->getTitle();
656  $tpl->setCurrentBlock('header_cell');
657  $tpl->setVariable('COL_INDEX', (string) $col->getIndex());
658  $tpl->setVariable('COL_TITLE', $col_title);
659  $tpl->setVariable('COL_TYPE', strtolower($col->getType()));
660  $tpl->parseCurrentBlock();
661  }
662 
663  $rows = iterator_to_array($rows);
664  $r = [];
665  foreach ($rows as $idx => $row) {
666  $r[] = $row
667  ->withPosition($idx + 1)
668  ->withOrderingDisabled($component->isOrderingDisabled());
669  }
670 
671  $this->renderActionsHeader($default_renderer, $component, $tpl);
672  $this->appendTableRows($tpl, $r, $default_renderer);
673 
674  if ($component->hasMultiActions()) {
675  $total_number_of_cols = $total_number_of_cols + 2;
676  $multi_actions = $component->getMultiActions();
677  $modal = $this->buildMultiActionsAllObjectsModal($multi_actions, $tableid);
678  $multi_actions_dropdown = $this->buildMultiActionsDropdown(
679  $multi_actions,
680  $component->getMultiActionSignal(),
681  $modal->getShowSignal()
682  );
683  $tpl->setVariable('MULTI_ACTION_TRIGGERER', $default_renderer->render($multi_actions_dropdown));
684  $tpl->setVariable('MULTI_ACTION_ALL_MODAL', $default_renderer->render($modal));
685  }
686 
687  $tpl->setVariable('COLUMN_COUNT', (string) $total_number_of_cols);
688  return $tpl->get();
689  }
690 
694  public function registerResources(ResourceRegistry $registry): void
695  {
696  parent::registerResources($registry);
697  $registry->register('assets/js/table.min.js');
698  $registry->register('assets/js/modal.min.js');
699  }
700 
702  {
703  $show = $component->getShowSignal();
704  $close = $component->getCloseSignal();
705  $toggle = $component->getToggleSignal();
706  $table_id = $component->getTableId();
707  return $component->withAdditionalOnLoadCode(
708  static fn($id): string =>
709  "$(document).on('$show', function() { il.UI.table.presentation.get('$table_id').expandRow('$id'); return false; });" .
710  "$(document).on('$close', function() { il.UI.table.presentation.get('$table_id').collapseRow('$id'); return false; });" .
711  "$(document).on('$toggle', function() { il.UI.table.presentation.get('$table_id').toggleRow('$id'); return false; });"
712  );
713  }
714 }
Registry for resources required by rendered output like Javascript or CSS.
button(string $caption, string $cmd)
registerSignals(Component\Table\PresentationRow $component)
Definition: Renderer.php:701
renderPresentationTable(Component\Table\Presentation $component, RendererInterface $default_renderer)
Definition: Renderer.php:64
Interface Observer Contains several chained tasks and infos about them.
renderTableHeader(RendererInterface $default_renderer, Component\Table\Data $component, Template $tpl, ?Component\Signal $sortation_signal)
Definition: Renderer.php:262
getActionRegistration(string $action_id, Action $action)
Definition: Renderer.php:502
txt(string $id)
Get a text from the language file.
registerResources(ResourceRegistry $registry)
Announce resources this renderer requires.
Definition: Renderer.php:694
setCurrentBlock(string $name)
Set the block to work on.
This describes commonalities between all types of Dropdowns.
Definition: Dropdown.php:34
buildMultiActionsAllObjectsModal(array $actions, string $table_id)
Definition: Renderer.php:416
setVariable(string $name, $value)
Set a variable in the current block.
render(Component\Component $component, RendererInterface $default_renderer)
Definition: Renderer.php:39
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
renderPresentationRow(Component\Table\PresentationRow $component, RendererInterface $default_renderer)
Definition: Renderer.php:125
getSingleActionsForRow(string $row_id, array $actions)
Definition: Renderer.php:598
getAsyncActionHandler(Component\Signal $action_signal)
Definition: Renderer.php:469
registerActions(Component\Table\Table $component)
Definition: Renderer.php:355
renderDataTable(Component\Table\Data $component, RendererInterface $default_renderer)
Definition: Renderer.php:201
renderFullWidthDataCell(Component\Table\Data $component, Template $tpl, string $content)
Renders a full-width cell with a single message within, indication there is no data to display...
Definition: Renderer.php:339
getTemplate(string $name, bool $purge_unfilled_vars, bool $purge_unused_blocks)
Get template of component this renderer is made for.
renderDataRow(Component\Table\DataRow $component, RendererInterface $default_renderer)
Definition: Renderer.php:517
fillCells(Component\Table\DataRow $row, Template $cell_tpl, RendererInterface $default_renderer)
Definition: Renderer.php:561
cannotHandleComponent(Component $component)
This method MUST be called by derived component renderers, if.
register(string $name)
Add a dependency.
getSelectionHandler(Component\Signal $selection_signal)
Definition: Renderer.php:490
renderOrderingTable(Component\Table\Ordering $component, RendererInterface $default_renderer)
Definition: Renderer.php:614
parseCurrentBlock()
Parse the block that is currently worked on.
appendTableRows(Template $tpl, \Generator|array $rows, RendererInterface $default_renderer)
Definition: Renderer.php:390
withNameFrom(NameSource $source, ?string $parent_name=null)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
touchBlock(string $name)
Touch a block without working further on it.
Describes a source for input names.
Definition: NameSource.php:26
const DESC
Definition: Order.php:31
renderEmptyPresentationRow(Template $tpl, RendererInterface $default_renderer, string $content)
Definition: Renderer.php:406
getMultiActionHandler(Component\Signal $action_signal)
Definition: Renderer.php:479
renderActionsHeader(RendererInterface $default_renderer, Component\Table\Table $component, Template $tpl)
Definition: Renderer.php:312
renderOrderingRow(Component\Table\OrderingRow $component, RendererInterface $default_renderer)
Definition: Renderer.php:526
buildMultiActionsDropdown(array $actions, Component\Signal $action_signal, Component\Signal $modal_signal,)
Definition: Renderer.php:445
$r
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.