Ich habe ein Feldset im Admin-Bereich mit einer übergeordneten Auswahl (hat 5 Optionen) und 2 Feldern , die angezeigt werden sollten, falls die übergeordnete Wertauswahl 3, 4 oder 5 sein soll. Ich habe die Beispiele für eine ähnliche Logik in Magento nicht gefunden und versuchte, analog mit der üblichen Abhängigkeit zu schreiben, aber es funktioniert nicht. In meinem Beispiel werden die abhängigen Felder nur angezeigt, wenn Sie die Optionen mit dem Wert 5 aus der Auswahl auswählen. Sie werden nicht angezeigt, wenn Sie 1, 2, 3 oder 4 auswählen.
Vollständiger Code (Blockbeispiel):
<?php
namespace Siarhey\Test\Block\Adminhtml\Promo\Quote\Edit\Tab;
class Actions extends \Magento\Backend\Block\Widget\Form\Generic implements
\Magento\Backend\Block\Widget\Tab\TabInterface
{
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Data\FormFactory $formFactory
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Data\FormFactory $formFactory,
array $data = []
) {
parent::__construct($context, $registry, $formFactory, $data);
}
public function getTabLabel()
{
return __('Actions');
}
public function getTabTitle()
{
return __('Actions');
}
public function canShowTab()
{
return true;
}
public function isHidden()
{
return false;
}
protected function _prepareForm()
{
$model = $this->_coreRegistry->registry('current_promo_quote_rule');
/** @var \Magento\Framework\Data\Form $form */
$form = $this->_formFactory->create();
$form->setHtmlIdPrefix('rule_');
$fieldset = $form->addFieldset(
'action_fieldset',
['legend' => __('Rules')]
);
$parentField = $fieldset->addField(
'simple_action',
'select',
[
'label' => __('Apply'),
'name' => 'simple_action',
'options' => [
1 => __('Amount 1'),
2 => __('Discount 1'),
3 => __('Amount 2'),
4 => __('Discount 2'),
]
]
);
$childFieldOne = $fieldset->addField(
'amount',
'text',
[
'name' => 'amount',
'required' => true,
'class' => 'validate-not-negative-number',
'label' => __('Amount')
]
);
$model->setAmount($model->getAmount() * 1);
$childFieldTwo = $fieldset->addField(
'percent',
'text',
['name' => 'percent', 'label' => __('Percent')]
);
$model->setPercent($model->getPercent() * 1);
$this->setChild(
'form_after',
$this->getLayout()->createBlock(
'Magento\Backend\Block\Widget\Form\Element\Dependence'
)->addFieldMap(
$parentField->getHtmlId(),
$parentField->getName()
)->addFieldMap(
$childFieldOne->getHtmlId(),
$childFieldOne->getName()
)->addFieldMap(
$childFieldTwo->getHtmlId(),
$childFieldTwo->getName()
)->addFieldDependence(
$childFieldOne->getName(),
$parentField->getName(),
'1,3'
)->addFieldDependence(
$childFieldTwo->getName(),
$parentField->getName(),
'2,4'
)
);
$form->setValues($model->getData());
if ($model->isReadonly()) {
foreach ($fieldset->getElements() as $element) {
$element->setReadonly(true, true);
}
}
$this->setForm($form);
return parent::_prepareForm();
}
}
Ergebnis (Ansicht):
Codebeispiel 1 (funktioniert nicht):
/*
* $parentField is select with values (0,1,2,3,4,5)
*/
$this->setChild(
'form_after',
$this->getLayout()->createBlock(
'Magento\Backend\Block\Widget\Form\Element\Dependence'
)->addFieldMap(
$parentField->getHtmlId(),
$parentField->getName()
)->addFieldMap(
$childFieldOne->getHtmlId(),
$childFieldOne->getName()
)->addFieldDependence(
$childFieldOne->getName(),
$parentField->getName(),
'3'
)->addFieldDependence(
$childFieldOne->getName(),
$parentField->getName(),
'4'
)->addFieldDependence(
$childFieldOne->getName(),
$parentField->getName(),
'5'
)->addFieldMap(
$parentField->getHtmlId(),
$parentField->getName()
)->addFieldMap(
$childFieldTwo->getHtmlId(),
$childFieldTwo->getName()
)->addFieldDependence(
$childFieldTwo->getName(),
$parentField->getName(),
'3'
)->addFieldDependence(
$childFieldTwo->getName(),
$parentField->getName(),
'4'
)->addFieldDependence(
$childFieldTwo->getName(),
$parentField->getName(),
'5'
)
);
Codebeispiel 2 (funktioniert nicht):
/*
* $parentField is select with values (0,1,2,3,4,5)
*/
$this->setChild(
'form_after',
$this->getLayout()->createBlock(
'Magento\Backend\Block\Widget\Form\Element\Dependence'
)->addFieldMap(
$parentField->getHtmlId(),
$parentField->getName()
)->addFieldMap(
$childFieldOne->getHtmlId(),
$childFieldOne->getName()
)->addFieldMap(
$parentField->getHtmlId(),
$parentField->getName()
)->addFieldMap(
$childFieldTwo->getHtmlId(),
$childFieldTwo->getName()
)->addFieldDependence(
$childFieldOne->getName(),
$parentField->getName(),
array('3', '4', '5')
)->addFieldDependence(
$childFieldTwo->getName(),
$parentField->getName(),
array('3', '4', '5')
)
);
Ergebnis:
Hinweis: Konvertierung von Array in Zeichenfolge in /var/www/magento2/app/code/Magento/Backend/Block/Widget/Form/Element/Dependence.php in Zeile 95
AKTUALISIEREN:
Codebeispiel 3 (funktioniert nicht, wenn der ausgewählte Wert nicht ist
'3,4,5'
):
// Parent field
$typeField = $fieldset->addField(
'action_type',
'select',
[
'label' => __('Type'),
'name' => 'action_type',
'options' => ['1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '3,4,5' => '3,4,5']
]
);
$this->setChild(
'form_after',
$this->getLayout()->createBlock(
'Magento\Backend\Block\Widget\Form\Element\Dependence'
)->addFieldMap(
$parentField->getHtmlId(),
$parentField->getName()
)->addFieldMap(
$childFieldOne->getHtmlId(),
$childFieldOne->getName()
)->addFieldMap(
$typeField->getHtmlId(),
$typeField->getName()
)->addFieldMap(
$childFieldTwo->getHtmlId(),
$childFieldTwo->getName()
)->addFieldDependence(
$childFieldOne->getName(),
$parentField->getName(),
'3,4,5'
)->addFieldDependence(
$childFieldTwo->getName(),
$parentField->getName(),
'3,4,5'
)
);
Hat sich jemand dem gleichen Problem gestellt und eine Lösung gefunden?
Aktualisieren:
Vielleicht kann jemand anderes das Vorhandensein dieses Problems überprüfen? Ich habe es bei 3 verschiedenen Installationen überprüft und diese Lösung (die Zeile mit den durch Koma getrennten Werten) funktioniert immer noch nicht.
quelle
Antworten:
Wenn Sie den Code überprüfen, der für das Hinzufügen der entsprechenden Felder gemäß den Abhängigkeiten in der Datei verantwortlich ist
lib/web/mage/adminhtml/form.js
, wird dort das folgende Schema angezeigt:Wenn Sie durch Kommas getrennte Werte festlegen, zum Beispiel:
Während des Debuggens sehen Sie dann, dass
indexOf
versucht wird, den vorhandenen Wert im Ein-Element-Array zu finden, das in Ihrem Fall ein durch Kommas getrennter Wert ist. Dieses Element kann nicht gefunden werden:Eine schrittweise Ausgabe
console.log
der Methode:Um Felder mit mehreren Abhängigkeiten zu erstellen, können Sie denselben durch Komas getrennten Wert verwenden, jedoch mit einigen Änderungen. Sie benötigen nur den Block, der erweitert wird
\Magento\Backend\Block\Widget\Form\Element\Dependence
:Wie Sie sehen können, wird der Wert gezwungen, in ein Array mit einem Wert geändert zu werden.
Das Hauptproblem liegt in
addFieldDependence
der Klasse\Magento\Backend\Block\Widget\Form\Element\Dependence
:Der Punkt ist, dass der Wert (die Linie aus der Abhängigkeit) als einziges Element des Arrays übertragen wird.
indexOf
versucht, den Wert der entsprechenden ausgewählten Option zu finden, findet jedoch keine genaue Übereinstimmung. Infolgedessen wird "false" zurückgegeben.Es gibt auch keine Möglichkeit, die Werte als Array zu übertragen, da PHP die Werte
Notice: Array to string conversion
aufgrund der Konvertierung von zurückgibt'value' => (string)$refField
.In unserem Beispiel haben wir das Ein-Element-Array in ein Mehr-Element-Array umgewandelt, wobei jedes Element aus mehreren Abhängigkeiten besteht.
Der Code Ihrer Abhängigkeit sollte geändert werden (Sie müssen den Block ändern). So geht's:
Das Ergebnis sollte folgendermaßen aussehen:
UPD
Wenn Sie sicher sind, dass Sie in Zukunft einen durch Kommas getrennten Wert verwenden werden, fügen Sie
UNIQUE_DELIMITER
der Klasse am besten die Konstante mit dem erforderlichen Wert des Trennzeichens hinzuVendor\Module\Block\Widget\Form\Element\Dependence
: ZBÄndern Sie als Nächstes die Partitionsmethode:
Dann verwenden Sie
Vendor\Module\Block\Widget\Form\Element\Dependence::UNIQUE_DELIMITER
in Ihrer KlasseActions
.Fügen Sie zur Vereinfachung die Klasse hinzu
Dependence
(nach dem Namespace):Und schreiben Sie den Code folgendermaßen:
quelle
Ich kann mich irren, aber leider glaube ich nicht, dass Sie mit der Standardklasse können
Magento\Backend\Block\Widget\Form\Element\Dependence
.Lassen Sie mich erklären:
Die
addFieldDependence
Methode sieht folgendermaßen aus:Angenommen, Sie versuchen diesen Code:
Die
value
von der$refField
wird die folgende Zeichenfolge sein:2,4
so wie es kein solcher Wert in Ihrer Auswahl ist es wird nie funktionieren.Wenn Sie diesen Code versuchen:
Sie erhalten den
Array to string conversion
Fehler aufgrund des(string)$refField
CodesWenn Sie diesen Code versuchen:
Beim ersten Aufruf wird
$refField
der Wert auf 2 gesetzt und mit dem folgenden Code den Abhängigkeiten zugewiesen:Der zweite Code überschreibt diese Abhängigkeit jedoch, da die Variablen
$fieldName
und$fieldNameFrom
die gleichen sind wie beim ersten Aufruf.Welche Lösungen haben Sie?
Magento\Backend\Block\Widget\Form\Element\Dependence
Klasse zu ändernDie wichtigen Methoden, die hier zu betrachten sind, sind
addFieldDependence
und_getDependsJson
. Das Problem hierbei ist, dass es viele Möglichkeiten gibt, dass Sie auch die JavaScript-FormElementDependenceController
Klasse ändern müssen , die die Abhängigkeiten behandelt.Beispiel:
Dann benutze:
Das Problem hierbei ist, dass Sie dem Controller, der die Daten verarbeitet, mehrere Überprüfungen hinzufügen müssen, um sicherzustellen, dass Sie die richtigen Daten und nicht das versteckte Kopierfeld verarbeiten.
quelle
Form\Element\Dependence
Block?Form\Element\Dependence
die Art und Weise, wie es gemacht werden sollte. Das Problem ist, dass die Entwicklung einer solchen Funktion möglicherweise lange dauert, da Sie mit vielen verschiedenen Dateien arbeiten müssen. Die Lösung für mehrere Felder ist schmutziger, aber ich bin mir ziemlich sicher, dass Sie mit dieser Methode schnell das bekommen, was Sie wollen, und es wird funktionieren, ohne dass irgendetwasIch denke, dass Sie Klasse aussehen sollten
Magento\Backend\Block\Widget\Form\Element\Dependence
. Sie können Ihren eigenen Block erstellen, der von dieser Klasse geerbt wurde, und ihn nach Ihren Wünschen umschreiben. In Ihrem Code ersetzt Blockaufruf:zu:
Erstellen Sie einen Block,
Siarhey\Test\Block\Widget\Form\Element\Dependence
und Sie können darin Ihre Überprüfungslogik implementieren.Es ist nur ein Rat. Ich hoffe es hilft dir.
quelle
Erstellen Sie eine di.xml unter adminhtml und fügen Sie folgenden Code hinzu:
Jetzt können Sie folgenden Weg verwenden.
Leeren Sie den Magento2-Cache.
quelle
Ich bin mir nicht sicher, ich habe es nicht getestet, aber wenn ich mir die
addFieldDependence
Methode und den\Magento\Config\Model\Config\Structure\Element\Dependency\Field
Unterricht anschaue, denke ich, dass es funktionieren könnte.Fügen Sie dies in Ihre Klasse ein:
Dann statt
Versuche dies:
quelle
Definieren
$this->_fieldFactory
und versuchen Sie es unter einem, es funktioniert für mich:quelle