Puncte:0

Treci un filtru expus pe altul? (D9)

drapel pk

Am aproximativ o duzină de câmpuri de șir care conțin obiecte și stările acestora (de exemplu, să luăm „AC_on” și „heater_off”). Și am o vizualizare care arată noduri care conțin acele câmpuri. Sarcina pe care încerc să o îndeplinesc este aceasta. Un utilizator ar trebui să aibă două seturi de opțiuni pentru a filtra nodurile după câmpurile menționate mai sus:

  • Pentru a alege unul dintre obiecte prin intermediul butonului radio (AC sau încălzitor);
  • Pentru a alege stările în care opțiunea aleasă anterior ar trebui să fie în setul filtrat de noduri (doar „pornit”, sau doar „dezactivat”, sau „activat” și „dezactivat” - deci, evident, casete de selectare).

Nu este mare lucru să creați filtrele dorite din punct de vedere cosmetic: putem folosi filtrul de câmpuri combinate pentru setul de butoane radio (căutați prin toate câmpurile de obiect și dacă utilizatorul alege „AC”, filtrați toate valorile „AC_null”) și încă o dată - pentru casetele de selectare (pentru „On” includ acele valori care conțin „on” etc). Problema este că această abordare nu funcționează :) Al doilea set nu-i pasă ce obiect cu starea „off” îl filtrează.

Deci, m-am gândit că aș putea trece cumva orice a ales utilizatorul în partea radio (AC) în valorile filtrului casetei de selectare (deci nu ar căuta doar „on”, ci „AC_on”). Problema este că pentru viața mea nu găsesc un modul care să-mi permită să fac asta.

"Filtre dependente de vizualizări„pare doar instrumentul pentru muncă, dar, din păcate, este pentru D7 și am D9. Există vreo modalitate de a realiza acest lucru? Orice ajutor ar fi foarte apreciat.

PS Nu pot codifica, în afară de cele mai simple PHP one-liners și CSS, așa că soluția fără cod este de preferat.

misterdidi avatar
drapel de
Bună, bine ați venit la Drupal Answers. Poate ar trebui să aruncați o privire la acest tutorial https://bouteillenicolas.com/fr/blog-drupal/views-ajax-dynamic-dependent-exposed-filters. Deși este pentru D7, logica din spate rămâne aceeași pentru D9 (plus, hook_form_alter() încă există în D9). Mi-e teamă că nu poți scăpa de un pic de cod personalizat, totuși.
Basil Vlasyuk avatar
drapel pk
Salut @misterdidi! Mulțumesc. Am făcut deja pace că soluția fără cod nu există în acest caz. Mi-am creat propriul modul, dar ceea ce mă omoară este că, de cele mai multe ori, soluțiile de cod propuse pentru D8 nu funcționează pe D9 (și soluțiile D7 nu funcționează aproape niciodată). Deci, adaptarea lor necesită cunoștințele care îmi lipsesc. Acest articol pe care l-ați trimis arată exact ca lucrul de care am nevoie, îl voi verifica și voi reveni să spun dacă a funcționat. Multumesc din nou!
Puncte:1
drapel pk

Mulțumesc misterdidi pentru că m-a pus pe drumul cel bun. Articolul pe care l-ați oferit a ajutat, dar pentru a afla soluția, a trebuit să mai studiez câteva zeci și, în cele din urmă, a venit soluția.

Deci, pentru această sarcină, singura soluție sigură pe care am găsit-o este următoarea:

  1. Citiți orice se află în „Filtru radio”.
  2. Modificați „filtru de casetă de selectare”, astfel încât să conțină valoarea din „filtru radio” în fiecare opțiune.
  3. Îmbină toate „câmpurile de stare” într-un câmp cu mai multe valori, astfel încât să putem...
  4. Utilizați filtre contextuale pentru a citi valoarea „filtru casetă de selectare” din URL și căutați-o în câmpul nostru cu mai multe valori.

1. Citirea valorii din filtrul Radio

Am realizat asta cu views_pre_view cârlig:

funcția MY_MODULE_views_pre_view($view, $display_id, array &$args) {  
  // Verificați dacă este modul corect de vizualizare și afișare
  if ($view->id() == 'MY_VIEW') {
    comutator ($display_id) {
      cazul „MY_DISPLAY”:
        //Obțineți orice valoare se află în Radio Filter și scrieți-o în variabila globală
        $filter_input = $view->getExposedInput();
        global $arg;
        $arg= $filter_input['RADIO_FILTER'];
    }
  }
}

(Aici și înainte, totul în majuscule sunt numele pe care trebuie să le înlocuiți cu cele pe care le folosiți)

Cu acest cod, citesc ce este în filtrul radio și îl pun într-o variabilă globală $arg.

2. Introduceți valoarea din Filtru radio în Filtru casetă de selectare

Pentru aceasta parte am folosit form_views_exposed_form_alter cârlig:

funcția MY_MODULE_form_views_exposed_form_alter(&$form, $form_state, $form_id) {
  
  // Apelați variabila globală cu valoarea Radio Filter
  global $arg;
  
  // Convertim valoarea brută a filtrului radio în ceva ce putem folosi pentru filtrul contextual
  dacă ($arg == '1') {
    $arg= 'AC'; 
  }
  elseif ($arg == '2') {
    $arg= 'ÎNCĂLZIRE'; 
  }
  elseif ($arg == „Toate”) {
    $arg= ''; 
  }
  
  $arg_on = ($arg . '_on');
  $arg_off = ($arg . '_off');
  
  // Verificați dacă este forma corectă
  dacă ($form['#id'] == 'EXPOSED_FILTER_FORM_ID') {
    
    // Avem nevoie de valori diferite ale filtrului, în funcție de dacă este aleasă valoarea din Radio Filter sau dacă este setată la implicit ("Toate")
    dacă ($arg != '') {
    $form['CHECKBOX_FILTER']['#options'] = array(
      $arg_on => $arg_on,
      $arg_off => $arg_off,
      ); 
    }
    else {
      $form['CHECKBOX_FILTER']['#options'] = array(
      '_on' => '_on',
      '_off' => '_off', );
    }
    // Dacă nu se alege nimic, ar trebui să considerăm totul ales.
    dacă ($form['CHECKBOX_FILTER']['#value'] == '') {
      $form['CHECKBOX_FILTER']['#value'] = [$arg_on, $arg_off];
    }
  }
}

În acest fel modific valorile din Filtrul casetei de selectare. Acest lucru le face aproape inoperabile ca filtre expuse (nu sunt sigur de ce, dar în momentul în care formularul este modificat prin cârlig - nu mai filtrează nimic), dar oferă parametri URL, pe care îi vom folosi pentru filtre contextuale. .

3. Îmbinarea tuturor câmpurilor de parametri într-unul singur

Acesta este ceva pentru care mă așteptam să găsesc un modul, dar nu am reușit, deci hook_entity_presave este.

funcția MY_MODULE_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  
  // Aici pregătim variabile pentru fiecare câmp pe care vom avea nevoie pentru a îmbina...
  dacă ($entity->bundle() == 'MY_NODE_TYPE') {
    $par_ac = ($entity->field_AC_CHECK->value);
    $par_încălzitor = ($entitate->field_HEATER_CHECK->valoare);
    $par_all = ($par_ac . ',' . $par_heater);
  
    // ... și, de asemenea, verifică dacă există vreun „pornit” sau „dezactivat” printre ele...
    if (str_contains($par_all, 'on')) {
      $par_cont_on = '_on';
    }
    if (str_contains($par_all, 'off')) {
      $par_cont_off = '_off';
    }

    // ... pentru a le îmbina pe toate într-un singur câmp și a furniza valorile generale „pornit” și „dezactivat” pentru cazurile în care Filtrul radio nu este completat
    $entity->field_par_comb = [$par_ac, $par_heater, $par_cont_on, $par_cont_off];
  }
}

Nu sunt deosebit de mulțumit de faptul că câmpurile sunt codificate și nu sunt adunate dinamic, poate mai târziu mă voi gândi la o modalitate de a le decoda.

Dar, deocamdată, avem un câmp cu mai multe valori care conține o stare pentru fiecare parametru și, în sfârșit, putem...

4. Utilizați filtrul contextual

După cum am aflat la p. 2, filtrul de casetă de selectare expus nu face nimic atunci când este modificat. Dar îl putem face să verifice parametrul URL al unui filtru de casetă de selectare. În acest fel, dacă avem „checkbox_filter=heater_on”, filtrul contextual va căuta în câmpul nostru cu valori multiple de la p. 3 pentru valoarea „încălzitor_pornit”.

Deoarece Checkbox Filter poate conține mai multe valori, ar trebui să alegem conjuncția „SAU” în setările unui filtru.

Rețineți că filtrul radio ar trebui să fie „nu este necesar”. Se datorează faptului că, atunci când vizualizarea este încărcată pentru prima dată, valorile implicite ale filtrului expuse NU sunt afișate în parametrii URL, din anumite motive. Dar, deoarece valoarea implicită a filtrului radio este „Orice” (și ar trebui să o ascundem cu CSS prin :primul copil selector), în codul nostru există o parte care ține cont de acest caz prin înlocuirea valorii „Toate” filtrului radio cu „”. Și, deoarece avem valori speciale de verificare și „_on”/”_off” în câmpul nostru cu mai multe valori, va funcționa bine:

  • Dacă valoarea implicită „Orice” este aleasă în Radio Filter, codul nu va înlocui valorile Checkbox Filter.
  • În setările de vizualizare, valorile implicite ale filtrului casetei de selectare sunt setate la „_on” și „_off”, iar filtrul este operabil.
  • Când utilizatorul alege „AC”, „Încălzire” sau orice altă opțiune din Filtrul radio, acesta este introdus în valorile Filtrului casetei de selectare modificate și se activează Filtrul contextual.

Acesta a fost un caz al naibii pentru prima experiență de dezvoltare a modulelor Drupal, dar funcționează impecabil. Clientul este fericit, eu sunt fericit.

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.