Puncte:1

Validare pe formularul de modificare a entității personalizate

drapel lc

Am o entitate personalizată în care, în loc să folosesc modul obișnuit de a specifica opțiunile de formular de editare setDisplayOptions('form' și bazându-se pe ContentEntityForm pentru a-mi crea formularul de editare pentru mine, trebuie să-mi creez propriul formular în buildForm() (Am interacțiuni Ajax între câmpurile pe care stocul de la nu le poate furniza). Funcționează bine, doar că nu pot declanșa validarea ca în cazul formularului de stoc. Constrângerile sunt acolo și dacă depășesc:

funcția publică validateForm(matrice &$form, FormStateInterface $form_state) {
  $entity = parent::validateForm($form, $form_state);
  $încălcări = $entity->validate();
  foreach ($încălcări ca $v) {
    dpm($v->getMessage());
  }
  returnează $entitate;
}

erorile de validare sunt de fapt găsite și listate, doar că formularul nu va afișa avertismentele roșii obișnuite, împiedicând utilizatorul să continue. Pot reconcilia construirea formularului personalizat cu validarea automată?

Puncte:0
drapel us

Entitatea User este una dintre entitățile de bază Drupal care adaugă în mod programatic elemente de formular în clasa lor de formular de entitate și încă folosește constrângeri de validare.
AccountForm::form() adaugă elementele de formă și Utilizator::baseFieldDefinitions() adaugă constrângerile de validare la câmpurile de entitate.
(Formular cont este clasa extinsă de Formular de profil si Formular de înregistrare clase, care sunt două dintre cele trei clase de formulare de entitate utilizate pentru entitatea Utilizator.)

  // Informatii despre cont.
  $form['cont'] = [
    '#type' => 'container',
    '#weight' => -10,
  ];

  // Câmpul de e-mail NU este obligatoriu dacă contul inițial nu avea set de e-mailuri
  // iar utilizatorul care efectuează editarea are permisiunea de „administrare utilizatori”.
  // Acest lucru permite utilizatorilor fără adresă de e-mail să fie editați și șterse.
  // Vedeți și \Drupal\user\Plugin\Validation\Constraint\UserMailRequired.
  $form['account']['mail'] = [
    '#type' => 'e-mail',
    '#title' => $this->t('Adresa de e-mail'),
    '#description' => $this->t('O adresă de e-mail validă. Toate e-mailurile din sistem vor fi trimise la această adresă. Adresa de e-mail nu este făcută publică și va fi folosită numai dacă doriți să primiți o nouă parolă sau doriți să primiți anumite știri sau notificări prin e-mail.'),
    '#required' => !(!$account->getEmail() && $user->hasPermission('administer users')),
    '#default_value' => !$register ? $account->getEmail(): '',
  ];

  // Afișează numai câmpul de nume în formularul de înregistrare sau utilizatorul își poate schimba propriul nume de utilizator.
  $form['cont']['nume'] = [
    '#type' => 'câmp text',
    '#title' => $this->t('Nume de utilizator'),
    '#maxlength' => UserInterface::USERNAME_MAX_LENGTH,
    '#description' => $this->t("Sunt permise mai multe caractere speciale, inclusiv spațiu, punct (.), cratima (-), apostrof ('), liniuță de subliniere (_) și semnul @."),
    '#required' => TRUE,
    '#attributes' => [
      'clasa' => [
        'nume de utilizator',
      ],
      'autocorrect' => 'dezactivat',
      'autocapitalize' => 'dezactivat',
      'spellcheck' => 'fals',
    ],
    '#default_value' => !$register ? $account->getAccountName(): '',
    '#access' => $cont->nume->access('editare'),
  ];
  $fields['nume'] = BaseFieldDefinition::create('șir')
    ->setLabel(t('Nume'))
    ->setDescription(t('Numele acestui utilizator.'))
    ->setRequired(TRUE)
    ->setConstraints([
    // Nicio constrângere Length aici deoarece constrângerea UserName acoperă și
    // acea.
    „UserName” => [],
    „UserNameUnique” => [],
  ]);
  $fields['nume']
    ->getItemDefinition()
    ->setClass('\Drupal\user\UserNameItem');
  $fields['pass'] = BaseFieldDefinition::create('parolă')
    ->setLabel(t('Parola'))
    ->setDescription(t('Parola acestui utilizator (hashed).'))
    ->addConstraint('ProtectedUserField');

The Formular cont, ProfileForm și Formular de înregistrare clase, care extind [ContentEntityForm][6] clasa, nu extinde [ContentEntityForm::validateForm()][7], totuși. Ei implementează metode care sunt necesare pentru Drupal pentru a înțelege ce câmpuri de entitate sunt editate și ce încălcări ar trebui afișate: [AccountForm::getEditedFieldNames()][8] și [AccountForm::flagViolations()`]6.

funcția protejată getEditedFieldNames(FormStateInterface $form_state) {
  returnează array_merge([
    'Nume',
    'trece',
    'Poștă',
    'fus orar',
    „langcode”,
    „preferred_langcode”,
    „preferred_admin_langcode”,
  ], parent::getEditedFieldNames($form_state));
}
funcția protejată flagViolations(EntityConstraintViolationListInterface $încălcări, matrice $form, FormStateInterface $form_state) {
  // Semnalează manual încălcările câmpurilor care nu sunt gestionate de afișarea formularului. Acest
  // este necesar, deoarece formularul de entitate afișează doar încălcările de semnalizare pentru câmpuri
  // conținut în afișaj.
  $field_names = [
    'Nume',
    'trece',
    'Poștă',
    'fus orar',
    „langcode”,
    „preferred_langcode”,
    „preferred_admin_langcode”,
  ];
  foreach ($violations->getByFields($field_names) ca $violation) {
    list($field_name) = explode('.', $violation->getPropertyPath(), 2);
    $form_state->setErrorByName($field_name, $violation->getMessage());
  }
  parent::flagViolations($încălcări, $form, $form_state);
}

ContentEntityForm::validateForm() afișează numai erorile de validare pentru acele elemente de formular care sunt raportate a fi editate. Aceasta înseamnă că, dacă numele unui element de formular nu este returnat de la AccountForm::getEditedFieldNames() sau ContentEntityForm::getEditedFieldNames(), acel element de formular și câmpul de entitate corespunzător nu sunt considerate editate.

Pentru a răspunde la întrebare: Da, este posibil să adăugați elemente de formular în formă() metoda clasei de formulare de entitate și utilizează constrângeri de validare (și validarea lor „automată”), atâta timp cât clasa de formulare de entitate implementează getEditedFieldNames() și flagViolations() metode.

drapel lc
Foarte frumos, mulțumesc, voi merge pe acest traseu.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.