19 declare(strict_types=1);
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);
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);
80 ->standard($this->
txt(
'presentation_table_collapse'),
'')
81 ->withOnClick($sig_ta_collapse);
82 $component = $component->withAdditionalOnLoadCode(
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; }); 90 $tpl->setVariable(
"EXPANDCOLLAPSEALL", $default_renderer->render($expcollapsebtns));
92 $vcs = $component->getViewControls();
94 $tpl->setVariable(
"VC", $default_renderer->render($vcs));
98 $tpl->setVariable(
"ID",
$id);
100 $row_mapping = $component->getRowMapping();
101 $data = $component->getData();
109 foreach (
$data as $record) {
114 $component->getEnvironment()
117 $tpl->setCurrentBlock(
"row");
118 $tpl->setVariable(
"ROW", $default_renderer->render($row));
119 $tpl->parseCurrentBlock();
130 $tpl = $this->
getTemplate(
"tpl.presentationrow.html",
true,
true);
133 $sig_show = $component->getShowSignal();
134 $sig_hide = $component->getCloseSignal();
135 $sig_toggle = $component->getToggleSignal();
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);
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));
150 if ($symbol = $component->getLeadingSymbol()) {
151 $tpl->setVariable(
"SYMBOL", $default_renderer->render($symbol));
153 $tpl->setVariable(
"HEADLINE", $component->getHeadline());
154 $tpl->setVariable(
"TOGGLE_SIGNAL", $sig_toggle);
155 $subheadline = $component->getSubheadline();
157 $tpl->setVariable(
"SUBHEADLINE", $subheadline);
160 foreach ($component->getImportantFields() as $label => $value) {
161 $tpl->setCurrentBlock(
"important_field");
162 if (is_string($label)) {
163 $tpl->setVariable(
"IMPORTANT_FIELD_LABEL", $label);
165 $tpl->setVariable(
"IMPORTANT_FIELD_VALUE", $value);
166 $tpl->parseCurrentBlock();
169 $tpl->setVariable(
"DESCLIST", $default_renderer->render($component->getContent()));
171 $further_fields_headline = $component->getFurtherFieldsHeadline();
172 $further_fields = $component->getFurtherFields();
174 if (count($further_fields) > 0) {
175 $tpl->touchBlock(
"has_further_fields");
177 if ($further_fields_headline) {
178 $tpl->setVariable(
"FURTHER_FIELDS_HEADLINE", $further_fields_headline);
181 foreach ($further_fields as $label => $value) {
182 $tpl->setCurrentBlock(
"further_field");
183 if (is_string($label)) {
184 $tpl->setVariable(
"FIELD_LABEL", $label);
186 $tpl->setVariable(
"FIELD_VALUE", $value);
187 $tpl->parseCurrentBlock();
191 $action = $component->getAction();
192 if (!is_null($action)) {
193 $tpl->setCurrentBlock(
"button");
194 $tpl->setVariable(
"BUTTON", $default_renderer->render($action));
195 $tpl->parseCurrentBlock();
203 $tpl = $this->
getTemplate(
"tpl.datatable.html",
true,
true);
206 [$component, $view_controls] = $component->applyViewControls(
207 $component->getFilter() ?? [],
208 $component->getAdditionalParameters()
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()
221 $compensate_col_index = 1;
222 if ($component->hasMultiActions()) {
223 $compensate_col_index += 1;
225 $compensate_col_count = 0;
226 if ($component->hasMultiActions()) {
227 $compensate_col_count += 1;
229 if ($component->hasSingleActions()) {
230 $compensate_col_count += 1;
234 $tpl->setVariable(
'ID',
$id);
235 $tpl->setVariable(
'TITLE', $component->getTitle());
236 $tpl->setVariable(
'COL_COUNT', (
string) $component->getColumnCount() + $compensate_col_count);
237 $tpl->setVariable(
'VIEW_CONTROLS', $default_renderer->render($view_controls));
239 $sortation_signal =
null;
241 if (!$rows->valid()) {
247 if ($component->hasMultiActions()) {
248 $multi_actions = $component->getMultiActions();
252 $component->getMultiActionSignal(),
253 $modal->getShowSignal()
255 $multi_action_col_span = count($component->getVisibleColumns()) + $compensate_col_count;
256 $tpl->setVariable(
'MULTI_ACTION_SPAN', (
string) $multi_action_col_span);
257 $tpl->setVariable(
'MULTI_ACTION_TRIGGERER', $default_renderer->render($multi_actions_dropdown));
258 $tpl->setVariable(
'MULTI_ACTION_ALL_MODAL', $default_renderer->render($modal));
259 $tpl->setVariable(
'MULTI_ACTION_WARNING', $default_renderer->render($this->getUrlTooLongWarning()));
260 $tpl->setVariable(
'MULTI_ACTION_WARNING_BUTTON_CLOSE_LABEL', $this->
txt(
'datatable_close_warning'));
263 $sortation_view_control = array_filter(
264 $view_controls->getInputs(),
267 if ($sortation_view_control) {
268 $sortation_signal = array_shift($sortation_view_control)->getInternalSignal();
269 $sortation_signal->addOption(
'parent_container',
$id);
273 $this->
renderTableHeader($default_renderer, $component, $tpl, $sortation_signal, $compensate_col_index);
282 int $compensate_col_index,
284 $order = $component->getOrder();
285 $glyph_factory = $this->
getUIFactory()->symbol()->glyph();
286 $sort_col = key($order->get());
287 $sort_direction = current($order->get());
288 $columns = $component->getVisibleColumns();
290 foreach ($columns as $col_id => $col) {
292 $col_title = $col->getTitle();
293 if ($col_id === $sort_col) {
295 $sortation =
"ascending";
296 $sortation_glyph = $glyph_factory->sortAscending(
"#");
300 $sortation =
"descending";
301 $sortation_glyph = $glyph_factory->sortDescending(
"#");
307 $tpl->
setVariable(
'COL_INDEX', (
string) $col->getIndex() + $compensate_col_index);
309 if ($col->isSortable() && !is_null($sortation_signal)) {
310 $sort_signal = clone $sortation_signal;
311 $sort_signal->addOption(
'value',
"$col_id:$param_sort_direction");
312 $col_title = $default_renderer->render(
316 if ($col_id === $sort_col) {
317 $sortation_glyph = $default_renderer->render($sortation_glyph->withOnClick($sort_signal));
319 $tpl->
setVariable(
'COL_SORTATION_GLYPH', $sortation_glyph);
324 $tpl->
setVariable(
'COL_TYPE', strtolower($col->getType()));
333 int $compensate_col_count,
335 if ($component->hasSingleActions()) {
336 $tpl->
setVariable(
'COL_INDEX_ACTION', (
string) $component->getColumnCount() + $compensate_col_count);
340 if ($component->hasMultiActions()) {
341 $glyph_factory = $this->
getUIFactory()->symbol()->glyph();
342 $signal = $component->getSelectionSignal();
343 $sig_all = clone $signal;
344 $sig_all->addOption(
'select',
true);
345 $select_all = $glyph_factory->add()->withOnClick($sig_all);
346 $signal->addOption(
'select',
false);
347 $select_none = $glyph_factory->close()->withOnClick($signal);
348 $tpl->
setVariable(
'SELECTION_CONTROL_SELECT', $default_renderer->render($select_all));
349 $tpl->
setVariable(
'SELECTION_CONTROL_DESELECT', $default_renderer->render($select_none));
353 if (!$component->isOrderingDisabled() && !$component->hasMultiActions()) {
365 $cell_tpl = $this->
getTemplate(
'tpl.datacell.html',
true,
true);
366 $cell_tpl->setCurrentBlock(
'cell');
367 $cell_tpl->setVariable(
'CELL_CONTENT', $content);
368 $cell_tpl->setVariable(
'COL_SPAN', count($component->getVisibleColumns()));
369 $cell_tpl->setVariable(
'COL_TYPE',
'full-width');
370 $cell_tpl->setVariable(
'COL_INDEX',
'1');
371 $cell_tpl->parseCurrentBlock();
381 $opt_action_id = Action::OPT_ACTIONID;
382 $opt_row_id = Action::OPT_ROWID;
384 $component = $component
385 ->withAdditionalOnLoadCode(
386 static fn(
$id):
string =>
387 "il.UI.table.data.init('{$id}','{$opt_action_id}','{$opt_row_id}');" 394 foreach ($component->getAllActions() as $action_id => $action) {
395 $component = $component->withAdditionalOnLoadCode($this->
getActionRegistration((
string) $action_id, $action));
396 if ($action->isAsync()) {
397 $signal = clone $component->getAsyncActionSignal();
398 $signal->addOption(Action::OPT_ACTIONID, $action_id);
399 $action = $action->withSignalTarget($signal);
401 $actions[$action_id] = $action;
403 $component = $component->withActions($actions);
405 if ($component->hasMultiActions()) {
406 $component = $component->withAdditionalOnLoadCode(
407 static fn(
$id):
string =>
"il.UI.table.data.get('{$id}').selectAll(false);" 420 foreach ($rows as $row) {
421 $row_contents = $default_renderer->render($row);
422 $alternate = ($alternate ===
'odd') ?
'even' :
'odd';
432 $row_tpl = $this->
getTemplate(
'tpl.presentationrow_empty.html',
true,
true);
433 $row_tpl->setVariable(
'CONTENT', $content);
446 $msg =
$f->messageBox()->confirmation($this->
txt(
'datatable_multiactionmodal_msg'));
448 $select =
$f->input()->field()->select(
449 $this->
txt(
'datatable_multiactionmodal_actionlabel'),
451 static fn($action):
string => $action->getLabel(),
455 )->withRequired(
true);
456 $submit =
$f->button()->primary($this->
txt(
'datatable_multiactionmodal_apply'),
'')
458 static fn(
$id):
string =>
"$('#{$id}').click(function() { il.UI.table.data.get('{$table_id}').doActionForAll(this); return false; });" 461 ->roundtrip($this->
txt(
'datatable_multiactionmodal_title'), [$msg, $select])
462 ->withActionButtons([$submit]);
469 return $f->messageBox()->failure($this->
txt(
'warning_url_too_long_msg'));
480 if ($actions === []) {
484 $glyph =
$f->symbol()->glyph()->bulletlist();
486 $all_obj_buttons = [];
487 foreach ($actions as $action_id => $act) {
488 $signal = clone $action_signal;
489 $signal->addOption(Action::OPT_ACTIONID, $action_id);
490 $buttons[] =
$f->button()->shy($act->getLabel(), $signal);
493 $buttons[] =
$f->divider()->horizontal();
494 $buttons[] =
$f->button()->shy($this->
txt(
'datatable_multiactionmodal_listentry'),
'#')->withOnClick($modal_signal);
496 return $f->dropdown()->standard($buttons)->withLabel($this->
txt(
'datatable_multiaction_label'));
501 return static function (
$id) use ($action_signal):
string {
503 $(document).on('{$action_signal}', function(event, signal_data) { 504 il.UI.table.data.get('{$id}').doSingleAction(signal_data); 511 return static function (
$id) use ($action_signal):
string {
513 $(document).on('{$action_signal}', function(event, signal_data) { 514 il.UI.table.data.get('{$id}').doMultiAction(signal_data); 522 return static function (
$id) use ($selection_signal):
string {
524 $(document).on('{$selection_signal}', function(event, signal_data) { 525 il.UI.table.data.get('{$id}').selectAll(signal_data.options.select); 536 $async = $action->isAsync() ?
'true' :
'false';
537 $url_builder_js = $action->getURLBuilderJS();
538 $tokens_js = $action->getURLBuilderTokensJS();
540 return static function (
$id) use ($action_id, $async, $url_builder_js, $tokens_js):
string {
542 il.UI.table.data.get('{$id}').registerAction('{$action_id}', {$async}, {$url_builder_js}, {$tokens_js}); 549 $cell_tpl = $this->
getTemplate(
"tpl.datacell.html",
true,
true);
550 $this->
fillCells($component, $cell_tpl, $default_renderer);
553 return $cell_tpl->get();
558 $cell_tpl = $this->
getTemplate(
"tpl.orderingcell.html",
true,
true);
559 $this->
fillCells($component, $cell_tpl, $default_renderer);
562 if ($component->isOrderingDisabled()) {
563 return $cell_tpl->get();
566 $namesource =
new class () implements
NameSource {
567 public function getNewName():
string 571 public function getNewDedicatedName(
string $dedicated_name):
string 573 return $dedicated_name;
577 $numeric_label = $this->
txt(
"ui_table_order");
578 $input = $this->
getUIFactory()->input()->field()->numeric($numeric_label)
579 ->withDedicatedName($component->getId())
581 ->withValue($component->getPosition() * 10);
582 $cell_tpl->setVariable(
'ORDER_INPUT', $default_renderer->render($input));
584 return $cell_tpl->get();
593 $cols = $row->getColumns();
594 foreach ($cols as $col_id => $column) {
595 if ($column->isHighlighted()) {
599 $cell_tpl->
setVariable(
'COL_TYPE', strtolower($column->getType()));
600 $cell_content = $row->getCellContent($col_id);
602 $cell_content = $default_renderer->render($cell_content);
604 $cell_tpl->
setVariable(
'CELL_CONTENT', $cell_content);
605 $cell_tpl->
setVariable(
'CELL_COL_TITLE', $row->getColumns()[$col_id]->getTitle());
609 if ($row->tableHasMultiActions()) {
612 if ($row->tableHasSingleActions()) {
617 $cell_tpl->
setVariable(
'ACTION_CONTENT', $default_renderer->render($row_actions_dropdown));
621 if (!$row->isOrderingDisabled()) {
622 $drag_handle = $this->
getUIFactory()->symbol()->glyph()->dragHandle();
623 $drag_handle = $default_renderer->render($drag_handle);
624 $cell_tpl->
setVariable(
'DRAG_HANDLE', $drag_handle);
636 foreach ($actions as $act) {
637 $act = $act->withRowId($row_id);
638 $target = $act->getTarget();
639 if ($target instanceof
URI) {
640 $target = (string) $target;
642 $buttons[] =
$f->button()->shy($act->getLabel(), $target);
644 return $f->dropdown()->standard($buttons);
650 $tpl = $this->
getTemplate(
"tpl.orderingtable.html",
true,
true);
653 [$component, $view_controls] = $component->applyViewControls();
655 $rows = $component->getDataBinding()->getRows(
656 $component->getRowBuilder(),
657 array_keys($component->getVisibleColumns()),
661 if (!$component->isOrderingDisabled()) {
662 $component = $component->withAdditionalOnLoadCode(
663 static fn(
$id):
string =>
"il.UI.table.ordering.init('{$id}');" 668 $compensate_col_index = 1;
670 if ($component->hasMultiActions() || !$component->isOrderingDisabled()) {
671 $compensate_col_index += 1;
673 if (!$component->isOrderingDisabled()) {
674 $compensate_col_index += 1;
677 $compensate_col_count = 0;
678 if ($component->hasMultiActions() || !$component->isOrderingDisabled()) {
679 $compensate_col_count += 1;
681 if (!$component->isOrderingDisabled()) {
682 $compensate_col_count += 1;
684 if ($component->hasSingleActions()) {
685 $compensate_col_count += 1;
690 if (!$component->isOrderingDisabled()) {
691 $submit = $this->
getUIFactory()->button()->standard($this->
txt(
'sorting_save'),
"")
692 ->withOnLoadCode(
static fn(
$id) =>
"document.getElementById('$id').addEventListener('click', 693 function() {document.querySelector('#$tableid form.c-table-ordering__form').submit();return false;});");
695 $tpl->setVariable(
'FORM_BUTTONS', $default_renderer->render($submit));
696 $tpl->setVariable(
'POS_INPUT_TITLE', $this->
txt(
'table_posinput_col_title'));
700 $tpl->setVariable(
'ID', $tableid);
701 $tpl->setVariable(
'TARGET_URL', $component->getTargetURL() ? $component->getTargetURL()->__toString() :
'#');
702 $tpl->setVariable(
'TITLE', $component->getTitle());
703 $tpl->setVariable(
'COL_COUNT', (
string) $component->getColumnCount() + $compensate_col_count);
704 $tpl->setVariable(
'VIEW_CONTROLS', $default_renderer->render($view_controls));
706 $columns = $component->getVisibleColumns();
707 foreach ($columns as $col_id => $col) {
708 $col_title = $col->getTitle();
709 $tpl->setCurrentBlock(
'header_cell');
710 $tpl->setVariable(
'COL_INDEX', (
string) $col->getIndex() + $compensate_col_index);
711 $tpl->setVariable(
'COL_TITLE', $col_title);
712 $tpl->setVariable(
'COL_TYPE', strtolower($col->getType()));
713 $tpl->parseCurrentBlock();
716 $rows = iterator_to_array($rows);
718 foreach ($rows as $idx => $row) {
720 ->withPosition($idx + 1)
721 ->withOrderingDisabled($component->isOrderingDisabled());
727 if ($component->hasMultiActions()) {
728 $multi_actions = $component->getMultiActions();
732 $component->getMultiActionSignal(),
733 $modal->getShowSignal()
736 $tpl->setVariable(
'MULTI_ACTION_TRIGGERER', $default_renderer->render($multi_actions_dropdown));
737 $tpl->setVariable(
'MULTI_ACTION_ALL_MODAL', $default_renderer->render($modal));
738 $tpl->setVariable(
'MULTI_ACTION_WARNING', $default_renderer->render($this->getUrlTooLongWarning()));
739 $tpl->setVariable(
'MULTI_ACTION_WARNING_BUTTON_CLOSE_LABEL', $this->
txt(
'datatable_close_warning'));
741 if ($component->hasMultiActions() || !$component->isOrderingDisabled()) {
742 $multi_action_col_span = count($component->getVisibleColumns()) + $compensate_col_count;
743 $tpl->setVariable(
'MULTI_ACTION_SPAN', (
string) $multi_action_col_span);
754 parent::registerResources($registry);
755 $registry->
register(
'assets/js/table.min.js');
756 $registry->
register(
'assets/js/modal.min.js');
761 $show = $component->getShowSignal();
762 $close = $component->getCloseSignal();
763 $toggle = $component->getToggleSignal();
764 $table_id = $component->getTableId();
765 return $component->withAdditionalOnLoadCode(
766 static fn(
$id):
string =>
767 "$(document).on('$show', function() { il.UI.table.presentation.get('$table_id').expandRow('$id'); return false; });" .
768 "$(document).on('$close', function() { il.UI.table.presentation.get('$table_id').collapseRow('$id'); return false; });" .
769 "$(document).on('$toggle', function() { il.UI.table.presentation.get('$table_id').toggleRow('$id'); return false; });"
Registry for resources required by rendered output like Javascript or CSS.
button(string $caption, string $cmd)
registerSignals(Component\Table\PresentationRow $component)
renderPresentationTable(Component\Table\Presentation $component, RendererInterface $default_renderer)
renderTableHeader(RendererInterface $default_renderer, Component\Table\Data $component, Template $tpl, ?Component\Signal $sortation_signal, int $compensate_col_index,)
Interface Observer Contains several chained tasks and infos about them.
getActionRegistration(string $action_id, Action $action)
txt(string $id)
Get a text from the language file.
registerResources(ResourceRegistry $registry)
Announce resources this renderer requires.
setCurrentBlock(string $name)
Set the block to work on.
createId()
Get a fresh unique id.
This describes commonalities between all types of Dropdowns.
buildMultiActionsAllObjectsModal(array $actions, string $table_id)
setVariable(string $name, $value)
Set a variable in the current block.
render(Component\Component $component, RendererInterface $default_renderer)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
renderPresentationRow(Component\Table\PresentationRow $component, RendererInterface $default_renderer)
getSingleActionsForRow(string $row_id, array $actions)
getAsyncActionHandler(Component\Signal $action_signal)
registerActions(Component\Table\Table $component)
renderDataTable(Component\Table\Data $component, RendererInterface $default_renderer)
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...
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)
fillCells(Component\Table\DataRow $row, Template $cell_tpl, RendererInterface $default_renderer)
cannotHandleComponent(Component $component)
This method MUST be called by derived component renderers, if.
register(string $name)
Add a dependency.
getSelectionHandler(Component\Signal $selection_signal)
renderOrderingTable(Component\Table\Ordering $component, RendererInterface $default_renderer)
parseCurrentBlock()
Parse the block that is currently worked on.
appendTableRows(Template $tpl, \Generator|array $rows, RendererInterface $default_renderer)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
touchBlock(string $name)
Touch a block without working further on it.
getUIFactory()
Get a UI factory.
renderActionsHeader(RendererInterface $default_renderer, Component\Table\Table $component, Template $tpl, int $compensate_col_count,)
renderEmptyPresentationRow(Template $tpl, RendererInterface $default_renderer, string $content)
getMultiActionHandler(Component\Signal $action_signal)
Base class for all component renderers.
renderOrderingRow(Component\Table\OrderingRow $component, RendererInterface $default_renderer)
buildMultiActionsDropdown(array $actions, Component\Signal $action_signal, Component\Signal $modal_signal,)
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.