Profile 2 feat. hook_form_alter i #states

Opublikowano // Twój komentarz
Przypadek:
Masz formularz rejestracji użytkownika stworzony z poziomu modułu Profile2 w którym chcesz aby jakieś pole pojawiało się gdy np. wybrany checkbox zostanie zaznaczony.
Rozwiązaniem jest stworzenie własnego modułu z wykorzystaniem hook_form_alter i dodanie do wybranego pola atrybutu #states.

Problem:
Standardowo wystarczy podać samą nazwę pola które steruje widzialnością i wszystko gra. Jednak w przypadku Profile2 to nie zadziałało i nie mogłem pojąć dlaczego... .

Rozwiązanie:
Otóż okazało się, że wszystkiemu winna była źle podawana nazwa pola sterującego, która powinna wyglądać mniej więcej tak:
profile_nazwaprofilu[field_nazwapola][jezyk][parametr_value_pola]
a w praktyce najlepiej użyć Firebuga, zaznaczyć pole  i skopiować wartość jego atrybutu name :)

Oto przykładowy kod:


/**
 * Implements hook_form_alter().
 */
function testmodul_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'user_register_form') {
$form['profile_fadehelix']['field_inne_opcje']['#states'] = array(
'visible' => array(':input[name="profile_fadehelix[field_opcje][und][inne]"]' => array('checked' => TRUE)),
);
return $form;
}
}

* field_inne_opcje to pole tekstowe które ma się pojawić po zaznaczeniu checkboxa field_opcje[und][inne]

"Waga" modułów w Drupal 7

Opublikowano // Twój komentarz
Problem:
Potrzebujesz aby Twój  moduł wywoływał hook_form_alter jako ostatni - ma operować na formularzu już gotowym, przetworzonym przez wszystkie inne moduły.

Rozwiązaniem jest ustawienie kolejności wywołań danego hooka.
w D6 dało się to zrobić edytując bazę danych, co nie było zbyt elastycznym i eleganckim rozwiązaniem. Na szczęście w D7 stworzono hook_module_implements_alter który pozwala na kontrolę kolejności wywołań danego hooka przez określone przez programistę  moduły.
W najprostszej wersji wystarczy podać tylko nasz moduł i będzie on wtedy ustawiony na końcu kolejki.

Ponieważ sama dokumentacja hooka nie jest zbyt bogata polecam świetny tutorial na ten temat.

Rozwiązanie to działa w moim przypadku, gdzie musiałem wywołać hook_form_alter()  swojego modułu  po tym jak  Profile2 dodał swoje pola do formularza rejestracji użytkownika.


/**
* Implements hook_module_implements_alter()
*/
function alter_register_worker_module_implements_alter(&$implementations, $hook) {
  //Any change here requires Caches to be cleared.
//dpm($implementations);
  switch ($hook) {
    case 'form_alter':
      $m1 = $implementations['mojmodul'];
      unset($implementations['mojmodul']);

      $implementations['mojmodul'] = $m1;
      break;
  }
//dpm($implementations);
}



Jeśli odkomentujesz funkcje dpm() wyswietli się kolejność modułów - przed i po naszej implementacji.