19declare(strict_types=1);
53 throw new \LogicException(self::class .
" cannot render component '" . get_class($component) .
"'.");
58 RendererInterface $default_renderer
61 $tpl->setVariable(
"TITLE", $component->getTitle());
63 $vcs = $component->getViewControls();
65 $tpl->touchBlock(
"viewcontrols");
66 foreach ($vcs as $vc) {
67 $tpl->setCurrentBlock(
"vc");
68 $tpl->setVariable(
"VC", $default_renderer->render($vc));
69 $tpl->parseCurrentBlock();
73 $component = $component->withAdditionalOnLoadCode(
74 static fn (
$id) =>
"il.UI.table.presentation.init('{$id}');"
79 $row_mapping = $component->getRowMapping();
80 $data = $component->getData();
83 foreach (
$data as $record) {
87 $this->getUIFactory(),
88 $component->getEnvironment()
91 $tpl->setCurrentBlock(
"row");
92 $tpl->setVariable(
"ROW", $default_renderer->render($row));
93 $tpl->parseCurrentBlock();
101 RendererInterface $default_renderer
103 $f = $this->getUIFactory();
104 $tpl = $this->getTemplate(
"tpl.presentationrow.html",
true,
true);
106 $component = $this->registerSignals($component->withResetSignals());
107 $sig_show = $component->getShowSignal();
108 $sig_hide = $component->getCloseSignal();
109 $sig_toggle = $component->getToggleSignal();
110 $id = $this->bindJavaScript($component);
112 $expander =
$f->symbol()->glyph()->expand(
"#")
113 ->withOnClick($sig_show);
114 $collapser =
$f->symbol()->glyph()->collapse(
"#")
115 ->withOnClick($sig_hide);
116 $shy_expander =
$f->button()->shy($this->txt(
"presentation_table_more"),
"#")
117 ->withOnClick($sig_show);
120 $tpl->setVariable(
"EXPANDER", $default_renderer->render($expander));
121 $tpl->setVariable(
"COLLAPSER", $default_renderer->render($collapser));
122 $tpl->setVariable(
"SHY_EXPANDER", $default_renderer->render($shy_expander));
124 $tpl->setVariable(
"HEADLINE", $component->getHeadline());
125 $tpl->setVariable(
"TOGGLE_SIGNAL", $sig_toggle);
126 $subheadline = $component->getSubheadline();
128 $tpl->setVariable(
"SUBHEADLINE", $subheadline);
131 foreach ($component->getImportantFields() as $label => $value) {
132 $tpl->setCurrentBlock(
"important_field");
133 if (is_string($label)) {
134 $tpl->setVariable(
"IMPORTANT_FIELD_LABEL", $label);
136 $tpl->setVariable(
"IMPORTANT_FIELD_VALUE", $value);
137 $tpl->parseCurrentBlock();
140 $tpl->setVariable(
"DESCLIST", $default_renderer->render($component->getContent()));
142 $further_fields_headline = $component->getFurtherFieldsHeadline();
143 $further_fields = $component->getFurtherFields();
145 if (count($further_fields) > 0) {
146 $tpl->touchBlock(
"has_further_fields");
148 if ($further_fields_headline) {
149 $tpl->setVariable(
"FURTHER_FIELDS_HEADLINE", $further_fields_headline);
152 foreach ($further_fields as $label => $value) {
153 $tpl->setCurrentBlock(
"further_field");
154 if (is_string($label)) {
155 $tpl->setVariable(
"FIELD_LABEL", $label);
157 $tpl->setVariable(
"FIELD_VALUE", $value);
158 $tpl->parseCurrentBlock();
162 $action = $component->getAction();
163 if (!is_null($action)) {
164 $tpl->setCurrentBlock(
"button");
165 $tpl->setVariable(
"BUTTON", $default_renderer->render($action));
166 $tpl->parseCurrentBlock();
174 $tpl = $this->getTemplate(
"tpl.datatable.html",
true,
true);
176 $opt_action_id = Action::OPT_ACTIONID;
177 $opt_row_id = Action::OPT_ROWID;
178 $component = $component
179 ->withAdditionalOnLoadCode(
180 static fn (
$id):
string =>
181 "il.UI.table.data.init('{$id}','{$opt_action_id}','{$opt_row_id}');"
183 ->withAdditionalOnLoadCode($this->getAsyncActionHandler($component->getAsyncActionSignal()))
184 ->withAdditionalOnLoadCode($this->getMultiActionHandler($component->getMultiActionSignal()))
185 ->withAdditionalOnLoadCode($this->getSelectionHandler($component->getSelectionSignal()));
188 foreach ($component->getAllActions() as $action_id => $action) {
189 $component = $component->withAdditionalOnLoadCode($this->getActionRegistration((
string) $action_id, $action));
190 if ($action->isAsync()) {
191 $signal = clone $component->getAsyncActionSignal();
192 $signal->addOption(Action::OPT_ACTIONID, $action_id);
193 $action = $action->withSignalTarget($signal);
195 $actions[$action_id] = $action;
197 $component = $component->withActions($actions);
199 if ($component->hasMultiActions()) {
200 $component = $component->withAdditionalOnLoadCode(
201 static fn (
$id):
string =>
"il.UI.table.data.get('{$id}').selectAll(false);"
205 [$component, $view_controls] = $component->applyViewControls(
206 $component->getFilter() ?? [],
207 $component->getAdditionalParameters()
210 $tpl->setVariable(
'VIEW_CONTROLS', $default_renderer->render($view_controls));
212 $rows = $component->getDataRetrieval()->getRows(
213 $component->getRowBuilder(),
214 array_keys($component->getVisibleColumns()),
215 $component->getRange(),
216 $component->getOrder(),
217 $component->getFilter(),
218 $component->getAdditionalParameters()
221 $id = $this->bindJavaScript($component);
223 $tpl->setVariable(
'TITLE', $component->getTitle());
224 $tpl->setVariable(
'COL_COUNT', (
string) $component->getColumnCount());
226 $sortation_signal =
null;
228 if (!
$rows->valid()) {
229 $this->renderFullWidthDataCell($component,
$tpl, $this->txt(
'ui_table_no_records'));
231 $this->appendTableRows(
$tpl,
$rows, $default_renderer);
233 if ($component->hasMultiActions()) {
234 $multi_actions = $component->getMultiActions();
235 $modal = $this->buildMultiActionsAllObjectsModal($multi_actions,
$id);
236 $multi_actions_dropdown = $this->buildMultiActionsDropdown(
238 $component->getMultiActionSignal(),
239 $modal->getShowSignal()
241 $tpl->setVariable(
'MULTI_ACTION_TRIGGERER', $default_renderer->render($multi_actions_dropdown));
242 $tpl->setVariable(
'MULTI_ACTION_ALL_MODAL', $default_renderer->render($modal));
245 $sortation_signal =
null;
246 $sortation_view_control = array_filter(
247 $view_controls->getInputs(),
250 if($sortation_view_control) {
251 $sortation_signal = array_shift($sortation_view_control)->getInternalSignal();
252 $sortation_signal->addOption(
'parent_container',
$id);
256 $this->renderTableHeader($default_renderer, $component,
$tpl, $sortation_signal);
261 RendererInterface $default_renderer,
266 $order = $component->getOrder();
267 $glyph_factory = $this->getUIFactory()->symbol()->glyph();
268 $sort_col = key($order->get());
269 $sort_direction = current($order->get());
270 $columns = $component->getVisibleColumns();
272 foreach ($columns as $col_id => $col) {
273 $param_sort_direction = Order::ASC;
274 $col_title = $col->getTitle();
275 if ($col_id === $sort_col) {
276 if ($sort_direction === Order::ASC) {
277 $sortation = $this->txt(
'order_option_generic_ascending');
278 $sortation_glyph = $glyph_factory->sortAscending(
"#");
279 $param_sort_direction = Order::DESC;
281 if ($sort_direction === Order::DESC) {
282 $sortation = $this->txt(
'order_option_generic_descending');
283 $sortation_glyph = $glyph_factory->sortDescending(
"#");
287 $tpl->setCurrentBlock(
'header_cell');
288 $tpl->setVariable(
'COL_INDEX', (
string) $col->getIndex());
290 if ($col->isSortable() && ! is_null($sortation_signal)) {
291 $sort_signal = clone $sortation_signal;
292 $sort_signal->addOption(
'value',
"$col_id:$param_sort_direction");
293 $col_title = $default_renderer->render(
294 $this->getUIFactory()->button()->shy($col_title, $sort_signal)
297 if ($col_id === $sort_col) {
298 $sortation_glyph = $default_renderer->render($sortation_glyph->withOnClick($sort_signal));
299 $tpl->setVariable(
'COL_SORTATION', $sortation);
300 $tpl->setVariable(
'COL_SORTATION_GLYPH', $sortation_glyph);
304 $tpl->setVariable(
'COL_TITLE', $col_title);
305 $tpl->setVariable(
'COL_TYPE', strtolower($col->getType()));
306 $tpl->parseCurrentBlock();
309 if ($component->hasSingleActions()) {
310 $tpl->setVariable(
'COL_INDEX_ACTION', (
string) count($columns));
311 $tpl->setVariable(
'COL_TITLE_ACTION', $this->txt(
'actions'));
314 if ($component->hasMultiActions()) {
315 $signal = $component->getSelectionSignal();
316 $sig_all = clone $signal;
317 $sig_all->addOption(
'select',
true);
318 $select_all = $glyph_factory->add()->withOnClick($sig_all);
319 $signal->addOption(
'select',
false);
320 $select_none = $glyph_factory->close()->withOnClick($signal);
321 $tpl->setVariable(
'SELECTION_CONTROL_SELECT', $default_renderer->render($select_all));
322 $tpl->setVariable(
'SELECTION_CONTROL_DESELECT', $default_renderer->render($select_none));
332 $cell_tpl = $this->getTemplate(
'tpl.datacell.html',
true,
true);
333 $cell_tpl->setCurrentBlock(
'cell');
334 $cell_tpl->setVariable(
'CELL_CONTENT', $content);
335 $cell_tpl->setVariable(
'COL_SPAN', count($component->getVisibleColumns()));
336 $cell_tpl->setVariable(
'COL_TYPE',
'full-width');
337 $cell_tpl->setVariable(
'COL_INDEX',
'1');
338 $cell_tpl->parseCurrentBlock();
340 $tpl->setCurrentBlock(
'row');
341 $tpl->setVariable(
'ALTERNATION',
'even');
342 $tpl->setVariable(
'CELLS', $cell_tpl->get());
343 $tpl->parseCurrentBlock();
349 RendererInterface $default_renderer
352 foreach (
$rows as $row) {
353 $row_contents = $default_renderer->render($row);
354 $alternate = ($alternate ===
'odd') ?
'even' :
'odd';
355 $tpl->setCurrentBlock(
'row');
356 $tpl->setVariable(
'ALTERNATION', $alternate);
357 $tpl->setVariable(
'CELLS', $row_contents);
358 $tpl->parseCurrentBlock();
364 $row_tpl = $this->getTemplate(
'tpl.presentationrow_empty.html',
true,
true);
365 $row_tpl->setVariable(
'CONTENT', $content);
366 $tpl->setVariable(
'ROW', $row_tpl->get());
376 $f = $this->getUIFactory();
378 $msg =
$f->messageBox()->confirmation($this->txt(
'datatable_multiactionmodal_msg'));
380 $select =
$f->input()->field()->select(
381 $this->txt(
'datatable_multiactionmodal_actionlabel'),
383 static fn ($action):
string => $action->getLabel(),
388 $submit =
$f->button()->primary($this->txt(
'datatable_multiactionmodal_buttonlabel'),
'')
390 static fn (
$id):
string =>
"$('#{$id}').click(function() { il.UI.table.data.get('{$table_id}').doActionForAll(this); return false; });"
393 ->roundtrip($this->txt(
'datatable_multiactionmodal_title'), [$msg, $select])
394 ->withActionButtons([$submit]);
406 if ($actions === []) {
409 $f = $this->getUIFactory();
410 $glyph =
$f->symbol()->glyph()->bulletlist();
412 $all_obj_buttons = [];
413 foreach ($actions as $action_id => $act) {
414 $signal = clone $action_signal;
415 $signal->addOption(Action::OPT_ACTIONID, $action_id);
416 $buttons[] =
$f->button()->shy($act->getLabel(), $signal);
419 $buttons[] =
$f->divider()->horizontal();
420 $buttons[] =
$f->button()->shy($this->txt(
'datatable_multiactionmodal_listentry'),
'#')->withOnClick($modal_signal);
422 return $f->dropdown()->standard($buttons);
427 return static function (
$id) use ($action_signal):
string {
429 $(document).on('{$action_signal}', function(event, signal_data) {
430 il.UI.table.data.get('{$id}').doSingleAction(signal_data);
437 return static function (
$id) use ($action_signal):
string {
439 $(document).on('{$action_signal}', function(event, signal_data) {
440 il.UI.table.data.get('{$id}').doMultiAction(signal_data);
448 return static function (
$id) use ($selection_signal):
string {
450 $(document).on('{$selection_signal}', function(event, signal_data) {
451 il.UI.table.data.get('{$id}').selectAll(signal_data.options.select);
462 $async = $action->isAsync() ?
'true' :
'false';
463 $url_builder_js = $action->getURLBuilderJS();
464 $tokens_js = $action->getURLBuilderTokensJS();
466 return static function (
$id) use ($action_id, $async, $url_builder_js, $tokens_js):
string {
468 il.UI.table.data.get('{$id}').registerAction('{$action_id}', {$async}, {$url_builder_js}, {$tokens_js});
475 $cell_tpl = $this->getTemplate(
"tpl.datacell.html",
true,
true);
476 $cols = $component->getColumns();
478 foreach (
$cols as $col_id => $column) {
479 if ($column->isHighlighted()) {
480 $cell_tpl->touchBlock(
'highlighted');
482 $cell_tpl->setCurrentBlock(
'cell');
483 $cell_tpl->setVariable(
'COL_TYPE', strtolower($column->getType()));
484 $cell_tpl->setVariable(
'COL_INDEX', $column->getIndex());
485 $cell_content = $component->getCellContent($col_id);
487 $cell_content = $default_renderer->render($cell_content);
489 $cell_tpl->setVariable(
'CELL_CONTENT', $cell_content);
490 $cell_tpl->setVariable(
'CELL_COL_TITLE', $component->getColumns()[$col_id]->getTitle());
491 $cell_tpl->parseCurrentBlock();
494 if ($component->tableHasMultiActions()) {
495 $cell_tpl->setVariable(
'ROW_ID', $component->getId());
497 if ($component->tableHasSingleActions()) {
498 $row_actions_dropdown = $this->getSingleActionsForRow(
500 $component->getActions()
502 $cell_tpl->setVariable(
'ACTION_CONTENT', $default_renderer->render($row_actions_dropdown));
505 return $cell_tpl->get();
513 $f = $this->getUIFactory();
515 foreach ($actions as $act) {
516 $act = $act->withRowId($row_id);
517 $target = $act->getTarget();
518 if ($target instanceof
URI) {
519 $target = (string) $target;
521 $buttons[] =
$f->button()->shy($act->getLabel(), $target);
523 return $f->dropdown()->standard($buttons);
531 parent::registerResources($registry);
532 $registry->
register(
'./src/UI/templates/js/Table/dist/table.min.js');
533 $registry->
register(
'./src/UI/templates/js/Modal/modal.js');
538 $show = $component->getShowSignal();
539 $close = $component->getCloseSignal();
540 $toggle = $component->getToggleSignal();
541 $table_id = $component->getTableId();
543 static fn (
$id):
string =>
544 "$(document).on('$show', function() { il.UI.table.presentation.get('$table_id').expandRow('$id'); return false; });" .
545 "$(document).on('$close', function() { il.UI.table.presentation.get('$table_id').collapseRow('$id'); return false; });" .
546 "$(document).on('$toggle', function() { il.UI.table.presentation.get('$table_id').toggleRow('$id'); return false; });"
556 Component\Table\PresentationRow::class,
557 Component\Table\Presentation::class,
558 Component\Table\Data::class,
559 Component\Table\DataRow::class
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Both the subject and the direction need to be specified when expressing an order.
The scope of this class is split ilias-conform URI's into components.
registerSignals(Component\Table\PresentationRow $component)
renderDataRow(Component\Table\DataRow $component, RendererInterface $default_renderer)
getAsyncActionHandler(Component\Signal $action_signal)
getComponentInterfaceName()
Get the name of the component-interface this renderer is supposed to render.ATTENTION: Fully qualifie...
getMultiActionHandler(Component\Signal $action_signal)
getActionRegistration(string $action_id, Action $action)
buildMultiActionsAllObjectsModal(array $actions, string $table_id)
renderPresentationRow(Component\Table\PresentationRow $component, RendererInterface $default_renderer)
renderPresentationTable(Component\Table\Presentation $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.
getSingleActionsForRow(string $row_id, array $actions)
render(Component\Component $component, RendererInterface $default_renderer)
renderTableHeader(RendererInterface $default_renderer, Component\Table\Data $component, Template $tpl, ?Component\Signal $sortation_signal)
renderEmptyPresentationRow(Template $tpl, RendererInterface $default_renderer, string $content)
getSelectionHandler(Component\Signal $selection_signal)
appendTableRows(Template $tpl, \Generator $rows, RendererInterface $default_renderer)
renderDataTable(Component\Table\Data $component, RendererInterface $default_renderer)
registerResources(ResourceRegistry $registry)
Announce resources this renderer requires.
buildMultiActionsDropdown(array $actions, Component\Signal $action_signal, Component\Signal $modal_signal)
Base class for all component renderers.
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.
checkComponent(Component $component)
Check if a given component fits this renderer and throw \LogicError if that is not the case.
getTemplate(string $name, bool $purge_unfilled_vars, bool $purge_unused_blocks)
Get template of component this renderer is made for.
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This describes commonalities between all types of Dropdowns.
Interface to be extended by components that have the possibility to bind to Javascript.
withAdditionalOnLoadCode(Closure $binder)
Add some onload-code to the component instead of replacing the existing one.
Registry for resources required by rendered output like Javascript or CSS.
register(string $name)
Add a dependency.
Interface to templating as it is used in the UI framework.
An entity that renders components to a string output.
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ChatMainBarProvider \MainMenu\Provider.