Puncte:0

Câmpul de referință al entității widget ascuns sau editare dezactivată în formularul personalizat

drapel in

Am un formular personalizat de creare a nodurilor pe care îl redau într-un cârlig de preprocesare a vizualizărilor. În acest formular am două câmpuri de referință pentru entități. Setez [#value] și [#default_value] acelor câmpuri de referință în mod programatic.

Pe formularul de trimitere sunt create valorile pe care le-am stabilit, dar numai dacă câmpurile sunt „editabile” de către utilizator. Vreau să fac câmpurile „dezactivate” și/sau „ascunse” pentru utilizator. Nu doar ascuns cu CSS, ci cu întregul widget de completare automată fiind inaccesibil. Câmpul trebuie să fie de tip „ascuns”.

Cum pot face ca o referință de entitate de completare automată să fie dezactivată și/sau inaccesibilă pentru utilizatorul care creează conținutul?

Sau un alt mod de a spune, cum pot adăuga valorile de referință ale entității în mod programatic la trimiterea formularului fără ca utilizatorul să poată interacționa cu câmpurile?

Iată câteva lucruri pe care le-am încercat și care nu funcționează:

  1. $form['field_entity_reference']['#access'] = false; // Setarea #access la false pare că ar trebui să funcționeze, deoarece câmpurile formularului încă există la depanarea $form, dar nu funcționează deoarece împiedică trimiterea valorii.
  2. Adăugarea ['#attributes']['readonly'], schimbarea ['#type'] la ascuns sau alt tip de widget, adăugarea ['#attributed']['disabled']. Niciunul nu funcționează
  3. Prepopulare entitate - Acest lucru nu funcționează pentru această situație particulară, deoarece unele valori nu pot fi furnizate de jetoane

Cod pentru referință

funcția <temă>_preprocess_views_view_field(&$variabile) {
  $view = $variables['view'];
  
  if ($view->id() == '<view>') {
    $câmp = $variabile['câmp'];

    comutare($câmp->opțiuni['id']) {
      caz „<view_field>”:
        $nod = \Drupal::entityTypeManager()
          ->getStorage('nodul')
          ->create(['tip' => '<tip_nod>']);
        $form = \Drupal::service('entity.form_builder')->getForm($node, 'secundar');

        // Setați valoarea și valoarea implicită
        $form['field_entity_reference']['widget']['#default_value'] = (int)$cid; // Rețineți că se utilizează widgetul „listă de selectare” pentru câmpul de referință al entității
        $form['field_entity_reference']['widget']['#value'] = (int)$cid; // La fel ca mai sus

        // Lucruri care nu funcționează. Valorile nu se trimit decât dacă câmpul este editabil de către utilizator sau câmpul nu este ascuns/dezactivat
        $form['field_entity_reference']['#access'] = false; // Valoarea nu se trimite
        $form['field_entity_reference']['widget'][0]['#attributes']['readonly'] = 'numai citire'; // Nu face câmpul doar pentru citire
        $form['field_entity_reference']['widget'][0]['value']['#type'] = 'ascuns'; // Se pare că widgetul de completare automată și widgetul selectat nu au un tip „ascuns”.
        $form['field_entity_reference']['widget'][0]['target_id']['#type'] = 'textfield'; // Se pare că nu se poate schimba tipul în textfield

        // Schimbați ieșirea câmpului de vizualizare în formular
        $variabile['ieșire'] = $form;
      pauză;
    }
  }
}
Jaypan avatar
drapel de
Ce vrei să spui prin „formular de creare a nodurilor personalizate”?
drapel cn
Puteți seta valorile entităților în mod programatic în `hook_entity_presave()` în loc să setați `#value` în formularul în sine. Puteți folosi `hook_entity_presave()` chiar și atunci când câmpurile sunt ascunse sau utilizatorul nu are acces pentru a edita câmpurile.
Jaypan avatar
drapel de
Setați `#access` la `FALSE` pe un element de formular și nu va fi trimis în browser pentru a fi adus. Cu toate acestea, valoarea va fi procesată atunci când formularul este trimis, așa că atâta timp cât valoarea este prestabilită pe element fie în definiția formularului, fie într-un hook form_alter, valoarea poate fi transmisă.
Puncte:0
drapel in

Felicitari lui @Patrick Kenny pentru că m-a pus pe o cale viabilă cu hook_entity_presave(). Postez acest lucru ca „răspuns”, deoarece a oferit un mijloc de a realiza ceea ce aveam nevoie, dar încă cred că câmpului de referință al entității D8 îi lipsește un tip de widget „ascuns”. Poate un port de entityreference_hidden. Dacă cineva știe cum să realizeze asta în mod programatic, vă rugăm să distribuiți.

Iată cum am realizat ceea ce aveam nevoie.

  1. Creați un câmp întreg redundant pe tipul de conținut pentru a păstra valoarea care va fi aplicată câmpului de referință al entității o dată hook_entity_presave() aleargă.
  2. Setați câmpul întreg redundant să fie disponibil în formular, schimbați tipul câmpului la ascuns. Puteți folosi field_hidden modul pentru aceasta.
  3. În interiorul temei hook_preprocess_views_view_field() hook setează valoarea câmpului redundant la id-ul nodului țintă (vezi codul din întrebarea inițială pentru a înțelege ce vreau să spun aici). Rețineți că acest lucru este doar pentru exemplul meu, deoarece adaug formularul la un câmp specific pentru rândurile de vizualizări, dar ar putea fi aplicat în alte cârlige.
  4. Într-un modul personalizat, în interior hook_entity_presave() luați valoarea câmpului redundant și aplicați-o la câmpul de referință al entității înainte de a salva (vezi codul de mai jos)
function <modul>_entity_presave($entity) {
  if ($entity->getEntityType()->id() == 'nod') {
    if ($entity->bundle() == â<content_type>â) {
      // ----- Obține id-ul entității
      $eid = $entitate->nume_câmp_redundant->valoare;
      
      // ----- Setați câmpul entității target_value
      $entity->normal_entity_reference_field>target_id = $eid;
    }
  }
}

O notă laterală despre cârlige în interiorul <temă>.temă fişier

The hook_form_alter() cârlig când în interiorul <temă>.temă fișierul nu se aplică întotdeauna în modul/ordinea în care s-ar putea spera.

De exemplu punerea în aplicare [#ajax] la o acțiune de formular nu face acea formă capabilă ajax decât dacă hook-ul se află într-un modul (hook-urile pentru fișierele temă nu vor funcționa). Se pare că acest lucru se datorează faptului că aplicarea configurației necesare a formularului are loc înainte de a rula cârligele temei.

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.