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 $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));
226 $sortation_signal =
null;
228 if (!$rows->valid()) {
234 if ($component->hasMultiActions()) {
235 $multi_actions = $component->getMultiActions();
239 $component->getMultiActionSignal(),
240 $modal->getShowSignal()
242 $total_number_of_cols = count($component->getVisibleColumns()) + 2;
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));
248 $sortation_view_control = array_filter(
249 $view_controls->getInputs(),
252 if ($sortation_view_control) {
253 $sortation_signal = array_shift($sortation_view_control)->getInternalSignal();
254 $sortation_signal->addOption(
'parent_container',
$id);
258 $this->
renderTableHeader($default_renderer, $component, $tpl, $sortation_signal);
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();
274 foreach ($columns as $col_id => $col) {
276 $col_title = $col->getTitle();
277 if ($col_id === $sort_col) {
279 $sortation = $this->
txt(
'order_option_generic_ascending');
280 $sortation_glyph = $glyph_factory->sortAscending(
"#");
284 $sortation = $this->
txt(
'order_option_generic_descending');
285 $sortation_glyph = $glyph_factory->sortDescending(
"#");
290 $tpl->
setVariable(
'COL_INDEX', (
string) $col->getIndex());
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(
299 if ($col_id === $sort_col) {
300 $sortation_glyph = $default_renderer->render($sortation_glyph->withOnClick($sort_signal));
302 $tpl->
setVariable(
'COL_SORTATION_GLYPH', $sortation_glyph);
307 $tpl->
setVariable(
'COL_TYPE', strtolower($col->getType()));
317 if ($component->hasSingleActions()) {
318 $tpl->
setVariable(
'COL_INDEX_ACTION', (
string) count($component->getColumns()));
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));
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();
357 $opt_action_id = Action::OPT_ACTIONID;
358 $opt_row_id = Action::OPT_ROWID;
360 $component = $component
361 ->withAdditionalOnLoadCode(
362 static fn(
$id):
string =>
363 "il.UI.table.data.init('{$id}','{$opt_action_id}','{$opt_row_id}');" 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);
377 $actions[$action_id] = $action;
379 $component = $component->withActions($actions);
381 if ($component->hasMultiActions()) {
382 $component = $component->withAdditionalOnLoadCode(
383 static fn(
$id):
string =>
"il.UI.table.data.get('{$id}').selectAll(false);" 396 foreach ($rows as $row) {
397 $row_contents = $default_renderer->render($row);
398 $alternate = ($alternate ===
'odd') ?
'even' :
'odd';
408 $row_tpl = $this->
getTemplate(
'tpl.presentationrow_empty.html',
true,
true);
409 $row_tpl->setVariable(
'CONTENT', $content);
422 $msg =
$f->messageBox()->confirmation($this->
txt(
'datatable_multiactionmodal_msg'));
424 $select =
$f->input()->field()->select(
425 $this->
txt(
'datatable_multiactionmodal_actionlabel'),
427 static fn($action):
string => $action->getLabel(),
431 )->withRequired(
true);
432 $submit =
$f->button()->primary($this->
txt(
'datatable_multiactionmodal_apply'),
'')
434 static fn(
$id):
string =>
"$('#{$id}').click(function() { il.UI.table.data.get('{$table_id}').doActionForAll(this); return false; });" 437 ->roundtrip($this->
txt(
'datatable_multiactionmodal_title'), [$msg, $select])
438 ->withActionButtons([$submit]);
450 if ($actions === []) {
454 $glyph =
$f->symbol()->glyph()->bulletlist();
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);
463 $buttons[] =
$f->divider()->horizontal();
464 $buttons[] =
$f->button()->shy($this->
txt(
'datatable_multiactionmodal_listentry'),
'#')->withOnClick($modal_signal);
466 return $f->dropdown()->standard($buttons)->withLabel($this->
txt(
'datatable_multiaction_label'));
471 return static function (
$id) use ($action_signal):
string {
473 $(document).on('{$action_signal}', function(event, signal_data) { 474 il.UI.table.data.get('{$id}').doSingleAction(signal_data); 481 return static function (
$id) use ($action_signal):
string {
483 $(document).on('{$action_signal}', function(event, signal_data) { 484 il.UI.table.data.get('{$id}').doMultiAction(signal_data); 492 return static function (
$id) use ($selection_signal):
string {
494 $(document).on('{$selection_signal}', function(event, signal_data) { 495 il.UI.table.data.get('{$id}').selectAll(signal_data.options.select); 506 $async = $action->isAsync() ?
'true' :
'false';
507 $url_builder_js = $action->getURLBuilderJS();
508 $tokens_js = $action->getURLBuilderTokensJS();
510 return static function (
$id) use ($action_id, $async, $url_builder_js, $tokens_js):
string {
512 il.UI.table.data.get('{$id}').registerAction('{$action_id}', {$async}, {$url_builder_js}, {$tokens_js}); 519 $cell_tpl = $this->
getTemplate(
"tpl.datacell.html",
true,
true);
520 $this->
fillCells($component, $cell_tpl, $default_renderer);
523 return $cell_tpl->get();
528 $cell_tpl = $this->
getTemplate(
"tpl.orderingcell.html",
true,
true);
529 $this->
fillCells($component, $cell_tpl, $default_renderer);
531 $drag_handle = $this->
getUIFactory()->symbol()->glyph()->dragHandle();
532 $drag_handle = $default_renderer->render($drag_handle);
533 $cell_tpl->setVariable(
'DRAG_HANDLE', $drag_handle);
535 if ($component->isOrderingDisabled()) {
536 return $cell_tpl->get();
539 $namesource =
new class () implements
NameSource {
540 public function getNewName():
string 544 public function getNewDedicatedName(
string $dedicated_name):
string 546 return $dedicated_name;
550 $numeric_label = $this->
txt(
"ui_table_order");
551 $input = $this->
getUIFactory()->input()->field()->numeric($numeric_label)
552 ->withDedicatedName($component->getId())
554 ->withValue($component->getPosition() * 10);
555 $cell_tpl->setVariable(
'ORDER_INPUT', $default_renderer->render($input));
557 return $cell_tpl->get();
566 $cols = $row->getColumns();
567 foreach ($cols as $col_id => $column) {
568 if ($column->isHighlighted()) {
572 $cell_tpl->
setVariable(
'COL_TYPE', strtolower($column->getType()));
573 $cell_tpl->
setVariable(
'COL_INDEX', $column->getIndex());
574 $cell_content = $row->getCellContent($col_id);
576 $cell_content = $default_renderer->render($cell_content);
578 $cell_tpl->
setVariable(
'CELL_CONTENT', $cell_content);
579 $cell_tpl->
setVariable(
'CELL_COL_TITLE', $row->getColumns()[$col_id]->getTitle());
583 if ($row->tableHasMultiActions()) {
586 if ($row->tableHasSingleActions()) {
591 $cell_tpl->
setVariable(
'ACTION_CONTENT', $default_renderer->render($row_actions_dropdown));
602 foreach ($actions as $act) {
603 $act = $act->withRowId($row_id);
604 $target = $act->getTarget();
605 if ($target instanceof
URI) {
606 $target = (string) $target;
608 $buttons[] =
$f->button()->shy($act->getLabel(), $target);
610 return $f->dropdown()->standard($buttons);
616 $tpl = $this->
getTemplate(
"tpl.orderingtable.html",
true,
true);
619 [$component, $view_controls] = $component->applyViewControls();
621 $rows = $component->getDataBinding()->getRows(
622 $component->getRowBuilder(),
623 array_keys($component->getVisibleColumns()),
627 if (!$component->isOrderingDisabled()) {
628 $component = $component->withAdditionalOnLoadCode(
629 static fn(
$id):
string =>
"il.UI.table.ordering.init('{$id}');" 634 $total_number_of_cols = count($component->getVisibleColumns());
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;});");
642 $tpl->setVariable(
'FORM_BUTTONS', $default_renderer->render($submit));
643 $tpl->setVariable(
'POS_INPUT_TITLE', $this->
txt(
'table_posinput_col_title'));
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));
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();
663 $rows = iterator_to_array($rows);
665 foreach ($rows as $idx => $row) {
667 ->withPosition($idx + 1)
668 ->withOrderingDisabled($component->isOrderingDisabled());
674 if ($component->hasMultiActions()) {
675 $total_number_of_cols = $total_number_of_cols + 2;
676 $multi_actions = $component->getMultiActions();
680 $component->getMultiActionSignal(),
681 $modal->getShowSignal()
683 $tpl->setVariable(
'MULTI_ACTION_TRIGGERER', $default_renderer->render($multi_actions_dropdown));
684 $tpl->setVariable(
'MULTI_ACTION_ALL_MODAL', $default_renderer->render($modal));
687 $tpl->setVariable(
'COLUMN_COUNT', (
string) $total_number_of_cols);
696 parent::registerResources($registry);
697 $registry->
register(
'assets/js/table.min.js');
698 $registry->
register(
'assets/js/modal.min.js');
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; });"
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)
Interface Observer Contains several chained tasks and infos about them.
renderTableHeader(RendererInterface $default_renderer, Component\Table\Data $component, Template $tpl, ?Component\Signal $sortation_signal)
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.
renderEmptyPresentationRow(Template $tpl, RendererInterface $default_renderer, string $content)
getMultiActionHandler(Component\Signal $action_signal)
renderActionsHeader(RendererInterface $default_renderer, Component\Table\Table $component, Template $tpl)
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.