Closed christophboecker closed 1 year ago
Würde das auch das Kopieren von Datensätzen mit Relationen ermöglichen?
Ich bin da sehr zuversichtlich. Bei 1-n inline nutze ich es intensiv ohne Probleme. Bei den normalen Varianten 1 bis 4 (select/popup) sollte es für kein 1-n-Relationeneh kein Problem geben, denn die haben ja keine Relationen-Tabelle. Bei n-m-Relationen via Relationentabelle bin ich mir nicht sicher; ich meine es mal ausprobiert zu haben. Vermutung: ja
Wenn ich das so eingebe wie von Dir hier beschrieben bekomme ich:
Too few arguments to function Dataset::YFORM_DATA_LIST(), 0 passed in …and exactly 1 expected
Das passiert wenn ich rex_extension::register('rex_extension_point', Dataset::YFORM_DATA_LIST())
; einsetze.
Es gibt bereits 2 Tricks in diese Richtung. Vielleicht machen wir aus diesen drei einen Trick mit allen möglichen Varianten oder besser noch einen PR für YForm selbst?
Wenn ich das so eingebe wie von Dir hier beschrieben bekomme ich: ...
Danke für den Hinweis, hab es geändert.
rex_extension::register('YFORM_DATA_LIST', 'Dataset::YFORM_DATA_LIST');
GETESTET UND SUPER GEIL. @tbaddade ich würde diese Lösung favorisieren. 1-n Relationen wurden übernommen. Klasse. @christophboecker PR für YForm wäre super und das Klonen bitte in das Dropdown.
Habe gleichzeitig das Yform_usability angehabt. Dabei verschwand mal das Prio-Feld oder plötzlich gab es wieder den Bleistift zu sehen.
Super coooll! DANKE!
Ich hab einen leicht anderen Ansatz über einen Trait gewählt. Das hat den Vorteil, dass man den Trait einfach bei den Model-Klassen hinzufügen kann und keine abgeleiteten Klassen braucht.
<?php
namespace Project\Trait;
use rex_i18n
, rex_yform
, rex_yform_value_submit
, rex_yform_value_be_manager_relation;
trait Clonable
{
/**
* @param null|callable(rex_yform):void $afterFieldsExecuted
*/
public
function executeForm(rex_yform $yform, callable $afterFieldsExecuted = null): string
{
// clone angefordert? Wenn nein: normale Bearbeitung
if (1 !== rex_request('clone', 'integer', 0)) {
return parent::executeForm($yform, $afterFieldsExecuted);
}
// clone angefordert! afterFieldsExecuted wird durch ein eigenes Callback ersetzt,
$callback = function (rex_yform $yform) use ($afterFieldsExecuted) {
// Titelzeile frisieren: mangels EP wird die i18n-Tabelle geändert.
rex_i18n::addMsg('yform_editdata', 'Datensatz klonen [Original: {0}]');
// Für das Formular an sich: Auf "Add" umschalten, indem func auf "add" gesetzt und
// die Datensatznummer entfernt wird.
$yform->objparams['form_hiddenfields']['func'] = 'add';
unset($yform->objparams['form_hiddenfields']['data_id']);
// Änderungen in den Values: jeweils den vorgenerierten HTML-Code ändern
foreach ($yform->objparams['values'] as $k => $v) {
// Submit-Buttons von "Edit" auf "Add" zurückstellen
if ($v instanceof rex_yform_value_submit) {
$yform->objparams['form_output'][$k] = str_replace(
[rex_i18n::msg('yform_save') . '</button', rex_i18n::msg('yform_save_apply') . '</button'],
[rex_i18n::msg('yform_add') . '</button', rex_i18n::msg('yform_add_apply') . '</button'],
$yform->objparams['form_output'][$k]
);
continue;
}
// im Feldtyp be_manager_relation / Typ 5 (=inline) ebenfalls die hidden-inputs mit
// der Datensatz-ID der verbundenen Sätze entfernen
// Nur "inline" ist problematisch;
if ($v instanceof rex_yform_value_be_manager_relation && 5 == $v->getElement('type')) {
$fieldName = preg_quote($v->getFieldName());
$pattern = '/<input type="hidden" name="' . $fieldName . '(\[\d+\])*\[id\]" value="\d+" \/>/';
$yform->objparams['form_output'][$k] = preg_replace($pattern, '', $yform->objparams['form_output'][$k]);
}
}
call_user_func($afterFieldsExecuted, $yform);
};
return parent::executeForm($yform, $callback);
}
}
project/boot.php
\rex_extension::register('YFORM_DATA_LIST', function (\rex_extension_point $ep) {
/** @var \rex_list $list */
$list = $ep->getSubject();
if (rex_get('rex_yform_manager_opener', 'bool')) {
return $list;
}
// clone link
if ($className = \rex_yform_manager_dataset::getModelClass($ep->getParam('table')->getTableName())
and in_array(Clonable::class, class_uses($className))) {
$name = $list->getColumnNames()[0];
if (str_contains($name, 'href="index.php?func=add')) {
$list->addColumn('clone', '<i class="rex-icon rex-icon-duplicate"></i>', 1);
$list->setColumnLayout('clone', ['<th></th>', '<td class="rex-table-icon">###VALUE###</td>']);
$params = $list->getColumnParams($name);
$params['clone'] = 1;
$list->setColumnParams('clone', $params);
}
}
return $list;
});
Model-Klasse
<?php
namespace Project\Model;
use Project\Trait\Clonable;
class ModelClass extends \rex_yform_manager_dataset
{
use Clonable;
}
@xong Was passiert denn, wenn ich in der Klasse ModelClass
die Methode executeForm
erweitern will? Kann man das; ich dachte bisher, dass das zu Konflikten führt?
Dann müsstest du den Trait anders einbinden:
use Clonable {
executeForm as cloneExecuteForm;
}
public function executeForm(rex_yform $yform, callable $afterFieldsExecuted = null): string
{
return $this->cloneExecuteForm($yform, $afterFieldsExecuted);
}
Hab ich aber nicht getestet. Wollte hier nur mal meinen Weg darstellen.
Es gibt bereits 2 Tricks in diese Richtung.
@tbaddade Hast natürlich recht. Und einer der beiden ist ziemlich genau diese Lösung - kein Wunder, ist ja von mir. Autsch. Ich hab auch sofort das New-Trick-Label entfernt.
Aber hier hast du es einfacher erklärt @christophboecker :-)
Was wir vermeiden sollten, dass zum Schluss vier Tricks auf der Seite sind und keiner weiß welchen er nehmen soll.
PR für YForm wäre super
Wenn das so einfach wäre, ich hab´s mal probiert, aber das ist mir insgesamt zu heikel.
das Klonen bitte in das Dropdown.
In der neuen Version #311 ist es so gebaut, dass man beide Varianten wählen kann. Al Gusto
Habe gleichzeitig das Yform_usability angehabt. Dabei verschwand mal das Prio-Feld oder plötzlich gab es wieder den Bleistift zu sehen.
Hm, könnte mit fest verdrahteten Spaltennummer zu tun haben (0 = Edit, 1 = Clone). Baue ich aber nix für ein
Ziel: einen Datensatz per Button in der Liste aufrufen und beim Speichern als neuen Satz ablegen.
Der Lösungsweg:
Speichert man das Formular ab, wird es wie ein neuer Datensatz behandelt. Bendet man ohne zu speichern gibt es keine Reste in der Tabelle.
Wir packen alle Komponenten in einen eigenen rex_yform_manager_dataset:
Die Tabelle wird mit der eigenen Dataset-Klasse verbunden:
Und der Klon-Button wird per EP in die Tabelle eingefügt: